From e0d270d5d50f05ce66d1b4f2d9daf2670992be8e Mon Sep 17 00:00:00 2001 From: aramos Date: Mon, 26 Jun 2023 11:38:02 -0400 Subject: [PATCH 01/59] [BACKLOG-37772] Scheduler plugin POC code changes. --- .../platform/web/servlet/JAXRSServlet.java | 1 + scheduler/pom.xml | 23 +++++++++++++++ .../quartz/EmbeddedQuartzSystemListener.java | 28 ++++++++++++++----- .../scheduler2/quartz/QuartzScheduler.java | 6 ++++ .../EmbeddedVersionCheckSystemListener.java | 22 ++++++++++++--- .../ws/DefaultSchedulerService.java | 6 ++++ .../http/api/resources/SchedulerResource.java | 7 +++-- .../resources/proxies/BlockStatusProxy.java | 0 .../resources/services/SchedulerService.java | 0 9 files changed, 80 insertions(+), 13 deletions(-) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java (99%) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java (100%) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java (100%) diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java index 8b1967569e3..12cb768eb41 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java @@ -181,6 +181,7 @@ protected Resource getResourceByPath( String path ) { String springFile = PentahoSystem.getApplicationContext() .getSolutionPath( "system" + File.separator + "pentahoServices.spring.xml" ); //$NON-NLS-1$ //$NON-NLS-2$ + //wac.setConfigLocations( new String[] { springFile, "/Users/aramos/Documents/Hitachi/REPOS/BUILDS/pentaho-server/pentaho-solutions/system/scheduler-plugin/plugin.spring.xml" } ); wac.setConfigLocations( new String[] { springFile } ); wac.addBeanFactoryPostProcessor( new PentahoBeanScopeValidatorPostProcessor() ); wac.refresh(); diff --git a/scheduler/pom.xml b/scheduler/pom.xml index 237eef6ea51..01e59f13e41 100644 --- a/scheduler/pom.xml +++ b/scheduler/pom.xml @@ -184,6 +184,29 @@ ${hamcrest-core.version} test + + org.codehaus.enunciate + enunciate-jersey-rt + ${enunciate-jersey-rt.version} + compile + + + com.sun.xml.bind + jaxb-impl + + + org.codehaus.jackson + jackson-mapper-asl + + + + + + pentaho + pentaho-platform-extensions + 9.6.0.0-SNAPSHOT + compile + diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java index c64f117f73b..700afb24373 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java @@ -38,16 +38,15 @@ import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.data.DBDatasourceServiceException; import org.pentaho.platform.api.data.IDBDatasourceService; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.engine.ObjectFactoryException; +import org.pentaho.platform.api.engine.*; import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; import org.pentaho.platform.scheduler2.messsages.Messages; import org.quartz.SchedulerException; -public class EmbeddedQuartzSystemListener implements IPentahoSystemListener { +public class EmbeddedQuartzSystemListener implements IPluginLifecycleListener { /* * This is re-use by Copy and Paste to avoid a dependency on the bi-platform-scheduler project (which will eventually @@ -76,7 +75,19 @@ public synchronized void setUseNewDatasourceService( boolean useNewService ) { useNewDatasourceService = useNewService; } - public boolean startup( final IPentahoSession session ) { + public EmbeddedQuartzSystemListener() { + System.out.println("***************************************************************"); + System.out.println("EmbeddedQuartzSystemListener initialized."); + System.out.println("***************************************************************"); + } + + @Override + public void init() throws PluginLifecycleException { + } + + @Override + public void loaded() throws PluginLifecycleException { + IPentahoSession session = PentahoSessionHolder.getSession(); boolean result = true; Properties quartzProps = null; if ( quartzPropertiesFile != null ) { @@ -154,7 +165,9 @@ public boolean startup( final IPentahoSession session ) { "EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized", EmbeddedQuartzSystemListener.class.getName() ), e ); //$NON-NLS-1$ result = false; } - return result; + if ( !result ) { + throw new PluginLifecycleException(" Failed to start EmbeddedQuartzSystemListener"); + } } protected boolean verifyQuartzIsConfigured( DataSource ds ) throws SQLException { @@ -253,7 +266,8 @@ private Properties findPropertiesInClasspath() throws IOException { * * @see org.pentaho.core.system.IPentahoSystemListener#shutdown() */ - public void shutdown() { + @Override + public void unLoaded() throws PluginLifecycleException { try { QuartzScheduler scheduler = (QuartzScheduler) PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ scheduler.getQuartzScheduler().shutdown(); diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java index c762a1e72fa..b833c1667f7 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java @@ -128,10 +128,16 @@ public class QuartzScheduler implements IScheduler { public QuartzScheduler( SchedulerFactory schedulerFactory ) { this.quartzSchedulerFactory = schedulerFactory; + System.out.println("***************************************************************"); + System.out.println("QuartzScheduler initialized."); + System.out.println("***************************************************************"); } public QuartzScheduler() { this.quartzSchedulerFactory = new StdSchedulerFactory(); + System.out.println("***************************************************************"); + System.out.println("QuartzScheduler initialized."); + System.out.println("***************************************************************"); } /** diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java index d18df257d5d..7e0a3d289d1 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java @@ -30,6 +30,8 @@ import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; +import org.pentaho.platform.api.engine.IPluginLifecycleListener; +import org.pentaho.platform.api.engine.PluginLifecycleException; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.Job; @@ -39,7 +41,7 @@ import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.versionchecker.PentahoVersionCheckReflectHelper; -public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListener { +public class EmbeddedVersionCheckSystemListener implements IPluginLifecycleListener { /** * This is a direct copy of VersionCheckSystemListener except that the mechanism for talking to quartz goes through @@ -55,7 +57,18 @@ public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListene private String requestedReleases = "minor, ga"; //$NON-NLS-1$ private boolean disableVersionCheck = false; - public boolean startup( final IPentahoSession session ) { + public EmbeddedVersionCheckSystemListener() { + System.out.println("***************************************************************"); + System.out.println("EmbeddedVersionCheckSystemListener initialized."); + System.out.println("***************************************************************"); + } + + @Override + public void init() throws PluginLifecycleException { + } + + @Override + public void loaded() throws PluginLifecycleException { if ( isVersionCheckAvailable() ) { // register version check job try { @@ -84,7 +97,7 @@ public boolean startup( final IPentahoSession session ) { } } } - return true; +// return true; } public int calculateRepeatSeconds() { @@ -138,7 +151,8 @@ protected boolean isVersionCheckAvailable() { return PentahoVersionCheckReflectHelper.isVersionCheckerAvailable(); } - public void shutdown() { + @Override + public void unLoaded() throws PluginLifecycleException { } public int getRepeatIntervalSeconds() { diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java index 794a8c4810a..d64e457891b 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java @@ -54,6 +54,12 @@ public class DefaultSchedulerService implements ISchedulerService { private String defaultActionId; // for testing only + public DefaultSchedulerService() { + System.out.println("***************************************************************"); + System.out.println("DefaultSchedulerService initialized."); + System.out.println("***************************************************************"); + } + public void setDefaultActionId( String defaultActionId ) { this.defaultActionId = defaultActionId; } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java similarity index 99% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java index 5cfea213baf..614d1008e70 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java +++ b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java @@ -62,8 +62,8 @@ /** * The SchedulerResource service provides the means to create, read, update, delete, and list schedules and blockout periods. Also provides the ability to control the status of schedules and the scheduler. */ -@Path ( "/scheduler" ) -public class SchedulerResource extends AbstractJaxRSResource { +@Path ( "/scheduler-plugin/api/scheduler" ) +public class SchedulerResource { protected SchedulerService schedulerService; @@ -71,6 +71,9 @@ public class SchedulerResource extends AbstractJaxRSResource { public SchedulerResource() { schedulerService = new SchedulerService(); + System.out.println("-----------------------------------------------------------------------"); + System.out.println("SchedulerResource was initialized."); + System.out.println("-----------------------------------------------------------------------"); } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java similarity index 100% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java similarity index 100% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java From bd2e8382c8dadf085174eec18ef69540ea35b879 Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Wed, 12 Jul 2023 15:29:56 -0400 Subject: [PATCH 02/59] Moving scheduling code into a plugin --- assemblies/pentaho-server/pom.xml | 1 + .../commands/RefreshSchedulesCommand.java | 80 -- .../mantle/client/ui/column/HtmlColumn.java | 45 - .../mantle/client/ui/xul/MantleModel.java | 15 +- .../mantle/client/workspace/CellTable.css | 145 -- .../workspace/ClickableSafeHtmlCell.java | 71 - .../mantle/client/workspace/FilterDialog.java | 262 ---- .../mantle/client/workspace/IJobFilter.java | 25 - .../client/workspace/SchedulesPanel.java | 1259 ----------------- .../workspace/SchedulesPerspectivePanel.java | 148 -- .../workspace/cellTableSortAscending.png | Bin 175 -> 0 bytes .../workspace/cellTableSortDescending.png | Bin 166 -> 0 bytes 12 files changed, 9 insertions(+), 2042 deletions(-) delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png diff --git a/assemblies/pentaho-server/pom.xml b/assemblies/pentaho-server/pom.xml index f38542b126f..92d7e3445ce 100644 --- a/assemblies/pentaho-server/pom.xml +++ b/assemblies/pentaho-server/pom.xml @@ -55,6 +55,7 @@ org.hsqldb hsqldb ${hsqldb.version} + jdk8 mysql diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java deleted file mode 100644 index 1558a386284..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.commands; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.RunAsyncCallback; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.user.client.Window; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; - -public class RefreshSchedulesCommand extends AbstractCommand { - - public RefreshSchedulesCommand() { - } - - protected void performOperation() { - performOperation( true ); - } - - protected void performOperation( boolean feedback ) { - try { - final String url = GWT.getHostPageBaseURL() + "api/repo/files/canAdminister"; //$NON-NLS-1$ - RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.GET, url ); - requestBuilder.setHeader( "accept", "text/plain" ); - requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); - requestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - GWT.runAsync( new RunAsyncCallback() { - - public void onSuccess() { - SchedulesPerspectivePanel.getInstance().refresh(); - } - - public void onFailure( Throwable reason ) { - } - } ); - } - - public void onResponseReceived( Request request, final Response response ) { - GWT.runAsync( new RunAsyncCallback() { - - public void onSuccess() { - SchedulesPerspectivePanel.getInstance().refresh(); - } - - public void onFailure( Throwable reason ) { - } - } ); - } - - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - } - -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java deleted file mode 100644 index 44b8adc3fcf..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java +++ /dev/null @@ -1,45 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.ui.column; - -import com.google.gwt.cell.client.Cell; -import com.google.gwt.cell.client.SafeHtmlCell; -import com.google.gwt.safehtml.shared.OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.user.cellview.client.Column; - -public abstract class HtmlColumn extends Column { - - public HtmlColumn() { - super( new SafeHtmlCell() ); - } - - public HtmlColumn( Cell cell ) { - super( cell ); - } - - @Override - public SafeHtml getValue( T t ) { - return new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml( getStringValue( t ) ); - } - - public abstract String getStringValue( T t ); -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java index c53bd05d4cc..724dfb6a8d9 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java @@ -33,7 +33,7 @@ import org.pentaho.mantle.client.commands.OpenKettleStatusCommand; import org.pentaho.mantle.client.commands.PrintCommand; import org.pentaho.mantle.client.commands.RefreshRepositoryCommand; -import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; +//import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; import org.pentaho.mantle.client.commands.SaveCommand; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ISolutionBrowserEvent; @@ -283,14 +283,15 @@ public void onFailure( Throwable reason ) { @Bindable public void refreshContent() { - if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() - .getId() ) ) { - Command cmd = new RefreshSchedulesCommand(); - cmd.execute(); - } else { + // TODO Need to delegate this refresh to plugins as well + //if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() + // .getId() ) ) { + // Command cmd = new RefreshSchedulesCommand(); + //cmd.execute(); + //} else { Command cmd = new RefreshRepositoryCommand(); cmd.execute(); - } + //} } @Bindable diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css b/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css deleted file mode 100644 index a4b45fa3017..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -@def selectionBorderWidth 2px; - -/* - Add the @external flag to tell GWT compiler to NOT obfuscate the cellTable* classes (all of them). - This allows for theme-driven overrides in external CSS files. Treat these styles as defaults. - Themed overrides should be set in mantleCrystal.css/mantleOnyx.css/... -*/ -@external .cellTable*; - -.cellTableWidget { - background-color: white; - font-size: .7em; - border-bottom: 1px solid #6f7277; -} - -.cellTableFirstColumn { - -} - -.cellTableLastColumn { - -} - -.cellTableFooter { - border-top: 2px solid #6f7277; - padding: 3px 15px; - text-align: left; - color: #4b4a4a; - text-shadow: #ddf 1px 1px 0; - overflow: hidden; -} - -.cellTableHeader { - padding: 3px 15px; - text-align: left; - color: white; - overflow: hidden; -} - -.cellTableCell { - padding: 2px 10px; - overflow: hidden; - text-align: left; -} - -.cellTableFirstColumnFooter { - -} - -.cellTableFirstColumnHeader { - -} - -.cellTableLastColumnFooter { - -} - -.cellTableLastColumnHeader { - -} - -.cellTableSortableHeader { - cursor: pointer; - cursor: hand; -} - -.cellTableSortableHeader:hover { - color: #dfdfdf; -} - -.cellTableSortedHeaderAscending { - -} - -.cellTableSortedHeaderDescending { - -} - -.cellTableEvenRow { - background: #ffffff; -} - -.cellTableEvenRowCell { - border: selectionBorderWidth solid #ffffff; -} - -.cellTableOddRow { - background: #f0f0f0; -} - -.cellTableOddRowCell { - border: selectionBorderWidth solid #f0f0f0; -} - -.cellTableHoveredRow { - background: #cbefa3; -} - -.cellTableHoveredRowCell { - border: selectionBorderWidth solid #cbefa3; -} - -.cellTableKeyboardSelectedRow { - background: #BEBEBE; -} - -.cellTableKeyboardSelectedRowCell { - border: selectionBorderWidth solid #BEBEBE; -} - -.cellTableSelectedRow { - background: #BEBEBE; - color: white; - height: auto; - overflow: auto; -} - -.cellTableSelectedRowCell { - border: selectionBorderWidth solid #BEBEBE; -} - -/** - * The keyboard selected cell is visible over selection. - */ -.cellTableKeyboardSelectedCell { -} - -.cellTableLoading { - margin: 30px; -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java deleted file mode 100644 index 0f9dc7f341f..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java +++ /dev/null @@ -1,71 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.cell.client.AbstractCell; -import com.google.gwt.cell.client.ValueUpdater; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.EventTarget; -import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; - -/** - * @author Rowell Belen - */ -public class ClickableSafeHtmlCell extends AbstractCell { - - public ClickableSafeHtmlCell() { - super( "click" ); - } - - @Override - public void onBrowserEvent( Context context, Element parent, SafeHtml value, NativeEvent event, - ValueUpdater valueUpdater ) { - - // use default implementation for all events other than the click event - super.onBrowserEvent( context, parent, value, event, valueUpdater ); - - if ( "click".equals( event.getType() ) ) { - - // Ignore clicks that occur outside of the outermost element. - EventTarget eventTarget = event.getEventTarget(); - if ( parent.getFirstChildElement().isOrHasChild( Element.as( eventTarget ) ) ) { - onEnterKeyDown( context, parent, value, event, valueUpdater ); - } - } - } - - @Override - protected void onEnterKeyDown( Context context, Element parent, SafeHtml value, NativeEvent event, - ValueUpdater valueUpdater ) { - if ( valueUpdater != null ) { - valueUpdater.update( value ); - } - } - - @Override - public void render( Context context, SafeHtml value, SafeHtmlBuilder sb ) { - if ( value != null ) { - sb.append( value ); - } - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java deleted file mode 100644 index 879344000a3..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java +++ /dev/null @@ -1,262 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.core.client.JsArray; -import com.google.gwt.dom.client.Style; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.event.logical.shared.ValueChangeHandler; -import com.google.gwt.user.client.ui.CaptionPanel; -import com.google.gwt.user.client.ui.CheckBox; -import com.google.gwt.user.client.ui.FlexTable; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.ListBox; -import com.google.gwt.user.client.ui.MultiWordSuggestOracle; -import com.google.gwt.user.client.ui.SuggestBox; -import org.pentaho.gwt.widgets.client.controls.DateTimePicker; -import org.pentaho.gwt.widgets.client.controls.DateTimePicker.Layout; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.mantle.client.messages.Messages; - -import java.util.Date; -import java.util.HashSet; - -public class FilterDialog extends PromptDialogBox { - - private MultiWordSuggestOracle resourceOracle = new MultiWordSuggestOracle(); - private SuggestBox resourceSuggestBox = new SuggestBox( resourceOracle ); - - private CheckBox afterCheckBox = new CheckBox( Messages.getString( "after" ) ); - private CheckBox beforeCheckBox = new CheckBox( Messages.getString( "before" ) ); - private DateTimePicker afterDateBox = new DateTimePicker( Layout.HORIZONTAL ); - private DateTimePicker beforeDateBox = new DateTimePicker( Layout.HORIZONTAL ); - - private ListBox userListBox = new ListBox( false ); - private ListBox scheduleStateListBox = new ListBox( false ); - private ListBox scheduleTypeListBox = new ListBox( false ); - - private enum ScheduleStateEnum { - - SHOWALL( Messages.getString( "showAll" ) ), - NORMAL( "Normal" ), - PAUSED( "Paused" ), - COMPLETE( "Complete" ), - ERROR( "Error" ), - BLOCKED( "Blocked" ), - UNKNOWN( "Unknown" ); - - private final String value; - - ScheduleStateEnum( String value ) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } - } - - private enum ScheduleTypeEnum { - - SHOWALL( Messages.getString( "showAll" ) ), - DAILY( "Daily" ), - WEEKLY( "Weekly" ), - MONTHLY( "Monthly" ), - YEARLY( "Yearly" ); - - private final String value; - - ScheduleTypeEnum( String value ) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } - } - - public FilterDialog() { - super( - Messages.getString( "filterSchedules" ), Messages.getString( "ok" ), Messages.getString( "cancel" ), false, - true ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public FilterDialog( JsArray jobs, IDialogCallback callback ) { - super( - Messages.getString( "filterSchedules" ), Messages.getString( "ok" ), Messages.getString( "cancel" ), false, - true ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - initUI( jobs ); - // setSize("800px", "500px"); - setCallback( callback ); - } - - /** - * @param jobs - */ - public void initUI( JsArray jobs ) { - if ( jobs != null ) { - for ( int i = 0; i < jobs.length(); i++ ) { - resourceOracle.add( jobs.get( i ).getShortResourceName() ); - } - } - - resourceSuggestBox.setWidth( "240px" ); - userListBox.setWidth( "200px" ); - userListBox.getElement().getStyle().setTextTransform( Style.TextTransform.CAPITALIZE ); - scheduleStateListBox.setWidth( "200px" ); - scheduleTypeListBox.setWidth( "200px" ); - - // next execution filter - CaptionPanel executionFilterCaptionPanel = new CaptionPanel( Messages.getString( "executionTime" ) ); - FlexTable executionFilterPanel = new FlexTable(); - executionFilterPanel.setWidget( 0, 0, beforeCheckBox ); - executionFilterPanel.setWidget( 0, 1, beforeDateBox ); - executionFilterPanel.setWidget( 1, 0, afterCheckBox ); - executionFilterPanel.setWidget( 1, 1, afterDateBox ); - executionFilterCaptionPanel.add( executionFilterPanel ); - - afterCheckBox.addValueChangeHandler( new ValueChangeHandler() { - public void onValueChange( ValueChangeEvent event ) { - afterDateBox.setEnabled( event.getValue() ); - } - } ); - - beforeCheckBox.addValueChangeHandler( new ValueChangeHandler() { - public void onValueChange( ValueChangeEvent event ) { - beforeDateBox.setEnabled( event.getValue() ); - } - } ); - beforeDateBox.setEnabled( beforeCheckBox.getValue() ); - afterDateBox.setEnabled( afterCheckBox.getValue() ); - - final String showAll = Messages.getString( "showAll" ); - // user filter - int selectedIndex = getSelectedIndex( userListBox ); - userListBox.clear(); - userListBox.addItem( showAll ); - HashSet uniqueUsers = new HashSet(); - if ( jobs != null ) { - for ( int i = 0; i < jobs.length(); i++ ) { - uniqueUsers.add( jobs.get( i ).getUserName() ); - } - } - for ( String user : uniqueUsers ) { - userListBox.addItem( user ); - } - userListBox.setSelectedIndex( selectedIndex ); - - // state filter - scheduleStateListBox.setVisibleItemCount( 1 ); - selectedIndex = getSelectedIndex( scheduleStateListBox ); - scheduleStateListBox.clear(); - // NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN - scheduleStateListBox.addItem( showAll, ScheduleStateEnum.SHOWALL.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "normal" ), ScheduleStateEnum.NORMAL.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "paused" ), ScheduleStateEnum.PAUSED.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "complete" ), ScheduleStateEnum.COMPLETE.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "error" ), ScheduleStateEnum.ERROR.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "blocked" ), ScheduleStateEnum.BLOCKED.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "unknown" ), ScheduleStateEnum.UNKNOWN.getValue() ); - scheduleStateListBox.setSelectedIndex( selectedIndex ); - - // state filter - scheduleTypeListBox.setVisibleItemCount( 1 ); - selectedIndex = getSelectedIndex( scheduleTypeListBox ); - scheduleTypeListBox.clear(); - // DAILY, WEEKLY, MONTHLY, YEARLY - scheduleTypeListBox.addItem( showAll, ScheduleStateEnum.SHOWALL.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.daily" ), ScheduleTypeEnum.DAILY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.weekly" ), ScheduleTypeEnum.WEEKLY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.monthly" ), ScheduleTypeEnum.MONTHLY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.yearly" ), ScheduleTypeEnum.YEARLY.getValue() ); - scheduleTypeListBox.setSelectedIndex( selectedIndex ); - - FlexTable filterPanel = new FlexTable(); - filterPanel.setWidget( 0, 0, new Label( Messages.getString( "scheduledResource" ) ) ); - filterPanel.setWidget( 1, 0, resourceSuggestBox ); - - filterPanel.setWidget( 2, 0, new Label( Messages.getString( "_user" ) ) ); - filterPanel.setWidget( 3, 0, userListBox ); - - filterPanel.setWidget( 4, 0, new Label( Messages.getString( "scheduleState" ) ) ); - filterPanel.setWidget( 5, 0, scheduleStateListBox ); - - filterPanel.setWidget( 6, 0, new Label( Messages.getString( "scheduleType" ) ) ); - filterPanel.setWidget( 7, 0, scheduleTypeListBox ); - - filterPanel.setWidget( 8, 0, executionFilterCaptionPanel ); - - setContent( filterPanel ); - } - - public String getUserFilter() { - return userListBox.getItemText( userListBox.getSelectedIndex() ); - } - - public String getTypeFilter() { - return scheduleTypeListBox.getValue( scheduleTypeListBox.getSelectedIndex() ); - } - - public String getStateFilter() { - return scheduleStateListBox.getValue( scheduleStateListBox.getSelectedIndex() ); - } - - public Date getBeforeDate() { - if ( beforeCheckBox.getValue() ) { - return beforeDateBox.getDate(); - } - return null; - } - - public Date getAfterDate() { - if ( afterCheckBox.getValue() ) { - return afterDateBox.getDate(); - } - return null; - } - - public String getResourceName() { - return resourceSuggestBox.getText(); - } - - public CheckBox getAfterCheckBox() { - return afterCheckBox; - } - - private int getSelectedIndex( ListBox listBox ) { - int selectedIndex = listBox.getSelectedIndex(); - if ( selectedIndex == -1 ) { - selectedIndex = 0; - } - return selectedIndex; - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java deleted file mode 100644 index 65737b7ed52..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java +++ /dev/null @@ -1,25 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -public interface IJobFilter { - public boolean accept( JsJob job ); -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java deleted file mode 100644 index 291cf409310..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java +++ /dev/null @@ -1,1259 +0,0 @@ -/*! - * 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-2023 Hitachi Vantara. All rights reserved. - */ -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.cell.client.FieldUpdater; -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.core.client.JsonUtils; -import com.google.gwt.dom.client.BrowserEvents; -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.dom.client.TableCellElement; -import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestBuilder.Method; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.http.client.URL; -import com.google.gwt.i18n.client.DateTimeFormat; -import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; -import com.google.gwt.json.client.JSONArray; -import com.google.gwt.json.client.JSONObject; -import com.google.gwt.json.client.JSONString; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.AbstractCellTable; -import com.google.gwt.user.cellview.client.AbstractHeaderOrFooterBuilder; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; -import com.google.gwt.user.cellview.client.SimplePager; -import com.google.gwt.user.cellview.client.SimplePager.TextLocation; -import com.google.gwt.user.cellview.client.TextColumn; -import com.google.gwt.user.client.Command; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.HasHorizontalAlignment; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.view.client.CellPreviewEvent; -import com.google.gwt.view.client.ListDataProvider; -import com.google.gwt.view.client.MultiSelectionModel; -import com.google.gwt.view.client.ProvidesKey; -import com.google.gwt.view.client.Range; -import com.google.gwt.view.client.SelectionChangeEvent; -import com.google.gwt.view.client.SelectionChangeEvent.Handler; -import org.apache.http.protocol.HTTP; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.gwt.widgets.client.toolbar.Toolbar; -import org.pentaho.gwt.widgets.client.toolbar.ToolbarButton; -import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.mantle.client.EmptyRequestCallback; -import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; -import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -import org.pentaho.mantle.client.dialogs.scheduling.NewScheduleDialog; -import org.pentaho.mantle.client.dialogs.scheduling.OutputLocationUtils; -import org.pentaho.mantle.client.events.EventBusUtil; -import org.pentaho.mantle.client.events.GenericEvent; -import org.pentaho.mantle.client.images.ImageUtil; -import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; -import org.pentaho.mantle.client.ui.PerspectiveManager; -import org.pentaho.mantle.client.ui.column.HtmlColumn; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.CellTableResources; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.PAGE_SIZE; - -public class SchedulesPanel extends SimplePanel { - - private static final String JOB_STATE_NORMAL = "NORMAL"; - private static final String SCHEDULER_STATE_RUNNING = "RUNNING"; - - private static final String HTTP_ACCEPT_HEADER = "Accept"; - private static final String JSON_CONTENT_TYPE = "application/json"; - private static final String IF_MODIFIED_SINCE = "01 Jan 1970 00:00:00 GMT"; - - private static final String ICON_SMALL_STYLE = "icon-small"; - private static final String ICON_RUN_STYLE = "icon-run"; - - private static final String BLANK_VALUE = "-"; - - private static final int READ_PERMISSION = 0; - - private static final int OUTPUT_PATH_COLUMN = 3; - - private ToolbarButton controlScheduleButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, ICON_RUN_STYLE ) ); - private ToolbarButton editButton = new ToolbarButton( ImageUtil.getThemeableImage( "pentaho-editbutton" ) ); - private ToolbarButton triggerNowButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-execute" ) ); - private ToolbarButton scheduleRemoveButton = new ToolbarButton( ImageUtil.getThemeableImage( - "pentaho-deletebutton" ) ); - private ToolbarButton filterButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-filter-add" ) ); - private ToolbarButton filterRemoveButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-filter-remove" ) ); - - private JsArray allJobs; - - private ArrayList filters = new ArrayList(); - - private CellTable table = new CellTable( PAGE_SIZE, (CellTableResources) GWT.create( CellTableResources.class ) ); - - private ListDataProvider dataProvider = new ListDataProvider(); - - private SimplePager pager; - - private FilterDialog filterDialog; - - private IDialogCallback filterDialogCallback = new IDialogCallback() { - public void okPressed() { - filters.clear(); - // create filters - if ( filterDialog.getAfterDate() != null ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getNextRun().after( filterDialog.getAfterDate() ); - } - } ); - } - if ( filterDialog.getBeforeDate() != null ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getNextRun().before( filterDialog.getBeforeDate() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getResourceName() ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getShortResourceName().toLowerCase().contains( filterDialog.getResourceName().toLowerCase() ); - } - } ); - } - final String showAll = Messages.getString( "showAll" ); - if ( !StringUtils.isEmpty( filterDialog.getUserFilter() ) && !filterDialog.getUserFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getUserName().equalsIgnoreCase( filterDialog.getUserFilter() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getStateFilter() ) && !filterDialog.getStateFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getState().toLowerCase().equalsIgnoreCase( filterDialog.getStateFilter() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getTypeFilter() ) && !filterDialog.getTypeFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getJobTrigger().getScheduleType().equalsIgnoreCase( filterDialog.getTypeFilter() ); - } - } ); - } - filterRemoveButton.setEnabled( !filters.isEmpty() ); - filterAndShowData(); - } - - public void cancelPressed() { - } - }; - - @SuppressWarnings( "unchecked" ) - private Set getSelectedJobs() { - return ( (MultiSelectionModel) table.getSelectionModel() ).getSelectedSet(); - } - - private IDialogCallback scheduleDialogCallback = new IDialogCallback() { - public void okPressed() { - refresh(); - - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "scheduleUpdatedTitle" ), - Messages.getString( "scheduleUpdatedMessage" ), false, false, true ); - - dialogBox.center(); - } - - public void cancelPressed() { - } - }; - - public SchedulesPanel( final boolean isAdmin, final boolean isScheduler ) { - createUI( isAdmin, isScheduler ); - refresh(); - } - - public void refresh() { - String moduleBaseURL = GWT.getModuleBaseURL(); - String moduleName = GWT.getModuleName(); - String contextURL = moduleBaseURL.substring( 0, moduleBaseURL.lastIndexOf( moduleName ) ); - - final String apiEndpoint = "api/scheduler/getJobs"; - - RequestBuilder executableTypesRequestBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint, contextURL ); - executableTypesRequestBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - executableTypesRequestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - allJobs = parseJson( JsonUtils.escapeJsonForEval( response.getText() ) ); - filterAndShowData(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void filterAndShowData() { - - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return !job.getFullResourceName().equals( "GeneratedContentCleaner" ); - } - } ); - - ArrayList filteredList = new ArrayList(); - for ( int i = 0; i < allJobs.length(); i++ ) { - filteredList.add( allJobs.get( i ) ); - // filter if needed - for ( IJobFilter filter : filters ) { - if ( !filter.accept( allJobs.get( i ) ) ) { - filteredList.remove( allJobs.get( i ) ); - } - } - } - List list = dataProvider.getList(); - list.clear(); - list.addAll( filteredList ); - pager.setVisible( filteredList.size() > PAGE_SIZE ); - for ( JsJob job : filteredList ) { - table.getSelectionModel().setSelected( job, false ); - } - editButton.setEnabled( false ); - controlScheduleButton.setEnabled( false ); - scheduleRemoveButton.setEnabled( false ); - triggerNowButton.setEnabled( false ); - table.setPageStart( 0 ); - - table.setKeyboardSelectedRow( 0, false ); - table.setKeyboardSelectedColumn( 0, false ); - - table.redraw(); - } - - private void updateControlSchedulerButtonState( final ToolbarButton controlSchedulerButton, - final boolean isScheduler ) { - RequestBuilder builder = createRequestBuilder( RequestBuilder.GET, "api/scheduler/state" ); - - try { - builder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - updateControlSchedulerButtonStyle( controlSchedulerButton, response.getText() ); - - controlSchedulerButton.setEnabled( isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - - private void updateControlSchedulerButtonStyle( ToolbarButton controlSchedulerButton, String state ) { - boolean isRunning = SCHEDULER_STATE_RUNNING.equalsIgnoreCase( state ); - - final String tooltip = isRunning ? "stopScheduler" : "startScheduler"; - controlSchedulerButton.setToolTip( tooltip ); - - final String buttonIconCss = isRunning ? "icon-stop-scheduler" : "icon-start-scheduler"; - controlSchedulerButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, buttonIconCss ) ); - } - - private void updateJobScheduleButtonStyle( String state ) { - boolean isRunning = JOB_STATE_NORMAL.equalsIgnoreCase( state ); - - String controlButtonCss = isRunning ? "icon-stop" : ICON_RUN_STYLE; - controlScheduleButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, controlButtonCss ) ); - - String controlButtonTooltip = isRunning ? Messages.getString( "stop" ) : Messages.getString( "start" ); - controlScheduleButton.setToolTip( controlButtonTooltip ); - - } - - private void toggleSchedulerOnOff( final ToolbarButton controlSchedulerButton, final boolean isScheduler ) { - RequestBuilder builder = createRequestBuilder( RequestBuilder.GET, "api/scheduler/state" ); - - try { - builder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - boolean isRunning = SCHEDULER_STATE_RUNNING.equalsIgnoreCase( response.getText() ); - - final String action = isRunning ? "pause" : "start"; - controlScheduler( controlSchedulerButton, action, isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void createUI( boolean isAdmin, final boolean isScheduler ) { - - table.getElement().setId( "schedule-table" ); - table.setStylePrimaryName( "pentaho-table" ); - table.setWidth( "100%", true ); - - // BISERVER-9331 Column sort indicators should be to the right of header text in the Manage Schedules table. - if ( table.getHeaderBuilder() instanceof AbstractHeaderOrFooterBuilder ) { - ( (AbstractHeaderOrFooterBuilder) table.getHeaderBuilder() ).setSortIconStartOfLine( false ); - } - - final MultiSelectionModel selectionModel = new MultiSelectionModel( new ProvidesKey() { - public Object getKey( JsJob item ) { - return item.getJobId(); - } - } ); - table.setSelectionModel( selectionModel ); - - Label noDataLabel = new Label( Messages.getString( "noSchedules" ) ); - noDataLabel.setStyleName( "noDataForScheduleTable" ); - table.setEmptyTableWidget( noDataLabel ); - - TextColumn idColumn = new TextColumn() { - public String getValue( JsJob job ) { - return job.getJobId(); - } - }; - idColumn.setSortable( true ); - - TextColumn nameColumn = new TextColumn() { - public String getValue( JsJob job ) { - return job.getJobName(); - } - }; - nameColumn.setSortable( true ); - - HtmlColumn resourceColumn = new HtmlColumn() { - @Override - public String getStringValue( JsJob job ) { - String name = job.getFullResourceName().split( "\\." )[ 0 ]; - return name.replaceAll( "/", "/" ); - } - }; - resourceColumn.setSortable( true ); - - HtmlColumn outputPathColumn = new HtmlColumn( new ClickableSafeHtmlCell() ) { - @Override - public String getStringValue( JsJob jsJob ) { - try { - String outputPath = jsJob.getOutputPath(); - if ( StringUtils.isEmpty( outputPath ) ) { - return BLANK_VALUE; - } - - outputPath = new SafeHtmlBuilder().appendEscaped( outputPath ).toSafeHtml().asString(); - - return MessageFormat.format( - "{0}", outputPath ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - - outputPathColumn.setFieldUpdater( new FieldUpdater() { - @Override - public void update( final int index, final JsJob jsJob, final SafeHtml value ) { - if ( value != null && !BLANK_VALUE.equals( value.asString() ) ) { - - final Command errorCallback = new Command() { - @Override - public void execute() { - showValidateOutputLocationError(); - } - }; - - final Command successCallback = new Command() { - @Override - public void execute() { - openOutputLocation( jsJob.getOutputPath() ); - } - }; - - OutputLocationUtils.validateOutputLocation( jsJob.getOutputPath(), successCallback, errorCallback ); - } - } - } ); - - outputPathColumn.setSortable( true ); - - TextColumn scheduleColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - return job.getJobTrigger().getDescription(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - scheduleColumn.setSortable( true ); - - TextColumn userNameColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - return job.getUserName(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - userNameColumn.setSortable( true ); - - TextColumn stateColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - // BISERVER-9965 - final String jobState = "COMPLETE".equalsIgnoreCase( job.getState() ) ? "FINISHED" : job.getState(); - // not css text-transform because tooltip will use pure text from the cell - return jobState.substring( 0, 1 ).toUpperCase() + jobState.substring( 1 ).toLowerCase(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - stateColumn.setSortable( true ); - - TextColumn nextFireColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - Date date = job.getNextRun(); - if ( date == null ) { - return BLANK_VALUE; - } - - DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM ); - - return format.format( date ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - nextFireColumn.setSortable( true ); - - TextColumn lastFireColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - Date date = job.getLastRun(); - if ( date == null ) { - return BLANK_VALUE; - } - - DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM ); - return format.format( date ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - lastFireColumn.setSortable( true ); - - // table.addColumn(idColumn, "ID"); - table.addColumn( nameColumn, Messages.getString( "scheduleName" ) ); - table.addColumn( scheduleColumn, Messages.getString( "recurrence" ) ); - table.addColumn( resourceColumn, Messages.getString( "sourceFile" ) ); - table.addColumn( outputPathColumn, Messages.getString( "outputPath" ) ); - - table.addColumn( lastFireColumn, Messages.getString( "lastFire" ) ); - table.addColumn( nextFireColumn, Messages.getString( "nextFire" ) ); - if ( isAdmin ) { - table.addColumn( userNameColumn, Messages.getString( "user" ) ); - } - table.addColumn( stateColumn, Messages.getString( "state" ) ); - - table.addColumnStyleName( 0, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 1, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 2, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 3, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 4, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 5, "backgroundContentHeaderTableCell" ); - if ( isAdmin ) { - table.addColumnStyleName( 6, "backgroundContentHeaderTableCell" ); - } - table.addColumnStyleName( isAdmin ? 7 : 6, "backgroundContentHeaderTableCell" ); - - table.setColumnWidth( nameColumn, 160, Unit.PX ); - table.setColumnWidth( resourceColumn, 200, Unit.PX ); - table.setColumnWidth( outputPathColumn, 180, Unit.PX ); - table.setColumnWidth( scheduleColumn, 170, Unit.PX ); - table.setColumnWidth( lastFireColumn, 120, Unit.PX ); - table.setColumnWidth( nextFireColumn, 120, Unit.PX ); - if ( isAdmin ) { - table.setColumnWidth( userNameColumn, 100, Unit.PX ); - } - table.setColumnWidth( stateColumn, 90, Unit.PX ); - - dataProvider.addDataDisplay( table ); - List list = dataProvider.getList(); - - ListHandler columnSortHandler = new ListHandler( list ); - - columnSortHandler.setComparator( idColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getJobId().compareTo( o2.getJobId() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( nameColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getJobName().compareTo( o2.getJobName() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( resourceColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - String r1 = o1.getShortResourceName(); - String r2 = null; - if ( o2 != null ) { - r2 = o2.getShortResourceName(); - } - - return ( o2 != null ) ? r1.compareTo( r2 ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( outputPathColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - String r1 = o1.getOutputPath(); - String r2 = null; - if ( o2 != null ) { - r2 = o2.getOutputPath(); - } - - return ( o2 != null ) ? r1.compareTo( r2 ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( scheduleColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - String s1 = o1.getJobTrigger().getDescription(); - String s2 = o2.getJobTrigger().getDescription(); - return s1.compareTo( s2 ); - } - } ); - columnSortHandler.setComparator( userNameColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getUserName().compareTo( o2.getUserName() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( stateColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getState().compareTo( o2.getState() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( nextFireColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 == null || o1.getNextRun() == null ) { - return -1; - } - if ( o2 == null || o2.getNextRun() == null ) { - return 1; - } - - if ( o1.getNextRun() == o2.getNextRun() ) { - return 0; - } - - return o1.getNextRun().compareTo( o2.getNextRun() ); - } - } ); - columnSortHandler.setComparator( lastFireColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 == null || o1.getLastRun() == null ) { - return -1; - } - if ( o2 == null || o2.getLastRun() == null ) { - return 1; - } - - if ( o1.getLastRun() == o2.getLastRun() ) { - return 0; - } - - return o1.getLastRun().compareTo( o2.getLastRun() ); - } - } ); - table.addColumnSortHandler( columnSortHandler ); - - table.getColumnSortList().push( idColumn ); - table.getColumnSortList().push( resourceColumn ); - table.getColumnSortList().push( outputPathColumn ); - table.getColumnSortList().push( nameColumn ); - - table.getSelectionModel().addSelectionChangeHandler( new Handler() { - public void onSelectionChange( SelectionChangeEvent event ) { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob job = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - updateJobScheduleButtonStyle( job.getState() ); - - controlScheduleButton.setEnabled( isScheduler ); - editButton.setEnabled( isScheduler ); - controlScheduleButton.setEnabled( isScheduler ); - scheduleRemoveButton.setEnabled( isScheduler ); - triggerNowButton.setEnabled( isScheduler ); - } else { - editButton.setEnabled( false ); - controlScheduleButton.setEnabled( false ); - scheduleRemoveButton.setEnabled( false ); - triggerNowButton.setEnabled( false ); - } - } - } ); - - // BISERVER-9965 - table.addCellPreviewHandler( new CellPreviewEvent.Handler() { - @Override - public void onCellPreview( CellPreviewEvent event ) { - if ( "mouseover".equals( event.getNativeEvent().getType() ) ) { - final TableCellElement cell = table.getRowElement( event.getIndex() ).getCells().getItem( event.getColumn() ); - cell.setTitle( cell.getInnerText() ); - } - } - } ); - - /* - * For Left & Right, the below code is there to override the base class implementation i.e., - * navigates focus only amongst interactive cells, while our implementation navigates through all cells. - * - * For Enter, goes to the output path. - */ - table.setKeyboardSelectionHandler( new AbstractCellTable.CellTableKeyboardSelectionHandler( table ) { - @Override - public void onCellPreview( CellPreviewEvent event ) { - int keyboardSelectedColumn = table.getKeyboardSelectedColumn(); - if ( BrowserEvents.KEYDOWN.equals( event.getNativeEvent().getType() ) ) { - if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_RIGHT ) { - table.setKeyboardSelectedColumn( Math.min( keyboardSelectedColumn + 1, table.getColumnCount() - 1 ) ); - handledEvent( event ); - } else if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_LEFT ) { - table.setKeyboardSelectedColumn( Math.max( 0, keyboardSelectedColumn - 1 ) ); - handledEvent( event ); - } else if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER && keyboardSelectedColumn == OUTPUT_PATH_COLUMN ) { - int index = event.getIndex(); - JsJob job = table.getVisibleItem( event.getIndex() ); - outputPathColumn.getFieldUpdater().update( index, job, outputPathColumn.getValue( job ) ); - } else if ( !event.getNativeEvent().getCtrlKey() && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_SPACE ) { - ( (MultiSelectionModel) table.getSelectionModel() ).clear(); - super.onCellPreview( event ); - } else { - super.onCellPreview( event ); - } - } else { - super.onCellPreview( event ); - } - } - - private void handledEvent( CellPreviewEvent event ) { - event.setCanceled( true ); - event.getNativeEvent().preventDefault(); - } - } ); - - SimplePager.Resources pagerResources = GWT.create( SimplePager.Resources.class ); - pager = new SimplePager( TextLocation.CENTER, pagerResources, false, 0, true ) { - @Override - public void setPageStart( int index ) { - if ( getDisplay() != null ) { - Range range = getDisplay().getVisibleRange(); - int pageSize = range.getLength(); - - index = Math.max( 0, index ); - if ( index != range.getStart() ) { - getDisplay().setVisibleRange( index, pageSize ); - } - } - } - }; - pager.setDisplay( table ); - - VerticalPanel tableAndPager = new VerticalPanel(); - tableAndPager.setHorizontalAlignment( HasHorizontalAlignment.ALIGN_CENTER ); - - Toolbar bar = new Toolbar(); - bar.addSpacer( 10 ); - - bar.add( Toolbar.GLUE ); - - // Add control scheduler button - if ( isAdmin ) { - final ToolbarButton controlSchedulerButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-start-scheduler" ) ); - - controlSchedulerButton.setCommand( new Command() { - public void execute() { - toggleSchedulerOnOff( controlSchedulerButton, isScheduler ); - } - } ); - updateControlSchedulerButtonState( controlSchedulerButton, isScheduler ); - - bar.add( controlSchedulerButton ); - bar.addSpacer( 20 ); - } - - // Add filter button - filterButton.setCommand( new Command() { - public void execute() { - if ( filterDialog == null ) { - filterDialog = new FilterDialog( allJobs, filterDialogCallback ); - } else { - filterDialog.initUI( allJobs ); - } - - filterDialog.center(); - } - } ); - - filterButton.setToolTip( Messages.getString( "filterSchedules" ) ); - if ( isAdmin ) { - bar.add( filterButton ); - } - - // Add remove filters button - filterRemoveButton.setCommand( new Command() { - public void execute() { - filterDialog = null; - filters.clear(); - filterAndShowData(); - filterRemoveButton.setEnabled( false ); - filterButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, "icon-filter-add" ) ); - } - } ); - filterRemoveButton.setToolTip( Messages.getString( "removeFilters" ) ); - filterRemoveButton.setEnabled( !filters.isEmpty() ); - if ( isAdmin ) { - bar.add( filterRemoveButton ); - } - - // Add refresh button - ToolbarButton refresh = new ToolbarButton( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, "icon-refresh" ) ); - refresh.setToolTip( Messages.getString( "refreshTooltip" ) ); - refresh.setCommand( new Command() { - public void execute() { - RefreshSchedulesCommand cmd = new RefreshSchedulesCommand(); - cmd.execute(); - } - } ); - bar.add( refresh ); - - bar.addSpacer( 20 ); - - // Add execute now button - triggerNowButton.setToolTip( Messages.getString( "executeNow" ) ); - triggerNowButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - if ( !selectedJobs.isEmpty() ) { - triggerExecuteNow( selectedJobs ); - } - } - } ); - triggerNowButton.setEnabled( false ); - bar.add( triggerNowButton ); - - // Add control schedule button - controlScheduleButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob job = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - - boolean isRunning = JOB_STATE_NORMAL.equalsIgnoreCase( job.getState() ); - - final String action = isRunning ? "pauseJob" : "resumeJob"; - controlJobs( selectedJobs, action, RequestBuilder.POST, false ); - } - } - } ); - controlScheduleButton.setEnabled( false ); - bar.add( controlScheduleButton ); - - bar.addSpacer( 20 ); - - // Add edit button - editButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob editJob = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - - canAccessJobRequest( editJob, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - promptForScheduleResourceError( Collections.singleton( editJob ) ); - } - - public void onResponseReceived( Request request, Response response ) { - boolean canEditJob = "true".equalsIgnoreCase( response.getText() ); - if ( !canEditJob ) { - promptForScheduleResourceError( Collections.singleton( editJob ) ); - return; - } - - editJob( editJob ); - } - } ); - } - } - } ); - - editButton.setEnabled( false ); - editButton.setToolTip( Messages.getString( "editTooltip" ) ); - bar.add( editButton ); - - // Add remove button - scheduleRemoveButton.setCommand( new Command() { - public void execute() { - final Set selectedJobs = getSelectedJobs(); - - int selectionSize = selectedJobs.size(); - if ( selectionSize > 0 ) { - final MessageDialogBox prompt = new MessageDialogBox( - Messages.getString( "warning" ), - Messages.getString( "deleteConfirmSchedles", "" + selectionSize ), - false, - Messages.getString( "yes" ), - Messages.getString( "no" ) ); - - prompt.setCallback( new IDialogCallback() { - public void okPressed() { - controlJobs( selectedJobs, "removeJob", RequestBuilder.DELETE, true ); - prompt.hide(); - } - - public void cancelPressed() { - prompt.hide(); - } - } ); - - prompt.center(); - } - } - } ); - scheduleRemoveButton.setToolTip( Messages.getString( "remove" ) ); - scheduleRemoveButton.setEnabled( false ); - bar.add( scheduleRemoveButton ); - - tableAndPager.add( bar ); - tableAndPager.add( table ); - tableAndPager.add( pager ); - - // Add it to the root panel. - setWidget( tableAndPager ); - } - - private void editJob( final JsJob editJob ) { - final String jobId = editJob.getJobId(); - final String apiEndpoint = "api/scheduler/jobinfo?jobId=" + URL.encodeQueryString( jobId ); - - RequestBuilder executableTypesRequestBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint ); - executableTypesRequestBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - executableTypesRequestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - final JsJob jsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); - - // check email is setup - final String checkEmailEndpoint = "api/emailconfig/isValid"; - RequestBuilder emailValidRequest = createRequestBuilder( RequestBuilder.GET, checkEmailEndpoint ); - - emailValidRequest.setHeader( "accept", "text/plain" ); - - try { - emailValidRequest.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "error" ), - exception.toString(), false, false, true ); - - dialogBox.center(); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - final boolean isEmailConfValid = Boolean.parseBoolean( response.getText() ); - final NewScheduleDialog scheduleDialog = new NewScheduleDialog( jsJob, - scheduleDialogCallback, isEmailConfValid ); - - scheduleDialog.center(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - - } else { - String message = Messages.getString( "serverErrorColon" ) + " " + response.getStatusCode(); - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "error" ), message, - false, false, true ); - - dialogBox.center(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void triggerExecuteNow( final Set jobs ) { - final Map> candidateJobs = new HashMap>( jobs.size() ); - for ( JsJob job : jobs ) { - List jobList = candidateJobs.get( job.getFullResourceName() ); - if ( null == jobList ) { - jobList = new ArrayList(); - candidateJobs.put( job.getFullResourceName(), jobList ); - } - jobList.add( job ); - } - - canAccessJobListRequest( jobs, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - promptForScheduleResourceError( jobs ); - } - - public void onResponseReceived( Request request, Response response ) { - final Set executeList = getExecutableJobs( candidateJobs, response ); - - // execute job schedules that can be executed - if ( !executeList.isEmpty() ) { - executeJobs( executeList ); - } - - final Set removeList = new HashSet(); - for ( JsJob job : jobs ) { - if ( !executeList.contains( job ) ) { - removeList.add( job ); - } - } - - // remove job schedules that no longer can be executed - if ( !removeList.isEmpty() ) { - promptForScheduleResourceError( removeList ); - } - } - } ); - } - - private void executeJobs( Set jobs ) { - final String title = Messages.getString( "executeNow" ); - final String message = Messages.getString( "executeNowStarted" - + ( jobs.size() > 1 ? "Multiple" : "" ) ); - - MessageDialogBox messageDialog = new MessageDialogBox( title, message, false, true, true ); - messageDialog.center(); - - controlJobs( jobs, "triggerNow", RequestBuilder.POST, true ); - } - - private Set getExecutableJobs( Map> candidateJobs, Response response ) { - final Set executeList = new HashSet(); - - try { - final List readableFiles = parseJsonAccessList( response.getText() ).getReadableFiles(); - - for ( String resourceName : readableFiles ) { - executeList.addAll( candidateJobs.get( resourceName ) ); - } - } catch ( Exception e ) { - // noop - } - - return executeList; - } - - private void promptForScheduleResourceError( final Set jobs ) { - final String promptContent = Messages.getString( - "editScheduleResourceDoesNotExist" + ( jobs.size() > 1 ? "Multiple" : "" ) ); - final MessageDialogBox prompt = new MessageDialogBox( - Messages.getString( "fileUnavailable" ), - promptContent, - true, - Messages.getString( "yesDelete" ), - Messages.getString( "no" ) ); - - prompt.setCallback( new IDialogCallback() { - public void okPressed() { - controlJobs( jobs, "removeJob", RequestBuilder.DELETE, true ); - prompt.hide(); - } - - public void cancelPressed() { - prompt.hide(); - } - } ); - - prompt.setWidth( "530px" ); - prompt.center(); - } - - private void controlJobs( final Set jobs, String function, final Method method, final boolean refreshData ) { - for ( final JsJob job : jobs ) { - RequestBuilder builder = createRequestBuilder( method, "api/scheduler/" + function ); - - builder.setHeader( HTTP.CONTENT_TYPE, JSON_CONTENT_TYPE ); - - JSONObject startJobRequest = new JSONObject(); - startJobRequest.put( "jobId", new JSONString( job.getJobId() ) ); - - try { - builder.sendRequest( startJobRequest.toString(), new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - final String jobState = response.getText(); - - job.setState( jobState ); - table.redraw(); - - updateJobScheduleButtonStyle( jobState ); - - if ( refreshData ) { - refresh(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - } - - private void controlScheduler( final ToolbarButton controlSchedulerButton, final String function, - final boolean isScheduler ) { - final RequestBuilder builder = createRequestBuilder( RequestBuilder.POST, "api/scheduler/" + function ); - - try { - builder.sendRequest( null, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - updateControlSchedulerButtonStyle( controlSchedulerButton, response.getText() ); - - controlSchedulerButton.setEnabled( isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void openOutputLocation( final String outputLocation ) { - - PerspectiveManager.getInstance().setPerspective( PerspectiveManager.BROWSER_PERSPECTIVE ); - - String url = GWT.getHostPageBaseURL() + "api/mantle/session-variable?key=scheduler_folder&value=" + outputLocation; - RequestBuilder executableTypesRequestBuilder = new CsrfRequestBuilder( RequestBuilder.POST, url ); - try { - executableTypesRequestBuilder.sendRequest( null, EmptyRequestCallback.getInstance() ); - } catch ( RequestException e ) { - // IGNORE - } - - GenericEvent event = new GenericEvent(); - event.setEventSubType( "RefreshFolderEvent" ); - event.setStringParam( outputLocation ); - EventBusUtil.EVENT_BUS.fireEvent( event ); - } - - private void showValidateOutputLocationError() { - String title = Messages.getString( "outputLocationErrorTitle" ); - String message = Messages.getString( "outputLocationErrorMessage" ); - String okText = Messages.getString( "close" ); - - MessageDialogBox dialogBox = new MessageDialogBox( title, message, - false, false, true, okText, null, null ); - - dialogBox.addStyleName( "pentaho-dialog-small" ); - dialogBox.center(); - } - - private void canAccessJobRequest( final JsJob job, RequestCallback callback ) { - final String jobId = SolutionBrowserPanel.pathToId( job.getFullResourceName() ); - - final String apiEndpoint = "api/repo/files/" + jobId + "/canAccess?cb=" + System.currentTimeMillis() - + "&permissions=" + READ_PERMISSION; - - final RequestBuilder accessBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint ); - - try { - accessBuilder.sendRequest( null, callback ); - } catch ( RequestException re ) { - // noop - } - } - - private void canAccessJobListRequest( final Set jobs, RequestCallback callback ) { - final JSONArray jobNameList = new JSONArray(); - - int idx = 0; - for ( JsJob job : jobs ) { - jobNameList.set( idx++, new JSONString( job.getFullResourceName() ) ); - } - - final JSONObject payload = new JSONObject(); - payload.put( "strings", jobNameList ); - - final String accessListEndpoint = "api/repo/files/pathsAccessList?cb=" + System.currentTimeMillis(); - RequestBuilder accessListBuilder = createRequestBuilder( RequestBuilder.POST, accessListEndpoint ); - - accessListBuilder.setHeader( HTTP.CONTENT_TYPE, JSON_CONTENT_TYPE ); - accessListBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - accessListBuilder.sendRequest( payload.toString(), callback ); - } catch ( RequestException re ) { - // noop - } - } - - private RequestBuilder createRequestBuilder( Method method, String apiEndpoint ) { - return createRequestBuilder( method, apiEndpoint, GWT.getHostPageBaseURL() ); - } - - private RequestBuilder createRequestBuilder( Method method, String apiEndpoint, String context ) { - final String url = context + apiEndpoint; - - RequestBuilder builder = new RequestBuilder( method, url ); - builder.setHeader( "If-Modified-Since", IF_MODIFIED_SINCE ); - - return builder; - } - - private native JsArray parseJson( String json ) /*-{ - var obj = JSON.parse(json); - - if (obj != null && obj.hasOwnProperty("job")) { - return obj.job; - } - - return []; - }-*/; - - private native JsJob parseJsonJob( String json ) /*-{ - return JSON.parse(json); - }-*/; - - private native JsPermissionsList parseJsonAccessList( String json ) /*-{ - return JSON.parse(json); - }-*/; -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java deleted file mode 100644 index adc2af361f5..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java +++ /dev/null @@ -1,148 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.resources.client.ImageResource; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import org.pentaho.mantle.client.messages.Messages; - -public class SchedulesPerspectivePanel extends SimplePanel { - static final int PAGE_SIZE = 25; - private static SchedulesPerspectivePanel instance = new SchedulesPerspectivePanel(); - - private VerticalPanel wrapperPanel; - private SchedulesPanel schedulesPanel; - private BlockoutPanel blockoutPanel; - - private boolean isScheduler; - private boolean isAdmin; - - public static SchedulesPerspectivePanel getInstance() { - return instance; - } - - public SchedulesPerspectivePanel() { - try { - final String url = GWT.getHostPageBaseURL() + "api/repo/files/canAdminister"; //$NON-NLS-1$ - RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.GET, url ); - requestBuilder.setHeader( "accept", "text/plain" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - isAdmin = false; - isScheduler = false; - } - - public void onResponseReceived( Request request, Response response ) { - isAdmin = "true".equalsIgnoreCase( response.getText() ); //$NON-NLS-1$ - - try { - final String url2 = GWT.getHostPageBaseURL() + "api/scheduler/canSchedule"; //$NON-NLS-1$ - RequestBuilder requestBuilder2 = new RequestBuilder( RequestBuilder.GET, url2 ); - requestBuilder2.setHeader( "accept", "application/json" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder2.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); - requestBuilder2.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - isScheduler = false; - createUI(); - - } - - public void onResponseReceived( Request request, Response response ) { - isScheduler = "true".equalsIgnoreCase( response.getText() ); //$NON-NLS-1$ - createUI(); - } - - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - } - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - - } - - private void createUI() { - - this.setStyleName( "schedulerPerspective" ); //$NON-NLS-1$ - - wrapperPanel = new VerticalPanel(); - - String schedulesLabelStr = Messages.getString( "mySchedules" ); //$NON-NLS-1$ - if ( isAdmin ) { - schedulesLabelStr = Messages.getString( "manageSchedules" ); //$NON-NLS-1$ - } - - Label schedulesLabel = new Label( schedulesLabelStr ); - schedulesLabel.setStyleName( "workspaceHeading" ); //$NON-NLS-1$ - wrapperPanel.add( schedulesLabel ); - - schedulesPanel = new SchedulesPanel( isAdmin, isScheduler ); - schedulesPanel.setStyleName( "schedulesPanel" ); //$NON-NLS-1$ - schedulesPanel.addStyleName( "schedules-panel-wrapper" ); //$NON-NLS-1$ - wrapperPanel.add( schedulesPanel ); - - blockoutPanel = new BlockoutPanel( isAdmin ); - blockoutPanel.setStyleName( "schedulesPanel" ); //$NON-NLS-1$ - blockoutPanel.addStyleName( "blockout-schedules-panel-wrapper" ); //$NON-NLS-1$ - wrapperPanel.add( blockoutPanel ); - - SimplePanel sPanel = new SimplePanel(); - sPanel.add( wrapperPanel ); - sPanel.setStylePrimaryName( "schedulerPerspective-wrapper" ); //$NON-NLS-1$ - add( sPanel ); - - } - - public void refresh() { - schedulesPanel.refresh(); - blockoutPanel.refresh(); - } - - public interface CellTableResources extends CellTable.Resources { - @Override - public ImageResource cellTableSortAscending(); - - @Override - public ImageResource cellTableSortDescending(); - - /** - * The styles used in this widget. - */ - @Source( "org/pentaho/mantle/client/workspace/CellTable.css" ) - public CellTable.Style cellTableStyle(); - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png b/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png deleted file mode 100644 index 06446f9d99c2ede0cab3917da60aaca3ebc06827..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gfu1goAr-fh{`~)M&#c+d+2~@xVseJ%(f^DJ(Jrn44aLNz z|7SRGM)K}r6VP)Hy3?rF@7t^(u)jIUv7}N==U)~75m5&nj?~2rZnKV?I5aRay!_wP UbUbU*44~l*p00i_>zopr09KnhAOHXW diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png b/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png deleted file mode 100644 index 98c16ee36fe9b2155501f132cf414961af36a730..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G9-c0aAr-fh{`~)M&#c+d+34b6%A4sB(-+G2gxy4k Date: Tue, 18 Jul 2023 13:12:59 -0400 Subject: [PATCH 03/59] Getting the user-console module to a compiling state. --- .../client/admin/ContentCleanerPanel.java | 52 ++++++++++++------- .../commands/AdhocRunInBackgroundCommand.java | 8 +-- .../commands/RunInBackgroundCommand.java | 46 +++++++++------- .../solutionbrowser/ScheduleCallback.java | 6 ++- .../solutionbrowser/SolutionBrowserPanel.java | 9 ++-- .../solutionbrowser/filelist/FileCommand.java | 8 +-- .../mantle/client/ui/PerspectiveManager.java | 8 +-- 7 files changed, 84 insertions(+), 53 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java index 559612c53fd..e5b7e5de202 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java @@ -52,10 +52,12 @@ import org.pentaho.gwt.widgets.client.utils.string.StringUtils; import org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog; import org.pentaho.mantle.client.dialogs.WaitPopup; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.workspace.JsJob; -import org.pentaho.mantle.client.workspace.JsJobParam; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.workspace.JsJob; +//import org.pentaho.mantle.client.workspace.JsJobParam; import java.util.Date; @@ -104,7 +106,8 @@ public void onResponseReceived( Request request, Response response ) { nowTextBox.getElement().getStyle().setMarginRight( 5, Unit.PX ); final TextBox scheduleTextBox = new TextBox(); scheduleTextBox.setVisibleLength( 4 ); - + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /* JsJob tmpJsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); boolean fakeJob = false; @@ -131,7 +134,7 @@ public void onChange( ChangeEvent event ) { } } } - } ); + } );*/ Label settingsLabel = new Label( Messages.getString( "settings" ) ); settingsLabel.setStyleName( "pentaho-fieldgroup-major" ); @@ -190,27 +193,30 @@ public void cancelPressed() { scheduledPanel.add( deleteScheduleLabel ); Label descLabel; - if ( !fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*if ( !fakeJob ) { String desc = jsJob.getJobTrigger().getDescription(); descLabel = new Label( desc ); scheduledPanel.add( descLabel ); - } else { + } else {*/ descLabel = new Label( Messages.getString( "generatedFilesAreNotScheduledToBeDeleted" ) ); scheduledPanel.add( descLabel ); - } + //} descLabel.getElement().getStyle().setPaddingTop( 10, Unit.PX ); descLabel.getElement().getStyle().setPaddingBottom( 10, Unit.PX ); Button editScheduleButton = new Button( Messages.getString( "edit" ) ); - if ( fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*if ( fakeJob ) { editScheduleButton.setText( Messages.getString( "scheduleDeletion" ) ); - } + }*/ Button deleteScheduleButton = new Button( Messages.getString( "cancelSchedule" ) ); deleteScheduleButton.setStylePrimaryName( "pentaho-button" ); deleteScheduleButton.addStyleName( "last" ); deleteScheduleButton.addClickHandler( new ClickHandler() { public void onClick( ClickEvent event ) { - deleteContentCleaner( jsJob ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //deleteContentCleaner( jsJob ); } } ); editScheduleButton.setStylePrimaryName( "pentaho-button" ); @@ -219,7 +225,8 @@ public void onClick( ClickEvent event ) { public void onClick( ClickEvent event ) { IDialogCallback callback = new IDialogCallback() { public void okPressed() { - deleteContentCleaner( jsJob ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //deleteContentCleaner( jsJob ); } public void cancelPressed() { @@ -230,19 +237,21 @@ public void cancelPressed() { scheduleLabelPanel.add( new Label( Messages.getString( "deleteGeneratedFilesOlderThan" ), false ) ); scheduleLabelPanel.add( scheduleTextBox ); scheduleLabelPanel.add( new Label( Messages.getString( "daysUsingTheFollowingRules" ), false ) ); - ScheduleRecurrenceDialog editSchedule = + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*ScheduleRecurrenceDialog editSchedule = new ScheduleRecurrenceDialog( null, jsJob, callback, false, false, AbstractWizardDialog.ScheduleDialogType.SCHEDULER ); editSchedule.setShowSuccessDialog( false ); editSchedule.addCustomPanel( scheduleLabelPanel, DockPanel.NORTH ); - editSchedule.center(); + editSchedule.center();*/ } } ); HorizontalPanel scheduleButtonPanel = new HorizontalPanel(); scheduleButtonPanel.add( editScheduleButton ); - if ( !fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //if ( !fakeJob ) { scheduleButtonPanel.add( deleteScheduleButton ); - } + //} scheduledPanel.add( scheduleButtonPanel ); add( scheduledPanel, DockPanel.NORTH ); @@ -335,7 +344,8 @@ public void onError( Request request, Throwable throwable ) { } } - private final native JsJob parseJsonJob( String json ) + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //private final native JsJob parseJsonJob( String json ) /*-{ window.parent.jobjson = json; if (null == json || "" == json) { @@ -345,7 +355,8 @@ private final native JsJob parseJsonJob( String json ) return obj; }-*/; - private final native JsJob createJsJob() + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //private final native JsJob createJsJob() /*-{ var jsJob = new Object(); jsJob.jobParams = new Object(); @@ -366,7 +377,8 @@ private final native JsJob createJsJob() return jsJob; }-*/; - private void deleteContentCleaner( JsJob jsJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*private void deleteContentCleaner( JsJob jsJob ) { if ( jsJob == null || StringUtils.isEmpty( jsJob.getJobId() ) ) { activate(); return; @@ -394,7 +406,7 @@ public void onResponseReceived( Request request, Response response ) { } catch ( RequestException re ) { Window.alert( re.getMessage() ); } - } + }*/ private static void showLoadingIndicator() { WaitPopup.getInstance().setVisible( true ); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java index 117f3e283ab..c255d48ff1a 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java @@ -34,7 +34,8 @@ import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -94,7 +95,8 @@ public void handle( RepositoryFile repositoryFile ) { @Override protected void showDialog( final boolean feedback ) { - final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { @Override protected void onSelect( final String name, final String outputPath, final boolean overwriteFile, final String dateFormat ) { setOutputName( name ); @@ -122,7 +124,7 @@ protected void onSelect( final String name, final String outputPath, final boole outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); outputLocationDialog.setScheduleNameText( Messages.getString( "scheduleNameColonReportviewer" ) ); - outputLocationDialog.center(); + outputLocationDialog.center();*/ } public static native void onCancel() diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index 36bd4d73970..29c6c41195d 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -40,10 +40,11 @@ import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.ScheduleCreateStatusDialog; @@ -196,7 +197,8 @@ protected JSONObject getJsonSimpleTrigger( int repeatCount, int interval, Date s } protected void showDialog( final boolean feedback ) { - final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { @Override protected void onSelect( final String name, final String outputLocationPath, final boolean overwriteFile, final String dateFormat ) { setOutputName( name ); @@ -205,7 +207,7 @@ protected void onSelect( final String name, final String outputLocationPath, fin setDateFormat( dateFormat ); performOperation( feedback ); } - }; + };*/ final String filePath = solutionPath; String urlPath = NameUtils.URLEncode( NameUtils.encodeRepositoryPath( filePath ) ); @@ -225,9 +227,11 @@ public void onResponseReceived( Request request, Response response ) { String responseMessage = response.getText(); boolean hasParams = hasParameters( responseMessage, isXAction ); if ( !hasParams ) { - outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); } - outputLocationDialog.center(); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //outputLocationDialog.center(); } else { MessageDialogBox dialogBox = new MessageDialogBox( @@ -379,18 +383,21 @@ public void onResponseReceived( Request request, Response response ) { // on final boolean isEmailConfValid = false; if ( hasParams ) { - ScheduleParamsDialog dialog = - new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); - dialog.center(); - dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleParamsDialog dialog = + // new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); + //dialog.center(); + //dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); } else if ( isEmailConfValid ) { - ScheduleEmailDialog scheduleEmailDialog = - new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); - scheduleEmailDialog.center(); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleEmailDialog scheduleEmailDialog = + // new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); + //scheduleEmailDialog.center(); } else { // Handle Schedule Parameters - JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); - scheduleRequest.put( "jobParameters", scheduleParams ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); + //scheduleRequest.put( "jobParameters", scheduleParams ); // just run it RequestBuilder scheduleFileRequestBuilder = @@ -459,7 +466,8 @@ public void onResponseReceived( Request request, Response response ) { } } - ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { @Override public void onResponse( JSONValue rib ) { if ( rib != null && rib.isBoolean() != null && rib.isBoolean().booleanValue() ) { @@ -480,5 +488,5 @@ public void onResponse( JSONValue rib ) { dialogBox.center(); } } - }; + };*/ } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java index 290683bb129..6a66f9274bd 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java @@ -23,7 +23,8 @@ import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.messages.Messages; public class ScheduleCallback implements IDialogCallback { @@ -54,7 +55,8 @@ public void cancelPressed() { } }; - ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); } else { final MessageDialogBox dialogBox = new MessageDialogBox( diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index 0dc2091f911..b17d7b690d7 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -56,7 +56,8 @@ import org.pentaho.mantle.client.commands.ExecuteUrlInNewTabCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ShowDescriptionsEvent; import org.pentaho.mantle.client.events.ShowHiddenFilesEvent; @@ -336,7 +337,8 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga } $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - @org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //r@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); } $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES @@ -481,7 +483,8 @@ public void openFile( final RepositoryFile repositoryFile, final FileCommand.COM PerspectiveManager.getInstance().setPerspective( PerspectiveManager.OPENED_PERSPECTIVE ); editFile( repositoryFile ); } else if ( mode == FileCommand.COMMAND.SCHEDULE_NEW ) { - ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); return; } else if ( mode == FileCommand.COMMAND.SHARE ) { ShareFileCommand sfc = new ShareFileCommand(); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 4c1ff25bb3c..7f094f42c08 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -30,7 +30,8 @@ import org.pentaho.mantle.client.commands.NewFolderCommand; import org.pentaho.mantle.client.commands.RunInBackgroundCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.solutionbrowser.IRepositoryFileProvider; import org.pentaho.mantle.client.solutionbrowser.ScheduleCallback; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -97,8 +98,9 @@ public void execute() { } else if ( mode == COMMAND.BACKGROUND ) { new RunInBackgroundCommand( selectedItem ).execute( true ); } else if ( mode == COMMAND.SCHEDULE_NEW ) { - ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem - .getRepositoryFile() ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem + // .getRepositoryFile() ) ); } else if ( mode == COMMAND.SHARE ) { new ShareFileCommand().execute(); } else if ( mode == COMMAND.IMPORT ) { diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index b4d1677af3d..44a90be0510 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -54,7 +54,8 @@ import org.pentaho.mantle.client.ui.xul.JsPerspective; import org.pentaho.mantle.client.ui.xul.JsXulOverlay; import org.pentaho.mantle.client.ui.xul.MantleXul; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; import org.pentaho.platform.api.engine.perspective.pojo.IPluginPerspective; import org.pentaho.platform.plugin.services.pluginmgr.perspective.pojo.DefaultPluginPerspective; import org.pentaho.ui.xul.XulOverlay; @@ -437,14 +438,15 @@ private void showSchedulesPerspective() { GWT.runAsync( new RunAsyncCallback() { public void onSuccess() { - DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); if ( MantleApplication.getInstance().getContentDeck().getWidgetIndex( SchedulesPerspectivePanel.getInstance() ) == -1 ) { contentDeck.add( SchedulesPerspectivePanel.getInstance() ); } else { SchedulesPerspectivePanel.getInstance().refresh(); } - contentDeck.showWidget( contentDeck.getWidgetIndex( SchedulesPerspectivePanel.getInstance() ) ); + contentDeck.showWidget( contentDeck.getWidgetIndex( SchedulesPerspectivePanel.getInstance() ) );*/ } public void onFailure( Throwable reason ) { From 7849502db8a9ce035a2eedf69fadaf662f2d47bf Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Wed, 26 Jul 2023 16:12:34 -0400 Subject: [PATCH 04/59] [BACKLOG-38035] SCHEDULER - moving the scheduler UI into the new scheduler plugin --- user-console/pom.xml | 4 +- .../mantle/client/MantleEntryPoint.java | 1 + .../pentaho/mantle/client/MantleUtils.java | 91 ++++++++++++ .../client/admin/ContentCleanerPanel.java | 136 +++++------------- .../commands/AdhocRunInBackgroundCommand.java | 38 +---- .../commands/RunInBackgroundCommand.java | 116 +++++++-------- .../solutionbrowser/ScheduleCallback.java | 82 ----------- .../ScheduleCreateStatusDialog.java | 46 ------ .../solutionbrowser/SolutionBrowserPanel.java | 15 +- .../solutionbrowser/filelist/FileCommand.java | 12 +- .../mantle/client/ui/PerspectiveManager.java | 26 ++-- .../org/pentaho/mantle/public/Mantle.jsp | 5 +- 12 files changed, 232 insertions(+), 340 deletions(-) create mode 100644 user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java diff --git a/user-console/pom.xml b/user-console/pom.xml index 0c354eb76a6..2c41719e7d0 100644 --- a/user-console/pom.xml +++ b/user-console/pom.xml @@ -374,9 +374,9 @@ org.pentaho.mantle.MantleApplication ${gwt.outputDirectory} -Xms512m -Xmx1024m - + - --> diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java index 14889ff0e99..09ef1974262 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java @@ -41,6 +41,7 @@ public void onModuleLoad() { "mantleMessages", true, MantleEntryPoint.this ); + new MantleUtils(); } public void bundleLoaded( String bundleName ) { diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java new file mode 100644 index 00000000000..cedfb4d991a --- /dev/null +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java @@ -0,0 +1,91 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.mantle.client; + +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestException; +import org.pentaho.mantle.client.events.EventBusUtil; +import org.pentaho.mantle.client.events.GenericEvent; +import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; +import org.pentaho.mantle.client.ui.PerspectiveManager; + +public class MantleUtils { + + static { + setupNativeHooks( new MantleUtils() ); + } + + + public void setSchedulesPerspective() { + PerspectiveManager.getInstance().setPerspective( PerspectiveManager.SCHEDULES_PERSPECTIVE ); + } + + public void setBrowserPerspective() { + PerspectiveManager.getInstance().setPerspective( PerspectiveManager.BROWSER_PERSPECTIVE ); + } + + public boolean containsExtension( String extension ) { + return SolutionBrowserPanel.getInstance().getExecutableFileExtensions().contains( extension ); + } + + public void sendRequest( RequestBuilder executableTypesRequestBuilder ) { + try { + executableTypesRequestBuilder.sendRequest( null, EmptyRequestCallback.getInstance() ); + } catch ( RequestException e ) { + // IGNORE + } + } + + public void fireRefreshFolderEvent( String outputLocation ) { + GenericEvent event = new GenericEvent(); + event.setEventSubType( "RefreshFolderEvent" ); + event.setStringParam( outputLocation ); + EventBusUtil.EVENT_BUS.fireEvent( event ); + } + + private static native void setupNativeHooks( MantleUtils utils ) + /*-{ + $wnd.mantle.setSchedulesPerspective = function() { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::setSchedulesPerspective()(); + } + + $wnd.mantle.setBrowserPerspective = function() { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::setBrowserPerspective()(); + } + + $wnd.mantle.containsExtension = function(extension) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + return utils.@org.pentaho.mantle.client.MantleUtils::containsExtension(Ljava/lang/String;)(extension); + } + + $wnd.mantle.sendRequest = function(executableTypesRequestBuilder) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::sendRequest(Lcom/google/gwt/http/client/RequestBuilder;)(executableTypesRequestBuilder); + } + + $wnd.mantle.fireRefreshFolderEvent = function(outputLocation) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::fireRefreshFolderEvent(Ljava/lang/String;)(outputLocation); + } + }-*/; +} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java index e5b7e5de202..3e68466f92a 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java @@ -21,11 +21,8 @@ package org.pentaho.mantle.client.admin; import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.Request; @@ -49,15 +46,8 @@ import com.google.gwt.user.client.ui.VerticalPanel; import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog; import org.pentaho.mantle.client.dialogs.WaitPopup; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; import org.pentaho.mantle.client.messages.Messages; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.workspace.JsJob; -//import org.pentaho.mantle.client.workspace.JsJobParam; import java.util.Date; @@ -106,35 +96,7 @@ public void onResponseReceived( Request request, Response response ) { nowTextBox.getElement().getStyle().setMarginRight( 5, Unit.PX ); final TextBox scheduleTextBox = new TextBox(); scheduleTextBox.setVisibleLength( 4 ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /* - JsJob tmpJsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); - - boolean fakeJob = false; - if ( tmpJsJob == null ) { - tmpJsJob = createJsJob(); - fakeJob = true; - } - final JsJob jsJob = tmpJsJob; - - if ( jsJob != null ) { - scheduleTextBox.setValue( "" + ( Long.parseLong( jsJob.getJobParamValue( "age" ) ) / DAY_IN_MILLIS ) ); - } else { - scheduleTextBox.setText( "180" ); - } - scheduleTextBox.addChangeHandler( new ChangeHandler() { - public void onChange( ChangeEvent event ) { - if ( jsJob != null ) { - JsArray params = jsJob.getJobParams(); - for ( int i = 0; i < params.length(); i++ ) { - if ( params.get( i ).getName().equals( "age" ) ) { - params.get( i ).setValue( "" + ( Long.parseLong( scheduleTextBox.getText() ) * DAY_IN_MILLIS ) ); - break; - } - } - } - } - } );*/ + processScheduleTextBox( JsonUtils.escapeJsonForEval( response.getText() ), scheduleTextBox ); Label settingsLabel = new Label( Messages.getString( "settings" ) ); settingsLabel.setStyleName( "pentaho-fieldgroup-major" ); @@ -193,30 +155,28 @@ public void cancelPressed() { scheduledPanel.add( deleteScheduleLabel ); Label descLabel; - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*if ( !fakeJob ) { - String desc = jsJob.getJobTrigger().getDescription(); + boolean fakeJob = isFakeJob(); + if ( !fakeJob ) { + String desc = getJobDescription(); descLabel = new Label( desc ); scheduledPanel.add( descLabel ); - } else {*/ + } else { descLabel = new Label( Messages.getString( "generatedFilesAreNotScheduledToBeDeleted" ) ); scheduledPanel.add( descLabel ); - //} + } descLabel.getElement().getStyle().setPaddingTop( 10, Unit.PX ); descLabel.getElement().getStyle().setPaddingBottom( 10, Unit.PX ); Button editScheduleButton = new Button( Messages.getString( "edit" ) ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*if ( fakeJob ) { + if ( fakeJob ) { editScheduleButton.setText( Messages.getString( "scheduleDeletion" ) ); - }*/ + } Button deleteScheduleButton = new Button( Messages.getString( "cancelSchedule" ) ); deleteScheduleButton.setStylePrimaryName( "pentaho-button" ); deleteScheduleButton.addStyleName( "last" ); deleteScheduleButton.addClickHandler( new ClickHandler() { public void onClick( ClickEvent event ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //deleteContentCleaner( jsJob ); + deleteContentCleaner(); } } ); editScheduleButton.setStylePrimaryName( "pentaho-button" ); @@ -225,8 +185,7 @@ public void onClick( ClickEvent event ) { public void onClick( ClickEvent event ) { IDialogCallback callback = new IDialogCallback() { public void okPressed() { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //deleteContentCleaner( jsJob ); + deleteContentCleaner(); } public void cancelPressed() { @@ -237,21 +196,14 @@ public void cancelPressed() { scheduleLabelPanel.add( new Label( Messages.getString( "deleteGeneratedFilesOlderThan" ), false ) ); scheduleLabelPanel.add( scheduleTextBox ); scheduleLabelPanel.add( new Label( Messages.getString( "daysUsingTheFollowingRules" ), false ) ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*ScheduleRecurrenceDialog editSchedule = - new ScheduleRecurrenceDialog( null, jsJob, callback, false, false, - AbstractWizardDialog.ScheduleDialogType.SCHEDULER ); - editSchedule.setShowSuccessDialog( false ); - editSchedule.addCustomPanel( scheduleLabelPanel, DockPanel.NORTH ); - editSchedule.center();*/ + createScheduleRecurrenceDialog( scheduleLabelPanel, callback ); } } ); HorizontalPanel scheduleButtonPanel = new HorizontalPanel(); scheduleButtonPanel.add( editScheduleButton ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //if ( !fakeJob ) { + if ( !fakeJob ) { scheduleButtonPanel.add( deleteScheduleButton ); - //} + } scheduledPanel.add( scheduleButtonPanel ); add( scheduledPanel, DockPanel.NORTH ); @@ -344,42 +296,8 @@ public void onError( Request request, Throwable throwable ) { } } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //private final native JsJob parseJsonJob( String json ) - /*-{ - window.parent.jobjson = json; - if (null == json || "" == json) { - return null; - } - var obj = JSON.parse(json); - return obj; - }-*/; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //private final native JsJob createJsJob() - /*-{ - var jsJob = new Object(); - jsJob.jobParams = new Object(); - jsJob.jobParams.jobParams = []; - jsJob.jobParams.jobParams[0] = new Object(); - jsJob.jobParams.jobParams[0].name = "ActionAdapterQuartzJob-ActionClass"; - jsJob.jobParams.jobParams[0].value = "org.pentaho.platform.admin.GeneratedContentCleaner"; - jsJob.jobParams.jobParams[1] = new Object(); - jsJob.jobParams.jobParams[1].name = "age"; - jsJob.jobParams.jobParams[1].value = "15552000000"; - jsJob.jobTrigger = new Object(); - jsJob.jobTrigger['@type'] = "simpleJobTrigger"; - jsJob.jobTrigger.repeatCount = -1; - jsJob.jobTrigger.repeatInterval = 86400; - jsJob.jobTrigger.scheduleType = "DAILY"; - //jsJob.jobTrigger.startTime = "2013-03-22T09:35:52.276-04:00"; - jsJob.jobName = "GeneratedContentCleaner"; - return jsJob; - }-*/; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*private void deleteContentCleaner( JsJob jsJob ) { - if ( jsJob == null || StringUtils.isEmpty( jsJob.getJobId() ) ) { + private void deleteContentCleaner() { + if ( getJobId() == null ) { activate(); return; } @@ -389,7 +307,7 @@ public void onError( Request request, Throwable throwable ) { builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ JSONObject startJobRequest = new JSONObject(); - startJobRequest.put( "jobId", new JSONString( jsJob.getJobId() ) ); //$NON-NLS-1$ + startJobRequest.put( "jobId", new JSONString( getJobId() ) ); //$NON-NLS-1$ try { builder.sendRequest( startJobRequest.toString(), new RequestCallback() { @@ -406,7 +324,7 @@ public void onResponseReceived( Request request, Response response ) { } catch ( RequestException re ) { Window.alert( re.getMessage() ); } - }*/ + } private static void showLoadingIndicator() { WaitPopup.getInstance().setVisible( true ); @@ -416,4 +334,24 @@ private static void hideLoadingIndicator() { WaitPopup.getInstance().setVisible( false ); } + private native void processScheduleTextBox( String jsonJobString, TextBox scheduleTextBox )/*-{ + $wnd.pho.processScheduleTextBox( jsonJobString, scheduleTextBox ); + }-*/; + + private native boolean isFakeJob()/*-{ + return $wnd.pho.isFakeJob(); + }-*/; + + private native String getJobDescription()/*-{ + return $wnd.pho.getJobDescription(); + }-*/; + + private native String getJobId()/*-{ + return $wnd.pho.getJobId(); + }-*/; + + private native void createScheduleRecurrenceDialog( HorizontalPanel scheduleLabelPanel, IDialogCallback callback )/*-{ + $wnd.pho.createScheduleRecurrenceDialog( scheduleLabelPanel, callback); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java index c255d48ff1a..35742945aa4 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java @@ -34,8 +34,6 @@ import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -95,36 +93,7 @@ public void handle( RepositoryFile repositoryFile ) { @Override protected void showDialog( final boolean feedback ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { - @Override - protected void onSelect( final String name, final String outputPath, final boolean overwriteFile, final String dateFormat ) { - setOutputName( name ); - setOutputLocationPath( outputPath ); - setOverwriteFile( String.valueOf( overwriteFile ) ); - setDateFormat( dateFormat ); - performOperation( feedback ); - } - - @Override protected void onCancel() { - super.onCancel(); - AdhocRunInBackgroundCommand.onCancel(); - } - - @Override protected void onOk() { - super.onOk(); - AdhocRunInBackgroundCommand.onOk( getOutputLocationPath() ); - } - - @Override protected void onAttach() { - super.onAttach(); - AdhocRunInBackgroundCommand.onAttach(); - } - }; - - outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); - outputLocationDialog.setScheduleNameText( Messages.getString( "scheduleNameColonReportviewer" ) ); - outputLocationDialog.center();*/ + createScheduleOutputLocationDialog( getSolutionPath(), getOutputLocationPath(), feedback ); } public static native void onCancel() @@ -243,4 +212,9 @@ private void onError( Throwable exception ) { true ); dialogBox.center(); } + + public native void createScheduleOutputLocationDialog(String solutionPath, String outputLocationPath, Boolean feedback) /*-{ + $wnd.pho.createScheduleOutputLocationDialog(solutionPath, outputLocationPath, feedback); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index 29c6c41195d..bf4e01f0007 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -28,26 +28,18 @@ import com.google.gwt.http.client.Response; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; -import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONBoolean; import com.google.gwt.json.client.JSONNull; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; -import com.google.gwt.json.client.JSONValue; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.solutionbrowser.ScheduleCreateStatusDialog; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; import org.pentaho.mantle.client.solutionbrowser.filelist.FileItem; import org.pentaho.mantle.client.ui.PerspectiveManager; @@ -197,17 +189,9 @@ protected JSONObject getJsonSimpleTrigger( int repeatCount, int interval, Date s } protected void showDialog( final boolean feedback ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { - @Override - protected void onSelect( final String name, final String outputLocationPath, final boolean overwriteFile, final String dateFormat ) { - setOutputName( name ); - setOutputLocationPath( outputLocationPath ); - setOverwriteFile( String.valueOf( overwriteFile ) ); - setDateFormat( dateFormat ); - performOperation( feedback ); - } - };*/ + + createScheduleOutputLocationDialog( getSolutionPath(), feedback ); + final String filePath = solutionPath; String urlPath = NameUtils.URLEncode( NameUtils.encodeRepositoryPath( filePath ) ); @@ -227,11 +211,9 @@ public void onResponseReceived( Request request, Response response ) { String responseMessage = response.getText(); boolean hasParams = hasParameters( responseMessage, isXAction ); if ( !hasParams ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); + setOkButtonText(); } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //outputLocationDialog.center(); + centerScheduleOutputLocationDialog(); } else { MessageDialogBox dialogBox = new MessageDialogBox( @@ -383,21 +365,13 @@ public void onResponseReceived( Request request, Response response ) { // on final boolean isEmailConfValid = false; if ( hasParams ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleParamsDialog dialog = - // new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); - //dialog.center(); - //dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); + boolean isSchedulesPerspectiveActive = !PerspectiveManager.getInstance().getActivePerspective().getId().equals(PerspectiveManager.SCHEDULES_PERSPECTIVE ); + createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid, isSchedulesPerspectiveActive ); } else if ( isEmailConfValid ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleEmailDialog scheduleEmailDialog = - // new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); - //scheduleEmailDialog.center(); + crateScheduleEmailDialog( filePath, scheduleRequest ); } else { // Handle Schedule Parameters - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); - //scheduleRequest.put( "jobParameters", scheduleParams ); + getScheduleParams( scheduleRequest ); // just run it RequestBuilder scheduleFileRequestBuilder = @@ -466,27 +440,55 @@ public void onResponseReceived( Request request, Response response ) { } } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { - @Override - public void onResponse( JSONValue rib ) { - if ( rib != null && rib.isBoolean() != null && rib.isBoolean().booleanValue() ) { - MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "runInBackground" ), Messages.getString( "backgroundExecutionStarted" ), //$NON-NLS-1$ //$NON-NLS-2$ - false, false, true ); - dialogBox.center(); - } else if ( !PerspectiveManager.getInstance().getActivePerspective().getId().equals( - PerspectiveManager.SCHEDULES_PERSPECTIVE ) ) { - ScheduleCreateStatusDialog successDialog = new ScheduleCreateStatusDialog(); - successDialog.center(); - } else { - MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "scheduleUpdatedTitle" ), Messages.getString( "scheduleUpdatedMessage" ), //$NON-NLS-1$ //$NON-NLS-2$ - false, false, true ); - dialogBox.center(); - } + private native void setupNativeHooks( RunInBackgroundCommand cmd ) + /*-{ + $wnd.mantle_runInBackgroundCommand.setOutputName = function(name) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(name); + } + + $wnd.mantle_runInBackgroundCommand.setOutputLocationPath = function(outputPath) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputPath); + } + + $wnd.mantle_runInBackgroundCommand.setOverwriteFile = function(overwriteFile) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOverwriteFile(Ljava/lang/String;)(overwriteFile); + } + + $wnd.mantle_runInBackgroundCommand.setDateFormat = function(dateFormat) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setDateFormat(Ljava/lang/String;)(dateFormat); } - };*/ + + $wnd.mantle_runInBackgroundCommand.performOperation = function(feedback) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Ljava/lang/Boolean;)(feedback); + } + }-*/; + + public native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ + $wnd.pho.createScheduleOutputLocationDialog(solutionPath, feedback); + }-*/; + + public native void setOkButtonText() /*-{ + $wnd.pho.setOkButtonText(); + }-*/; + + public native void centerScheduleOutputLocationDialog() /*-{ + $wnd.pho.centerScheduleOutputLocationDialog(); + }-*/; + + public native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ + $wnd.pho.createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfigValid, isSchedulesPerspectiveActive ); + }-*/; + + public native void crateScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ + $wnd.pho.crateScheduleEmailDialog( filePath, scheduleRequest ); + }-*/; + + public native void getScheduleParams( JSONObject scheduleRequest) /*-{ + $wnd.pho.getScheduleParams( scheduleRequest ); + }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java deleted file mode 100644 index 6a66f9274bd..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.solutionbrowser; - -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; -import org.pentaho.mantle.client.messages.Messages; - -public class ScheduleCallback implements IDialogCallback { - private final RepositoryFile repositoryFile; - - public ScheduleCallback( RepositoryFile repositoryFile ) { - this.repositoryFile = repositoryFile; - } - - @Override - public void okPressed() { - String extension = ""; //$NON-NLS-1$ - if ( repositoryFile.getPath().lastIndexOf( "." ) > 0 ) { //$NON-NLS-1$ - extension = repositoryFile.getPath().substring( repositoryFile.getPath().lastIndexOf( "." ) + 1 ); //$NON-NLS-1$ - } - - if ( SolutionBrowserPanel.getInstance().getExecutableFileExtensions().contains( extension ) ) { - - IDialogCallback callback = new IDialogCallback() { - @Override - public void okPressed() { - ScheduleCreateStatusDialog dialog = new ScheduleCreateStatusDialog(); - dialog.center(); - } - - @Override - public void cancelPressed() { - } - }; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); - } else { - final MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "open" ), Messages.getString( "scheduleInvalidFileType", repositoryFile.getPath() ), false, false, true ); //$NON-NLS-1$ //$NON-NLS-2$ - - dialogBox.setCallback( new IDialogCallback() { - public void cancelPressed() { - } - - public void okPressed() { - dialogBox.hide(); - } - } ); - - dialogBox.center(); - return; - } - } - - @Override - public void cancelPressed() { - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java deleted file mode 100644 index 6569111fe22..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.solutionbrowser; - -import com.google.gwt.user.client.ui.HasHorizontalAlignment; -import com.google.gwt.user.client.ui.Label; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.ui.PerspectiveManager; - -public class ScheduleCreateStatusDialog extends PromptDialogBox { - - public ScheduleCreateStatusDialog() { - super( Messages.getString( "scheduleCreated" ), Messages.getString( "yes" ), Messages.getString( "no" ), false, - true ); - Label label = new Label(); - label.setText( Messages.getString( "scheduleCreateSuccess" ) ); - label.setHorizontalAlignment( HasHorizontalAlignment.ALIGN_LEFT ); - setContent( label ); - setWidth( "400px" ); - } - - protected void onOk() { - super.onOk(); - PerspectiveManager.getInstance().setPerspective( PerspectiveManager.SCHEDULES_PERSPECTIVE ); - } - -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index b17d7b690d7..b332c7a2bea 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -47,6 +47,7 @@ import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.TreeListener; import com.google.gwt.user.client.ui.Widget; +import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; @@ -56,8 +57,6 @@ import org.pentaho.mantle.client.commands.ExecuteUrlInNewTabCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ShowDescriptionsEvent; import org.pentaho.mantle.client.events.ShowHiddenFilesEvent; @@ -336,9 +335,10 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga return solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::setNavigatorShowing(Z)(show); } $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { - //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //r@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); + //MAY NOT BE USED ANYMORE!!!!! + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + //@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); } $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES @@ -483,8 +483,7 @@ public void openFile( final RepositoryFile repositoryFile, final FileCommand.COM PerspectiveManager.getInstance().setPerspective( PerspectiveManager.OPENED_PERSPECTIVE ); editFile( repositoryFile ); } else if ( mode == FileCommand.COMMAND.SCHEDULE_NEW ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); + createSchedule( repositoryFile ); return; } else if ( mode == FileCommand.COMMAND.SHARE ) { ShareFileCommand sfc = new ShareFileCommand(); @@ -836,4 +835,8 @@ public InfoDialog( String title, String message, boolean isHTML, boolean autoHid cancelButton.removeFromParent(); } } + + private native void createSchedule( final RepositoryFile repositoryFile )/*-{ + $wnd.pho.createSchedule( repositoryFile ); + }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 7f094f42c08..81be807abae 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -23,6 +23,7 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.PopupPanel; +import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.mantle.client.commands.ExportFileCommand; import org.pentaho.mantle.client.commands.FilePropertiesCommand; @@ -30,10 +31,7 @@ import org.pentaho.mantle.client.commands.NewFolderCommand; import org.pentaho.mantle.client.commands.RunInBackgroundCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.solutionbrowser.IRepositoryFileProvider; -import org.pentaho.mantle.client.solutionbrowser.ScheduleCallback; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; import org.pentaho.mantle.client.solutionbrowser.filepicklist.FavoritePickList; @@ -98,9 +96,7 @@ public void execute() { } else if ( mode == COMMAND.BACKGROUND ) { new RunInBackgroundCommand( selectedItem ).execute( true ); } else if ( mode == COMMAND.SCHEDULE_NEW ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem - // .getRepositoryFile() ) ); + createSchedule( selectedItem.getRepositoryFile() ); } else if ( mode == COMMAND.SHARE ) { new ShareFileCommand().execute(); } else if ( mode == COMMAND.IMPORT ) { @@ -118,4 +114,8 @@ public void execute() { } } + private native void createSchedule( final RepositoryFile repositoryFile )/*-{ + $wnd.pho.createSchedule( repositoryFile ); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 44a90be0510..18c00bb5172 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -54,8 +54,6 @@ import org.pentaho.mantle.client.ui.xul.JsPerspective; import org.pentaho.mantle.client.ui.xul.JsXulOverlay; import org.pentaho.mantle.client.ui.xul.MantleXul; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; import org.pentaho.platform.api.engine.perspective.pojo.IPluginPerspective; import org.pentaho.platform.plugin.services.pluginmgr.perspective.pojo.DefaultPluginPerspective; import org.pentaho.ui.xul.XulOverlay; @@ -438,15 +436,13 @@ private void showSchedulesPerspective() { GWT.runAsync( new RunAsyncCallback() { public void onSuccess() { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); - if ( MantleApplication.getInstance().getContentDeck().getWidgetIndex( - SchedulesPerspectivePanel.getInstance() ) == -1 ) { - contentDeck.add( SchedulesPerspectivePanel.getInstance() ); + DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); + if ( getSchedulerPerspectivePanelIndex( contentDeck ) == -1 ) { + addSchedulesPerspectivePanel( contentDeck ); } else { - SchedulesPerspectivePanel.getInstance().refresh(); + refreshSchedulesPerspectivePanel(); } - contentDeck.showWidget( contentDeck.getWidgetIndex( SchedulesPerspectivePanel.getInstance() ) );*/ + contentDeck.showWidget( getSchedulerPerspectivePanelIndex( contentDeck ) ); } public void onFailure( Throwable reason ) { @@ -495,6 +491,18 @@ private void hijackContentArea( IPluginPerspective perspective ) { perspectiveActivated( frameElement ); } + public native int getSchedulerPerspectivePanelIndex( DeckPanel contentDeck ) /*-{ + return $wnd.pho.getSchedulerPerspectivePanelIndex( contentDeck ); + }-*/; + + public native void addSchedulesPerspectivePanel( DeckPanel contentDeck ) /*-{ + $wnd.pho.addSchedulesPerspectivePanel( contentDeck ); + }-*/; + + public native void refreshSchedulesPerspectivePanel() /*-{ + $wnd.pho.refreshSchedulesPerspectivePanel(); + }-*/; + private native void perspectiveActivated( Element frameElement ) /*-{ try { diff --git a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp index 3c17035ea82..bdcae39f892 100644 --- a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp +++ b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp @@ -261,7 +261,10 @@ <%if ( hasDataAccessPlugin ) {%> - + + <%}}}%> From d721d74c0489f2e115dbca7ed4bd214af4fc9234 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Fri, 4 Aug 2023 17:34:19 -0400 Subject: [PATCH 05/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../mantle/client/MantleEntryPoint.java | 4 +++ .../commands/RunInBackgroundCommand.java | 35 ++++++++++--------- .../solutionbrowser/SolutionBrowserPanel.java | 4 +-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java index 09ef1974262..634be15f24d 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java @@ -41,6 +41,10 @@ public void onModuleLoad() { "mantleMessages", true, MantleEntryPoint.this ); + initializeNativeHooks(); + } + + private void initializeNativeHooks() { new MantleUtils(); } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index bf4e01f0007..86d516b6051 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -65,6 +65,7 @@ public class RunInBackgroundCommand extends AbstractCommand { private FileItem repositoryFile; public RunInBackgroundCommand() { + setupNativeHooks( this ); } public RunInBackgroundCommand( FileItem fileItem ) { @@ -368,7 +369,7 @@ public void onResponseReceived( Request request, Response response ) { boolean isSchedulesPerspectiveActive = !PerspectiveManager.getInstance().getActivePerspective().getId().equals(PerspectiveManager.SCHEDULES_PERSPECTIVE ); createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid, isSchedulesPerspectiveActive ); } else if ( isEmailConfValid ) { - crateScheduleEmailDialog( filePath, scheduleRequest ); + createScheduleEmailDialog( filePath, scheduleRequest ); } else { // Handle Schedule Parameters getScheduleParams( scheduleRequest ); @@ -440,55 +441,55 @@ public void onResponseReceived( Request request, Response response ) { } } - private native void setupNativeHooks( RunInBackgroundCommand cmd ) + private static native void setupNativeHooks( RunInBackgroundCommand cmd ) /*-{ - $wnd.mantle_runInBackgroundCommand.setOutputName = function(name) { + $wnd.mantle_runInBackgroundCommand_setOutputName = function(outputName) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(name); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(outputName); } - $wnd.mantle_runInBackgroundCommand.setOutputLocationPath = function(outputPath) { + $wnd.mantle_runInBackgroundCommand_setOutputLocationPath = function(outputLocationPath) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputPath); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputLocationPath); } - $wnd.mantle_runInBackgroundCommand.setOverwriteFile = function(overwriteFile) { + $wnd.mantle_runInBackgroundCommand_setOverwriteFile = function(overwriteFile) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOverwriteFile(Ljava/lang/String;)(overwriteFile); } - $wnd.mantle_runInBackgroundCommand.setDateFormat = function(dateFormat) { + $wnd.mantle_runInBackgroundCommand_setDateFormat = function(dateFormat) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setDateFormat(Ljava/lang/String;)(dateFormat); } - $wnd.mantle_runInBackgroundCommand.performOperation = function(feedback) { + $wnd.mantle_runInBackgroundCommand_performOperation = function(feedback) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Ljava/lang/Boolean;)(feedback); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Z)(feedback); } }-*/; - public native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ + private native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ $wnd.pho.createScheduleOutputLocationDialog(solutionPath, feedback); }-*/; - public native void setOkButtonText() /*-{ + private native void setOkButtonText() /*-{ $wnd.pho.setOkButtonText(); }-*/; - public native void centerScheduleOutputLocationDialog() /*-{ + private native void centerScheduleOutputLocationDialog() /*-{ $wnd.pho.centerScheduleOutputLocationDialog(); }-*/; - public native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ + private native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ $wnd.pho.createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfigValid, isSchedulesPerspectiveActive ); }-*/; - public native void crateScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ - $wnd.pho.crateScheduleEmailDialog( filePath, scheduleRequest ); + private native void createScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ + $wnd.pho.createScheduleEmailDialog( filePath, scheduleRequest ); }-*/; - public native void getScheduleParams( JSONObject scheduleRequest) /*-{ + private native void getScheduleParams( JSONObject scheduleRequest) /*-{ $wnd.pho.getScheduleParams( scheduleRequest ); }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index b332c7a2bea..bc605b551db 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -334,12 +334,12 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES return solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::setNavigatorShowing(Z)(show); } - $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { + //$wnd.mantle_confirmBackgroundExecutionDialog = function (url) { //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui //MAY NOT BE USED ANYMORE!!!!! //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES //@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); - } + //} $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::openFile(Ljava/lang/String;Ljava/lang/String;)(pathToFile, mode); From 940c25cc3ab53099ab0e267ab098a735c0158277 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Sun, 20 Aug 2023 18:37:23 -0400 Subject: [PATCH 06/59] BACKLOG-38036 - WIP move scheduler to plugin --- assemblies/pom.xml | 2 +- extensions/pom.xml | 2 +- .../platform/admin/GatherStatsListener.java | 7 +- .../admin/GeneratedContentCleaner.java | 4 +- .../exporter/PentahoPlatformExporter.java | 6 +- .../services/exporter/ScheduleExportUtil.java | 35 +- .../importer/SolutionImportHandler.java | 10 +- .../api/resources/JobScheduleRequest.java | 18 +- .../http/api/resources/SchedulerResource.java | 31 +- .../api/resources/SchedulerResourceUtil.java | 22 +- .../resources/services/SchedulerService.java | 67 +- .../admin/GatherStatsListenerTest.java | 16 +- .../admin/GeneratedContentCleanerTest.java | 4 +- .../exporter/PentahoPlatformExporterTest.java | 18 +- .../exporter/ScheduleExportUtilTest.java | 58 +- .../exportManifest/ExportManifestTest.java | 6 +- .../RepositoryCleanerSystemListenerTest.java | 16 +- .../api/resources/SchedulerResourceTest.java | 44 +- .../resources/SchedulerResourceUtilTest.java | 153 +-- .../services/SchedulerServiceTest.java | 85 +- repository/pom.xml | 2 +- .../blockout/PentahoBlockoutManagerIT.java | 370 ------- .../scheduler2/quartz/QuartzSchedulerIT.java | 325 ------ .../quartz/test/QuartzSchedulerIT.java | 585 ----------- .../quartz/test/QuartzThreadsIT.java | 128 --- .../EmbeddedVersionCheckSystemListenerIT.java | 152 --- .../ws/test/JaxWsSchedulerServiceIT.java | 441 -------- .../ws/test/ScheduleAuthorizationPolicy.java | 36 - .../test/JaxWsSchedulerServiceIT-context.xml | 70 -- .../api/scheduler2/ComplexJobTrigger.java | 631 ------------ .../api/scheduler2/CronJobTrigger.java | 49 - .../IBackgroundExecutionStreamProvider.java | 5 - .../api/scheduler2/IBlockoutManager.java | 19 +- .../api/scheduler2/IComplexJobTrigger.java | 26 + .../{JobParam.java => ICronJobTrigger.java} | 10 +- .../pentaho/platform/api/scheduler2/IJob.java | 28 + .../platform/api/scheduler2/IJobFilter.java | 2 +- .../platform/api/scheduler2/IJobResult.java | 22 +- .../platform/api/scheduler2/IJobTrigger.java | 31 +- .../platform/api/scheduler2/IScheduler.java | 50 +- ...gerAdapter.java => ISimpleJobTrigger.java} | 25 +- .../pentaho/platform/api/scheduler2/Job.java | 248 ----- .../platform/api/scheduler2/JobParams.java | 30 - .../api/scheduler2/JobParamsAdapter.java | 107 -- .../platform/api/scheduler2/JobTrigger.java | 126 --- .../api/scheduler2/SimpleJobTrigger.java | 83 -- .../wrappers/DayOfMonthWrapper.java | 44 - .../scheduler2/wrappers/DayOfWeekWrapper.java | 46 - .../scheduler2/wrappers/HourlyWrapper.java | 42 - .../api/scheduler2/wrappers/ITimeWrapper.java | 4 +- .../scheduler2/wrappers/MinuteWrapper.java | 42 - .../scheduler2/wrappers/MonthlyWrapper.java | 42 - .../scheduler2/wrappers/SecondWrapper.java | 42 - .../scheduler2/wrappers/YearlyWrapper.java | 42 - .../RepositoryCleanerSystemListener.java | 48 +- .../services/repository/RepositoryGcJob.java | 10 +- .../versionchecker/VersionCheckerJob.java | 44 - .../scheduler2/action/ActionRunner.java | 1 - .../action/DefaultActionInvoker.java | 4 +- .../SchedulerOutputPathResolver.java | 2 +- .../scheduler2/blockout/BlockoutAction.java | 66 -- .../blockout/BlockoutManagerUtil.java | 425 -------- .../IBlockoutAction.java} | 26 +- .../blockout/PentahoBlockoutManager.java | 130 --- .../quartz/ActionAdapterQuartzJob.java | 298 ------ .../scheduler2/quartz/BlockingQuartzJob.java | 132 --- .../quartz/EmbeddedQuartzSystemListener.java | 287 ------ .../quartz/QuartzCronStringFactory.java | 153 --- .../scheduler2/quartz/QuartzJobKey.java | 102 -- .../scheduler2/quartz/QuartzScheduler.java | 939 ------------------ .../quartz/QuartzSchedulerAvailability.java | 97 -- .../scheduler2/recur/ITimeRecurrence.java | 2 +- .../recur/IncrementalRecurrence.java | 2 - .../scheduler2/recur/QualifiedDayOfMonth.java | 2 - .../scheduler2/recur/QualifiedDayOfWeek.java | 2 - .../scheduler2/recur/RecurrenceList.java | 2 - .../recur/SequentialRecurrence.java | 2 - .../EmbeddedVersionCheckSystemListener.java | 33 +- .../ws/DefaultSchedulerService.java | 184 ---- .../scheduler2/ws/ISchedulerService.java | 97 -- .../platform/scheduler2/ws/JaxBSafeMap.java | 131 --- .../platform/scheduler2/ws/JobAdapter.java | 172 ---- .../scheduler2/ws/JobParamsAdapter.java | 72 -- .../scheduler2/ws/ListParamValue.java | 29 - .../platform/scheduler2/ws/MapParamValue.java | 29 - .../platform/scheduler2/ws/ParamValue.java | 29 - .../scheduler2/ws/StringParamValue.java | 47 - .../scheduler2/messsages/messages.properties | 46 - .../messsages/messages_de.properties | 44 - .../messsages/messages_fr.properties | 44 - .../messsages/messages_ja.properties | 44 - .../messsages/messages_zh_CN.properties | 46 - .../api/scheduler2/JobParamsAdapterTest.java | 229 ----- .../scheduler2/action/ActionRunnerTest.java | 185 ---- .../action/DefaultActionInvokerTest.java | 86 -- .../platform/scheduler2/email/MockMail.java | 58 -- .../quartz/BlockingQuartzJobTest.java | 202 ---- .../quartz/QuartzSchedulerTest.java | 200 ---- .../quartz/test/ComplexTriggerTest.java | 523 ---------- .../quartz/test/QuartzJobKeyTest.java | 112 --- .../quartz/test/SimpleTriggerTest.java | 56 -- .../quartz/test/StubUserDetailsService.java | 46 - .../quartz/test/StubUserRoleListService.java | 84 -- .../ws/test/ComplexTriggerJAXBTest.java | 143 --- .../ws/test/ComplianceJaxBTest.java | 121 --- .../ws/test/DefaultSchedulerServiceTest.java | 133 --- .../platform/scheduler2/ws/test/JaxBUtil.java | 79 -- .../ws/test/TestQuartzScheduler.java | 35 - .../resources/META-INF/javamail.providers | 2 - 109 files changed, 491 insertions(+), 10135 deletions(-) delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManagerIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzSchedulerIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzThreadsIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListenerIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT.java delete mode 100644 scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/ScheduleAuthorizationPolicy.java delete mode 100644 scheduler/src/it/resources/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT-context.xml delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ComplexJobTrigger.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/CronJobTrigger.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java rename scheduler/src/main/java/org/pentaho/platform/api/scheduler2/{JobParam.java => ICronJobTrigger.java} (87%) create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java rename scheduler/src/main/java/org/pentaho/platform/api/scheduler2/{JobTriggerAdapter.java => ISimpleJobTrigger.java} (59%) delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/Job.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParams.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParamsAdapter.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTrigger.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SimpleJobTrigger.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java rename {extensions => scheduler}/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java (80%) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java (81%) delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler/versionchecker/VersionCheckerJob.java rename scheduler/src/main/java/org/pentaho/platform/scheduler2/{quartz => action}/SchedulerOutputPathResolver.java (99%) delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutManagerUtil.java rename scheduler/src/main/java/org/pentaho/platform/scheduler2/{quartz/StandaloneQuartzSystemListener.java => blockout/IBlockoutAction.java} (56%) delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManager.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/ActionAdapterQuartzJob.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJob.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzCronStringFactory.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzJobKey.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerAvailability.java rename scheduler/src/main/java/org/pentaho/platform/{api => }/scheduler2/recur/ITimeRecurrence.java (95%) delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ISchedulerService.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JaxBSafeMap.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobAdapter.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobParamsAdapter.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ListParamValue.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/MapParamValue.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ParamValue.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/StringParamValue.java delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties delete mode 100644 scheduler/src/test/java/org/pentaho/platform/api/scheduler2/JobParamsAdapterTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/action/ActionRunnerTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/action/DefaultActionInvokerTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/email/MockMail.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJobTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/ComplexTriggerTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/QuartzJobKeyTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/SimpleTriggerTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserDetailsService.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserRoleListService.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplexTriggerJAXBTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplianceJaxBTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/DefaultSchedulerServiceTest.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/JaxBUtil.java delete mode 100644 scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/TestQuartzScheduler.java delete mode 100644 scheduler/src/test/resources/META-INF/javamail.providers diff --git a/assemblies/pom.xml b/assemblies/pom.xml index 8e903f461fa..cf0f438b005 100644 --- a/assemblies/pom.xml +++ b/assemblies/pom.xml @@ -15,7 +15,7 @@ Platform assemblies - 3.0.0 + 3.3.1 plugins ${pentaho-server.directory}/pentaho-solutions Pentaho BI Platform Community Edition diff --git a/extensions/pom.xml b/extensions/pom.xml index add980bc3e3..bb217a6ead9 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -2687,7 +2687,7 @@ org.apache.jackrabbit - jackrabbit-api + oak-jackrabbit-api compile diff --git a/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java b/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java index 18bac176417..e64d5610eb3 100644 --- a/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java +++ b/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java @@ -25,8 +25,8 @@ import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.JobTrigger; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.IJobTrigger; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; import java.io.Serializable; @@ -63,7 +63,8 @@ public boolean startup( IPentahoSession arg0 ) { private void scheduleJob( int intervalInSeconds ) throws Exception { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - JobTrigger trigger = new SimpleJobTrigger( new Date(), null, -1, intervalInSeconds ); + assert scheduler != null; + IJobTrigger trigger = scheduler.createSimpleJobTrigger( new Date(), null, -1, intervalInSeconds ); jobMap.put( "transFileName", getTransFileName() ); scheduler.createJob( GatherStatsListener.JOB_NAME, GatherStatsAction.class, jobMap, trigger ); diff --git a/extensions/src/main/java/org/pentaho/platform/admin/GeneratedContentCleaner.java b/extensions/src/main/java/org/pentaho/platform/admin/GeneratedContentCleaner.java index 669b7fc3d72..fc69792bc3b 100644 --- a/extensions/src/main/java/org/pentaho/platform/admin/GeneratedContentCleaner.java +++ b/extensions/src/main/java/org/pentaho/platform/admin/GeneratedContentCleaner.java @@ -26,9 +26,9 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.RepositoryFileTree; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.repository2.ClientRepositoryPaths; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import java.io.Serializable; import java.util.ArrayList; @@ -83,7 +83,7 @@ private void findGeneratedContent( List generatedContentList, Re logger.debug( "File passes age criteria" ); // now check metadata for RESERVEDMAPKEY_LINEAGE_ID (all generated content has) Map metadata = repository.getFileMetadata( parentFile.getId() ); - if ( metadata.containsKey( QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID ) ) { + if ( metadata.containsKey( IScheduler.RESERVEDMAPKEY_LINEAGE_ID ) ) { logger.debug( "File is generated content - adding to delete list" ); generatedContentList.add( parentFile ); } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java index f7252be11e3..2102b12332e 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java @@ -35,7 +35,7 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; @@ -311,8 +311,8 @@ protected boolean parseXmlaEnabled( String dataSourceInfo ) { protected void exportSchedules() { log.debug( "export schedules" ); try { - List jobs = getScheduler().getJobs( null ); - for ( Job job : jobs ) { + List jobs = getScheduler().getJobs( null ); + for ( IJob job : jobs ) { if ( job.getJobName().equals( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ) ) { // don't bother exporting the Version Checker schedule, it gets created automatically on server start // if it doesn't exist and fails if you try to import it due to a null ActionClass diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java index 83034c8a535..8a408018ce1 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java @@ -26,14 +26,16 @@ import java.util.Map; import org.apache.commons.lang.ArrayUtils; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.IJob; + +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; +import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.repository.RepositoryFilenameUtils; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; @@ -46,11 +48,12 @@ public ScheduleExportUtil() { // to get 100% coverage } - public static JobScheduleRequest createJobScheduleRequest( Job job ) { + public static JobScheduleRequest createJobScheduleRequest( IJob job ) { if ( job == null ) { throw new IllegalArgumentException( Messages.getInstance().getString( "ScheduleExportUtil.JOB_MUST_NOT_BE_NULL" ) ); } - + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + assert scheduler != null; JobScheduleRequest schedule = new JobScheduleRequest(); schedule.setJobName( job.getJobName() ); schedule.setDuration( job.getJobTrigger().getDuration() ); @@ -58,7 +61,7 @@ public static JobScheduleRequest createJobScheduleRequest( Job job ) { Map jobParams = job.getJobParams(); - Object streamProviderObj = jobParams.get( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ); + Object streamProviderObj = jobParams.get( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER ); RepositoryFileStreamProvider streamProvider = null; if ( streamProviderObj instanceof RepositoryFileStreamProvider ) { streamProvider = (RepositoryFileStreamProvider) streamProviderObj; @@ -111,7 +114,7 @@ public static JobScheduleRequest createJobScheduleRequest( Job job ) { JobScheduleParam param = null; if ( serializable instanceof String ) { String value = (String) serializable; - if ( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS.equals( key ) ) { + if ( IScheduler.RESERVEDMAPKEY_ACTIONCLASS.equals( key ) ) { schedule.setActionClass( value ); } else if ( IBlockoutManager.TIME_ZONE_PARAM.equals( key ) ) { schedule.setTimeZone( value ); @@ -130,22 +133,22 @@ public static JobScheduleRequest createJobScheduleRequest( Job job ) { } } - if ( job.getJobTrigger() instanceof SimpleJobTrigger ) { - SimpleJobTrigger jobTrigger = (SimpleJobTrigger) job.getJobTrigger(); + if ( job.getJobTrigger() instanceof ISimpleJobTrigger ) { + ISimpleJobTrigger jobTrigger = (ISimpleJobTrigger) job.getJobTrigger(); schedule.setSimpleJobTrigger( jobTrigger ); - } else if ( job.getJobTrigger() instanceof ComplexJobTrigger ) { - ComplexJobTrigger jobTrigger = (ComplexJobTrigger) job.getJobTrigger(); + } else if ( job.getJobTrigger() instanceof IComplexJobTrigger ) { + IComplexJobTrigger jobTrigger = (IComplexJobTrigger) job.getJobTrigger(); // force it to a cron trigger to get the auto-parsing of the complex trigger - CronJobTrigger cron = new CronJobTrigger(); + ICronJobTrigger cron = scheduler.createCronJobTrigger(); cron.setCronString( jobTrigger.getCronString() ); cron.setStartTime( jobTrigger.getStartTime() ); cron.setEndTime( jobTrigger.getEndTime() ); cron.setDuration( jobTrigger.getDuration() ); cron.setUiPassParam( jobTrigger.getUiPassParam() ); schedule.setCronJobTrigger( cron ); - } else if ( job.getJobTrigger() instanceof CronJobTrigger ) { - CronJobTrigger jobTrigger = (CronJobTrigger) job.getJobTrigger(); + } else if ( job.getJobTrigger() instanceof ICronJobTrigger ) { + ICronJobTrigger jobTrigger = (ICronJobTrigger) job.getJobTrigger(); schedule.setCronJobTrigger( jobTrigger ); } else { // don't know what this is, can't export it diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index d395303d889..262bdf562f3 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -55,8 +55,8 @@ import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.Job.JobState; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJob.JobState; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; @@ -296,7 +296,7 @@ public void importFile( IPlatformImportBundle bundle ) throws PlatformImportExce localeFilesProcessor.processLocaleFiles( importer ); } - List getAllJobs( SchedulerResource schedulerResource ) { + List getAllJobs( SchedulerResource schedulerResource ) { return schedulerResource.getAllJobs(); } @@ -314,7 +314,7 @@ protected void importSchedules( List scheduleList ) throws P boolean jobExists = false; - List jobs = getAllJobs( schedulerResource ); + List jobs = getAllJobs( schedulerResource ); if ( jobs != null ) { //paramRequest to map @@ -323,7 +323,7 @@ protected void importSchedules( List scheduleList ) throws P mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() ); } - for ( Job job : jobs ) { + for ( IJob job : jobs ) { if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null ) && ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java index e06c996129d..ba3b54a158c 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java @@ -26,9 +26,9 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; -import org.pentaho.platform.api.scheduler2.Job.JobState; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; +import org.pentaho.platform.api.scheduler2.IJob.JobState; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; @XmlRootElement public class JobScheduleRequest implements Serializable { @@ -87,11 +87,11 @@ public class JobScheduleRequest implements Serializable { String actionClass; - CronJobTrigger cronJobTrigger; + ICronJobTrigger cronJobTrigger; ComplexJobTriggerProxy complexJobTrigger; - SimpleJobTrigger simpleJobTrigger; + ISimpleJobTrigger simpleJobTrigger; ArrayList jobParameters = new ArrayList(); @@ -117,11 +117,11 @@ public void setOutputFile( String file ) { this.outputFile = file; } - public CronJobTrigger getCronJobTrigger() { + public ICronJobTrigger getCronJobTrigger() { return cronJobTrigger; } - public void setCronJobTrigger( CronJobTrigger jobTrigger ) { + public void setCronJobTrigger( ICronJobTrigger jobTrigger ) { if ( jobTrigger != null ) { setComplexJobTrigger( null ); setSimpleJobTrigger( null ); @@ -141,11 +141,11 @@ public void setComplexJobTrigger( ComplexJobTriggerProxy jobTrigger ) { this.complexJobTrigger = jobTrigger; } - public SimpleJobTrigger getSimpleJobTrigger() { + public ISimpleJobTrigger getSimpleJobTrigger() { return simpleJobTrigger; } - public void setSimpleJobTrigger( SimpleJobTrigger jobTrigger ) { + public void setSimpleJobTrigger( ISimpleJobTrigger jobTrigger ) { if ( jobTrigger != null ) { setCronJobTrigger( null ); setComplexJobTrigger( null ); diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java index 5cfea213baf..9aa0803be3c 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java @@ -50,9 +50,8 @@ import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.Job.JobState; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; @@ -123,7 +122,7 @@ public SchedulerResource() { } ) public Response createJob( JobScheduleRequest scheduleRequest ) { try { - Job job = schedulerService.createJob( scheduleRequest ); + IJob job = schedulerService.createJob( scheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); } catch ( SchedulerException e ) { return buildServerErrorResponse( e.getCause().getMessage() ); @@ -186,7 +185,7 @@ public Response createJob( JobScheduleRequest scheduleRequest ) { } ) public Response updateJob( JobScheduleRequest scheduleRequest ) { try { - Job job = schedulerService.updateJob( scheduleRequest ); + IJob job = schedulerService.updateJob( scheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); } catch ( SchedulerException e ) { return buildServerErrorResponse( e.getCause().getMessage() ); @@ -233,7 +232,7 @@ public Response updateJob( JobScheduleRequest scheduleRequest ) { } ) public Response triggerNow( JobRequest jobRequest ) { try { - Job job = schedulerService.triggerNow( jobRequest.getJobId() ); + IJob job = schedulerService.triggerNow( jobRequest.getJobId() ); return buildPlainTextOkResponse( job.getState().name() ); } catch ( SchedulerException e ) { throw new RuntimeException( e ); @@ -302,7 +301,7 @@ public Response triggerNow( JobRequest jobRequest ) { @ResponseCode ( code = 200, condition = "Content cleaner job successfully retrieved." ), @ResponseCode ( code = 204, condition = "No content cleaner job exists." ), } ) - public Job getContentCleanerJob() { + public IJob getContentCleanerJob() { try { return schedulerService.getContentCleanerJob(); } catch ( SchedulerException e ) { @@ -414,7 +413,7 @@ public Job getContentCleanerJob() { @ResponseCode ( code = 200, condition = "Jobs retrieved successfully." ), @ResponseCode ( code = 500, condition = "Error while retrieving jobs." ) } ) - public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString" ) Boolean asCronString ) { + public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString" ) Boolean asCronString ) { try { return schedulerService.getJobs(); } catch ( SchedulerException e ) { @@ -523,7 +522,7 @@ public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString" @ResponseCode ( code = 200, condition = "Jobs retrieved successfully." ), @ResponseCode ( code = 500, condition = "Error while retrieving jobs." ), } ) - public List getAllJobs() { + public List getAllJobs() { try { return schedulerService.getJobs(); } catch ( SchedulerException e ) { @@ -792,7 +791,7 @@ public Response getJobState( JobRequest jobRequest ) { } ) public Response pauseJob( JobRequest jobRequest ) { try { - JobState state = schedulerService.pauseJob( jobRequest.getJobId() ); + IJob.JobState state = schedulerService.pauseJob( jobRequest.getJobId() ); return buildPlainTextOkResponse( state.name() ); } catch ( SchedulerException e ) { throw new RuntimeException( e ); @@ -832,7 +831,7 @@ public Response pauseJob( JobRequest jobRequest ) { } ) public Response resumeJob( JobRequest jobRequest ) { try { - JobState state = schedulerService.resumeJob( jobRequest.getJobId() ); + IJob.JobState state = schedulerService.resumeJob( jobRequest.getJobId() ); return buildPlainTextOkResponse( state.name() ); } catch ( SchedulerException e ) { throw new RuntimeException( e ); @@ -911,7 +910,7 @@ public Response deleteJob( JobRequest jobRequest ) { if ( schedulerService.removeJob( jobRequest.getJobId() ) ) { return buildPlainTextOkResponse( "REMOVED" ); } - Job job = schedulerService.getJob( jobRequest.getJobId() ); + IJob job = schedulerService.getJob( jobRequest.getJobId() ); return buildPlainTextOkResponse( job.getState().name() ); } catch ( SchedulerException e ) { throw new RuntimeException( e ); @@ -946,7 +945,7 @@ public Response deleteJob( JobRequest jobRequest ) { public Response getJob( @QueryParam( "jobId" ) String jobId, @DefaultValue( "false" ) @QueryParam( "asCronString" ) String asCronString ) { try { - Job jobInfo = schedulerService.getJobInfo( jobId ); + IJob jobInfo = schedulerService.getJobInfo( jobId ); if ( jobInfo == null ) { return buildStatusResponse( Status.NO_CONTENT ); } @@ -973,7 +972,7 @@ public JobScheduleRequest getJobInfo() { */ @Deprecated @Facet ( name = "Unsupported" ) - public List getJobs() { + public List getJobs() { return getBlockoutJobs(); } @@ -1070,7 +1069,7 @@ public List getJobs() { @StatusCodes ( { @ResponseCode ( code = 200, condition = "Successfully retrieved blockout jobs." ), } ) - public List getBlockoutJobs() { + public List getBlockoutJobs() { return schedulerService.getBlockOutJobs(); } @@ -1146,7 +1145,7 @@ public Response hasBlockouts() { } ) public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { try { - Job job = schedulerService.addBlockout( jobScheduleRequest ); + IJob job = schedulerService.addBlockout( jobScheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); } catch ( IOException e ) { return buildStatusResponse( UNAUTHORIZED ); @@ -1204,7 +1203,7 @@ public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { } ) public Response updateBlockout( @QueryParam ( "jobid" ) String jobId, JobScheduleRequest jobScheduleRequest ) { try { - Job job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); + IJob job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); } catch ( IOException e ) { return buildStatusResponse( Status.UNAUTHORIZED ); diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java index 1bc50f70db4..5e1b0bc57a9 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java @@ -30,14 +30,13 @@ 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.IComplexJobTrigger; 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.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.plugin.services.exporter.ScheduleExportUtil; import org.pentaho.platform.repository.RepositoryFilenameUtils; -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; @@ -64,6 +63,7 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest IScheduler scheduler ) throws SchedulerException, UnifiedRepositoryException { + // Used to determine if created by a RunInBackgroundCommand boolean runInBackground = scheduleRequest.getSimpleJobTrigger() == null && scheduleRequest.getComplexJobTrigger() == null @@ -71,11 +71,11 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest // 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 ) + runInBackground ? scheduler.createSimpleJobTrigger( new Date( System.currentTimeMillis() + 10000 ), null, 0, 0 ) : scheduleRequest.getSimpleJobTrigger(); if ( scheduleRequest.getSimpleJobTrigger() != null ) { - SimpleJobTrigger simpleJobTrigger = scheduleRequest.getSimpleJobTrigger(); + ISimpleJobTrigger simpleJobTrigger = scheduleRequest.getSimpleJobTrigger(); if ( simpleJobTrigger.getStartTime() == null ) { simpleJobTrigger.setStartTime( new Date() ); @@ -87,7 +87,7 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest ComplexJobTriggerProxy proxyTrigger = scheduleRequest.getComplexJobTrigger(); String cronString = proxyTrigger.getCronString(); - ComplexJobTrigger complexJobTrigger = null; + IComplexJobTrigger complexJobTrigger = null; /** * We will have two options. Either it is a daily scehdule to ignore DST or any other * complex schedule @@ -95,9 +95,9 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest if(cronString != null && cronString.equals("TO_BE_GENERATED")) { cronString = generateCronString((int)proxyTrigger.getRepeatInterval()/86400 ,proxyTrigger.getStartTime()); - complexJobTrigger = QuartzScheduler.createComplexTrigger( cronString ); + complexJobTrigger = scheduler.createComplexTrigger( cronString ); } else { - complexJobTrigger = new ComplexJobTrigger(); + complexJobTrigger = scheduler.createComplexJobTrigger(); if ( proxyTrigger.getDaysOfWeek().length > 0 ) { if ( proxyTrigger.getWeeksOfMonth().length > 0 ) { for ( int dayOfWeek : proxyTrigger.getDaysOfWeek() ) { @@ -137,7 +137,7 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest Calendar calendar = Calendar.getInstance(); calendar.setTime( proxyTrigger.getStartTime() ); complexJobTrigger.setHourlyRecurrence( calendar.get( Calendar.HOUR_OF_DAY ) ); - complexJobTrigger.setMinuteRecurrence( calendar.get( Calendar.MINUTE ) ); + complexJobTrigger.addMinuteRecurrence( calendar.get( Calendar.MINUTE ) ); } complexJobTrigger.setStartTime( proxyTrigger.getStartTime() ); @@ -148,14 +148,14 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest } else if ( scheduleRequest.getCronJobTrigger() != null ) { - if ( scheduler instanceof QuartzScheduler ) { + if ( scheduler instanceof IScheduler ) { 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 ); + IComplexJobTrigger complexJobTrigger = scheduler.createComplexTrigger( cronString ); complexJobTrigger.setStartTime( scheduleRequest.getCronJobTrigger().getStartTime() ); complexJobTrigger.setEndTime( scheduleRequest.getCronJobTrigger().getEndTime() ); complexJobTrigger.setDuration( scheduleRequest.getCronJobTrigger().getDuration() ); diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java index 864fe1dc998..7b39cbe3e5d 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java @@ -33,18 +33,17 @@ import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.scheduler2.IBlockoutManager; +import org.pentaho.platform.scheduler2.blockout.IBlockoutAction; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.Job.JobState; +import org.pentaho.platform.api.scheduler2.IJob.JobState; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.security.SecurityHelper; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.scheduler2.blockout.BlockoutAction; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; import org.pentaho.platform.util.ActionUtil; @@ -84,7 +83,7 @@ public class SchedulerService { private static final Log logger = LogFactory.getLog( FileService.class ); - public Job createJob( JobScheduleRequest scheduleRequest ) + public IJob createJob( JobScheduleRequest scheduleRequest ) throws IOException, SchedulerException, IllegalAccessException { // Used to determine if created by a RunInBackgroundCommand @@ -137,7 +136,7 @@ public Job createJob( JobScheduleRequest scheduleRequest ) updateStartDateForTimeZone( scheduleRequest ); } - Job job = null; + IJob job = null; IJobTrigger jobTrigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); @@ -179,20 +178,20 @@ public Job createJob( JobScheduleRequest scheduleRequest ) return job; } - public Job updateJob( JobScheduleRequest scheduleRequest ) + public IJob updateJob( JobScheduleRequest scheduleRequest ) throws IllegalAccessException, IOException, SchedulerException { - Job job = getScheduler().getJob( scheduleRequest.getJobId() ); + IJob job = getScheduler().getJob( scheduleRequest.getJobId() ); if ( job != null ) { scheduleRequest.getJobParameters() - .add( new JobScheduleParam( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER, job.getUserName() ) ); + .add( new JobScheduleParam( IScheduler.RESERVEDMAPKEY_ACTIONUSER, job.getUserName() ) ); } - Job newJob = createJob( scheduleRequest ); + IJob newJob = createJob( scheduleRequest ); removeJob( scheduleRequest.getJobId() ); return newJob; } - public Job triggerNow( String jobId ) throws SchedulerException { - Job job = getScheduler().getJob( jobId ); + public IJob triggerNow( String jobId ) throws SchedulerException { + IJob job = getScheduler().getJob( jobId ); if ( getPolicy().isAllowed( SchedulerAction.NAME ) ) { getScheduler().triggerNow( jobId ); } else { @@ -206,13 +205,13 @@ public Job triggerNow( String jobId ) throws SchedulerException { return job; } - public Job getContentCleanerJob() throws SchedulerException { + public IJob getContentCleanerJob() throws SchedulerException { IPentahoSession session = getSession(); final String principalName = session.getName(); // this authentication wasn't matching with the job user name, // changed to get name via the current session final Boolean canAdminister = getPolicy().isAllowed( AdministerSecurityAction.NAME ); - List jobs = getScheduler().getJobs( getJobFilter( canAdminister, principalName ) ); + List jobs = getScheduler().getJobs( getJobFilter( canAdminister, principalName ) ); if ( jobs.size() > 0 ) { return jobs.get( 0 ); @@ -228,10 +227,10 @@ public Job getContentCleanerJob() throws SchedulerException { */ public List doGetGeneratedContentForSchedule( String lineageId ) throws FileNotFoundException { return getFileService().searchGeneratedContent( getSessionResource().doGetCurrentUserDir(), lineageId, - QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID ); + IScheduler.RESERVEDMAPKEY_LINEAGE_ID ); } - public Job getJob( String jobId ) throws SchedulerException { + public IJob getJob( String jobId ) throws SchedulerException { return getScheduler().getJob( jobId ); } @@ -265,7 +264,7 @@ public JobFilter( boolean canAdminister, String principalName ) { } @Override - public boolean accept( Job job ) { + public boolean accept( IJob job ) { String actionClass = (String) job.getJobParams().get( "ActionAdapterQuartzJob-ActionClass" ); if ( canAdminister && "org.pentaho.platform.admin.GeneratedContentCleaner".equals( actionClass ) ) { return true; @@ -305,7 +304,7 @@ public String shutdown() throws SchedulerException { } public JobState pauseJob( String jobId ) throws SchedulerException { - Job job = getJob( jobId ); + IJob job = getJob( jobId ); if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { getScheduler().pauseJob( jobId ); } @@ -314,7 +313,7 @@ public JobState pauseJob( String jobId ) throws SchedulerException { } public JobState resumeJob( String jobId ) throws SchedulerException { - Job job = getJob( jobId ); + IJob job = getJob( jobId ); if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { getScheduler().resumeJob( jobId ); } @@ -323,7 +322,7 @@ public JobState resumeJob( String jobId ) throws SchedulerException { } public boolean removeJob( String jobId ) throws SchedulerException { - Job job = getJob( jobId ); + IJob job = getJob( jobId ); if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { getScheduler().removeJob( jobId ); return true; @@ -331,8 +330,8 @@ public boolean removeJob( String jobId ) throws SchedulerException { return false; } - public Job getJobInfo( String jobId ) throws SchedulerException { - Job job = getJob( jobId ); + public IJob getJobInfo( String jobId ) throws SchedulerException { + IJob job = getJob( jobId ); if ( job == null ) { return null; } @@ -354,12 +353,12 @@ public Job getJobInfo( String jobId ) throws SchedulerException { } } - public List getBlockOutJobs() { + public List getBlockOutJobs() { return getBlockoutManager().getBlockOutJobs(); } public boolean hasBlockouts() { - List jobs = getBlockoutManager().getBlockOutJobs(); + List jobs = getBlockoutManager().getBlockOutJobs(); return jobs != null && jobs.size() > 0; } @@ -371,10 +370,10 @@ public boolean shouldFireNow() { return getBlockoutManager().shouldFireNow(); } - public Job addBlockout( JobScheduleRequest jobScheduleRequest ) + public IJob addBlockout( JobScheduleRequest jobScheduleRequest ) throws IOException, IllegalAccessException, SchedulerException { if ( canAdminister() ) { - jobScheduleRequest.setActionClass( BlockoutAction.class.getCanonicalName() ); + jobScheduleRequest.setActionClass( IBlockoutAction.getCanonicalName() ); jobScheduleRequest.getJobParameters().add( getJobScheduleParam( IBlockoutManager.DURATION_PARAM, jobScheduleRequest.getDuration() ) ); jobScheduleRequest.getJobParameters() @@ -396,12 +395,12 @@ protected void updateStartDateForTimeZone( JobScheduleRequest jobScheduleRequest SchedulerResourceUtil.updateStartDateForTimeZone( jobScheduleRequest ); } - public Job updateBlockout( String jobId, JobScheduleRequest jobScheduleRequest ) + public IJob updateBlockout( String jobId, JobScheduleRequest jobScheduleRequest ) throws IllegalAccessException, SchedulerException, IOException { if ( canAdminister() ) { boolean isJobRemoved = removeJob( jobId ); if ( isJobRemoved ) { - Job job = addBlockout( jobScheduleRequest ); + IJob job = addBlockout( jobScheduleRequest ); return job; } } @@ -449,7 +448,7 @@ public JobScheduleRequest getJobInfo() { } public JobState getJobState( JobRequest jobRequest ) throws SchedulerException { - Job job = getJob( jobRequest.getJobId() ); + IJob job = getJob( jobRequest.getJobId() ); if ( isScheduleAllowed() || getSession().getName().equals( job.getUserName() ) ) { return job.getState(); } @@ -505,7 +504,7 @@ protected HashMap handlePDIScheduling( RepositoryFile file public boolean getAutoCreateUniqueFilename( final JobScheduleRequest scheduleRequest ) { ArrayList jobParameters = scheduleRequest.getJobParameters(); for ( JobScheduleParam jobParameter : jobParameters ) { - if ( QuartzScheduler.RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME.equals( jobParameter.getName() ) && "boolean" + if ( IScheduler.RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME.equals( jobParameter.getName() ) && "boolean" .equals( jobParameter.getType() ) ) { return (Boolean) jobParameter.getValue(); } @@ -516,7 +515,7 @@ public boolean getAutoCreateUniqueFilename( final JobScheduleRequest scheduleReq public String getAppendDateFormat( final JobScheduleRequest scheduleRequest ) { ArrayList jobParameters = scheduleRequest.getJobParameters(); for ( JobScheduleParam jobParameter : jobParameters ) { - if ( QuartzScheduler.RESERVEDMAPKEY_APPEND_DATE_FORMAT.equals( jobParameter.getName() ) && "string" + if ( IScheduler.RESERVEDMAPKEY_APPEND_DATE_FORMAT.equals( jobParameter.getName() ) && "string" .equals( jobParameter.getType() ) ) { return (String) jobParameter.getValue(); } @@ -524,15 +523,15 @@ public String getAppendDateFormat( final JobScheduleRequest scheduleRequest ) { return null; } - public List getJobs() throws SchedulerException { + public List getJobs() throws SchedulerException { IPentahoSession session = getSession(); final String principalName = session.getName(); // this authentication wasn't matching with the job user name, // changed to get name via the current session final Boolean canAdminister = canAdminister( session ); - List jobs = getScheduler().getJobs( new IJobFilter() { + List jobs = getScheduler().getJobs( new IJobFilter() { @Override - public boolean accept( Job job ) { + public boolean accept( IJob job ) { if ( canAdminister ) { return !IBlockoutManager.BLOCK_OUT_JOB_NAME.equals( job.getJobName() ); } diff --git a/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java b/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java index 8d903a27a79..ce4e3dd74ec 100644 --- a/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java +++ b/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java @@ -28,8 +28,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.JobTrigger; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.engine.core.system.PentahoSystem; @@ -63,12 +63,12 @@ public void setUp() throws Exception { public void testStartUp() throws Exception { PentahoSystem.registerObject( scheduler ); - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); when( scheduler.createJob( eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( JobTrigger.class ) ) ).thenReturn( job ); + any( IJobTrigger.class ) ) ).thenReturn( job ); boolean startup = gatherStatsListener.startup( session ); assertTrue( startup ); @@ -79,7 +79,7 @@ public void testStartUp() throws Exception { eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( JobTrigger.class ) ); + any( IJobTrigger.class ) ); } @Test @@ -96,7 +96,7 @@ public void testStartup_withExceptionFromScheduleJobCall() throws Exception { eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( JobTrigger.class ) ) ).thenThrow( new SchedulerException( "error" ) ); + any( IJobTrigger.class ) ) ).thenThrow( new SchedulerException( "error" ) ); boolean startup = gatherStatsListener.startup( session ); assertTrue( startup ); @@ -107,11 +107,11 @@ public void testStartup_withExceptionFromScheduleJobCall() throws Exception { eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( JobTrigger.class ) ); + any( IJobTrigger.class ) ); } @After public void cleanup() { PentahoSystem.clearObjectFactory(); } -} \ No newline at end of file +} diff --git a/extensions/src/test/java/org/pentaho/platform/admin/GeneratedContentCleanerTest.java b/extensions/src/test/java/org/pentaho/platform/admin/GeneratedContentCleanerTest.java index 6c7607ec38e..d5e06b7ed65 100644 --- a/extensions/src/test/java/org/pentaho/platform/admin/GeneratedContentCleanerTest.java +++ b/extensions/src/test/java/org/pentaho/platform/admin/GeneratedContentCleanerTest.java @@ -30,8 +30,8 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.RepositoryFileTree; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import java.io.Serializable; import java.text.SimpleDateFormat; @@ -101,7 +101,7 @@ public void testExecute_oldFilesInFolderDeleted() throws Exception { when( repo.getTree( nullable( String.class ), eq( -1 ), nullable( String.class ), eq( true ) ) ).thenReturn( rootRepoFileTree ); Map values = new HashMap<>(); - values.put( QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID, "lineageIdGoesHere" ); + values.put( IScheduler.RESERVEDMAPKEY_LINEAGE_ID, "lineageIdGoesHere" ); when( repo.getFileMetadata( FILE_ID ) ).thenReturn( values ); generatedContentCleaner.execute(); diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java index 347d69d418b..e345e08ace3 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java @@ -32,10 +32,10 @@ import org.pentaho.platform.api.mt.ITenant; import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.JobTrigger; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; @@ -121,13 +121,13 @@ public void tearDown() { @Test public void testExportSchedules() throws Exception { - List jobs = new ArrayList<>(); - ComplexJobTrigger trigger = mock( ComplexJobTrigger.class ); - JobTrigger unknownTrigger = mock( JobTrigger.class ); + List jobs = new ArrayList<>(); + IComplexJobTrigger trigger = mock( IComplexJobTrigger.class ); + IJobTrigger unknownTrigger = mock( IJobTrigger.class ); - Job job1 = mock( Job.class ); - Job job2 = mock( Job.class ); - Job job3 = mock( Job.class ); + IJob job1 = mock( IJob.class ); + IJob job2 = mock( IJob.class ); + IJob job3 = mock( IJob.class ); jobs.add( job1 ); jobs.add( job2 ); jobs.add( job3 ); diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java index 866eabba9b0..aa3bf08e6a9 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java @@ -22,13 +22,13 @@ import org.junit.Before; import org.junit.Test; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.JobTrigger; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; @@ -58,8 +58,8 @@ public void testCreateJobScheduleRequest_null() throws Exception { public void testCreateJobScheduleRequest_unknownTrigger() throws Exception { String jobName = "JOB"; - Job job = mock( Job.class ); - JobTrigger trigger = mock( JobTrigger.class ); + IJob job = mock( IJob.class ); + IJobTrigger trigger = mock( IJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); @@ -71,8 +71,8 @@ public void testCreateJobScheduleRequest_unknownTrigger() throws Exception { public void testCreateJobScheduleRequest_SimpleJobTrigger() throws Exception { String jobName = "JOB"; - Job job = mock( Job.class ); - SimpleJobTrigger trigger = mock( SimpleJobTrigger.class ); + IJob job = mock( IJob.class ); + ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -88,8 +88,8 @@ public void testCreateJobScheduleRequest_SimpleJobTrigger() throws Exception { public void testCreateJobScheduleRequest_NoStreamProvider() throws Exception { String jobName = "JOB"; - Job job = mock( Job.class ); - SimpleJobTrigger trigger = mock( SimpleJobTrigger.class ); + IJob job = mock( IJob.class ); + ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -117,13 +117,13 @@ public void testCreateJobScheduleRequest_NoStreamProvider() throws Exception { public void testCreateJobScheduleRequest_StringStreamProvider() throws Exception { String jobName = "JOB"; - Job job = mock( Job.class ); - SimpleJobTrigger trigger = mock( SimpleJobTrigger.class ); + IJob job = mock( IJob.class ); + ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); Map params = new HashMap<>(); - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "import file = /home/admin/myJob.kjb:output file=/home/admin/myJob*" ); + params.put( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "import file = /home/admin/myJob.kjb:output file=/home/admin/myJob*" ); when( job.getJobParams() ).thenReturn( params ); JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); @@ -140,8 +140,8 @@ public void testCreateJobScheduleRequest_ComplexJobTrigger() throws Exception { String jobName = "JOB"; Date now = new Date(); - Job job = mock( Job.class ); - ComplexJobTrigger trigger = mock( ComplexJobTrigger.class ); + IJob job = mock( IJob.class ); + IComplexJobTrigger trigger = mock( IComplexJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -173,8 +173,8 @@ public void testCreateJobScheduleRequest_ComplexJobTrigger() throws Exception { public void testCreateJobScheduleRequest_CronJobTrigger() throws Exception { String jobName = "JOB"; - Job job = mock( Job.class ); - CronJobTrigger trigger = mock( CronJobTrigger.class ); + IJob job = mock( IJob.class ); + ICronJobTrigger trigger = mock( ICronJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -195,10 +195,10 @@ public void testCreateJobScheduleRequest_StreamProviderJobParam() throws Excepti Map params = new HashMap<>(); RepositoryFileStreamProvider streamProvider = mock( RepositoryFileStreamProvider.class ); - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, streamProvider ); + params.put( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER, streamProvider ); - Job job = mock( Job.class ); - CronJobTrigger trigger = mock( CronJobTrigger.class ); + IJob job = mock( IJob.class ); + ICronJobTrigger trigger = mock( ICronJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -218,10 +218,10 @@ public void testCreateJobScheduleRequest_ActionClassJobParam() throws Exception String actionClass = "com.pentaho.Action"; Map params = new HashMap<>(); - params.put( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS, actionClass ); + params.put( IScheduler.RESERVEDMAPKEY_ACTIONCLASS, actionClass ); - Job job = mock( Job.class ); - CronJobTrigger trigger = mock( CronJobTrigger.class ); + IJob job = mock( IJob.class ); + ICronJobTrigger trigger = mock( ICronJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -240,8 +240,8 @@ public void testCreateJobScheduleRequest_TimeZoneJobParam() throws Exception { params.put( IBlockoutManager.TIME_ZONE_PARAM, timeZone ); - Job job = mock( Job.class ); - CronJobTrigger trigger = mock( CronJobTrigger.class ); + IJob job = mock( IJob.class ); + ICronJobTrigger trigger = mock( ICronJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); @@ -265,8 +265,8 @@ public void testCreateJobScheduleRequest_MultipleTypesJobParam() throws Exceptio params.put( "DateValue", d ); params.put( "BooleanValue", b ); - Job job = mock( Job.class ); - CronJobTrigger trigger = mock( CronJobTrigger.class ); + IJob job = mock( IJob.class ); + ICronJobTrigger trigger = mock( ICronJobTrigger.class ); when( job.getJobTrigger() ).thenReturn( trigger ); when( job.getJobName() ).thenReturn( jobName ); diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java index 08264c5b166..a2c9f8a03c5 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java @@ -26,7 +26,7 @@ import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl; import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; import org.pentaho.platform.api.repository2.unified.RepositoryFileSid; -import org.pentaho.platform.api.scheduler2.Job; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; import org.pentaho.platform.plugin.services.importexport.UserExport; import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseAccessType; @@ -111,7 +111,7 @@ public ExportManifestTest() { pdiParameters.put( "parm1", "val1" ); jobScheduleRequest.setPdiParameters( pdiParameters ); jobScheduleRequest.setJobName( "jobName" ); - jobScheduleRequest.setJobState( Job.JobState.UNKNOWN ); + jobScheduleRequest.setJobState( IJob.JobState.UNKNOWN ); jobScheduleRequest.setActionClass( "actionClass" ); jobScheduleRequest.setDuration( 3600 ); jobScheduleRequest.setTimeZone( "someTimeZone" ); @@ -209,7 +209,7 @@ public void testUnMarshal() { assertEquals( 1, jobScheduleRequest.getPdiParameters().size() ); assertEquals( "val1", jobScheduleRequest.getPdiParameters().get( "parm1" ) ); assertEquals( "jobName", jobScheduleRequest.getJobName() ); - assertEquals( Job.JobState.UNKNOWN, jobScheduleRequest.getJobState() ); + assertEquals( IJob.JobState.UNKNOWN, jobScheduleRequest.getJobState() ); assertEquals( "actionClass", jobScheduleRequest.getActionClass() ); assertEquals( 3600, jobScheduleRequest.getDuration() ); assertEquals( "someTimeZone", jobScheduleRequest.getTimeZone() ); diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java index c6c33147cad..c03aa803dd1 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java @@ -24,11 +24,10 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatchers; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener.Frequency; import org.pentaho.test.platform.engine.core.MicroPlatform; @@ -119,7 +118,7 @@ public void returnsTrue_EvenGetsExceptions() throws Exception { @Test public void removesJobs_WhenDisabled() throws Exception { final String jobId = "jobId"; - Job job = new Job(); + IJob job = scheduler.createJob( null, (String)null , null, null ); job.setJobId( jobId ); when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( job ) ); @@ -148,7 +147,7 @@ public void schedulesJob_Monthly() throws Exception { private void testSchedulesJob( Frequency frequency ) throws Exception { - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); + when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); prepareMp(); listener.setExecute( frequency.getValue() ); @@ -167,7 +166,7 @@ public void schedulesJob_Null() throws Exception { } private void testSchedulesJob_IncorrectExecute( String execute ) throws Exception { - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); + when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); prepareMp(); listener.setExecute( execute ); @@ -179,8 +178,9 @@ private void testSchedulesJob_IncorrectExecute( String execute ) throws Exceptio @Test public void reschedulesJob_IfFoundDifferent() throws Exception { final String oldJobId = "oldJobId"; - Job oldJob = new Job(); - oldJob.setJobTrigger( new CronJobTrigger() ); +// IJob oldJob = new Job(); + IJob oldJob = scheduler.createJob( null, (String)null , null, null ); + oldJob.setJobTrigger( scheduler.createCronJobTrigger() ); oldJob.setJobId( oldJobId ); when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( oldJob ) ); @@ -196,7 +196,7 @@ public void reschedulesJob_IfFoundDifferent() throws Exception { @Test public void doesNotRescheduleJob_IfFoundSame() throws Exception { final String oldJobId = "oldJobId"; - Job oldJob = new Job(); + IJob oldJob = scheduler.createJob( null, (String)null , null, null ); oldJob.setJobTrigger( Frequency.WEEKLY.createTrigger() ); oldJob.setJobId( oldJobId ); when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( oldJob ) ); diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java index 98f511a5ea1..cbf31b8ee4d 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java @@ -25,8 +25,10 @@ import org.junit.Test; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.Job; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.SchedulerException; +import org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener; import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; import org.pentaho.platform.web.http.api.resources.services.SchedulerService; @@ -45,9 +47,11 @@ public class SchedulerResourceTest { SchedulerResource schedulerResource; + private IScheduler scheduler; @Before public void setUp() { + scheduler = mock( IScheduler.class ); schedulerResource = spy( new SchedulerResource() ); schedulerResource.schedulerService = mock( SchedulerService.class ); } @@ -61,7 +65,7 @@ public void tearDown() { public void testCreateJob() throws Exception { JobScheduleRequest mockRequest = mock( JobScheduleRequest.class ); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).createJob( mockRequest ); String jobId = "jobId"; @@ -155,10 +159,10 @@ public void testTriggerNow() throws Exception { String jobId = "jobId"; doReturn( jobId ).when( mockJobRequest ).getJobId(); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).triggerNow( jobId ); - Job.JobState mockJobState = Job.JobState.BLOCKED; + IJob.JobState mockJobState = IJob.JobState.BLOCKED; doReturn( mockJobState ).when( mockJob ).getState(); Response mockResponse = mock( Response.class ); @@ -196,10 +200,10 @@ public void testTriggerNowError() throws Exception { @Test public void testGetContentCleanerJob() throws Exception { - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).getContentCleanerJob(); - Job testJob = schedulerResource.getContentCleanerJob(); + IJob testJob = schedulerResource.getContentCleanerJob(); assertEquals( mockJob, testJob ); verify( schedulerResource.schedulerService, times( 1 ) ).getContentCleanerJob(); @@ -222,12 +226,12 @@ public void testGetContentCleanerJobError() throws Exception { @Test public void testGetJobs() throws Exception { - List mockJobs = mock( List.class ); + List mockJobs = mock( List.class ); doReturn( mockJobs ).when( schedulerResource.schedulerService ).getJobs(); Boolean asCronString = Boolean.FALSE; - List testJobs = schedulerResource.getJobs( asCronString ); + List testJobs = schedulerResource.getJobs( asCronString ); assertEquals( mockJobs, testJobs ); verify( schedulerResource.schedulerService, times( 1 ) ).getJobs(); @@ -398,7 +402,7 @@ public void testShutdownError() throws Exception { public void testGetJobState() throws Exception { JobRequest mockJobRequest = mock( JobRequest.class ); - Job.JobState mockJobState = Job.JobState.BLOCKED; + IJob.JobState mockJobState = IJob.JobState.BLOCKED; doReturn( mockJobState ).when( schedulerResource.schedulerService ).getJobState( mockJobRequest ); Response mockResponse = mock( Response.class ); @@ -448,7 +452,7 @@ public void testPauseJob() throws Exception { JobRequest mockJobRequest = mock( JobRequest.class ); doReturn( jobId ).when( mockJobRequest ).getJobId(); - Job.JobState state = Job.JobState.BLOCKED; + IJob.JobState state = IJob.JobState.BLOCKED; doReturn( state ).when( schedulerResource.schedulerService ).pauseJob( jobId ); Response mockResponse = mock( Response.class ); @@ -488,7 +492,7 @@ public void testResumeJob() throws Exception { JobRequest mockJobRequest = mock( JobRequest.class ); doReturn( jobId ).when( mockJobRequest ).getJobId(); - Job.JobState state = Job.JobState.BLOCKED; + IJob.JobState state = IJob.JobState.BLOCKED; doReturn( state ).when( schedulerResource.schedulerService ).resumeJob( jobId ); Response mockResponse = mock( Response.class ); @@ -528,10 +532,10 @@ public void testRemoveJob() throws Exception { String jobId = "jobId"; doReturn( jobId ).when( mockJobRequest ).getJobId(); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).getJob( jobId ); - Job.JobState mockJobState = Job.JobState.BLOCKED; + IJob.JobState mockJobState = IJob.JobState.BLOCKED; doReturn( mockJobState ).when( mockJob ).getState(); Response mockRemovedResponse = mock( Response.class ); @@ -583,7 +587,7 @@ public void testGetJob() throws Exception { String jobId = "jobId"; String asCronString = "asCronString"; - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).getJobInfo( jobId ); Response mockResponse = mock( Response.class ); @@ -640,10 +644,10 @@ public void testGetJobInfo() { @Test public void testGetBlockoutJobs() { - List mockJobs = mock( List.class ); + List mockJobs = mock( List.class ); doReturn( mockJobs ).when( schedulerResource.schedulerService ).getBlockOutJobs(); - List blockoutJobs = schedulerResource.getBlockoutJobs(); + List blockoutJobs = schedulerResource.getBlockoutJobs(); assertNotNull( blockoutJobs ); verify( schedulerResource, times( 1 ) ).getBlockoutJobs(); @@ -668,7 +672,7 @@ public void testHasBlockouts() { public void testAddBlockout() throws Exception { JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).addBlockout( mockJobScheduleRequest ); String jobId = "jobId"; @@ -728,7 +732,7 @@ public void testUpdateBlockout() throws Exception { JobRequest mockJobRequest = mock( JobRequest.class ); doReturn( mockJobRequest ).when( schedulerResource ).getJobRequest(); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerResource.schedulerService ).updateBlockout( jobId, mockJobScheduleRequest ); doReturn( jobId ).when( mockJob ).getJobId(); @@ -872,7 +876,7 @@ public void testGetBlockStatus() throws Exception { @Test public void updateJob_ReturnsJobId() throws Exception { JobScheduleRequest request = new JobScheduleRequest(); - Job job = new Job(); + IJob job = scheduler.createJob( null, (String)null , null, null ); job.setJobId( "job-id" ); when( schedulerResource.schedulerService.updateJob( request ) ).thenReturn( job ); @@ -920,4 +924,4 @@ private void assertUpdateJob( JobScheduleRequest request, Response.Status expect assertEquals( expectedStatus.getStatusCode(), response.getStatus() ); assertEquals( expectedResponse, response.getEntity() ); } -} \ No newline at end of file +} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java index 8f2387f6ee2..b7de41b3970 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java @@ -27,13 +27,14 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; 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.RecurrenceList; @@ -59,10 +60,10 @@ public class SchedulerResourceUtilTest { @Mock JobScheduleRequest scheduleRequest; - @Mock QuartzScheduler scheduler; - @Mock SimpleJobTrigger simple; + @Mock IScheduler scheduler; + @Mock ISimpleJobTrigger simple; @Mock RepositoryFile repo; - CronJobTrigger cron; + ICronJobTrigger cron; ComplexJobTriggerProxy complex; Date now; @@ -90,7 +91,7 @@ public void tearDown() { public void testConvertScheduleRequestToJobTrigger_SimpleJobTrigger() throws Exception { IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof SimpleJobTrigger ); + assertTrue( trigger instanceof ISimpleJobTrigger ); assertTrue( trigger.getStartTime().getTime() > System.currentTimeMillis() ); } @@ -110,15 +111,15 @@ public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_daysOfMonth when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; - List recurrences = trig.getDayOfMonthRecurrences().getRecurrences(); + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; + List recurrences = trig.getDayOfMonthRecurrences(); assertEquals( 2, recurrences.size() ); - RecurrenceList rec = (RecurrenceList) recurrences.get( 0 ); - assertEquals( 1, rec.getValues().get( 0 ).intValue() ); - rec = (RecurrenceList) recurrences.get( 1 ); - assertEquals( 25, rec.getValues().get( 0 ).intValue() ); + ITimeWrapper rec = recurrences.get( 0 ); + assertEquals( 1, rec.getRecurrences().size() ); + rec = recurrences.get( 1 ); + assertEquals( 25, rec.getRecurrences().size() ); } @Test @@ -128,15 +129,15 @@ public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_monthsOfYea when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; - List recurrences = trig.getMonthlyRecurrences().getRecurrences(); + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; + List recurrences = trig.getMonthlyRecurrences(); assertEquals( 2, recurrences.size() ); - RecurrenceList rec = (RecurrenceList) recurrences.get( 0 ); - assertEquals( 2, rec.getValues().get( 0 ).intValue() ); - rec = (RecurrenceList) recurrences.get( 1 ); - assertEquals( 9, rec.getValues().get( 0 ).intValue() ); + ITimeWrapper rec = recurrences.get( 0 ); + assertEquals( 2, rec.getRecurrences().size() ); + rec = recurrences.get( 1 ); + assertEquals( 9, rec.getRecurrences().size() ); } @Test @@ -146,15 +147,15 @@ public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_years() thr when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; - List recurrences = trig.getYearlyRecurrences().getRecurrences(); + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; + List recurrences = trig.getYearlyRecurrences(); assertEquals( 2, recurrences.size() ); - RecurrenceList rec = (RecurrenceList) recurrences.get( 0 ); - assertEquals( 2016, rec.getValues().get( 0 ).intValue() ); - rec = (RecurrenceList) recurrences.get( 1 ); - assertEquals( 2020, rec.getValues().get( 0 ).intValue() ); + ITimeWrapper rec = recurrences.get( 0 ); + assertEquals( 2016, rec.getRecurrences().size() ); + rec = recurrences.get( 1 ); + assertEquals( 2020, rec.getRecurrences().size() ); } @Test @@ -164,15 +165,15 @@ public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_daysOfWeek( when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; - List recurrences = trig.getDayOfWeekRecurrences().getRecurrences(); + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; + List recurrences = trig.getDayOfWeekRecurrences(); assertEquals( 2, recurrences.size() ); - RecurrenceList rec = (RecurrenceList) recurrences.get( 0 ); - assertEquals( 2, rec.getValues().get( 0 ).intValue() ); - rec = (RecurrenceList) recurrences.get( 1 ); - assertEquals( 6, rec.getValues().get( 0 ).intValue() ); + ITimeWrapper rec = recurrences.get( 0 ); + assertEquals( 2, rec.getRecurrences().size() ); + rec = recurrences.get( 1 ); + assertEquals( 6, rec.getRecurrences().size() ); } @Test @@ -183,32 +184,32 @@ public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_weeksOfMont when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); assertNotNull( trigger ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; - List recurrences = trig.getDayOfWeekRecurrences().getRecurrences(); + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; + List recurrences = trig.getDayOfWeekRecurrences(); assertEquals( 4, recurrences.size() ); - QualifiedDayOfWeek rec = (QualifiedDayOfWeek) recurrences.get( 0 ); - assertEquals( "MON", rec.getDayOfWeek().toString() ); - assertEquals( "FOURTH", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 1 ); - assertEquals( "MON", rec.getDayOfWeek().toString() ); - assertEquals( "LAST", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 2 ); - assertEquals( "FRI", rec.getDayOfWeek().toString() ); - assertEquals( "FOURTH", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 3 ); - assertEquals( "FRI", rec.getDayOfWeek().toString() ); - assertEquals( "LAST", rec.getQualifier().toString() ); +// ITimeWrapper rec = (QualifiedDayOfWeek) recurrences.get( 0 ); +// assertEquals( "MON", rec.getDayOfWeek().toString() ); +// assertEquals( "FOURTH", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 1 ); +// assertEquals( "MON", rec.getDayOfWeek().toString() ); +// assertEquals( "LAST", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 2 ); +// assertEquals( "FRI", rec.getDayOfWeek().toString() ); +// assertEquals( "FOURTH", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 3 ); +// assertEquals( "FRI", rec.getDayOfWeek().toString() ); +// assertEquals( "LAST", rec.getQualifier().toString() ); } @Test public void testConvertScheduleRequestToJobTrigger_CronString() throws Exception { - cron = new CronJobTrigger(); + cron = scheduler.createCronJobTrigger(); cron.setCronString( "0 45 16 ? * 2#4,2L,6#4,6L *" ); cron.setDuration( 200000 ); cron.setStartTime( now ); @@ -218,38 +219,38 @@ public void testConvertScheduleRequestToJobTrigger_CronString() throws Exception when( scheduleRequest.getCronJobTrigger() ).thenReturn( cron ); IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertTrue( trigger instanceof ComplexJobTrigger ); + assertTrue( trigger instanceof IComplexJobTrigger ); - ComplexJobTrigger trig = (ComplexJobTrigger) trigger; + IComplexJobTrigger trig = (IComplexJobTrigger) trigger; assertEquals( now, trig.getStartTime() ); assertEquals( now, trig.getEndTime() ); assertEquals( 200000, trig.getDuration() ); assertEquals( "param", trig.getUiPassParam() ); - List recurrences = trig.getDayOfWeekRecurrences().getRecurrences(); + List recurrences = trig.getDayOfWeekRecurrences(); assertEquals( 4, recurrences.size() ); - QualifiedDayOfWeek rec = (QualifiedDayOfWeek) recurrences.get( 0 ); - assertEquals( "MON", rec.getDayOfWeek().toString() ); - assertEquals( "FOURTH", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 1 ); - assertEquals( "MON", rec.getDayOfWeek().toString() ); - assertEquals( "LAST", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 2 ); - assertEquals( "FRI", rec.getDayOfWeek().toString() ); - assertEquals( "FOURTH", rec.getQualifier().toString() ); - - rec = (QualifiedDayOfWeek) recurrences.get( 3 ); - assertEquals( "FRI", rec.getDayOfWeek().toString() ); - assertEquals( "LAST", rec.getQualifier().toString() ); +// QualifiedDayOfWeek rec = (QualifiedDayOfWeek) recurrences.get( 0 ); +// assertEquals( "MON", rec.getDayOfWeek().toString() ); +// assertEquals( "FOURTH", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 1 ); +// assertEquals( "MON", rec.getDayOfWeek().toString() ); +// assertEquals( "LAST", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 2 ); +// assertEquals( "FRI", rec.getDayOfWeek().toString() ); +// assertEquals( "FOURTH", rec.getQualifier().toString() ); +// +// rec = (QualifiedDayOfWeek) recurrences.get( 3 ); +// assertEquals( "FRI", rec.getDayOfWeek().toString() ); +// assertEquals( "LAST", rec.getQualifier().toString() ); } @Test public void testUpdateStartDateForTimeZone_simple() throws Exception { - SimpleJobTrigger sjt = new SimpleJobTrigger(); + ISimpleJobTrigger sjt = scheduler.createSimpleJobTrigger( null, null, 0, 0 ); sjt.setStartTime( now ); when( scheduleRequest.getSimpleJobTrigger() ).thenReturn( sjt ); when( scheduleRequest.getTimeZone() ).thenReturn( "GMT" ); @@ -275,7 +276,7 @@ public void testUpdateStartDateForTimeZone_complex() throws Exception { @Test public void testUpdateStartDateForTimeZone_cron() throws Exception { - CronJobTrigger t = new CronJobTrigger(); + ICronJobTrigger t = scheduler.createCronJobTrigger(); t.setStartTime( now ); when( scheduleRequest.getCronJobTrigger() ).thenReturn( t ); when( scheduleRequest.getTimeZone() ).thenReturn( "GMT" ); diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java index f87f9fa85a7..36648c0aa0f 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java @@ -64,10 +64,9 @@ import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; import org.pentaho.platform.web.http.api.resources.JobRequest; @@ -106,7 +105,7 @@ public void testCreateJob() throws Exception { doReturn( "value1" ).when( jobScheduleParam1 ).getValue(); jobParameters.add( jobScheduleParam1 ); - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); JobScheduleRequest scheduleRequest = mock( JobScheduleRequest.class ); doReturn( "className" ).when( scheduleRequest ).getActionClass(); @@ -123,7 +122,7 @@ public void testCreateJob() throws Exception { doReturn( "outputFile" ).when( schedulerOutputPathResolver ).resolveOutputFilePath(); doReturn( schedulerOutputPathResolver ).when( schedulerService ).getSchedulerOutputPathResolver( any( JobScheduleRequest.class ) ); - SimpleJobTrigger simpleJobTrigger = mock( SimpleJobTrigger.class ); + ISimpleJobTrigger simpleJobTrigger = mock( ISimpleJobTrigger.class ); RepositoryFile repositoryFile = mock( RepositoryFile.class ); doReturn( "file.ext" ).when( repositoryFile ).getName(); @@ -191,7 +190,7 @@ public void testCreateJobException() throws Exception { doReturn( "value1" ).when( jobScheduleParam1 ).getValue(); jobParameters.add( jobScheduleParam1 ); - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); JobScheduleRequest scheduleRequest = mock( JobScheduleRequest.class ); doReturn( "className" ).when( scheduleRequest ).getActionClass(); @@ -203,7 +202,7 @@ public void testCreateJobException() throws Exception { SchedulerOutputPathResolver schedulerOutputPathResolver = mock( SchedulerOutputPathResolver.class ); - SimpleJobTrigger simpleJobTrigger = mock( SimpleJobTrigger.class ); + ISimpleJobTrigger simpleJobTrigger = mock( ISimpleJobTrigger.class ); RepositoryFile repositoryFile = mock( RepositoryFile.class ); @@ -265,14 +264,14 @@ public void testCreateJobException() throws Exception { public void testTriggerNow() throws Exception { JobRequest jobRequest = mock( JobRequest.class ); - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService.scheduler ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService.policy ).isAllowed( nullable( String.class ) ); doNothing().when( schedulerService.scheduler ).triggerNow( nullable( String.class ) ); //Test 1 - Job resultJob1 = schedulerService.triggerNow( jobRequest.getJobId() ); + IJob resultJob1 = schedulerService.triggerNow( jobRequest.getJobId() ); assertEquals( job, resultJob1 ); @@ -284,7 +283,7 @@ public void testTriggerNow() throws Exception { doReturn( "test" ).when( pentahoSession ).getName(); doReturn( pentahoSession ).when( schedulerService ).getSession(); - Job resultJob2 = schedulerService.triggerNow( jobRequest.getJobId() ); + IJob resultJob2 = schedulerService.triggerNow( jobRequest.getJobId() ); assertEquals( job, resultJob2 ); @@ -298,7 +297,7 @@ public void testGetContentCleanerJob() throws Exception { IJobFilter jobFilter = mock( IJobFilter.class ); - List jobs = new ArrayList<>(); + List jobs = new ArrayList<>(); IPentahoSession session = mock( IPentahoSession.class ); doReturn( session ).when( schedulerService ).getSession(); @@ -309,12 +308,12 @@ public void testGetContentCleanerJob() throws Exception { doReturn( jobs ).when( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); //Test 1 - Job job = schedulerService.getContentCleanerJob(); + IJob job = schedulerService.getContentCleanerJob(); assertNull( job ); //Test 2 - Job job1 = mock( Job.class ); + IJob job1 = mock( IJob.class ); jobs.add( job1 ); job = schedulerService.getContentCleanerJob(); @@ -332,7 +331,7 @@ public void testGetContentCleanerJobException() throws Exception { IJobFilter jobFilter = mock( IJobFilter.class ); - List jobs = new ArrayList<>(); + List jobs = new ArrayList<>(); IPentahoSession session = mock( IPentahoSession.class ); doReturn( session ).when( schedulerService ).getSession(); @@ -474,7 +473,7 @@ public void testPause() throws SchedulerException { @Test public void testPauseJob() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doNothing().when( schedulerService.scheduler ).pauseJob( nullable( String.class ) ); @@ -483,7 +482,7 @@ public void testPauseJob() throws SchedulerException { @Test public void testPauseJobException() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).pauseJob( nullable( String.class ) ); @@ -496,7 +495,7 @@ public void testPauseJobException() throws SchedulerException { @Test public void testResumeJob() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doNothing().when( schedulerService.scheduler ).resumeJob( nullable( String.class ) ); @@ -505,7 +504,7 @@ public void testResumeJob() throws SchedulerException { @Test public void testResumeJobException() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).resumeJob( nullable( String.class ) ); @@ -518,7 +517,7 @@ public void testResumeJobException() throws SchedulerException { @Test public void testRemoveJob() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doNothing().when( schedulerService.scheduler ).removeJob( nullable( String.class ) ); @@ -527,7 +526,7 @@ public void testRemoveJob() throws SchedulerException { @Test public void testRemoveJobException() throws SchedulerException { - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); doReturn( true ).when( schedulerService ).isScheduleAllowed(); doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).removeJob( nullable( String.class ) ); @@ -606,11 +605,11 @@ public void testGetJobs() throws Exception { doReturn( mockPentahoSession ).when( schedulerService ).getSession(); doReturn( "admin" ).when( mockPentahoSession ).getName(); doReturn( true ).when( schedulerService ).canAdminister( mockPentahoSession ); - List mockJobs = new ArrayList<>(); - mockJobs.add( mock( Job.class ) ); + List mockJobs = new ArrayList<>(); + mockJobs.add( mock( IJob.class ) ); doReturn( mockJobs ).when( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); - List jobs = schedulerService.getJobs(); + List jobs = schedulerService.getJobs(); assertEquals( mockJobs, jobs ); @@ -635,7 +634,7 @@ public void testDoGetGeneratedContentForSchedule() throws Exception { List mockList = mock( List.class ); doReturn( mockList ).when( mockFileService ) - .searchGeneratedContent( currentUserDir, lineageId, QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID ); + .searchGeneratedContent( currentUserDir, lineageId, IScheduler.RESERVEDMAPKEY_LINEAGE_ID ); List list = schedulerService.doGetGeneratedContentForSchedule( lineageId ); assertEquals( mockList, list ); @@ -651,9 +650,9 @@ public void testGetJobState() throws Exception { IPentahoSession mockSession = mock( IPentahoSession.class ); doReturn( mockSession ).when( schedulerService ).getSession(); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerService ).getJob( jobId ); - doReturn( Job.JobState.BLOCKED ).when( mockJob ).getState(); + doReturn( IJob.JobState.BLOCKED ).when( mockJob ).getState(); String username = "username"; doReturn( username ).when( mockJob ).getUserName(); @@ -662,14 +661,14 @@ public void testGetJobState() throws Exception { // Test 1 doReturn( true ).when( schedulerService ).isScheduleAllowed(); - Job.JobState testState = schedulerService.getJobState( mockJobRequest ); - assertEquals( Job.JobState.BLOCKED, testState ); + IJob.JobState testState = schedulerService.getJobState( mockJobRequest ); + assertEquals( IJob.JobState.BLOCKED, testState ); // Test 2 doReturn( false ).when( schedulerService ).isScheduleAllowed(); testState = schedulerService.getJobState( mockJobRequest ); - assertEquals( Job.JobState.BLOCKED, testState ); + assertEquals( IJob.JobState.BLOCKED, testState ); verify( mockJobRequest, times( 2 ) ).getJobId(); verify( schedulerService, times( 1 ) ).getSession(); @@ -689,7 +688,7 @@ public void testGetJobStateError() throws Exception { IPentahoSession mockSession = mock( IPentahoSession.class ); doReturn( mockSession ).when( schedulerService ).getSession(); - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerService ).getJob( jobId ); String username = "username"; @@ -712,7 +711,7 @@ public void testGetJobStateError() throws Exception { public void testGetJobInfo() throws Exception { String jobId = "jobId"; - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerService ).getJob( jobId ); IPentahoSession mockPentahoSession = mock( IPentahoSession.class ); @@ -736,7 +735,7 @@ public void testGetJobInfo() throws Exception { doReturn( testArray ).when( mockJobParams ).get( jobParamKey ); // Test 1 - Job testJob = schedulerService.getJobInfo( jobId ); + IJob testJob = schedulerService.getJobInfo( jobId ); assertEquals( mockJob, testJob ); // Test 2 @@ -758,7 +757,7 @@ public void testGetJobInfo() throws Exception { public void testGetJobInfoError() throws Exception { String jobId = "jobId"; - Job mockJob = mock( Job.class ); + IJob mockJob = mock( IJob.class ); doReturn( mockJob ).when( schedulerService ).getJob( jobId ); IPentahoSession mockPentahoSession = mock( IPentahoSession.class ); @@ -827,11 +826,11 @@ public void testIsScheduleAllowed() { @Test public void testGetBlockoutJobs() { - List jobs = new ArrayList<>(); + List jobs = new ArrayList<>(); doReturn( jobs ).when( schedulerService.blockoutManager ).getBlockOutJobs(); - List returnJobs = schedulerService.getBlockOutJobs(); + List returnJobs = schedulerService.getBlockOutJobs(); assertEquals( returnJobs, jobs ); @@ -841,7 +840,7 @@ public void testGetBlockoutJobs() { @Test public void testHasBlockouts() { - List jobs = new ArrayList<>(); + List jobs = new ArrayList<>(); doReturn( jobs ).when( schedulerService.blockoutManager ).getBlockOutJobs(); @@ -851,7 +850,7 @@ public void testHasBlockouts() { assertFalse( hasBlockouts ); // Test 2 - jobs.add( mock( Job.class ) ); + jobs.add( mock( IJob.class ) ); hasBlockouts = schedulerService.hasBlockouts(); assertTrue( hasBlockouts ); @@ -863,7 +862,7 @@ public void testHasBlockouts() { public void testAddBlockout() throws Exception { JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - Job jobMock = mock( Job.class ); + IJob jobMock = mock( IJob.class ); JobScheduleParam jobScheduleParamMock1 = mock( JobScheduleParam.class ); JobScheduleParam jobScheduleParamMock2 = mock( JobScheduleParam.class ); @@ -877,7 +876,7 @@ public void testAddBlockout() throws Exception { doReturn( jobScheduleParamMock2 ).when( schedulerService ).getJobScheduleParam( nullable( String.class ), anyLong() ); doReturn( jobMock ).when( schedulerService ).createJob( any( JobScheduleRequest.class ) ); - Job job = schedulerService.addBlockout( jobScheduleRequest ); + IJob job = schedulerService.addBlockout( jobScheduleRequest ); assertNotNull( job ); assertEquals( 2, jobScheduleParams.size() ); @@ -903,7 +902,7 @@ public void testAddBlockoutException() throws Exception { } // Test 2 - Job jobMock = mock( Job.class ); + IJob jobMock = mock( IJob.class ); JobScheduleParam jobScheduleParamMock1 = mock( JobScheduleParam.class ); JobScheduleParam jobScheduleParamMock2 = mock( JobScheduleParam.class ); @@ -946,13 +945,13 @@ public void testUpdateBlockout() throws Exception { String jobId = "jobId"; JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - Job jobMock = mock( Job.class ); + IJob jobMock = mock( IJob.class ); doReturn( true ).when( schedulerService ).canAdminister(); doReturn( true ).when( schedulerService ).removeJob( nullable( String.class ) ); doReturn( jobMock ).when( schedulerService ).addBlockout( jobScheduleRequest ); - Job job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); + IJob job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); assertNotNull( job ); @@ -966,7 +965,7 @@ public void testUpdateBlockoutException() throws Exception { String jobId = "jobId"; JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - Job job = mock( Job.class ); + IJob job = mock( IJob.class ); // Test 1 doReturn( false ).when( schedulerService ).canAdminister(); diff --git a/repository/pom.xml b/repository/pom.xml index 210f3883ebe..490129b5009 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -503,7 +503,7 @@ org.apache.jackrabbit - jackrabbit-api + oak-jackrabbit-api org.apache.jackrabbit diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManagerIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManagerIT.java deleted file mode 100644 index ed4eef48de4..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManagerIT.java +++ /dev/null @@ -1,370 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.blockout; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertTrue; - -import java.io.Serializable; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -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.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.scheduler2.blockout.BlockoutManagerUtil.TIME; -import org.pentaho.platform.scheduler2.quartz.test.StubUserDetailsService; -import org.pentaho.platform.scheduler2.quartz.test.StubUserRoleListService; -import org.pentaho.platform.scheduler2.ws.test.TestQuartzScheduler; -import org.pentaho.platform.scheduler2.ws.test.JaxWsSchedulerServiceIT.TstPluginManager; -import org.pentaho.test.platform.engine.core.MicroPlatform; -import org.springframework.security.core.userdetails.UserDetailsService; - -/** - * @author wseyler - * - */ -public class PentahoBlockoutManagerIT { - - private final long duration; - - IBlockoutManager blockOutManager; - - IScheduler scheduler; - - Set jobIdsToClear = new HashSet(); - - public PentahoBlockoutManagerIT() { - duration = TIME.HOUR.time * 2; - } - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - MicroPlatform mp = new MicroPlatform(); - mp.define( IPluginManager.class, TstPluginManager.class ); - mp.define( "IScheduler2", TestQuartzScheduler.class ); //$NON-NLS-1$ - mp.define( IUserRoleListService.class, StubUserRoleListService.class ); - mp.define( UserDetailsService.class, StubUserDetailsService.class ); - mp.define( IBlockoutManager.class, PentahoBlockoutManager.class ); - mp.start(); - - blockOutManager = new PentahoBlockoutManager(); - scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$; - - jobIdsToClear.clear(); - } - - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - - Set jobIdsIter = new HashSet( this.jobIdsToClear ); - // Clear all jobs after each test - for ( String jobId : jobIdsIter ) { - deleteJob( jobId ); - } - } - - /** - * Test method for - * {@link org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager#getBlockOut(java.lang.String)}. - */ - @Test - public void testGetBlockout() throws Exception { - IJobTrigger blockOutJobTrigger1 = new SimpleJobTrigger( new Date(), null, -1, 1000000 ); - IJobTrigger blockOutJobTrigger2 = new SimpleJobTrigger( new Date(), null, -1, 1000000 ); - - Job blockOutJob1 = addBlockOutJob( blockOutJobTrigger1 ); - Job blockOutJob2 = addBlockOutJob( blockOutJobTrigger2 ); - - assertEquals( blockOutManager.getBlockOut( blockOutJob1.getJobId() ).toString(), blockOutJobTrigger1.toString() ); - assertEquals( blockOutManager.getBlockOut( blockOutJob2.getJobId() ).toString(), blockOutJobTrigger2.toString() ); - assertNotSame( blockOutJobTrigger1, blockOutManager.getBlockOut( blockOutJob2.getJobId() ) ); - } - - @Test - public void testGetBlockouts() throws Exception { - IJobTrigger trigger1 = new SimpleJobTrigger( new Date(), null, -1, 1000000 ); - IJobTrigger trigger2 = new SimpleJobTrigger( new Date(), null, -1, 1000000 ); - addBlockOutJob( trigger1 ); - addBlockOutJob( trigger2 ); - - assertEquals( 2, this.blockOutManager.getBlockOutJobs().size() ); - } - - /** - * Test method for - * {@link org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager#willFire(org.quartz.IJobTrigger)}. - */ - @Test - public void testWillFire() throws Exception { - Calendar blockOutStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 7 ); - IJobTrigger blockOutJobTrigger = - new SimpleJobTrigger( blockOutStartDate.getTime(), null, -1, TIME.WEEK.time / 1000 ); - blockOutJobTrigger.setDuration( duration ); - - /* - * Simple Schedule Triggers - */ - Calendar scheduleStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 7, 1, 0, 0 ); - IJobTrigger trueScheduleTrigger = - new SimpleJobTrigger( scheduleStartDate.getTime(), null, -1, TIME.DAY.time / 1000 ); - - IJobTrigger falseScheduleTrigger = - new SimpleJobTrigger( scheduleStartDate.getTime(), null, -1, TIME.WEEK.time / 1000 ); - - Job blockOutJob = addBlockOutJob( blockOutJobTrigger ); - assertTrue( this.blockOutManager.willFire( trueScheduleTrigger ) ); - assertFalse( this.blockOutManager.willFire( falseScheduleTrigger ) ); - - /* - * Complex Schedule Triggers - */ - IJobTrigger trueComplexScheduleTrigger = new ComplexJobTrigger(); - trueComplexScheduleTrigger.setStartTime( scheduleStartDate.getTime() ); - trueComplexScheduleTrigger.setCronString( "0 0 1 ? * 2-3 *" ); //$NON-NLS-1$ - - IJobTrigger falseComplexScheduleTrigger = new ComplexJobTrigger(); - falseComplexScheduleTrigger.setStartTime( scheduleStartDate.getTime() ); - falseComplexScheduleTrigger.setCronString( "0 0 1 ? * 2 *" ); //$NON-NLS-1$ - - assertTrue( this.blockOutManager.willFire( trueComplexScheduleTrigger ) ); - assertFalse( this.blockOutManager.willFire( falseComplexScheduleTrigger ) ); - - /* - * Complex Block out - */ - deleteJob( blockOutJob.getJobId() ); - blockOutJobTrigger = new ComplexJobTrigger(); - blockOutJobTrigger.setStartTime( blockOutStartDate.getTime() ); - blockOutJobTrigger.setDuration( duration ); - blockOutJobTrigger.setCronString( "0 0 0 ? * 2 *" ); //$NON-NLS-1$ - - addBlockOutJob( blockOutJobTrigger ); - - assertTrue( this.blockOutManager.willFire( trueScheduleTrigger ) ); - assertFalse( this.blockOutManager.willFire( falseScheduleTrigger ) ); - assertTrue( this.blockOutManager.willFire( trueComplexScheduleTrigger ) ); - assertFalse( this.blockOutManager.willFire( falseComplexScheduleTrigger ) ); - - } - - /** - * Test method for - * {@link org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager#isPartiallyBlocked(org.quartz.IJobTrigger)}. - */ - @Test - public void testIsPartiallyBlocked() throws Exception { - Calendar blockOutStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 1, 0, 0, 0 ); - IJobTrigger blockOutTrigger = - new SimpleJobTrigger( blockOutStartDate.getTime(), null, -1, TIME.WEEK.time * 2 / 1000 ); - blockOutTrigger.setDuration( duration ); - - /* - * Simple Schedule Triggers - */ - Calendar trueScheduleStartDate1 = new GregorianCalendar( 2013, Calendar.JANUARY, 15, 0, 0, 0 ); - IJobTrigger trueSchedule1 = - new SimpleJobTrigger( trueScheduleStartDate1.getTime(), null, -1, TIME.WEEK.time * 2 / 1000 ); - - Calendar trueScheduleStartDate2 = new GregorianCalendar( 2013, Calendar.JANUARY, 15, 0, 0, 0 ); - IJobTrigger trueSchedule2 = - new SimpleJobTrigger( trueScheduleStartDate2.getTime(), null, -1, TIME.WEEK.time / 1000 ); - - Calendar falseScheduleStartDate1 = new GregorianCalendar( 2013, Calendar.JANUARY, 1, 3, 0, 0 ); - IJobTrigger falseSchedule1 = - new SimpleJobTrigger( falseScheduleStartDate1.getTime(), null, -1, TIME.WEEK.time / 1000 ); - - Job blockOutJob = addBlockOutJob( blockOutTrigger ); - - assertTrue( this.blockOutManager.isPartiallyBlocked( trueSchedule1 ) ); - assertTrue( this.blockOutManager.isPartiallyBlocked( trueSchedule2 ) ); - assertFalse( this.blockOutManager.isPartiallyBlocked( falseSchedule1 ) ); - - /* - * Complex Schedule Triggers - */ - IJobTrigger trueComplexScheduleTrigger = new ComplexJobTrigger(); - trueComplexScheduleTrigger.setStartTime( trueScheduleStartDate1.getTime() ); - trueComplexScheduleTrigger.setCronString( "0 0 1 ? * 2-3 *" ); //$NON-NLS-1$ - - IJobTrigger falseComplexScheduleTrigger = new ComplexJobTrigger(); - falseComplexScheduleTrigger.setStartTime( trueScheduleStartDate1.getTime() ); - falseComplexScheduleTrigger.setCronString( "0 0 1 ? * 2 *" ); //$NON-NLS-1$ - - assertTrue( this.blockOutManager.isPartiallyBlocked( trueComplexScheduleTrigger ) ); - assertFalse( this.blockOutManager.isPartiallyBlocked( falseComplexScheduleTrigger ) ); - - /* - * Complex Block Out IJobTrigger - */ - deleteJob( blockOutJob.getJobId() ); - blockOutTrigger = new ComplexJobTrigger(); - blockOutTrigger.setStartTime( blockOutStartDate.getTime() ); - blockOutTrigger.setCronString( "0 0 0 ? * 3 *" ); //$NON-NLS-1$ - blockOutTrigger.setDuration( duration ); - addBlockOutJob( blockOutTrigger ); - - assertTrue( this.blockOutManager.isPartiallyBlocked( trueSchedule1 ) ); - assertTrue( this.blockOutManager.isPartiallyBlocked( trueSchedule2 ) ); - assertFalse( this.blockOutManager.isPartiallyBlocked( falseSchedule1 ) ); - assertTrue( this.blockOutManager.isPartiallyBlocked( trueComplexScheduleTrigger ) ); - assertFalse( this.blockOutManager.isPartiallyBlocked( falseComplexScheduleTrigger ) ); - } - - /** - * Test method for {@link org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager#shouldFireNow()}. - */ - @Test - public void testShouldFireNow() throws Exception { - Date blockOutStartDate = new Date( System.currentTimeMillis() ); - IJobTrigger blockOutJobTrigger = new SimpleJobTrigger( blockOutStartDate, null, -1, TIME.WEEK.time * 2 / 1000 ); - blockOutJobTrigger.setDuration( duration ); - - Job blockOutJob = addBlockOutJob( blockOutJobTrigger ); - - assertFalse( this.blockOutManager.shouldFireNow() ); - - deleteJob( blockOutJob.getJobId() ); - blockOutStartDate = new Date( System.currentTimeMillis() + TIME.HOUR.time ); - blockOutJobTrigger = new SimpleJobTrigger( blockOutStartDate, null, -1, TIME.WEEK.time * 2 / 1000 ); - blockOutJobTrigger.setDuration( duration ); - addBlockOutJob( blockOutJobTrigger ); - - assertTrue( this.blockOutManager.shouldFireNow() ); - } - - /** - * Test method for - * {@link org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager#willBlockSchedules - * (org.pentaho.platform.scheduler2.blockout.SimpleBlockoutTrigger)} - * . - */ - @Test - public void testWillBlockSchedules() throws Exception { - Calendar trueBlockOutStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 7 ); - IJobTrigger trueBlockOutTrigger = - new SimpleJobTrigger( trueBlockOutStartDate.getTime(), null, -1, TIME.WEEK.time / 1000 ); - trueBlockOutTrigger.setDuration( duration ); - - Calendar falseBlockOutStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 9 ); - IJobTrigger falseBlockOutTrigger = - new SimpleJobTrigger( falseBlockOutStartDate.getTime(), null, -1, TIME.WEEK.time / 1000 ); - falseBlockOutTrigger.setDuration( duration ); - - IJobTrigger trueComplexBlockOutTrigger = new ComplexJobTrigger(); - trueComplexBlockOutTrigger.setStartTime( trueBlockOutStartDate.getTime() ); - trueComplexBlockOutTrigger.setCronString( "0 0 0 ? * 2 *" ); //$NON-NLS-1$ - trueComplexBlockOutTrigger.setDuration( duration ); - - IJobTrigger falseComplexBlockOutTrigger = new ComplexJobTrigger(); - falseComplexBlockOutTrigger.setStartTime( falseBlockOutStartDate.getTime() ); - falseComplexBlockOutTrigger.setCronString( "0 0 0 ? * WED *" ); //$NON-NLS-1$ - falseComplexBlockOutTrigger.setDuration( duration ); - - Calendar scheduleStartDate = new GregorianCalendar( 2013, Calendar.JANUARY, 7, 1, 0, 0 ); - IJobTrigger scheduleTrigger = new SimpleJobTrigger( scheduleStartDate.getTime(), null, -1, TIME.WEEK.time / 1000 ); - addJob( scheduleTrigger, "scheduleTrigger" ); //$NON-NLS-1$ - - assertEquals( 1, this.blockOutManager.willBlockSchedules( trueBlockOutTrigger ).size() ); - assertEquals( 1, this.blockOutManager.willBlockSchedules( trueComplexBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseComplexBlockOutTrigger ).size() ); - - IJobTrigger cronTrigger = new ComplexJobTrigger(); - cronTrigger.setStartTime( scheduleStartDate.getTime() ); - cronTrigger.setCronString( "0 0 1 ? * 2-3 *" ); //$NON-NLS-1$ - addJob( cronTrigger, "cronTrigger" ); //$NON-NLS-1$ - - assertEquals( 2, this.blockOutManager.willBlockSchedules( trueBlockOutTrigger ).size() ); - assertEquals( 2, this.blockOutManager.willBlockSchedules( trueComplexBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseComplexBlockOutTrigger ).size() ); - - IJobTrigger complexJobTrigger1 = new ComplexJobTrigger( null, null, null, ComplexJobTrigger.MONDAY, 0 ); - complexJobTrigger1.setStartTime( scheduleStartDate.getTime() ); - addJob( complexJobTrigger1, "complexJobTrigger1" ); //$NON-NLS-1$ - - assertEquals( 3, this.blockOutManager.willBlockSchedules( trueBlockOutTrigger ).size() ); - assertEquals( 3, this.blockOutManager.willBlockSchedules( trueComplexBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseBlockOutTrigger ).size() ); - assertEquals( 0, this.blockOutManager.willBlockSchedules( falseComplexBlockOutTrigger ).size() ); - - // Test non-standard interval - IJobTrigger complexJobTrigger2 = new ComplexJobTrigger( null, null, 1, null, 0 ); - complexJobTrigger2.setStartTime( scheduleStartDate.getTime() ); - addJob( complexJobTrigger2, "complexJobTrigger2" ); //$NON-NLS-1$ - - assertEquals( 4, this.blockOutManager.willBlockSchedules( trueBlockOutTrigger ).size() ); - assertEquals( 4, this.blockOutManager.willBlockSchedules( trueComplexBlockOutTrigger ).size() ); - assertEquals( 1, this.blockOutManager.willBlockSchedules( falseBlockOutTrigger ).size() ); - assertEquals( 1, this.blockOutManager.willBlockSchedules( falseComplexBlockOutTrigger ).size() ); - } - - private Job addBlockOutJob( IJobTrigger blockOutJobTrigger ) throws Exception { - Map jobParams = new HashMap(); - jobParams.put( IBlockoutManager.DURATION_PARAM, blockOutJobTrigger.getDuration() ); - - return addJob( blockOutJobTrigger, IBlockoutManager.BLOCK_OUT_JOB_NAME, new BlockoutAction(), jobParams ); - } - - private Job addJob( IJobTrigger jobTrigger, String jobName ) throws Exception { - return addJob( jobTrigger, jobName, new IAction() { - @Override - public void execute() throws Exception { - } - }, new HashMap() ); - } - - private Job addJob( IJobTrigger jobTrigger, String jobName, IAction action, Map jobParams ) - throws Exception { - Job job = this.scheduler.createJob( jobName, action.getClass(), jobParams, jobTrigger ); - this.jobIdsToClear.add( job.getJobId() ); - return job; - } - - private void deleteJob( String jobId ) throws Exception { - this.scheduler.removeJob( jobId ); - this.jobIdsToClear.remove( jobId ); - } -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerIT.java deleted file mode 100644 index b6ac8a01217..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerIT.java +++ /dev/null @@ -1,325 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.ISchedulerListener; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.engine.core.system.boot.PlatformInitializationException; -import org.quartz.CronTrigger; -import org.quartz.JobDataMap; -import org.quartz.JobDetail; -import org.quartz.Scheduler; -import org.quartz.SchedulerFactory; -import org.quartz.SimpleTrigger; -import org.quartz.Trigger; - -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 static junit.framework.Assert.*; -import static org.mockito.Mockito.*; - -@SuppressWarnings( "nls" ) -public class QuartzSchedulerIT { - private static final String CRON_EXPRESSION = "1 0 0 * * ? *"; - private static final String USER_NAME = "userName"; - private static final String JOB_NAME = "jobName"; - private static final String JOB_ID = USER_NAME + "\t" + JOB_NAME + "\t" + System.currentTimeMillis(); - - private QuartzScheduler scheduler; - private Scheduler quartzScheduler; - private final Map jobDetails = new HashMap<>(); - - @Before - public void init() throws SchedulerException, PlatformInitializationException, org.quartz.SchedulerException { - final SchedulerFactory schedulerFactory = mock( SchedulerFactory.class ); - quartzScheduler = mock( Scheduler.class ); - when( schedulerFactory.getScheduler() ).thenReturn( quartzScheduler ); - scheduler = spy( new QuartzScheduler( schedulerFactory ) ); - when( scheduler.getCurrentUser() ).thenReturn( USER_NAME ); - - jobDetails.clear(); - jobDetails.put( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS, "RESERVEDMAPKEY_ACTIONCLASS" ); - jobDetails.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "RESERVEDMAPKEY_STREAMPROVIDER" ); - jobDetails.put( QuartzScheduler.RESERVEDMAPKEY_UIPASSPARAM, "RESERVEDMAPKEY_UIPASSPARAM" ); - } - - @Test - public void getQuartzSchedulerTest() throws Exception { - assertEquals( quartzScheduler, scheduler.getQuartzScheduler() ); - } - - @Test - public void createJobTest() throws Exception { - String actionId = "actionId"; - ComplexJobTrigger trigger = getComplexJobTrigger(); - IBackgroundExecutionStreamProvider outputStreamProvider = mock( IBackgroundExecutionStreamProvider.class ); - final Job job = scheduler.createJob( JOB_NAME, actionId, null, trigger, outputStreamProvider ); - - assertNotNull( job ); - assertEquals( Job.JobState.NORMAL, job.getState() ); - - assertTrue( job.getJobParams().containsKey( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ) ); - assertEquals( actionId, job.getJobParams().get( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ) ); - assertTrue( job.getJobParams().containsKey( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ) ); - assertEquals( outputStreamProvider, job.getJobParams().get( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ) ); - assertTrue( job.getJobParams().containsKey( QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID ) ); - assertNotNull( job.getJobParams().get( QuartzScheduler.RESERVEDMAPKEY_LINEAGE_ID ) ); - assertTrue( job.getJobParams().containsKey( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ) ); - assertEquals( USER_NAME, job.getJobParams().get( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ) ); - } - - @Test - public void createJobTest_ForUser() throws Exception { - String actionId = "actionId"; - ComplexJobTrigger trigger = getComplexJobTrigger(); - IBackgroundExecutionStreamProvider outputStreamProvider = mock( IBackgroundExecutionStreamProvider.class ); - Map paramMap = new HashMap<>(); - paramMap.put( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER, "ninja" ); - final Job job = scheduler.createJob( JOB_NAME, paramMap, trigger, outputStreamProvider ); - - assertNotNull( job ); - assertEquals( "ninja", job.getUserName() ); - assertEquals( Job.JobState.NORMAL, job.getState() ); - } - - @Test - public void createQuartzTriggerComplexTriggerTest() throws Exception { - final Trigger quartzTrigger = QuartzScheduler.createQuartzTrigger( getComplexJobTrigger(), getJobKey() ); - - assertNotNull( quartzTrigger ); - assertTrue( quartzTrigger instanceof CronTrigger ); - assertEquals( SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW, quartzTrigger.getMisfireInstruction() ); - assertEquals( CRON_EXPRESSION, ( (CronTrigger) quartzTrigger ).getCronExpression() ); - assertEquals( USER_NAME, quartzTrigger.getGroup() ); - - } - - @Test - public void createQuartzTriggerSimpleTriggerTest() throws Exception { - final Calendar calendar = Calendar.getInstance(); - Date startTime = calendar.getTime(); - calendar.add( Calendar.MONTH, 1 ); - Date endTime = calendar.getTime(); - int repeatCount = 5; - long repeatIntervalSeconds = 10; - final SimpleJobTrigger simpleJobTrigger = new SimpleJobTrigger( startTime, endTime, repeatCount, - repeatIntervalSeconds ); - final Trigger quartzTrigger = QuartzScheduler.createQuartzTrigger( simpleJobTrigger, getJobKey() ); - - assertNotNull( quartzTrigger ); - assertTrue( quartzTrigger instanceof SimpleTrigger ); - assertEquals( SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT, - quartzTrigger.getMisfireInstruction() ); - assertEquals( USER_NAME, quartzTrigger.getGroup() ); - - SimpleTrigger simpleTrigger = (SimpleTrigger) quartzTrigger; - assertEquals( startTime, simpleTrigger.getStartTime() ); - assertEquals( endTime, simpleTrigger.getEndTime() ); - assertEquals( repeatCount, simpleTrigger.getRepeatCount() ); - assertEquals( repeatIntervalSeconds * 1000, simpleTrigger.getRepeatInterval() ); - } - - @Test( expected = SchedulerException.class ) - public void createQuartzTriggerNotDefinedTriggerTest() throws Exception { - final IJobTrigger trigger = mock( IJobTrigger.class ); - QuartzScheduler.createQuartzTrigger( trigger, getJobKey() ); - } - - @Test - public void updateJobTest() throws Exception { - final JobDetail jobDetail = setJobDataMap( USER_NAME ); - - scheduler.updateJob( JOB_ID, new HashMap(), getComplexJobTrigger() ); - - verify( quartzScheduler, times( 1 ) ).addJob( eq( jobDetail ), eq( true ) ); - verify( quartzScheduler, times( 1 ) ).rescheduleJob( eq( JOB_ID ), eq( USER_NAME ), any( Trigger.class ) ); - } - - @Test - public void triggerNowTest() throws Exception { - final SimpleTrigger simpleTrigger = mock( SimpleTrigger.class ); - final CronTrigger cronTrigger = mock( CronTrigger.class ); - when( quartzScheduler.getTriggersOfJob( eq( JOB_ID ), eq( USER_NAME ) ) ).thenReturn( new Trigger[] { simpleTrigger, - cronTrigger - } ); - - scheduler.triggerNow( JOB_ID ); - - verify( simpleTrigger, times( 1 ) ).setPreviousFireTime( any( Date.class ) ); - verify( cronTrigger, times( 1 ) ).setPreviousFireTime( any( Date.class ) ); - verify( quartzScheduler, times( 1 ) ).rescheduleJob( eq( JOB_ID ), eq( USER_NAME ), eq( simpleTrigger ) ); - verify( quartzScheduler, times( 1 ) ).rescheduleJob( eq( JOB_ID ), eq( USER_NAME ), eq( cronTrigger ) ); - verify( quartzScheduler, times( 1 ) ).triggerJob( eq( JOB_ID ), eq( USER_NAME ) ); - } - - @Test - public void getJobTest() throws Exception { - final CronTrigger cronTrigger = mock( CronTrigger.class ); - when( cronTrigger.getCronExpression() ).thenReturn( CRON_EXPRESSION ); - when( quartzScheduler.getTriggersOfJob( eq( JOB_ID ), eq( USER_NAME ) ) ).thenReturn( new Trigger[] { cronTrigger } ); - setJobDataMap( USER_NAME ); - - final Job job = scheduler.getJob( JOB_ID ); - - assertEquals( JOB_ID, job.getJobId() ); - assertEquals( jobDetails, job.getJobParams() ); - assertEquals( USER_NAME, job.getUserName() ); - assertEquals( JOB_NAME, job.getJobName() ); - assertEquals( Job.JobState.NORMAL, job.getState() ); - } - - @Test - public void getJobsTest() throws Exception { - final IJobFilter jobFilter = mock( IJobFilter.class ); - when( jobFilter.accept( any( Job.class ) ) ).thenReturn( true ); - - final String groupName = "groupName"; - when( quartzScheduler.getJobGroupNames() ).thenReturn( new String[] { groupName } ); - when( quartzScheduler.getJobNames( eq( groupName ) ) ).thenReturn( new String[] { JOB_ID } ); - final Trigger trigger = mock( Trigger.class ); - Date date1 = new Date(); - when( trigger.getPreviousFireTime() ).thenReturn( new Date( ) ); - when( trigger.getFireTimeAfter( any( Date.class ) ) ).thenReturn( date1 ); - when( trigger.getNextFireTime() ).thenReturn( date1 ); - final Trigger trigger2 = mock( Trigger.class ); - when( trigger2.getGroup() ).thenReturn( "MANUAL_TRIGGER" ); - when( quartzScheduler.getTriggersOfJob( eq( JOB_ID ), eq( groupName ) ) ).thenReturn( new Trigger[] { trigger, trigger2 } ); - setJobDataMap( groupName ); - - final List jobs = scheduler.getJobs( jobFilter ); - - assertNotNull( jobs ); - assertEquals( 1, jobs.size() ); - - Job job = jobs.get( 0 ); - assertEquals( groupName, job.getGroupName() ); - assertEquals( USER_NAME, job.getUserName() ); - assertEquals( jobDetails, job.getJobParams() ); - assertEquals( JOB_ID, job.getJobId() ); - assertEquals( JOB_NAME, job.getJobName() ); - assertEquals( trigger.getPreviousFireTime(), job.getLastRun() ); - assertEquals( trigger.getNextFireTime(), job.getNextRun() ); - } - - private JobDetail setJobDataMap( String groupName ) throws org.quartz.SchedulerException { - final JobDetail jobDetail = new JobDetail( JOB_ID, USER_NAME, BlockingQuartzJob.class ); - jobDetail.setJobDataMap( new JobDataMap( jobDetails ) ); - when( quartzScheduler.getJobDetail( eq( JOB_ID ), eq( groupName ) ) ).thenReturn( jobDetail ); - return jobDetail; - } - - @Test - public void pauseTest() throws Exception { - scheduler.pause(); - - verify( quartzScheduler, times( 1 ) ).standby(); - } - - @Test - public void pauseJobTest() throws Exception { - scheduler.pauseJob( JOB_ID ); - - verify( quartzScheduler, times( 1 ) ).pauseJob( eq( JOB_ID ), eq( USER_NAME ) ); - } - - @Test - public void removeJobTest() throws Exception { - scheduler.removeJob( JOB_ID ); - - verify( quartzScheduler, times( 1 ) ).deleteJob( eq( JOB_ID ), eq( USER_NAME ) ); - } - - @Test - public void startTest() throws Exception { - scheduler.start(); - - verify( quartzScheduler, times( 1 ) ).start(); - } - - @Test - public void resumeJobTest() throws Exception { - scheduler.resumeJob( JOB_ID ); - verify( quartzScheduler, times( 1 ) ).resumeJob( eq( JOB_ID ), eq( USER_NAME ) ); - } - - @Test - public void getStatusTest() throws Exception { - when( quartzScheduler.isInStandbyMode() ).thenReturn( true ); - assertEquals( IScheduler.SchedulerStatus.PAUSED, scheduler.getStatus() ); - - when( quartzScheduler.isInStandbyMode() ).thenReturn( false ); - when( quartzScheduler.isStarted() ).thenReturn( true ); - assertEquals( IScheduler.SchedulerStatus.RUNNING, scheduler.getStatus() ); - - when( quartzScheduler.isInStandbyMode() ).thenThrow( new org.quartz.SchedulerException() ); - try { - scheduler.getStatus(); - fail(); - } catch ( SchedulerException e ) { - // it's expected - } - } - - @Test - public void shutdownTest() throws Exception { - scheduler.shutdown(); - - verify( quartzScheduler, times( 1 ) ).shutdown( eq( true ) ); - } - - @Test - public void fireJobCompletedTest() throws Exception { - final IAction actionBean = mock( IAction.class ); - final String actionUser = "actionUser"; - final ISchedulerListener schedulerListener = mock( ISchedulerListener.class ); - scheduler.addListener( schedulerListener ); - final Map params = new HashMap<>(); - final IBackgroundExecutionStreamProvider streamProvider = mock( IBackgroundExecutionStreamProvider.class ); - scheduler.fireJobCompleted( actionBean, actionUser, params, streamProvider ); - - verify( schedulerListener, times( 1 ) ).jobCompleted( eq( actionBean ), eq( actionUser ), eq( params ), eq( streamProvider ) ); - } - - private QuartzJobKey getJobKey() throws SchedulerException { - return new QuartzJobKey( JOB_NAME, USER_NAME ); - } - - private ComplexJobTrigger getComplexJobTrigger() { - final ComplexJobTrigger trigger = new ComplexJobTrigger(); - trigger.setSecondRecurrence( 1 ); - return trigger; - } -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzSchedulerIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzSchedulerIT.java deleted file mode 100644 index 63bb600e76c..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzSchedulerIT.java +++ /dev/null @@ -1,585 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import java.io.Serializable; -import java.security.Principal; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.engine.IAuditEntry; -import org.pentaho.platform.api.engine.IUserRoleListService; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -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.TestAuditEntry; -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.QuartzSchedulerAvailability; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; -import org.pentaho.platform.scheduler2.ws.test.TestQuartzScheduler; -import org.pentaho.test.platform.engine.core.MicroPlatform; -import org.springframework.security.core.userdetails.UserDetailsService; - -@SuppressWarnings( "nls" ) -public class QuartzSchedulerIT { - private QuartzScheduler scheduler; - - private String TEST_USER = "TestUser"; - - private HashMap jobParams; - - @Before - public void init() throws SchedulerException, PlatformInitializationException { - scheduler = new QuartzScheduler(); - scheduler.start(); - - TestAction.reset(); - TestAction2.reset(); - TestAction3.reset(); - TestActionCustomParam.reset(); - - MicroPlatform mp = new MicroPlatform(); - mp.define( "IScheduler2", TestQuartzScheduler.class ); //$NON-NLS-1$ - mp.define( IUserRoleListService.class, StubUserRoleListService.class ); - mp.define( UserDetailsService.class, StubUserDetailsService.class ); - mp.define( IAuditEntry.class, TestAuditEntry.class ); - mp.start(); - - SecurityHelper.getInstance().becomeUser( TEST_USER ); - jobParams = new HashMap(); - } - - @After - public void cleanup() throws SchedulerException { - // have to clear the jobs between tests since quartz is actually serving us the same base scheduler instance - for ( Job job : scheduler.getJobs( null ) ) { - scheduler.removeJob( job.getJobId() ); - } - Assert.assertEquals( "Stale jobs are hanging around!", scheduler.getJobs( null ).size(), 0 ); - } - - @Test - public void quartzAvailabilityTest() { - - Date startTime = new Date(); - Date endTime = new Date( startTime.getTime() + 1000 ); - org.quartz.Calendar calendar = new QuartzSchedulerAvailability( startTime, endTime ); - Assert.assertTrue( calendar.isTimeIncluded( startTime.getTime() ) ); - Assert.assertTrue( calendar.isTimeIncluded( endTime.getTime() ) ); - Assert.assertFalse( calendar.isTimeIncluded( startTime.getTime() - 1 ) ); - Assert.assertFalse( calendar.isTimeIncluded( endTime.getTime() + 1 ) ); - Assert.assertEquals( calendar.getNextIncludedTime( startTime.getTime() - 1 ), startTime.getTime() ); - Assert.assertEquals( calendar.getNextIncludedTime( startTime.getTime() ), startTime.getTime() + 1 ); - Assert.assertEquals( calendar.getNextIncludedTime( endTime.getTime() - 1 ), endTime.getTime() ); - Assert.assertEquals( calendar.getNextIncludedTime( endTime.getTime() ), 0 ); - Assert.assertEquals( calendar.getNextIncludedTime( endTime.getTime() + 1 ), 0 ); - - calendar = new QuartzSchedulerAvailability( null, endTime ); - Assert.assertTrue( calendar.isTimeIncluded( startTime.getTime() ) ); - Assert.assertTrue( calendar.isTimeIncluded( endTime.getTime() ) ); - Assert.assertFalse( calendar.isTimeIncluded( endTime.getTime() + 1 ) ); - Assert.assertEquals( calendar.getNextIncludedTime( startTime.getTime() ), startTime.getTime() + 1 ); - Assert.assertEquals( calendar.getNextIncludedTime( endTime.getTime() ), 0 ); - Assert.assertEquals( calendar.getNextIncludedTime( endTime.getTime() + 1 ), 0 ); - - calendar = new QuartzSchedulerAvailability( startTime, null ); - Assert.assertTrue( calendar.isTimeIncluded( startTime.getTime() ) ); - Assert.assertFalse( calendar.isTimeIncluded( startTime.getTime() - 1 ) ); - Assert.assertTrue( calendar.isTimeIncluded( endTime.getTime() ) ); - Assert.assertEquals( calendar.getNextIncludedTime( startTime.getTime() - 1 ), startTime.getTime() ); - Assert.assertEquals( calendar.getNextIncludedTime( startTime.getTime() ), startTime.getTime() + 1 ); - } - - @Test - public void runComplexTriggerTest() throws SchedulerException { - Calendar calendar = Calendar.getInstance(); - final int testTime = 7; // seconds - - int startingMinute = calendar.get( Calendar.MINUTE ); - int startingSec = calendar.get( Calendar.SECOND ) + 1; - // we can't finish until end of the minute - sleep for this time - if ( startingSec > 59 - testTime ) { - sleep( 59 - startingSec ); - startingSec = 0; - startingMinute++; - if ( startingMinute > 59 ) { - startingMinute = startingMinute % 60; - } - } - int endingSecond = startingSec + 5; - - RecurrenceList recurrenceList = new RecurrenceList( startingSec, endingSecond ); - SequentialRecurrence sequentialRecurrence = new SequentialRecurrence( startingSec, endingSecond ); - IncrementalRecurrence incrementalRecurrence = new IncrementalRecurrence( startingSec, 1 ); - - ComplexJobTrigger jobTrigger = new ComplexJobTrigger(); - jobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - jobTrigger.setMinuteRecurrence( startingMinute ); - - jobTrigger.setSecondRecurrence( recurrenceList ); - System.out.println( jobTrigger.toString() ); - String jobName = "complexJob1"; - Job job = scheduler.createJob( jobName, TestAction.class, new HashMap(), jobTrigger ); - Assert.assertTrue( job.getJobName().contains( jobName ) ); - Assert.assertEquals( job.getSchedulableClass(), TestAction.class.getName() ); - Assert.assertEquals( job.getJobTrigger().toString(), jobTrigger.toString() ); - - jobTrigger.setSecondRecurrence( sequentialRecurrence ); - jobName = "complexJob2"; - job = scheduler.createJob( jobName, TestAction2.class, new HashMap(), jobTrigger ); - Assert.assertTrue( job.getJobName().contains( jobName ) ); - Assert.assertEquals( job.getSchedulableClass(), TestAction2.class.getName() ); - Assert.assertEquals( job.getJobTrigger().toString(), jobTrigger.toString() ); - - jobTrigger.setSecondRecurrence( incrementalRecurrence ); - jobName = "complexJob3"; - job = scheduler.createJob( jobName, TestAction3.class, new HashMap(), jobTrigger ); - Assert.assertTrue( job.getJobName().contains( jobName ) ); - Assert.assertEquals( job.getSchedulableClass(), TestAction3.class.getName() ); - Assert.assertEquals( job.getJobTrigger().toString(), jobTrigger.toString() ); - - // - // Wait for the jobs to complete, then check that each action executed the correct number of times - // - sleep( testTime ); - - Assert.assertEquals( "Job did not run the correct number of times", 2, TestAction.counter ); - Assert.assertEquals( "Job did not run the correct number of times", 6, TestAction2.counter ); - System.out.println( "Counter = " + TestAction3.counter ); - Assert.assertTrue( "Job did not run.", TestAction3.counter > 3 ); - } - - @Test - public void editJobTest() throws SchedulerException { - SimpleJobTrigger repeater = new SimpleJobTrigger(); - repeater.setStartTime( new Date() ); - repeater.setRepeatInterval( 2 ); - repeater.setRepeatCount( 20 ); - - Job job = scheduler.createJob( "testName", TestAction.class, new HashMap(), repeater ); - - sleep( 3 ); - - Assert.assertTrue( "Job did not run the correct number of times", TestAction.counter >= 2 ); - - repeater = new SimpleJobTrigger(); - repeater.setStartTime( new Date() ); - repeater.setRepeatInterval( 5 ); - repeater.setRepeatCount( 3 ); - - int count = TestAction.counter; - System.out.println( "updating job! " + new Date() ); - scheduler.updateJob( job.getJobId(), new HashMap(), repeater ); - List jobs = scheduler.getJobs( null ); - Assert.assertEquals( "Unexpected number of scheduled jobs", 1, jobs.size() ); - SimpleJobTrigger simpleJobTrigger = (SimpleJobTrigger) jobs.get( 0 ).getJobTrigger(); - Assert.assertEquals( 5, simpleJobTrigger.getRepeatInterval() ); - Assert.assertEquals( 3, simpleJobTrigger.getRepeatCount() ); - sleep( 1 ); - Assert.assertEquals( "Job did not run the correct number of times", count + 1, TestAction.counter ); - count = TestAction.counter; - sleep( 3 ); - Assert.assertEquals( "Job ran unexpectedly", count, TestAction.counter ); - sleep( 3 ); - Assert.assertTrue( "Job did not run the correct number of times", count < TestAction.counter ); - } - - @Test - public void runTenTimesJobTest() throws SchedulerException { - SimpleJobTrigger repeater = new SimpleJobTrigger(); - repeater.setStartTime( new Date() ); - repeater.setRepeatInterval( 1 ); - repeater.setRepeatCount( 9 ); - - scheduler.createJob( "testName", TestAction.class, new HashMap(), repeater ); - - sleep( 5 ); - Assert.assertTrue( "Job did not run the correct number of times", TestAction.counter > 3 ); - System.out.println( "Counter = " + TestAction.counter ); - Assert.assertTrue( "Job did not run the correct number of times", TestAction.counter < 7 ); - sleep( 10 ); - Assert.assertEquals( "Job did not run the correct number of times", 10, TestAction.counter ); - - List jobs = scheduler.getJobs( null ); - Assert.assertEquals( 0, jobs.size() ); - } - - @Test - public void testJobRunsAsSchedulingUser() throws SchedulerException { - SimpleJobTrigger RUN_ONCE_IN_2_SECS = JobTrigger.ONCE_NOW; - RUN_ONCE_IN_2_SECS.setStartTime( new Date( System.currentTimeMillis() + 2000L ) ); - - scheduler.createJob( "testName", TestAction.class, new HashMap(), RUN_ONCE_IN_2_SECS ); - - SecurityHelper.getInstance().becomeUser( "Ima Wronguser" ); - - sleep( 3 ); - - Assert.assertEquals( "Job did not run the correct number of times", 1, TestAction.counter ); - Assert.assertEquals( "Job did not run as the correct user", TEST_USER, TestAction.executedAsUser ); - - List jobs = scheduler.getJobs( null ); - Assert.assertEquals( 0, jobs.size() ); - } - - @Test - public void testParamterizedJob() throws SchedulerException { - jobParams.put( "testParam1", "testParam1-value" ); - jobParams.put( "testParam2", "testParam2-value" ); - - scheduler.createJob( "testName", TestAction.class, jobParams, JobTrigger.ONCE_NOW ); - - sleep( 2 ); - - Assert.assertEquals( "Job did not run the correct number of times", 1, TestAction.counter ); - Assert.assertEquals( "A parameter was not properly set", "testParam1-value", TestAction.testParam1_public ); - Assert.assertEquals( "A parameter was not properly set", "testParam2-value", TestAction.testParam2_public ); - - List jobs = scheduler.getJobs( null ); - Assert.assertEquals( 0, jobs.size() ); - } - - @Test - public void testPauseAndResumeJob() throws SchedulerException { - String jobName = "complexJob1"; - int counter = TestAction.counter; - Calendar calendar = Calendar.getInstance(); - int startingMin = calendar.get( Calendar.MINUTE ); - int startingSec = calendar.get( Calendar.SECOND ) + 1; - if ( startingSec > 59 ) { - startingSec = startingSec % 60; - startingMin++; - if ( startingMin > 59 ) { - startingMin = startingMin % 60; - } - } - ComplexJobTrigger complexJobTrigger = new ComplexJobTrigger(); - complexJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - complexJobTrigger.setMinuteRecurrence( startingMin ); - complexJobTrigger.setSecondRecurrence( startingSec ); - Job job = scheduler.createJob( jobName, TestAction.class, jobParams, complexJobTrigger ); - scheduler.pauseJob( job.getJobId() ); - sleep( 2 ); - Assert.assertEquals( counter, TestAction.counter ); - Assert.assertEquals( 1, scheduler.getJobs( null ).size() ); - scheduler.resumeJob( job.getJobId() ); - sleep( 2 ); - Assert.assertTrue( counter != TestAction.counter ); - scheduler.removeJob( job.getJobId() ); - Assert.assertEquals( 0, scheduler.getJobs( null ).size() ); - } - - @Test - public void testPauseAndResumeScheduler() throws SchedulerException { - Calendar calendar = Calendar.getInstance(); - int startingSec = calendar.get( Calendar.SECOND ) + 1; - if ( startingSec > 59 ) { - startingSec = startingSec % 60; - } - ComplexJobTrigger complexJobTrigger = new ComplexJobTrigger(); - complexJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - complexJobTrigger.setMinuteRecurrence( (ITimeRecurrence) null ); - complexJobTrigger.setSecondRecurrence( startingSec ); - String jobName = "complexJob1"; - int counter = TestAction.counter; - - scheduler.pause(); - scheduler.createJob( jobName, TestAction.class, jobParams, complexJobTrigger ); - sleep( 3 ); - Assert.assertEquals( "Job executed while scheduler is supposedly paused!", counter, TestAction.counter ); - Assert.assertEquals( "Scheduler is not aware of the dormant job!", 1, scheduler.getJobs( null ).size() ); - - scheduler.start(); - sleep( 3 ); - Assert.assertTrue( "Job did not execute after scheduler started back up!", counter != TestAction.counter ); - } - - @Test - public void testStartAndEndDate() throws SchedulerException { - - ComplexJobTrigger startEndJobTrigger = new ComplexJobTrigger(); - ComplexJobTrigger startJobTrigger = new ComplexJobTrigger(); - ComplexJobTrigger endJobTrigger = new ComplexJobTrigger(); - startEndJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - startJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - endJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - startEndJobTrigger.setMinuteRecurrence( (ITimeRecurrence) null ); - startJobTrigger.setMinuteRecurrence( (ITimeRecurrence) null ); - endJobTrigger.setMinuteRecurrence( (ITimeRecurrence) null ); - startEndJobTrigger.setSecondRecurrence( new IncrementalRecurrence( 0, 1 ) ); - startJobTrigger.setSecondRecurrence( new IncrementalRecurrence( 0, 1 ) ); - endJobTrigger.setSecondRecurrence( new IncrementalRecurrence( 0, 1 ) ); - - Calendar calendar = Calendar.getInstance(); - int startingMin = calendar.get( Calendar.MINUTE ); - int startingSec = calendar.get( Calendar.SECOND ) + 3; - if ( startingSec > 59 ) { - startingSec = startingSec % 60; - startingMin++; - if ( startingMin > 59 ) { - startingMin = startingMin % 60; - } - } - calendar.set( Calendar.MINUTE, startingMin ); - calendar.set( Calendar.SECOND, startingSec ); - - startEndJobTrigger.setStartTime( calendar.getTime() ); - startJobTrigger.setStartTime( calendar.getTime() ); - - calendar.add( Calendar.SECOND, 3 ); - startEndJobTrigger.setEndTime( calendar.getTime() ); - endJobTrigger.setEndTime( calendar.getTime() ); - - int startEndCounter = TestAction.counter; - int startCounter = TestAction2.counter; - int endCounter = TestAction3.counter; - - Job job = scheduler.createJob( "startEndJob", TestAction.class, jobParams, startEndJobTrigger ); - Job job2 = scheduler.createJob( "startJob", TestAction2.class, jobParams, startJobTrigger ); - Job job3 = scheduler.createJob( "endJob", TestAction3.class, jobParams, endJobTrigger ); - try { - - sleep( 2 ); - Assert.assertEquals( startEndCounter, TestAction.counter ); - Assert.assertEquals( startCounter, TestAction2.counter ); - Assert.assertTrue( endCounter != TestAction3.counter ); - endCounter = TestAction3.counter; - sleep( 3 ); - Assert.assertTrue( startEndCounter != TestAction.counter ); - Assert.assertTrue( startCounter != TestAction2.counter ); - Assert.assertTrue( endCounter != TestAction3.counter ); - sleep( 3 ); - startEndCounter = TestAction.counter; - startCounter = TestAction2.counter; - endCounter = TestAction3.counter; - sleep( 3 ); - Assert.assertEquals( startEndCounter, TestAction.counter ); - Assert.assertTrue( startCounter != TestAction2.counter ); - Assert.assertEquals( endCounter, TestAction3.counter ); - } finally { - scheduler.removeJob( job.getJobId() ); - scheduler.removeJob( job2.getJobId() ); - scheduler.removeJob( job3.getJobId() ); - } - Assert.assertEquals( 0, scheduler.getJobs( null ).size() ); - } - - @Test - public void testWrongParameterTypeJob() throws SchedulerException { - jobParams.put( "customParam", "Should not be able to convert this string to the CustomParamType" ); - - scheduler.createJob( "testName", TestActionCustomParam.class, jobParams, JobTrigger.ONCE_NOW ); - - sleep( 2 ); - - Assert.assertEquals( "The job should have failed prior to execute being called", 0, TestActionCustomParam.counter ); - Assert.assertNull( "The root cause of failure should be the inability to convert a string to the custom type, " - + "thus this value should definitely be null", TestActionCustomParam.customParam_public ); - } - - @Test( expected = SchedulerException.class ) - public void testNullAction() throws SchedulerException { - scheduler.createJob( "testName", (Class) null, jobParams, JobTrigger.ONCE_NOW ); - } - - @Test - public void testRemoveJob() throws SchedulerException { - scheduler.pause(); - ComplexJobTrigger trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2050 ); - scheduler.createJob( "testName1", TestAction.class, jobParams, trigger ); - Assert.assertEquals( 1, scheduler.getJobs( null ).size() ); - - for ( Job oldJob : scheduler.getJobs( null ) ) { - scheduler.removeJob( oldJob.getJobId() ); - } - - Assert.assertEquals( 0, scheduler.getJobs( null ).size() ); - } - - @Test - public void testGetJobs() throws SchedulerException { - QuartzScheduler testGetJobsSchduler = new QuartzScheduler(); - - Assert.assertEquals( 0, testGetJobsSchduler.getJobs( null ).size() ); - - String PARAM_KEY = "testGetJobsKey"; - - jobParams.put( PARAM_KEY, "testParam1-value" ); - Calendar calendar = Calendar.getInstance(); - int startingMin = calendar.get( Calendar.MINUTE ); - int startingSec = calendar.get( Calendar.SECOND ) + 10; - if ( startingSec > 59 ) { - startingSec = startingSec % 60; - startingMin++; - if ( startingMin > 59 ) { - startingMin = startingMin % 60; - } - } - calendar.set( Calendar.MINUTE, startingMin ); - calendar.set( Calendar.SECOND, startingSec ); - SimpleJobTrigger jobTrigger = new SimpleJobTrigger( calendar.getTime(), null, 0, 0 ); - testGetJobsSchduler.createJob( "getJobsTestJob", TestAction.class, jobParams, jobTrigger ); - - List jobs = testGetJobsSchduler.getJobs( null ); - Assert.assertEquals( 1, jobs.size() ); - - Job theJob = jobs.get( 0 ); - Assert.assertTrue( theJob.getJobParams().containsKey( PARAM_KEY ) ); - Assert.assertTrue( theJob.getJobName().contains( "getJobsTestJob" ) ); - } - - public static class TestAction2 implements IAction { - public static int counter = 0; - - public static String executedAsUser; - - public void execute() throws Exception { - System.out.println( "TestAction2 execute called!" + new Date() ); - counter++; - Principal p = SecurityHelper.getInstance().getAuthentication(); - executedAsUser = ( p == null ) ? null : p.getName(); - } - - public static void reset() { - counter = 0; - executedAsUser = null; - } - } - - public static class TestAction3 implements IAction { - public static int counter = 0; - - public static String executedAsUser; - - public void execute() throws Exception { - System.out.println( "TestAction3 execute called!" + new Date() ); - counter++; - Principal p = SecurityHelper.getInstance().getAuthentication(); - executedAsUser = ( p == null ) ? null : p.getName(); - } - - public static void reset() { - counter = 0; - executedAsUser = null; - } - } - - public static class TestAction implements IAction { - public static int counter = 0; - - public static String executedAsUser; - - private String testParam1; - - private String testParam2; - - public static String testParam1_public, testParam2_public; - - public String getTestParam1() { - return testParam1; - } - - public void setTestParam1( String testParam1 ) { - this.testParam1 = testParam1; - } - - public String getTestParam2() { - return testParam2; - } - - public void setTestParam2( String testParam2 ) { - this.testParam2 = testParam2; - } - - public void execute() throws Exception { - System.out.println( "TestAction execute called! " + new Date() ); - counter++; - Principal p = SecurityHelper.getInstance().getAuthentication(); - executedAsUser = ( p == null ) ? null : p.getName(); - - testParam1_public = getTestParam1(); - testParam2_public = getTestParam2(); - } - - public static void reset() { - counter = 0; - executedAsUser = null; - testParam1_public = null; - testParam2_public = null; - } - } - - public static class TestActionCustomParam extends TestAction { - private CustomParamType customParam; - - public static CustomParamType customParam_public; - - public CustomParamType getCustomParam() { - return customParam; - } - - public void setCustomParam( CustomParamType customParam ) { - this.customParam = customParam; - } - - @Override - public void execute() throws Exception { - super.execute(); - customParam_public = getCustomParam(); - } - - public static void reset() { - TestAction.reset(); - customParam_public = null; - } - } - - public static class CustomParamType { - - } - - public static class NotAnIAction { - - } - - private void sleep( int seconds ) { - try { - Thread.sleep( seconds * 1000 ); - } catch ( InterruptedException e ) { - throw new RuntimeException( e ); - } - } -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzThreadsIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzThreadsIT.java deleted file mode 100644 index 8f1ae87e9f6..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/quartz/test/QuartzThreadsIT.java +++ /dev/null @@ -1,128 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import java.io.IOException; -import java.util.Properties; -import java.util.Set; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.engine.core.system.boot.PlatformInitializationException; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; - -@SuppressWarnings( "nls" ) -public class QuartzThreadsIT { - - private QuartzScheduler scheduler; - - private static final String SCHEDULER_NAME = "JUnitTestScheduler"; - private static final int WORKER_THREAD_COUNT = 3; - - @Before - public void init() throws SchedulerException, PlatformInitializationException, org.quartz.SchedulerException, - IOException { - scheduler = new QuartzScheduler(); - - Properties props = new Properties(); - props.put( "org.quartz.scheduler.makeSchedulerThreadDaemon", "true" ); - props.put( "org.quartz.threadPool.makeThreadsDaemons", "true" ); - props.put( "org.quartz.scheduler.instanceName", SCHEDULER_NAME ); - props.put( "org.quartz.scheduler.instanceId", "1" ); - props.put( "org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool" ); - props.put( "org.quartz.threadPool.threadCount", new Integer( WORKER_THREAD_COUNT ).toString() ); - props.put( "org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore" ); - - System.err.println( "Quartz initialized with properties:" ); - Assert.assertTrue( "Properties object is empty! Something went wrong!", props.size() > 0 ); - props.store( System.out, "QuartzThreadsTest" ); // BEWARE JUnit does not allow exceptions to fail a @Before, so this - // must be visually inspected - - // org.quartz.scheduler.rmi.export = false - // org.quartz.scheduler.rmi.proxy = false - - scheduler.setQuartzSchedulerFactory( new org.quartz.impl.StdSchedulerFactory( props ) ); - scheduler.start(); - } - - @After - public void printThreadDump() { - Set threads = Thread.getAllStackTraces().keySet(); - System.out.println( "LIVE QUARTZ THREADS DUMP:" ); - int lineCount = 0; - for ( Thread t : threads ) { - if ( t.isAlive() && t.getName().contains( SCHEDULER_NAME ) ) { - lineCount++; - String daemon = ( t.isDaemon() ) ? "(DAEMON)" : "(NON-DAEMON)"; - System.out.println( daemon + " " + t.toString() ); - } - } - if ( lineCount == 0 ) { - System.out.println( " THERE ARE NO LIVE QUARTZ THREADS" ); - } - } - - @Test - public void threadsAreRunningDaemon() { - Set threads = Thread.getAllStackTraces().keySet(); - for ( Thread t : threads ) { - if ( !t.isDaemon() ) { - if ( t.getName().contains( SCHEDULER_NAME ) ) { - Assert.fail( "Thread [" + t + "] should be a daemon" ); - } - } - } - } - - @Test - public void shutdownKillsAllSchedulerThreads() throws SchedulerException, InterruptedException { - int preCount = Thread.getAllStackTraces().keySet().size(); - int expectedThreadCount = preCount - 1 - WORKER_THREAD_COUNT; // 1 thread is the quartz scheduler itself - System.out.println( "Prior to shutdown, thread count is " + preCount ); - - scheduler.shutdown(); - - for ( int i = 0; i < 30; i++ ) { - int postCount = Thread.getAllStackTraces().keySet().size(); - if ( expectedThreadCount == postCount ) { - break; - } - Thread.sleep( 1000 ); // allow some time for the threads to be killed. apparently quartz does not wait on them - // before returning from shutdown - } - - int postCount = Thread.getAllStackTraces().keySet().size(); - System.out.println( "After shutdown, thread count is " + postCount ); - - Assert.assertEquals( "Shutdown did not kill all of the threads", expectedThreadCount, postCount ); - - Set threads = Thread.getAllStackTraces().keySet(); - for ( Thread t : threads ) { - // System.out.println(t.toString()); - if ( t.isAlive() && t.getName().contains( SCHEDULER_NAME ) ) { - Assert.fail( "Thread [" + t + "] should have been killed during Quartz shutdown" ); - } - } - } -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListenerIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListenerIT.java deleted file mode 100644 index 5b7f0a8bcbe..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListenerIT.java +++ /dev/null @@ -1,152 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.versionchecker; - -import java.io.Serializable; -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.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPluginManager; -import org.pentaho.platform.api.engine.IUserRoleListService; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.core.system.StandaloneSession; -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.ws.ParamValue; -import org.pentaho.platform.scheduler2.ws.test.JaxWsSchedulerServiceIT.TstPluginManager; -import org.pentaho.test.platform.engine.core.MicroPlatform; -import org.springframework.security.core.userdetails.UserDetailsService; - -@SuppressWarnings( "nls" ) -public class EmbeddedVersionCheckSystemListenerIT { - - // @Autowired - // private ApplicationContext applicationContext; - - private Map jobParams; - private IScheduler scheduler; - static final String TEST_USER = "TestUser"; - - @Before - public void init() throws SchedulerException, PlatformInitializationException { - 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(); - } - - @After - public void after() throws SchedulerException { - for ( Job job : scheduler.getJobs( null ) ) { - scheduler.removeJob( job.getJobId() ); - } - } - - @Test - public void testCreateJob() throws SchedulerException { - IPentahoSession testSession = new StandaloneSession( "TEST_USER" ); - TestEmbeddedVersionCheckSystemListener listener = new TestEmbeddedVersionCheckSystemListener(); - // First setup like defaults - listener.setDisableVersionCheck( false ); - listener.setRequestedReleases( "Minor, GA" ); - listener.setRepeatIntervalSeconds( 86400 ); - Assert.assertFalse( listener.isDisableVersionCheck() ); - Assert.assertEquals( "Minor, GA", listener.getRequestedReleases() ); - Assert.assertEquals( 86400, listener.getRepeatIntervalSeconds() ); - listener.setRepeatIntervalSeconds( 200 ); - Assert.assertEquals( 43200, listener.calculateRepeatSeconds() ); // makes sure that min isn't ignored - Assert.assertEquals( 0, listener.calculateRequestFlags() ); // Expect 0 because Minor <> minor and GA <> ga - listener.setRequestedReleases( "minor, ga" ); - Assert.assertEquals( 40, listener.calculateRequestFlags() ); // should be 8 + 32 = 40 - - listener.setFakeAvail(); // Fake availability of version checker. - listener.startup( testSession ); - - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - IJobFilter filter = new IJobFilter() { - public boolean accept( Job job ) { - return job.getJobName().contains( "PentahoSystemVersionCheck" ); - } - }; - List matchingJobs = scheduler.getJobs( filter ); - Assert.assertEquals( 1, matchingJobs.size() ); - Job aJob = matchingJobs.get( 0 ); - Assert.assertTrue( aJob.getJobName().startsWith( "PentahoSystemVersionCheck" ) ); - - Assert.assertEquals( TEST_USER, aJob.getUserName() ); - - Map vcJobParms = aJob.getJobParams(); - Assert.assertTrue( vcJobParms.size() > 0 ); - Assert.assertTrue( vcJobParms.containsKey( VersionCheckerAction.VERSION_REQUEST_FLAGS ) ); - Object val = vcJobParms.get( VersionCheckerAction.VERSION_REQUEST_FLAGS ); - Assert.assertNotNull( val ); - Assert.assertTrue( val instanceof Integer ); - Integer intVal = (Integer) val; - Assert.assertEquals( 40, intVal.intValue() ); - listener.deleteJobIfNecessary(); - - matchingJobs = scheduler.getJobs( null ); // Should have no jobs now - Assert.assertEquals( 0, matchingJobs.size() ); - - } - - public static class TestQuartzScheduler extends QuartzScheduler { - @Override - protected String getCurrentUser() { - SecurityHelper.getInstance().becomeUser( TEST_USER ); - return super.getCurrentUser(); - } - } - - public static class TestEmbeddedVersionCheckSystemListener extends EmbeddedVersionCheckSystemListener { - boolean fakeAvail; - - public void setFakeAvail() { - this.fakeAvail = true; - } - - public boolean isVersionCheckAvailable() { - if ( fakeAvail ) { - return true; - } else { - return super.isVersionCheckAvailable(); - } - } - } - -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT.java deleted file mode 100644 index 75a273c1654..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT.java +++ /dev/null @@ -1,441 +0,0 @@ -/*! - * - * 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-2019 Hitachi Vantara. 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.IAuthorizationPolicy; -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.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.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 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.define( IAuthorizationPolicy.class, ScheduleAuthorizationPolicy.class ); - mp.start(); - - scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - scheduler.start(); - - MyAction.executed = false; - MyAction.staticStringParam = null; - - jobParams = new HashMap(); - 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 ) ); - - // Force a job schedule to guarantee that all security session vars are ready to running all tests - String jobId = schedulerSvc.createSimpleJob( "test job", generateFullJobParams(), JobTrigger.ONCE_NOW ); - scheduler.removeJob( jobId ); - } - - @After - public void after() throws SchedulerException { - for ( Job job : scheduler.getJobs( null ) ) { - scheduler.removeJob( job.getJobId() ); - } - } - - private static Map generateFullJobParams() { - HashMap privateParams = new HashMap(); - - 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 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 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 listParam = (List) 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 mapParam = (Map) 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 staticListParam; - public static Map staticMapParam; - - public String stringParam; - public List listParam; - public Map mapParam; - - public void execute() throws Exception { - System.out.println( "I RANNNNNN!! at " + new Date() ); - executed = true; - } - - // - // Bean property getters/setters - // - - public List getListParam() { - return listParam; - } - - public void setListParam( List listParam ) { - this.listParam = listParam; - staticListParam = listParam; - } - - public Map getMapParam() { - return mapParam; - } - - public void setMapParam( Map 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 newJobParams = new HashMap( 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 newJobParams = new HashMap( 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() ); - } -} diff --git a/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/ScheduleAuthorizationPolicy.java b/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/ScheduleAuthorizationPolicy.java deleted file mode 100644 index 0b291f12106..00000000000 --- a/scheduler/src/it/java/org/pentaho/platform/scheduler2/ws/test/ScheduleAuthorizationPolicy.java +++ /dev/null @@ -1,36 +0,0 @@ -/*! - * - * 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-2019 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import org.pentaho.platform.api.engine.IAuthorizationPolicy; - -import java.util.Collections; -import java.util.List; - -public class ScheduleAuthorizationPolicy implements IAuthorizationPolicy { - public boolean isAllowed( String actionName ) { - return true; - } - - public List getAllowedActions( String actionNamespace ) { - return Collections.emptyList(); - } -} diff --git a/scheduler/src/it/resources/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT-context.xml b/scheduler/src/it/resources/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT-context.xml deleted file mode 100644 index 7b4ed46f6e9..00000000000 --- a/scheduler/src/it/resources/org/pentaho/platform/scheduler2/ws/test/JaxWsSchedulerServiceIT-context.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ComplexJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ComplexJobTrigger.java deleted file mode 100644 index 2151eff47b0..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ComplexJobTrigger.java +++ /dev/null @@ -1,631 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.TreeSet; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import com.cronutils.descriptor.CronDescriptor; -import com.cronutils.model.CronType; -import com.cronutils.model.definition.CronDefinition; -import com.cronutils.model.definition.CronDefinitionBuilder; -import com.cronutils.parser.CronParser; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.api.scheduler2.wrappers.DayOfMonthWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.DayOfWeekWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.HourlyWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.MinuteWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.MonthlyWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.SecondWrapper; -import org.pentaho.platform.api.scheduler2.wrappers.YearlyWrapper; -import org.pentaho.platform.scheduler2.quartz.QuartzCronStringFactory; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -/** - * Used to specify a recurrence of scheduled job execution or a recurrence of scheduler availability. - * - * @author arodriguez - */ -@XmlRootElement -public class ComplexJobTrigger extends JobTrigger { - - private static final long serialVersionUID = -2742874361158319735L; - - public static final int SUNDAY = 1; - public static final int MONDAY = 2; - public static final int TUESDAY = 3; - public static final int WEDNESDAY = 4; - public static final int THURSDAY = 5; - public static final int FRIDAY = 6; - public static final int SATURDAY = 7; - - public static final int JANUARY = 1; - public static final int FEBRUARY = 2; - public static final int MARCH = 3; - public static final int APRIL = 4; - public static final int MAY = 5; - public static final int JUNE = 6; - public static final int JULY = 7; - public static final int AUGUST = 8; - public static final int SEPTEMBER = 9; - public static final int OCTOBER = 10; - public static final int NOVEMBER = 11; - public static final int DECEMBER = 12; - - private YearlyWrapper yearlyRecurrences = new YearlyWrapper(); - private MonthlyWrapper monthlyRecurrences = new MonthlyWrapper(); - private DayOfMonthWrapper dayOfMonthRecurrences = new DayOfMonthWrapper(); - private DayOfWeekWrapper dayOfWeekRecurrences = new DayOfWeekWrapper(); - private HourlyWrapper hourlyRecurrences = new HourlyWrapper(); - private MinuteWrapper minuteRecurrences = new MinuteWrapper(); - private SecondWrapper secondRecurrences = new SecondWrapper(); - private long repeatInterval = 0; - private String cronDescription; - - public long getRepeatInterval() { - return repeatInterval; - } - public void setRepeatInterval( long repeatIntervalSeconds ) { - this.repeatInterval = repeatIntervalSeconds; - } - - /** - * Creates a recurrence for the specified date/time. Specifying both a day of month and day of week is not supported. - * At least one of them should be null. If both are specified only the day of month will be used. - * - * @param year - * the year to occur. If null recurrence will be every year. - * @param month - * the month to occur. If null recurrence will be every month. - * @param dayOfMonth - * the day of month to occur. If null recurrence will be every day of month. If specified day of week must be - * null. - * @param dayOfWeek - * the day of week to occur. If null recurrence will be every day of week. If specified day of month must be - * null. - * @param hourOfDay - * the hour of day to occur. If null recurrence will be every hour of day. - */ - public ComplexJobTrigger( Integer year, Integer month, Integer dayOfMonth, Integer dayOfWeek, Integer hourOfDay ) { - this(); - setYearlyRecurrence( year ); - setMonthlyRecurrence( month ); - if ( ( dayOfMonth != null ) && ( dayOfWeek == null ) ) { - setDayOfMonthRecurrence( dayOfMonth ); - } - if ( ( dayOfMonth == null ) && ( dayOfWeek != null ) ) { - setDayOfWeekRecurrence( dayOfWeek ); - } - setHourlyRecurrence( hourOfDay ); - } - - /** - * Creates a default recurrence of every day of every year at midnight. - */ - public ComplexJobTrigger() { - setHourlyRecurrence( 0 ); - setMinuteRecurrence( 0 ); - setSecondRecurrence( 0 ); - } - - private void setRecurrences( ITimeWrapper theList, Integer... recurrences ) { - theList.clear(); - addRecurrences( theList, recurrences ); - } - - private void addRecurrences( ITimeWrapper theList, Integer... recurrences ) { - List nonNullRecurrences = ( recurrences == null ? new ArrayList() : filterNulls( recurrences ) ); - if ( nonNullRecurrences.size() == 0 ) { - return; - } - if ( nonNullRecurrences.size() == 1 ) { - theList.add( new RecurrenceList( nonNullRecurrences.get( 0 ) ) ); - } else if ( nonNullRecurrences.size() == 2 ) { - TreeSet sortedRecurrences = new TreeSet( nonNullRecurrences ); - theList.add( new RecurrenceList( sortedRecurrences.toArray( new Integer[0] ) ) ); - } else { - TreeSet sortedRecurrences = new TreeSet( nonNullRecurrences ); - Integer previourOcurrence = null; - boolean isSequential = true; - for ( Integer value : sortedRecurrences ) { - if ( ( previourOcurrence != null ) && ( value.intValue() != previourOcurrence.intValue() + 1 ) ) { - isSequential = false; - break; - } - previourOcurrence = value; - } - if ( isSequential ) { - theList.add( new SequentialRecurrence( sortedRecurrences.first(), sortedRecurrences.last() ) ); - } else { - theList.add( new RecurrenceList( sortedRecurrences.toArray( new Integer[0] ) ) ); - } - } - } - - /** - * Add a recurrence to the yearly recurrences. - * - * @param recurrence - * the yearly recurrence. If null no addition occurs. - */ - public void addYearlyRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - yearlyRecurrences.add( recurrence ); - } - } - - /** - * Add a recurrence to the yearly recurrences. - * - * @param recurrence - * the yearly recurrence. If null no addition occurs. - */ - public void addYearlyRecurrence( Integer... recurrence ) { - addRecurrences( yearlyRecurrences, recurrence ); - } - - /** - * Overrides any previously applied yearly recurrences with the provided recurrence. - * - * @param recurrence - * the yearly recurrence. If null it will recur every year. - */ - public void setYearlyRecurrence( ITimeRecurrence recurrence ) { - yearlyRecurrences.clear(); - if ( recurrence != null ) { - yearlyRecurrences.add( recurrence ); - } - } - - /** - * Overrides any previously applied yearly recurrences with the provided recurrence. - * - * @param recurrence - * the yearly recurrence. If not recurrences are provided it will recur every year. - */ - public void setYearlyRecurrence( Integer... recurrence ) { - setRecurrences( yearlyRecurrences, recurrence ); - } - - /** - * Add a recurrence to the monthly recurrence. - * - * @param recurrence - * the monthly recurrence. If null no addition occurs. - */ - public void addMonthlyRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - monthlyRecurrences.add( recurrence ); - } - } - - /** - * Add a recurrence to the monthly recurrence (1=January, 12=December). - * - * @param recurrence - * the monthly recurrence. If null no addition occurs. - */ - public void addMonthlyRecurrence( Integer... recurrence ) { - addRecurrences( monthlyRecurrences, recurrence ); - } - - /** - * Overrides any previously applied monthly recurrences with the provided recurrence. - * - * @param recurrence - * the monthly recurrence. If null it will recur every month. - */ - public void setMonthlyRecurrence( ITimeRecurrence recurrence ) { - monthlyRecurrences.clear(); - if ( recurrence != null ) { - monthlyRecurrences.add( recurrence ); - } - } - - /** - * Overrides any previously applied monthly recurrences with the provided recurrence (1=January, 12=December). - * - * @param recurrence - * the monthly recurrence. If no recurrences are provided it will recur every month. - */ - public void setMonthlyRecurrence( Integer... recurrence ) { - setRecurrences( monthlyRecurrences, recurrence ); - } - - /** - * Add a recurrence to the day of month recurrence. Calling this method with a non-null parameter causes the day of - * week recurrence to be set to all days of the week. - * - * @param recurrence - * the day of month recurrences. If null no modification is made to this object. - */ - public void addDayOfMonthRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - dayOfMonthRecurrences.add( recurrence ); - dayOfWeekRecurrences.clear(); - } - } - - /** - * Add a recurrence to the day of week recurrence. Calling this method with a non-null parameter causes the day of - * month recurrence to be set to all days of the month. - * - * @param recurrence - * the day of week recurrences. If null no modification is made to this object. - */ - public void addDayOfMonthRecurrence( Integer... recurrence ) { - addRecurrences( dayOfMonthRecurrences, recurrence ); - dayOfWeekRecurrences.clear(); - } - - /** - * Overrides any previously applied day of month recurrences with the provided recurrence. Calling this method with a - * non-null parameter causes the day of week recurrence to be set to all days of the week. - * - * @param recurrence - * the day of month recurrences. If null it will recur every day of month. - */ - public void setDayOfMonthRecurrence( ITimeRecurrence recurrence ) { - dayOfMonthRecurrences.clear(); - if ( recurrence != null ) { - dayOfMonthRecurrences.add( recurrence ); - dayOfWeekRecurrences.clear(); - } - } - - /** - * Overrides any previously applied day of month recurrences with the provided recurrence. Calling this method with - * one or more days of month causes the day of week recurrence to be set to all days of the week. - * - * @param recurrence - * the day of month recurrences. If no days of month are provided it will recur every day of month. - */ - public void setDayOfMonthRecurrence( Integer... recurrence ) { - setRecurrences( dayOfMonthRecurrences, recurrence ); - if ( dayOfMonthRecurrences.size() > 0 ) { - dayOfWeekRecurrences.clear(); - } - } - - /** - * Add a recurrence to the day of week recurrence. Calling this method with a non-null parameter causes the day of - * month recurrence to be set to all days of the month. - * - * @param recurrence - * the day of week recurrences. If null no modification is made to this object. - */ - public void addDayOfWeekRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - dayOfWeekRecurrences.add( recurrence ); - dayOfMonthRecurrences.clear(); - } - } - - /** - * Add a recurrence to the day of week recurrence (1=Sunday, 7=Saturday). Calling this method with a non-null - * parameter causes the day of month recurrence to be set to all days of the month. - * - * @param recurrence - * the day of week recurrences. If null no modification is made to this object. - */ - public void addDayOfWeekRecurrence( Integer... recurrence ) { - addRecurrences( dayOfWeekRecurrences, recurrence ); - dayOfMonthRecurrences.clear(); - } - - /** - * Overrides any previously applied day of week recurrences with the provided recurrence. Calling this method with a - * non-null parameter causes the day of month recurrence to be set to all days of the month. - * - * @param recurrence - * the day of week recurrences. If null it will recur every day of week. - */ - public void setDayOfWeekRecurrence( ITimeRecurrence recurrence ) { - dayOfWeekRecurrences.clear(); - if ( recurrence != null ) { - dayOfWeekRecurrences.add( recurrence ); - dayOfMonthRecurrences.clear(); - } - } - - /** - * Overrides any previously applied day of week recurrences with the provided recurrence (1=Sunday, 7=Saturday). - * Calling this method with one or more days of week causes the day of month recurrence to be set to all days of the - * month. - * - * @param recurrence - * the day of week recurrences. If no days of week are provided it will recur every day of the week. - */ - public void setDayOfWeekRecurrence( Integer... recurrence ) { - setRecurrences( dayOfWeekRecurrences, recurrence ); - if ( dayOfWeekRecurrences.size() > 0 ) { - dayOfMonthRecurrences.clear(); - } - } - - /** - * Add a recurrence to the hourly recurrence. - * - * @param recurrence - * the hourly recurrence. If null no modification is made to this object. - */ - public void addHourlyRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - hourlyRecurrences.add( recurrence ); - } - } - - /** - * Add a recurrence to the minute recurrence. - * - * @param recurrence - * the minute recurrence. If null no modification is made to this object. - */ - public void addHourlyRecurrence( Integer... recurrence ) { - addRecurrences( hourlyRecurrences, recurrence ); - } - - /** - * Overrides any previously applied hourly recurrences with the provided recurrence. - * - * @param recurrence - * the hourly recurrence. If null it will recur every hour - */ - public void setHourlyRecurrence( ITimeRecurrence recurrence ) { - hourlyRecurrences.clear(); - if ( recurrence != null ) { - hourlyRecurrences.add( recurrence ); - } - } - - /** - * Overrides any previously applied hourly recurrences with the provided recurrence. - * - * @param recurrence - * the hourly recurrence. If no recurrence is provided it will recur every hour. - */ - public void setHourlyRecurrence( Integer... recurrence ) { - setRecurrences( hourlyRecurrences, recurrence ); - } - - /** - * Add a recurrence to the minute recurrence. - * - * @param recurrence - * the minute recurrence. If null no modification is made to this object. - */ - public void addMinuteRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - minuteRecurrences.add( recurrence ); - } - } - - /** - * Add a recurrence to the minute recurrence. - * - * @param recurrence - * the minute recurrence. If null no modification is made to this object. - */ - public void addMinuteRecurrence( Integer... recurrence ) { - addRecurrences( minuteRecurrences, recurrence ); - } - - /** - * Overrides any previously applied minute recurrences with the provided recurrence. - * - * @param recurrence - * the minute recurrence. If null it will recur every minute. - */ - public void setMinuteRecurrence( ITimeRecurrence recurrence ) { - minuteRecurrences.clear(); - if ( recurrence != null ) { - minuteRecurrences.add( recurrence ); - } - } - - /** - * Overrides any previously applied minute recurrences with the provided recurrence. - * - * @param recurrence - * the minute recurrence. If no recurrence is provided it will recur every minute. - */ - public void setMinuteRecurrence( Integer... recurrence ) { - setRecurrences( minuteRecurrences, recurrence ); - } - - /** - * Add a recurrence to the second recurrence. - * - * @param recurrence - * the second recurrence. If null no modification is made to this object. - */ - public void addSecondRecurrence( ITimeRecurrence recurrence ) { - if ( recurrence != null ) { - secondRecurrences.add( recurrence ); - } - } - - /** - * Add a recurrence to the second recurrence. - * - * @param recurrence - * the second recurrence. If null no modification is made to this object. - */ - public void addSecondRecurrence( Integer... recurrence ) { - addRecurrences( secondRecurrences, recurrence ); - } - - /** - * Overrides any previously applied second recurrences with the provided recurrence. - * - * @param recurrence - * the second recurrence. If null it will recur every second. - */ - public void setSecondRecurrence( ITimeRecurrence recurrence ) { - secondRecurrences.clear(); - if ( recurrence != null ) { - secondRecurrences.add( recurrence ); - } - } - - /** - * Overrides any previously applied second recurrences with the provided recurrence. - * - * @param recurrence - * the second recurrence. If no recurrence is provided it will recur every second. - */ - public void setSecondRecurrence( Integer... recurrence ) { - setRecurrences( secondRecurrences, recurrence ); - } - - /** - * Returns the yearly recurrence. - * - * @return the yearly recurrence. An empty list indicates a recurrence of every year. - */ - @XmlElement - public YearlyWrapper getYearlyRecurrences() { - return yearlyRecurrences; - } - - /** - * Returns the monthly recurrence. - * - * @return the monthly recurrence. An empty list indicates a recurrence of every month. - */ - @XmlElement - public MonthlyWrapper getMonthlyRecurrences() { - return monthlyRecurrences; - } - - /** - * Returns the day of month recurrence. - * - * @return the day of month recurrence. An empty list indicates a recurrence of every day of month. - */ - @XmlElement - public DayOfMonthWrapper getDayOfMonthRecurrences() { - return dayOfMonthRecurrences; - } - - /** - * Returns the day of week recurrence. - * - * @return the day of week recurrence. An empty list indicates a recurrence of every day of week. - */ - @XmlElement - public DayOfWeekWrapper getDayOfWeekRecurrences() { - return dayOfWeekRecurrences; - } - - /** - * Returns the day of hourly recurrence. - * - * @return the day of hourly recurrence. An empty list indicates a recurrence of every hour. - */ - @XmlElement - public SecondWrapper getSecondRecurrences() { - return secondRecurrences; - } - - /** - * Returns the day of minute recurrence. - * - * @return the day of minute recurrence. An empty list indicates a recurrence of every minute. - */ - @XmlElement - public HourlyWrapper getHourlyRecurrences() { - return hourlyRecurrences; - } - - @XmlElement - public MinuteWrapper getMinuteRecurrences() { - return minuteRecurrences; - } - - // this setters are for JaxB unmarshalling - private void setYearlyRecurrences( YearlyWrapper yearlyRecurrences ) { - this.yearlyRecurrences = yearlyRecurrences; - } - - private void setMonthlyRecurrences( MonthlyWrapper monthlyRecurrences ) { - this.monthlyRecurrences = monthlyRecurrences; - } - - private void setDayOfMonthRecurrences( DayOfMonthWrapper dayOfMonthRecurrences ) { - this.dayOfMonthRecurrences = dayOfMonthRecurrences; - } - - private void setDayOfWeekRecurrences( DayOfWeekWrapper dayOfWeekRecurrences ) { - this.dayOfWeekRecurrences = dayOfWeekRecurrences; - } - - private void setHourlyRecurrences( HourlyWrapper hourlyRecurrences ) { - this.hourlyRecurrences = hourlyRecurrences; - } - - private void setMinuteRecurrences( MinuteWrapper minuteRecurrences ) { - this.minuteRecurrences = minuteRecurrences; - } - - private void setSecondRecurrences( SecondWrapper secondRecurrences ) { - this.secondRecurrences = secondRecurrences; - } - - public String toString() { - return QuartzCronStringFactory.createCronString( this ); - } - - private List filterNulls( U[] args ) { - List nonNullArgs = new ArrayList(); - for ( U recurrence : args ) { - if ( recurrence != null ) { - nonNullArgs.add( recurrence ); - } - } - return nonNullArgs; - } - - @Override - public void setCronString(String cronString) { - super.setCronString(cronString); - getCronDescription(); - } - - @Override - public String getCronDescription() { - if(getCronString() != null && !getCronString().isEmpty() && (cronDescription == null || cronDescription.isEmpty())) { - CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); - CronDescriptor descriptor = CronDescriptor.instance(Locale.US); - CronParser parser = new CronParser(cronDefinition); - cronDescription = descriptor.describe(parser.parse(getCronString())); - } - return cronDescription; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/CronJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/CronJobTrigger.java deleted file mode 100644 index de2af4eb374..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/CronJobTrigger.java +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class CronJobTrigger extends JobTrigger { - private static final long serialVersionUID = 2460248678333124471L; - String cronString; - - public CronJobTrigger() { - } - - protected CronJobTrigger( String cronString ) { - this.cronString = cronString; - } - - public String getCronString() { - return cronString; - } - - public void setCronString( String crongString ) { - this.cronString = crongString; - } - - public String toString() { - return cronString; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java index e6932de93c3..c7c89f49cc8 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java @@ -35,14 +35,9 @@ public interface IBackgroundExecutionStreamProvider extends Serializable { String getMimeType(); - String getOutputPath(); - OutputStream getOutputStream() throws Exception; - InputStream getInputStream() throws Exception; - void setStreamingAction( IStreamingAction streamingAction ); - void setOutputFilePath( String filePath ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java index 65ddea21450..c42674a8c11 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java @@ -36,18 +36,10 @@ public interface IBlockoutManager { public static final String SCHEDULED_FIRE_TIME = "scheduledFireTime"; - /** - * @param blockOutJobId - * @return a IBlockOutTrigger that represents the blockOut with the name blockOutName - * @throws SchedulerException - */ - IJobTrigger getBlockOut( String blockOutJobId ); - /** * @return a list of jobs essentially should be used instead of getBlockOuts which is deprecated */ - List getBlockOutJobs(); - + List getBlockOutJobs(); /** * @param scheduleJobTrigger * {@link IJobTrigger} @@ -55,20 +47,11 @@ public interface IBlockoutManager { * @throws SchedulerException */ boolean willFire( IJobTrigger scheduleJobTrigger ); - /** * @return true if there are no current blockOuts active at the moment this method is called * @throws SchedulerException */ boolean shouldFireNow(); - - /** - * @param testBlockOutJobTrigger - * @return the {@link List} of {@link IJobTrigger}s which would be blocked by the {@link IJobTrigger} - * @throws SchedulerException - */ - List willBlockSchedules( IJobTrigger testBlockOutJobTrigger ); - /** * @param scheduleJobTrigger * {@link IJobTrigger} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java new file mode 100644 index 00000000000..b54823d04cd --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java @@ -0,0 +1,26 @@ +package org.pentaho.platform.api.scheduler2; + +import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; + +import java.util.List; + +public interface IComplexJobTrigger extends IJobTrigger { + static final int SUNDAY = 1; + + long getRepeatInterval(); + void setRepeatInterval( long repeatIntervalSeconds ); + void addYearlyRecurrence( Integer... recurrence ); + void addMonthlyRecurrence( Integer... recurrence ); + void addDayOfMonthRecurrence( Integer... recurrence ); + void addDayOfWeekRecurrence( ITimeRecurrence recurrence ); + void addDayOfWeekRecurrence( Integer... recurrence ); + void setHourlyRecurrence( Integer... recurrence ); + void addMinuteRecurrence( Integer... recurrence ); + void setCronString(String cronString); + + List getDayOfMonthRecurrences(); + List getMonthlyRecurrences(); + List getYearlyRecurrences(); + List getDayOfWeekRecurrences(); +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParam.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java similarity index 87% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParam.java rename to scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java index 4ad8bdd9f15..b25d57eaba0 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParam.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java @@ -20,11 +20,7 @@ package org.pentaho.platform.api.scheduler2; -import javax.xml.bind.annotation.XmlElement; - -public class JobParam { - @XmlElement - String name; - @XmlElement - String value; +public interface ICronJobTrigger extends IJobTrigger { + String getCronString(); + void setCronString( String crongString ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java new file mode 100644 index 00000000000..eb975c7d0bd --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java @@ -0,0 +1,28 @@ +package org.pentaho.platform.api.scheduler2; + +import java.io.Serializable; +import java.util.Map; +import java.util.Date; + + +public interface IJob { + + enum JobState { + NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN + } + + JobState state = JobState.UNKNOWN; + + public IJobTrigger getJobTrigger(); + public Map getJobParams(); + public String getJobId(); + public String getJobName(); + public Date getLastRun(); + public String getUserName(); + public void setJobTrigger( IJobTrigger jobTrigger ); + public void setJobId( String jobId ); + public void setUserName( String userName ); + public void setJobName( String jobName ); + public JobState getState(); + public void setState( JobState state ); +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java index 4d1b6bb98cd..0c72c6799db 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java @@ -33,5 +33,5 @@ public interface IJobFilter { * the job to decide to accept or reject * @return true if the job should be accepted as part of the filtered results */ - public boolean accept( Job job ); + boolean accept( IJob job ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java index fe5cc129be6..6baa9f29ae6 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java @@ -37,26 +37,6 @@ public interface IJobResult { * * @return a unique id of the job run */ - public String getId(); + String getId(); - /** - * The job parameters used during this job run. - * - * @return set of parameters used during job run - */ - public Map getJobParams(); - - /** - * The start date/time of the job run - * - * @return start date/time of the job run - */ - public Date getStartDate(); - - /** - * The end date/time of the job run - * - * @return end date/time of the job run - */ - public Date getCompletionDate(); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java index 9e83362e6ec..6ff9d3820ef 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java @@ -28,7 +28,7 @@ public interface IJobTrigger { * * @return the trigger start time. */ - public Date getStartTime(); + Date getStartTime(); /** * Sets the trigger start time. @@ -36,14 +36,14 @@ public interface IJobTrigger { * @param startTime * when to start the trigger. If null the trigger starts immediately. */ - public void setStartTime( Date startTime ); + void setStartTime( Date startTime ); /** * Returns the trigger end time. * * @return the trigger end time. */ - public Date getEndTime(); + Date getEndTime(); /** * Sets the trigger end time. @@ -51,12 +51,12 @@ public interface IJobTrigger { * @param endTime * when to end the trigger. If null the trigger runs indefinitely */ - public void setEndTime( Date endTime ); + void setEndTime( Date endTime ); /** * @return the uiPassParam */ - public String getUiPassParam(); + String getUiPassParam(); /** * The value of this field comes from the UI and is persisted in quartz but not used by quartz or the server. It is @@ -66,14 +66,14 @@ public interface IJobTrigger { * @param uiPassParam * A User Interface provided string */ - public void setUiPassParam( String uiPassParam ); + void setUiPassParam( String uiPassParam ); /** * Returns the Cron String used by quartz Scheduler * * @return the cronString */ - public String getCronString(); + String getCronString(); /** * Sets the cron String used by the quartz scheduler @@ -81,22 +81,7 @@ public interface IJobTrigger { * @param cronString * the cronString to set */ - public void setCronString( String cronString ); - - /** - * Returns the User friendly description of a Cron String - * - * @return the cronDescription - */ - public String getCronDescription(); - - /** - * Sets the user friendly description of a cron String= - * - * @param cronDescription - * the cronString to set - */ - public void setCronDescription( String cronDescription ); + void setCronString( String cronString ); /** * @return a long that represents in milliseconds how long this trigger should be in effect once triggered diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java index 863c8f25a73..7bd76037160 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java @@ -21,10 +21,12 @@ package org.pentaho.platform.api.scheduler2; import java.io.Serializable; +import java.util.Date; import java.util.List; import java.util.Map; import org.pentaho.platform.api.action.IAction; +import org.pentaho.platform.util.ActionUtil; /** * An object that allows for the scheduling of IActions on the Pentaho platform @@ -32,6 +34,26 @@ * @author arodriguez */ public interface IScheduler { + + public static final String RESERVEDMAPKEY_ACTIONCLASS = ActionUtil.QUARTZ_ACTIONCLASS; + public static final String RESERVEDMAPKEY_ACTIONUSER = ActionUtil.QUARTZ_ACTIONUSER; + + public static final String RESERVEDMAPKEY_ACTIONID = ActionUtil.QUARTZ_ACTIONID; + + public static final String RESERVEDMAPKEY_STREAMPROVIDER = ActionUtil.QUARTZ_STREAMPROVIDER; + + public static final String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; + + public static final String RESERVEDMAPKEY_UIPASSPARAM = ActionUtil.QUARTZ_UIPASSPARAM; + + public static final String RESERVEDMAPKEY_LINEAGE_ID = ActionUtil.QUARTZ_LINEAGE_ID; + + public static final String RESERVEDMAPKEY_RESTART_FLAG = ActionUtil.QUARTZ_RESTART_FLAG; + + public static final String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = ActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; + + public static final String RESERVEDMAPKEY_APPEND_DATE_FORMAT = ActionUtil.QUARTZ_APPEND_DATE_FORMAT; + public enum SchedulerStatus { RUNNING, PAUSED, STOPPED }; @@ -51,7 +73,7 @@ public enum SchedulerStatus { * @throws SchedulerException * If the job could not be scheduled */ - public Job createJob( String jobName, Class action, Map jobParams, + public IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger ) throws SchedulerException; /** @@ -69,7 +91,7 @@ public Job createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger ) + public IJob createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger ) throws SchedulerException; /** @@ -90,7 +112,7 @@ public Job createJob( String jobName, String actionId, Map * @throws SchedulerException * If the job could not be scheduled */ - public Job createJob( String jobName, Class action, Map jobParams, + public IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger, IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException; /** @@ -111,7 +133,7 @@ public Job createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger, + public IJob createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger, IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException; /** @@ -160,7 +182,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be returned */ - public Job getJob( String jobId ) throws SchedulerException; + public IJob getJob( String jobId ) throws SchedulerException; /** * Triggers the given quartz job by jobId to be executed immediately @@ -178,7 +200,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param window * the window of time at which the scheduler is available */ - public void setSubjectAvailabilityWindow( IScheduleSubject subject, ComplexJobTrigger window ); + public void setSubjectAvailabilityWindow( IScheduleSubject subject, IComplexJobTrigger window ); /** * Replaces the scheduler availability map with the provided availability map. @@ -186,7 +208,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param windows * the new scheduler availability map */ - public void setAvailabilityWindows( Map windows ); + public void setAvailabilityWindows( Map windows ); /** * Gets the scheduler availability window to the specified subject @@ -195,14 +217,14 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the subject whose window is being requested * @return the subject's availability window */ - public ComplexJobTrigger getSubjectAvailabilityWindow( IScheduleSubject subject ); + public IComplexJobTrigger getSubjectAvailabilityWindow( IScheduleSubject subject ); /** * Gets the scheduler availability window for all subjects for whom a window has been set * * @return the scheduler availability map */ - public Map getAvailabilityWindows(); + public Map getAvailabilityWindows(); /** * Pauses the entire scheduler, which prevents all scheduled jobs from running. Any currently running jobs are allowed @@ -249,7 +271,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the filter to use to determine which jobs to return. If null all scheduled jobs are return. * @return the scheduled jobs */ - public List getJobs( IJobFilter filter ) throws SchedulerException; + public List getJobs( IJobFilter filter ) throws SchedulerException; /** * Returns a history of the runs for a particular job. @@ -280,6 +302,14 @@ public void updateJob( String jobId, Map jobParams, IJobTr public void fireJobCompleted( final IAction actionBean, final String actionUser, final Map params, IBackgroundExecutionStreamProvider streamProvider ); + public ISimpleJobTrigger createSimpleJobTrigger( Date startTime, Date endTime, int repeatCount, long repeatIntervalSeconds ); + + public ICronJobTrigger createCronJobTrigger(); + + public IComplexJobTrigger createComplexTrigger( String cronString ); + + IComplexJobTrigger createComplexJobTrigger(); + IComplexJobTrigger createComplexTrigger( Integer year, Integer month, Integer dayOfMonth, Integer dayOfWeek, Integer hourOfDay ); /** * A default implementation which doesn't do anything and exists for the backward compatibility sake. * @param jobParams scheduling job parameters diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTriggerAdapter.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java similarity index 59% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTriggerAdapter.java rename to scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java index a2eb6573776..f2b8a045fbe 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTriggerAdapter.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java @@ -20,18 +20,17 @@ package org.pentaho.platform.api.scheduler2; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; - -public class JobTriggerAdapter extends XmlAdapter { - - public JobTrigger marshal( JobTrigger v ) throws Exception { - return v instanceof ComplexJobTrigger ? new CronJobTrigger( v.toString() ) : v; - } - - public JobTrigger unmarshal( JobTrigger v ) throws Exception { - return v instanceof CronJobTrigger ? QuartzScheduler.createComplexTrigger( v.toString() ) : v; - } +/** + * A simple way of specifying a schedule on which a job will fire as opposed to {@link IComplexJobTrigger}. The + * {@link ISimpleJobTrigger} can meet your needs if you are looking for a way to have a job start, execute a set number + * of times on a regular interval and then end either after a specified number of runs or at an end date. + * + * @author aphillips + */ +public interface ISimpleJobTrigger extends IJobTrigger { + public int getRepeatCount(); + public void setRepeatCount( int repeatCount ); + public long getRepeatInterval(); + public void setRepeatInterval( long repeatIntervalSeconds ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/Job.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/Job.java deleted file mode 100644 index 91545288ca6..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/Job.java +++ /dev/null @@ -1,248 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -/** - * A {@link Job} is a representation of the union between an action to be performed, data to be supplied, and a schedule - * upon which the action will be fired. The scheduling system is responsible for creating {@link Job}s via - * {@link IScheduler#createJob(String, Class, Map, JobTrigger)}. Jobs are likely persistent, at least for the life of a - * {@link IScheduler} instance. In other words, an {@link IScheduler} instance should never forget about a Job it has - * created, unless the Job has been removed via {@link IScheduler#removeJob(Job)}. - *

- * Note: once the scheduler engine processes a job run, it will create a new {@link IJobResult}, which will contain full - * historical information about job runs. {@link Job} will contain only minimal of such temporal information. - * - * @author aphillips - */ -@XmlRootElement -public class Job { - - public enum JobState { - NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN - }; - - JobTrigger jobTrigger; - - Map jobParams = new HashMap(); - - Date lastRun; - - Date nextRun; - - @XmlTransient - String schedulableClass; - - String jobId; - - String userName; - - String jobName; - - String groupName; - - JobState state = JobState.UNKNOWN; - - /** - * @return the trigger that determines when the job executes - */ - public JobTrigger getJobTrigger() { - return jobTrigger; - } - - /** - * @return the map containing the parameters to be passed to the action executed by this job - */ - @XmlJavaTypeAdapter( JobParamsAdapter.class ) - public Map getJobParams() { - return jobParams; - } - - /** - * @return the last time this job ran or null if the job has not run yet. - */ - public Date getLastRun() { - return lastRun; - } - - /** - * @return the next time the job is scheduled to run or null if the job will not run again. - */ - public Date getNextRun() { - return nextRun; - } - - /** - * @return the class name of the IAction that will be executed by this job. - */ - @XmlTransient - public String getSchedulableClass() { - return schedulableClass; - } - - /** - * @return the id that uniquely defines this job. - */ - public String getJobId() { - return jobId; - } - - /** - * @return the user defined name of this job. - */ - public String getJobName() { - return jobName; - } - - /** - * @return the user that scheduled this job - */ - public String getUserName() { - return userName; - } - - /** - * @return the group name of this job - */ - public String getGroupName() { - return groupName; - } - - /** - * Sets the trigger used to determine when this job runs. - * - * @param jobTrigger - * the job trigger - */ - public void setJobTrigger( JobTrigger jobTrigger ) { - this.jobTrigger = jobTrigger; - } - - /** - * Sets the parameters that will be passed to the scheduled IAction when the job executes. - * - * @param jobParams - * the parameters to be passed to the IAction - */ - public void setJobParams( Map jobParams ) { - if ( jobParams != this.jobParams ) { - this.jobParams.clear(); - if ( jobParams != null ) { - this.jobParams.putAll( jobParams ); - } - } - } - - /** - * Sets the last time the job executed. - * - * @param lastRun - * the last time the job ran. null if the job has not run. - */ - public void setLastRun( Date lastRun ) { - this.lastRun = lastRun; - } - - /** - * Sets the next time the job will execute - * - * @param nextRun - * the next time the job will run. null if the job will not run again. - */ - public void setNextRun( Date nextRun ) { - this.nextRun = nextRun; - } - - /** - * Sets the name of the IAction class that will run when the job is executed. - * - * @param schedulableClass - * the name of the IAction to run. - */ - public void setSchedulableClass( String schedulableClass ) { - this.schedulableClass = schedulableClass; - } - - /** - * Sets the id that uniquely defines this job. - * - * @param jobId - * the job id - */ - public void setJobId( String jobId ) { - this.jobId = jobId; - } - - /** - * Sets the name of the user that has scheduled this job - * - * @param userName - * the user name - */ - public void setUserName( String userName ) { - this.userName = userName; - } - - /** - * Sets the user defined name of this job. - * - * @param jobName - * the job name - */ - public void setJobName( String jobName ) { - this.jobName = jobName; - } - - /** - * @return the current job state - */ - public JobState getState() { - return state; - } - - /** - * Sets the current state of this job - * - * @param state - * the job state - */ - public void setState( JobState state ) { - this.state = state; - } - - /** - * Sets the group name of this job - * - * @param groupName - * the group name - */ - public void setGroupName( final String groupName ) { - this.groupName = groupName; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParams.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParams.java deleted file mode 100644 index 2cc86cd682a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParams.java +++ /dev/null @@ -1,30 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class JobParams { - @XmlElement - JobParam[] jobParams; -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParamsAdapter.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParamsAdapter.java deleted file mode 100644 index 6c722d8c060..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobParamsAdapter.java +++ /dev/null @@ -1,107 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -public class JobParamsAdapter extends XmlAdapter> { - - private static final String VARIABLES = "variables"; - private static final String PARAMETERS = "parameters"; - - public JobParams marshal( Map v ) throws Exception { - Object variables = v.get( VARIABLES ); - Object parameters = v.get( PARAMETERS ); - if ( parameters != null && parameters instanceof Map - && variables != null && variables instanceof Map ) { - Map paramMap = (Map) parameters; - Map variableMap = (Map) variables; - if ( !paramMap.isEmpty() && !variableMap.isEmpty() ) { - for ( Map.Entry paramEntry : paramMap.entrySet() ) { - if ( variableMap.containsKey( paramEntry.getKey() ) && paramEntry.getValue() != null ) { - variableMap.remove( paramEntry.getKey() ); - } - } - } - } - - ArrayList params = new ArrayList(); - for ( Map.Entry entry : v.entrySet() ) { - if ( entry != null && entry.getKey() != null && entry.getValue() != null ) { - if ( entry.getValue() instanceof Collection ) { - for ( Object iValue : (Collection) entry.getValue() ) { - if ( iValue != null ) { - JobParam jobParam = new JobParam(); - jobParam.name = entry.getKey(); - jobParam.value = iValue.toString(); - params.add( jobParam ); - } - } - } else if ( entry.getValue() instanceof Map ) { - ( (Map) entry.getValue() ).forEach( ( key, value ) -> { - if ( value != null ) { - JobParam jobParam = new JobParam(); - jobParam.name = key; - jobParam.value = value.toString(); - params.add( jobParam ); - } - } ); - } else { - JobParam jobParam = new JobParam(); - jobParam.name = entry.getKey(); - jobParam.value = entry.getValue().toString(); - params.add( jobParam ); - } - } - } - JobParams jobParams = new JobParams(); - jobParams.jobParams = params.toArray( new JobParam[0] ); - return jobParams; - } - - public Map unmarshal( JobParams v ) throws Exception { - HashMap> draftParamMap = new HashMap>(); - for ( JobParam jobParam : v.jobParams ) { - ArrayList p = draftParamMap.get( jobParam.name ); - if ( p == null ) { - p = new ArrayList(); - draftParamMap.put( jobParam.name, p ); - } - p.add( jobParam.value ); - } - HashMap paramMap = new HashMap(); - for ( String paramName : draftParamMap.keySet() ) { - ArrayList p = draftParamMap.get( paramName ); - if ( p.size() == 1 ) { - paramMap.put( paramName, p.get( 0 ) ); - } else { - paramMap.put( paramName, p ); - } - } - return paramMap; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTrigger.java deleted file mode 100644 index 2d45f62232f..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobTrigger.java +++ /dev/null @@ -1,126 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.io.Serializable; -import java.util.Date; - -import javax.xml.bind.annotation.XmlSeeAlso; - -/** - * The marker superclass for the various types of job triggers. - * - * @author aphillips - * - * @see SimpleJobTrigger - * @see ComplexJobTrigger - */ -@XmlSeeAlso( { SimpleJobTrigger.class, ComplexJobTrigger.class, CronJobTrigger.class } ) -public abstract class JobTrigger implements Serializable, IJobTrigger { - /** - * - */ - private static final long serialVersionUID = -2110414852036623140L; - - public static final SimpleJobTrigger ONCE_NOW = new SimpleJobTrigger( new Date(), null, 0, 0L ); - - private Date startTime; - - private Date endTime; - - private String uiPassParam; - - private String cronString; - - private String cronDescription; - - private long duration = -1; - - public JobTrigger() { - } - - public JobTrigger( Date startTime, Date endTime ) { - this.startTime = startTime; - this.endTime = endTime; - } - - @Override - public Date getStartTime() { - return startTime; - } - - @Override - public void setStartTime( Date startTime ) { - this.startTime = startTime; - } - - @Override - public Date getEndTime() { - return endTime; - } - - @Override - public void setEndTime( Date endTime ) { - this.endTime = endTime; - } - - @Override - public String getUiPassParam() { - return uiPassParam; - } - - @Override - public void setUiPassParam( String uiPassParam ) { - this.uiPassParam = uiPassParam; - } - - @Override - public String getCronString() { - return cronString; - } - - @Override - public void setCronString( String cronString ) { - this.cronString = cronString; - } - - @Override - public long getDuration() { - return this.duration; - } - - @Override - public void setDuration( long duration ) { - this.duration = duration; - } - - - @Override - public String getCronDescription() { - return cronDescription; - } - - @Override - public void setCronDescription(String cronDescription) { - this.cronDescription = cronDescription; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SimpleJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SimpleJobTrigger.java deleted file mode 100644 index 293784f865d..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SimpleJobTrigger.java +++ /dev/null @@ -1,83 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.io.Serializable; -import java.util.Date; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * A simple way of specifying a schedule on which a job will fire as opposed to {@link ComplexJobTrigger}. The - * {@link SimpleJobTrigger} can meet your needs if you are looking for a way to have a job start, execute a set number - * of times on a regular interval and then end either after a specified number of runs or at an end date. - * - * @author aphillips - */ -@XmlRootElement -public class SimpleJobTrigger extends JobTrigger implements Serializable { - private static final long serialVersionUID = 7838270781497116177L; - public static final int REPEAT_INDEFINITELY = -1; - private int repeatCount = 0; - private long repeatInterval = 0; - - public SimpleJobTrigger( Date startTime, Date endTime, int repeatCount, long repeatIntervalSeconds ) { - super( startTime, endTime ); - this.repeatCount = repeatCount; - this.repeatInterval = repeatIntervalSeconds; - } - - public SimpleJobTrigger() { - } - - public int getRepeatCount() { - return repeatCount; - } - - public void setRepeatCount( int repeatCount ) { - this.repeatCount = repeatCount; - } - - public long getRepeatInterval() { - return repeatInterval; - } - - public void setRepeatInterval( long repeatIntervalSeconds ) { - this.repeatInterval = repeatIntervalSeconds; - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append( "repeatCount=" ); //$NON-NLS-1$ - b.append( repeatCount ); - b.append( ", " ); //$NON-NLS-1$ - b.append( "repeatInterval=" ); //$NON-NLS-1$ - b.append( repeatInterval ); - b.append( ", " ); //$NON-NLS-1$ - b.append( "startTime=" ); //$NON-NLS-1$ - b.append( super.getStartTime() ); - b.append( ", " ); //$NON-NLS-1$ - b.append( "endTime=" ); //$NON-NLS-1$ - b.append( super.getEndTime() ); - return b.toString(); - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java deleted file mode 100644 index 209eb68d27a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfMonth; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class DayOfMonthWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = QualifiedDayOfMonth.class ), - @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java deleted file mode 100644 index b48625025f3..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class DayOfWeekWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ), - @XmlElementRef( type = QualifiedDayOfWeek.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } - - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java deleted file mode 100644 index 3f4f7300850..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class HourlyWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java index ac514c8a92e..6adaa798928 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java @@ -20,9 +20,7 @@ package org.pentaho.platform.api.scheduler2.wrappers; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - -import javax.xml.bind.annotation.XmlRootElement; +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; import java.util.ArrayList; import java.util.List; diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java deleted file mode 100644 index 12ccd7939fb..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class MinuteWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java deleted file mode 100644 index 6ce862d827a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class MonthlyWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java deleted file mode 100644 index 9b9b8eee634..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class SecondWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java deleted file mode 100644 index 8bb648bcb44..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2.wrappers; - -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.List; - -@XmlRootElement -public class YearlyWrapper extends ITimeWrapper { - @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), - @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) - @Override - public List getRecurrences() { - return recurrences; - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java similarity index 80% rename from extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java rename to scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java index 9beb22cd50a..032ec9aa0c0 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java @@ -24,13 +24,13 @@ import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.JobTrigger; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.StringUtil; @@ -65,23 +65,27 @@ public class RepositoryCleanerSystemListener implements IPentahoSystemListener, enum Frequency { NOW( "now" ) { - @Override public JobTrigger createTrigger() { - return new SimpleJobTrigger( new Date(), + @Override public IJobTrigger createTrigger() { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); + return scheduler.createSimpleJobTrigger(new Date(), new Date( Long.MAX_VALUE ), 0, 1 ); } }, WEEKLY( "weekly" ) { - @Override public JobTrigger createTrigger() { + @Override public IJobTrigger createTrigger() { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); // execute each first day of week at 0 hours - return new ComplexJobTrigger( null, null, null, ComplexJobTrigger.SUNDAY, 0 ); + return scheduler.createComplexTrigger( null, null, null, IComplexJobTrigger.SUNDAY, 0 ); } }, MONTHLY( "monthly" ) { - @Override public JobTrigger createTrigger() { + @Override public IJobTrigger createTrigger() { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); + // execute each first day of month at 0 hours - return new ComplexJobTrigger( null, null, 1, null, 0 ); + return scheduler.createComplexTrigger( null, null, 1, null, 0 ); } }; @@ -91,7 +95,7 @@ enum Frequency { this.value = value; } - public abstract JobTrigger createTrigger(); + public abstract IJobTrigger createTrigger(); public static Frequency fromString( String name ) { for ( Frequency frequency : values() ) { @@ -119,7 +123,7 @@ public boolean startup( IPentahoSession session ) { } try { - List jobs = scheduler.getJobs( this ); + List jobs = scheduler.getJobs( this ); if ( gcEnabled ) { if ( jobs.isEmpty() ) { scheduleJob( scheduler ); @@ -137,7 +141,7 @@ public boolean startup( IPentahoSession session ) { return true; } - private JobTrigger findJobTrigger() { + private IJobTrigger findJobTrigger() { if ( StringUtil.isEmpty( execute ) ) { logger.error( "\"execute\" property is not specified!" ); return null; @@ -153,22 +157,22 @@ private JobTrigger findJobTrigger() { } private void scheduleJob( IScheduler scheduler ) throws SchedulerException { - JobTrigger trigger = findJobTrigger(); + IJobTrigger trigger = findJobTrigger(); if ( trigger != null ) { logger.info( "Creating new job with trigger: " + trigger ); scheduler.createJob( RepositoryGcJob.JOB_NAME, RepositoryGcJob.class, null, trigger ); } } - private void rescheduleIfNecessary( IScheduler scheduler, List jobs ) throws SchedulerException { - JobTrigger trigger = findJobTrigger(); + private void rescheduleIfNecessary( IScheduler scheduler, List jobs ) throws SchedulerException { + IJobTrigger trigger = findJobTrigger(); if ( trigger == null ) { return; } - List matched = new ArrayList( jobs.size() ); - for ( Job job : jobs ) { - JobTrigger tr = job.getJobTrigger(); + List matched = new ArrayList( jobs.size() ); + for ( IJob job : jobs ) { + IJobTrigger tr = job.getJobTrigger(); // unfortunately, JobTrigger does not override equals if ( trigger.getClass() != tr.getClass() ) { logger.info( "Removing job with id: " + job.getJobId() ); @@ -184,8 +188,8 @@ private void rescheduleIfNecessary( IScheduler scheduler, List jobs ) throw } } - private void unscheduleJob( IScheduler scheduler, List jobs ) throws SchedulerException { - for ( Job job : jobs ) { + private void unscheduleJob( IScheduler scheduler, List jobs ) throws SchedulerException { + for ( IJob job : jobs ) { logger.info( "Removing job with id: " + job.getJobId() ); scheduler.removeJob( job.getJobId() ); } @@ -198,7 +202,7 @@ public void shutdown() { } @Override - public boolean accept( Job job ) { + public boolean accept( IJob job ) { return RepositoryGcJob.JOB_NAME.equals( job.getJobName() ); } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java similarity index 81% rename from extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java rename to scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java index 67f6aca745f..81a3c4a31bb 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java +++ b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java @@ -22,8 +22,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.openide.util.NotImplementedException; import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.repository2.unified.jcr.RepositoryCleaner; +//import org.pentaho.platform.repository2.unified.jcr.RepositoryCleaner; /** * @author Andrey Khayrutdinov @@ -35,8 +36,9 @@ public class RepositoryGcJob implements IAction { @Override public void execute() throws Exception { - logger.info( "Starting repository GC" ); - new RepositoryCleaner().gc(); - logger.info( "Repository GC has been finished" ); +// logger.info( "Starting repository GC" ); +// new RepositoryCleaner().gc(); +// logger.info( "Repository GC has been finished" ); + throw new NotImplementedException(); } } diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler/versionchecker/VersionCheckerJob.java b/scheduler/src/main/java/org/pentaho/platform/scheduler/versionchecker/VersionCheckerJob.java deleted file mode 100644 index 17cd75f44fe..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler/versionchecker/VersionCheckerJob.java +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler.versionchecker; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -/** - * This class is here for legacy reasons, to allow existing system with the old version checker class to exist and be - * instanced by quartz. The code here is a no-op, the new version checker job will remove the old one before it is added - * with the correct/new classname. - */ -public class VersionCheckerJob implements Job { - - public static final String VERSION_REQUEST_FLAGS = "versionRequestFlags"; //$NON-NLS-1$ - - public Log getLogger() { - return LogFactory.getLog( VersionCheckerJob.class ); - } - - public void execute( final JobExecutionContext context ) throws JobExecutionException { - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java index d33350b911c..5b3950d59c5 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java @@ -39,7 +39,6 @@ import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.solution.ActionSequenceCompatibilityFormatter; import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.scheduler2.quartz.SchedulerOutputPathResolver; import org.pentaho.platform.util.ActionUtil; import org.pentaho.platform.util.beans.ActionHarness; import org.pentaho.platform.util.messages.LocaleHelper; diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java index b289aa13880..6986d1535fb 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java @@ -29,9 +29,9 @@ import org.pentaho.platform.api.action.IActionInvokeStatus; import org.pentaho.platform.api.action.IActionInvoker; import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.engine.security.SecurityHelper; import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import org.pentaho.platform.util.ActionUtil; import org.pentaho.platform.util.StringUtil; import org.pentaho.platform.util.messages.LocaleHelper; @@ -60,7 +60,7 @@ protected IBackgroundExecutionStreamProvider getStreamProvider( final Map args ) { - if ( args.containsKey( IBlockoutManager.DURATION_PARAM ) ) { - this.duration = ( (Number) args.get( IBlockoutManager.DURATION_PARAM ) ).longValue(); - } - if ( args.containsKey( IBlockoutManager.SCHEDULED_FIRE_TIME ) ) { - this.scheduledFireTime = ( (Date) args.get( IBlockoutManager.SCHEDULED_FIRE_TIME ) ); - } - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutManagerUtil.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutManagerUtil.java deleted file mode 100644 index c51e3fe8858..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutManagerUtil.java +++ /dev/null @@ -1,425 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.blockout; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.CronJobTrigger; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.scheduler2.quartz.QuartzJobKey; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; -import org.quartz.Trigger; - -public class BlockoutManagerUtil { - - /** - * Standard Units of Time - */ - public static enum TIME { - MILLISECOND( 1 ), SECOND( MILLISECOND.time * 1000 ), MINUTE( SECOND.time * 60 ), HOUR( MINUTE.time * 60 ), DAY( - HOUR.time * 24 ), WEEK( DAY.time * 7 ), YEAR( DAY.time * 365 ); - - public long time; - - private TIME( long time ) { - this.time = time; - } - } - - public static boolean willFire( IJobTrigger jobTrigger, List blockOutTriggers, IScheduler scheduler ) { - - // Short return as to avoid having to calculate fire times - if ( blockOutTriggers.isEmpty() ) { - return true; - } - - List fireTimes = getFireTimes( jobTrigger, scheduler ); - - for ( IJobTrigger blockOutJobTrigger : blockOutTriggers ) { - - // We must verify further if the schedule is blocked completely or if it will fire - if ( willBlockSchedule( jobTrigger, blockOutJobTrigger, scheduler ) ) { - - boolean isBlockoutComplex = isComplexTrigger( blockOutJobTrigger ); - - // If recurrence intervals are the same, it will never fire - if ( !isBlockoutComplex && !isComplexTrigger( jobTrigger ) - && getRecurrenceInterval( blockOutJobTrigger ) == getRecurrenceInterval( jobTrigger ) ) { - return false; - } - - List blockoutFireTimes = null; - if ( isBlockoutComplex ) { - blockoutFireTimes = getFireTimes( blockOutJobTrigger, scheduler ); - } - - // Loop through fire times and verify whether block out is blocking the schedule completely - boolean scheduleCompletelyBlocked = true; - for ( Date fireTime : fireTimes ) { - scheduleCompletelyBlocked = - isBlockoutComplex ? willComplexBlockOutTriggerBlockDate( blockOutJobTrigger, blockoutFireTimes, fireTime ) - : willBlockDate( blockOutJobTrigger, fireTime, scheduler ); - - if ( !scheduleCompletelyBlocked ) { - break; - } - } - - // Return false if after n iterations - if ( scheduleCompletelyBlocked ) { - return false; - } - } - } - - return true; - } - - public static boolean willBlockSchedule( IJobTrigger scheduleTrigger, IJobTrigger blockOutJobTrigger, - IScheduler scheduler ) { - - boolean isScheduleTriggerComplex = isComplexTrigger( scheduleTrigger ); - boolean isBlockOutTriggerComplex = isComplexTrigger( blockOutJobTrigger ); - - // Both Schedule and BlockOut are complex - if ( isScheduleTriggerComplex && isBlockOutTriggerComplex ) { - return willComplexBlockOutBlockComplexScheduleTrigger( blockOutJobTrigger, scheduleTrigger, scheduler ); - } - - // Complex Schedule Trigger - if ( isScheduleTriggerComplex ) { - return willBlockComplexScheduleTrigger( scheduleTrigger, blockOutJobTrigger, scheduler ); - } - - // Complex BlockOut Trigger - if ( isBlockOutTriggerComplex ) { - return willComplexBlockOutTriggerBlockSchedule( blockOutJobTrigger, scheduleTrigger, scheduler ); - } - - /* - * Both blockOut and schedule triggers are simple. Continue with mathematical calculations - */ - long blockOutRecurrence = getRecurrenceInterval( blockOutJobTrigger ); - long scheduleRecurrence = getRecurrenceInterval( scheduleTrigger ); - - for ( int i = 0; i < 1000; i++ ) { - double shiftBy = ( blockOutRecurrence - scheduleRecurrence ) * i / (double) scheduleRecurrence; - - double x1 = - ( blockOutJobTrigger.getStartTime().getTime() - scheduleTrigger.getStartTime().getTime() ) - / (double) scheduleRecurrence + shiftBy; - - double x2 = - ( blockOutJobTrigger.getStartTime().getTime() + blockOutJobTrigger.getDuration() - scheduleTrigger - .getStartTime().getTime() ) - / (double) scheduleRecurrence + shiftBy; - - if ( hasIntBetween( x1, x2 ) ) { - - int xShift = (int) Math.ceil( x1 < x2 ? x1 : x2 ); - - long scheduleDate = scheduleTrigger.getStartTime().getTime() + scheduleRecurrence * ( i + xShift ); - long blockOutStartDate = blockOutJobTrigger.getStartTime().getTime() + blockOutRecurrence * i; - - // Test intersection of dates fall within range - if ( scheduleTrigger.getStartTime().getTime() <= scheduleDate - && ( scheduleTrigger.getEndTime() == null || scheduleDate <= scheduleTrigger.getEndTime().getTime() ) - && blockOutJobTrigger.getStartTime().getTime() <= blockOutStartDate - && ( blockOutJobTrigger.getEndTime() == null || blockOutStartDate <= blockOutJobTrigger.getEndTime() - .getTime() ) ) { - return true; - } - } - } - - return false; - } - - private static boolean willComplexBlockOutTriggerBlockSchedule( IJobTrigger blockOutJobTrigger, - IJobTrigger scheduleTrigger, IScheduler scheduler ) { - - // Short circuit if schedule trigger after end time of block out trigger - if ( ( blockOutJobTrigger.getEndTime() != null && scheduleTrigger.getStartTime().after( - blockOutJobTrigger.getEndTime() ) ) - || ( scheduleTrigger.getEndTime() != null && blockOutJobTrigger.getStartTime().after( - scheduleTrigger.getEndTime() ) ) ) { - return false; - } - - long duration = blockOutJobTrigger.getDuration(); - - // Loop through fire times of block out trigger - for ( Date blockOutStartDate : getFireTimes( blockOutJobTrigger, scheduler ) ) { - Date blockOutEndDate = new Date( blockOutStartDate.getTime() + duration ); - - if ( willBlockOutRangeBlockSimpleTrigger( blockOutStartDate, blockOutEndDate, scheduleTrigger, scheduler ) ) { - return true; - } - } - - return false; - } - - private static boolean willBlockOutRangeBlockSimpleTrigger( Date startBlockOutRange, Date endBlockOutRange, - IJobTrigger scheduleTrigger, IScheduler scheduler ) { - // ( S1 - S ) / R <= x <= ( S2 - S ) / R - - double recurrence = getRecurrenceInterval( scheduleTrigger ); - recurrence = recurrence != 0 ? recurrence : 1; - double x1 = ( startBlockOutRange.getTime() - scheduleTrigger.getStartTime().getTime() ) / recurrence; - double x2 = ( endBlockOutRange.getTime() - scheduleTrigger.getStartTime().getTime() ) / recurrence; - - return hasPositiveIntBetween( x1, x2 ); - } - - private static boolean willBlockComplexScheduleTrigger( IJobTrigger trigger, IJobTrigger blockOut, - IScheduler scheduler ) { - - for ( Date fireTime : getFireTimes( trigger, scheduler ) ) { - if ( willBlockDate( blockOut, fireTime, scheduler ) ) { - return true; - } - } - - return false; - } - - private static boolean willComplexBlockOutBlockComplexScheduleTrigger( IJobTrigger blockOutJobTrigger, - IJobTrigger jobTrigger, IScheduler scheduler ) { - List blockOutFireTimes = getFireTimes( blockOutJobTrigger, scheduler ); - - int iStart = 0; - for ( Date scheduleFireTime : getFireTimes( jobTrigger, scheduler ) ) { - for ( int i = iStart; i < blockOutFireTimes.size(); i++ ) { - Date blockOutStartDate = blockOutFireTimes.get( i ); - - // BlockOut start date after scheduled fire time - if ( blockOutStartDate.after( scheduleFireTime ) ) { - iStart = i; - break; - } - - Date blockOutEndDate = new Date( blockOutStartDate.getTime() + blockOutJobTrigger.getDuration() ); - - if ( isDateIncludedInRangeInclusive( blockOutStartDate, blockOutEndDate, scheduleFireTime ) ) { - return true; - } - } - - } - - return false; - } - - private static boolean willBlockDate( IJobTrigger blockOutJobTrigger, Date date, IScheduler scheduler ) { - // S + Rx <= d <= S + Rx + D - - // Out of range of block out - if ( date.before( blockOutJobTrigger.getStartTime() ) - || ( blockOutJobTrigger.getEndTime() != null && date.after( blockOutJobTrigger.getEndTime() ) ) ) { - return false; - } - - if ( isComplexTrigger( blockOutJobTrigger ) ) { - return willComplexBlockOutTriggerBlockDate( blockOutJobTrigger, getFireTimes( blockOutJobTrigger, scheduler ), - date ); - } - - long blockOutRecurrenceInterval = getRecurrenceInterval( blockOutJobTrigger ); - - double x1 = ( date.getTime() - blockOutJobTrigger.getStartTime().getTime() ) / (double) blockOutRecurrenceInterval; - double x2 = - ( date.getTime() - ( blockOutJobTrigger.getStartTime().getTime() + blockOutJobTrigger.getDuration() ) ) - / (double) blockOutRecurrenceInterval; - - return hasPositiveIntBetween( x1, x2 ); - } - - private static boolean willComplexBlockOutTriggerBlockDate( IJobTrigger blockOutJobTrigger, List blockOutDates, - Date date ) { - - // Short circuit if date does not fall within a valid start/end date range - if ( date.before( blockOutJobTrigger.getStartTime() ) - || ( blockOutJobTrigger.getEndTime() != null && date.after( blockOutJobTrigger.getEndTime() ) ) ) { - return false; - } - - long blockOutDuration = blockOutJobTrigger.getDuration(); - for ( Date blockOutStartDate : blockOutDates ) { - - // Block out date has passed the date being tested - if ( blockOutStartDate.after( date ) ) { - break; - } - - Date blockOutEndDate = new Date( blockOutStartDate.getTime() + blockOutDuration ); - - // Date falls within inclusive block out range - if ( isDateIncludedInRangeInclusive( blockOutStartDate, blockOutEndDate, date ) ) { - return true; - } - } - - return false; - } - - public static boolean isComplexTrigger( IJobTrigger jobTrigger ) { - return jobTrigger instanceof ComplexJobTrigger || jobTrigger instanceof CronJobTrigger; - } - - private static long getRecurrenceInterval( IJobTrigger jobTrigger ) { - - if ( !isComplexTrigger( jobTrigger ) ) { - return ( (SimpleJobTrigger) jobTrigger ).getRepeatInterval() * 1000; // Have to convert to milliseconds - } - - throw new RuntimeException( "Can not get recurrence interval from JobTriggers which are not SimpleJobTrigger" ); //$NON-NLS-1$ - } - - public static List getFireTimes( IJobTrigger jobTrigger, IScheduler scheduler ) { - // Determines the maximum amount of fire times allowed to be calculated - int n = 1000; - - Date startDate = new Date( System.currentTimeMillis() ); - Date endDate = new Date( startDate.getTime() + 4 * TIME.YEAR.time ); - - // Quartz Triggers - if ( scheduler instanceof QuartzScheduler ) { - try { - - List dates = new ArrayList(); - boolean endDateIsNull = jobTrigger.getEndTime() == null; - Trigger trigger = QuartzScheduler.createQuartzTrigger( jobTrigger, new QuartzJobKey( "test", "test" ) ); //$NON-NLS-1$ //$NON-NLS-2$ - - // add previous trigger (it might be currently active) - IBlockoutManager manager = PentahoSystem.get( IBlockoutManager.class, "IBlockoutManager", null ); //$NON-NLS-1$; - if ( manager != null ) { - List blockouts = manager.getBlockOutJobs(); - for ( Job blockout : blockouts ) { - if ( blockout.getLastRun() != null ) { - dates.add( blockout.getLastRun() ); - } - } - } - - for ( int i = 0; i < n; i++ ) { - Date nextFireTime = trigger.getFireTimeAfter( startDate ); - - if ( ( nextFireTime == null ) - || ( nextFireTime.after( endDate ) || ( !endDateIsNull - && nextFireTime.after( jobTrigger.getEndTime() ) ) ) ) { - break; - } - - dates.add( nextFireTime ); - startDate = nextFireTime; - } - - return dates; - - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - throw new RuntimeException( "Can not calculate fire times for unsupported Scheduler Type: " //$NON-NLS-1$ - + scheduler.getClass().getSimpleName() ); - } - - public static boolean shouldFireNow( List blockOutJobTriggers, IScheduler scheduler ) { - - Date currentTime = new Date( System.currentTimeMillis() ); - for ( IJobTrigger blockOutJobTrigger : blockOutJobTriggers ) { - - if ( willBlockDate( blockOutJobTrigger, currentTime, scheduler ) ) { - return false; - } - } - - return true; - } - - public static boolean isPartiallyBlocked( IJobTrigger scheduleJobTrigger, List blockOutJobTriggers, - IScheduler scheduler ) { - - // Loop through blockout triggers - for ( IJobTrigger blockOut : blockOutJobTriggers ) { - if ( willBlockSchedule( scheduleJobTrigger, blockOut, scheduler ) ) { - return true; - } - } - - return false; - } - - /** - * @param x1 - * double - * @param x2 - * double - * @return whether an {@link Integer} exists between x1 and x2 - */ - private static boolean hasIntBetween( double x1, double x2 ) { - double ceilX = Math.ceil( x1 ); - double floorX = Math.floor( x2 ); - - if ( x1 > x2 ) { - ceilX = Math.ceil( x2 ); - floorX = Math.floor( x1 ); - } - - return ( floorX - ceilX ) >= 0; - } - - /** - * @param x1 - * double - * @param x2 - * double - * @return whether there is a positive integer between x1 and x2 - */ - private static boolean hasPositiveIntBetween( double x1, double x2 ) { - return ( x1 < x2 ? x2 >= 0 : x1 >= 0 ) && hasIntBetween( x1, x2 ); - } - - /** - * @param dateRangeStart - * {@link Date} start of range - * @param dateRangeEnd - * {@link Date} end of range - * @param date - * {@link Date} - * @return whether the date falls within the date inclusive date range - */ - private static boolean isDateIncludedInRangeInclusive( Date dateRangeStart, Date dateRangeEnd, Date date ) { - long dateTime = date.getTime(); - return dateRangeStart.getTime() <= dateTime && dateTime <= dateRangeEnd.getTime(); - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/StandaloneQuartzSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java similarity index 56% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/StandaloneQuartzSystemListener.java rename to scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java index c34ac91b1c9..ec1bc302d74 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/StandaloneQuartzSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java @@ -18,21 +18,23 @@ * */ -package org.pentaho.platform.scheduler2.quartz; +package org.pentaho.platform.scheduler2.blockout; -import javax.sql.DataSource; -import java.sql.SQLException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.pentaho.platform.api.action.IVarArgsAction; +import org.pentaho.platform.api.scheduler2.IBlockoutManager; + +import java.util.Date; +import java.util.Map; /** - * This Subclasses of the embeddedQuartzSystemListener is to prevent the check for database creation and calling of the - * creation script, which we only want to happen with people running the H2 embedded database. - * - * User: nbaker Date: 7/17/12 + * @author wseyler This is the job that executes when the a block out trigger fires. This job essentially does nothing + * more than logging the firing of the trigger. */ -public class StandaloneQuartzSystemListener extends EmbeddedQuartzSystemListener { - - @Override - protected boolean verifyQuartzIsConfigured( DataSource ds ) throws SQLException { - return true; +public interface IBlockoutAction { + public static String getCanonicalName() { + return "org.pentaho.platform.scheduler2.blockout.BlockoutAction"; } + public void execute() throws Exception; } diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManager.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManager.java deleted file mode 100644 index 1f888063a0d..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/PentahoBlockoutManager.java +++ /dev/null @@ -1,130 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.blockout; - -import java.util.ArrayList; -import java.util.List; - -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.engine.core.system.PentahoSystem; - -public class PentahoBlockoutManager implements IBlockoutManager { - - private IScheduler scheduler; - - public PentahoBlockoutManager() { - this.scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - } - - @Override - public IJobTrigger getBlockOut( String blockOutJobId ) { - try { - Job blockOutJob = this.scheduler.getJob( blockOutJobId ); - IJobTrigger blockOutJobTrigger = blockOutJob.getJobTrigger(); - blockOutJobTrigger.setDuration( ( (Number) blockOutJob.getJobParams().get( DURATION_PARAM ) ).longValue() ); - return blockOutJobTrigger; - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - @Override - public List getBlockOutJobs() { - try { - List jobs = scheduler.getJobs( new IJobFilter() { - public boolean accept( Job job ) { - if ( BLOCK_OUT_JOB_NAME.equals( job.getJobName() ) ) { - job.getJobTrigger().setDuration( ( (Number) job.getJobParams().get( DURATION_PARAM ) ).longValue() ); - return true; - } - return false; - } - } ); - return jobs; - - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - - } - - @Override - public boolean willFire( IJobTrigger scheduleTrigger ) { - - return BlockoutManagerUtil.willFire( scheduleTrigger, getBlockOutJobTriggers(), this.scheduler ); - } - - @Override - public boolean shouldFireNow() { - return BlockoutManagerUtil.shouldFireNow( getBlockOutJobTriggers(), this.scheduler ); - } - - @Override - public List willBlockSchedules( IJobTrigger testBlockOutJobTrigger ) { - List blockedSchedules = new ArrayList(); - - List scheduledJobs = new ArrayList(); - try { - scheduledJobs = this.scheduler.getJobs( new IJobFilter() { - - @Override - public boolean accept( Job job ) { - return !BLOCK_OUT_JOB_NAME.equals( job.getJobName() ); - } - } ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - - // Loop over trigger group names - for ( Job scheduledJob : scheduledJobs ) { - - // Add schedule to list if block out conflicts at all - if ( BlockoutManagerUtil.willBlockSchedule( scheduledJob.getJobTrigger(), - testBlockOutJobTrigger, this.scheduler ) ) { - blockedSchedules.add( scheduledJob.getJobTrigger() ); - } - } - - return blockedSchedules; - } - - @Override - public boolean isPartiallyBlocked( IJobTrigger scheduleJobTrigger ) { - return BlockoutManagerUtil.isPartiallyBlocked( scheduleJobTrigger, getBlockOutJobTriggers(), this.scheduler ); - } - - private List getBlockOutJobTriggers() { - List blockOutJobTriggers = new ArrayList(); - - for ( Job blockOutJob : getBlockOutJobs() ) { - blockOutJobTriggers.add( blockOutJob.getJobTrigger() ); - } - - return blockOutJobTriggers; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/ActionAdapterQuartzJob.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/ActionAdapterQuartzJob.java deleted file mode 100644 index 87b9466212e..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/ActionAdapterQuartzJob.java +++ /dev/null @@ -1,298 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.action.IActionInvokeStatus; -import org.pentaho.platform.api.action.IActionInvoker; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.scheduler2.action.DefaultActionInvoker; -import org.pentaho.platform.scheduler2.blockout.BlockoutAction; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.scheduler2.ws.ListParamValue; -import org.pentaho.platform.scheduler2.ws.MapParamValue; -import org.pentaho.platform.scheduler2.ws.StringParamValue; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.util.StringUtil; -import org.pentaho.platform.workitem.WorkItemLifecycleEventUtil; -import org.pentaho.platform.workitem.WorkItemLifecyclePhase; -import org.quartz.Job; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -import java.io.Serializable; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.Callable; - -/** - * A Quartz job that is responsible for executing the {@link IAction} referred to in the job context. - * - * @author aphillips - */ -public class ActionAdapterQuartzJob implements Job { - - static final Log log = LogFactory.getLog( ActionAdapterQuartzJob.class ); - - private IActionInvoker actionInvoker = new DefaultActionInvoker(); // default - - public void execute( JobExecutionContext context ) throws JobExecutionException { - JobDataMap jobDataMap = context.getMergedJobDataMap(); - String actionUser = jobDataMap.getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ); - - final String actionClassName = jobDataMap.getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS ); - final String actionId = jobDataMap.getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ); - - try { - invokeAction( actionClassName, actionId, actionUser, context, jobDataMap.getWrappedMap() ); - - } catch ( Throwable t ) { - // We should not distinguish between checked and unchecked exceptions here. All job execution failures - // should result in a rethrow of a quartz exception - throw new LoggingJobExecutionException( Messages.getInstance().getErrorString( - "ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED", //$NON-NLS-1$ - getActionIdentifier( null, actionClassName, actionId ) ), t ); - } - } - - private static String getActionIdentifier( final IAction actionBean, final String actionClassName, final String - actionId ) { - if ( actionBean != null ) { - return actionBean.getClass().getName(); - } else if ( !StringUtil.isEmpty( actionClassName ) ) { - return actionClassName; - } else if ( !StringUtil.isEmpty( actionId ) ) { - return actionId; - } - return "?"; //$NON-NLS-1$ - } - - /** - * @deprecated as of 8.0, use {@link #invokeAction(String, String, String, JobExecutionContext, Map)}} instead - */ - @Deprecated - protected void invokeAction( final IAction actionBean, final String actionUser, final JobExecutionContext context, - final Map params ) throws Exception { - - final JobDataMap jobDataMap = context.getMergedJobDataMap(); - final String actionClass = jobDataMap.getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS ); - final String actionId = jobDataMap.getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ); - - invokeAction( actionClass, actionId, actionUser, context, params ); - } - - private static Map getSerializableMap( final Map originalMap ) { - final Map serializableMap = new HashMap<>( ); - - final Iterator> iter = originalMap.entrySet().iterator(); - while ( iter.hasNext() ) { - final Map.Entry entry = iter.next(); - final String key = entry.getKey(); - final Serializable value = entry.getValue(); - if ( value instanceof MapParamValue ) { - serializableMap.put( key, new HashMap( (MapParamValue) value ) ); - } else if ( value instanceof ListParamValue ) { - serializableMap.put( key, new ArrayList( (ListParamValue) value ) ); - } else if ( value instanceof StringParamValue ) { - serializableMap.put( key, ( (StringParamValue) value ).getStringValue() ); - } else { - serializableMap.put( key, value ); - } - } - - return serializableMap; - } - - /** - * Invokes the {@link IAction} bean that is created from the provided {@code actionClassName} and {@code actionId} as - * the provided {@code actionUser}. If the {@code IAction} execution fails as-is, the scheduler attempts to re-create - * the job that will try to invoke the {@link IAction} again. - * - * @param actionClassName The class name of the {@link IAction} bean; used as a backup, if the {@code actionId} is not - * available or vald - * @param actionId The bean id of the {@link IAction} requested to be invoked. - * @param actionUser The user invoking the {@link IAction} - * @param context the {@code JobExecutionContext} - * @param params the {@link Map} or parameters needed to invoke the {@link IAction} - * @throws Exception when the {@code IAction} cannot be invoked for some reason. - */ - protected void invokeAction( final String actionClassName, final String actionId, final String actionUser, final - JobExecutionContext context, final Map params ) throws Exception { - - final String workItemName = ActionUtil.extractName( params ); - - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.SUBMITTED ); - - // creates an instance of IActionInvoker, which knows how to invoke this IAction - if the IActionInvoker bean is - // not defined through spring, fall back on the default action invoker - final IActionInvoker actionInvoker = Optional.ofNullable( PentahoSystem.get( IActionInvoker.class ) ).orElse( - getActionInvoker() ); - // Instantiate the requested IAction bean - final IAction actionBean = (IAction) ActionUtil.createActionBean( actionClassName, actionId ); - - if ( actionInvoker == null || actionBean == null ) { - final String failureMessage = Messages.getInstance().getErrorString( - "ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION", //$NON-NLS-1$ - getActionIdentifier( null, actionClassName, actionId ), StringUtil.getMapAsPrettyString( params ) ); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, failureMessage ); - throw new LoggingJobExecutionException( failureMessage ); - } - - if ( actionBean instanceof BlockoutAction ) { - params.put( IBlockoutManager.SCHEDULED_FIRE_TIME, context.getScheduledFireTime() ); - } - - // Invoke the action and get the status of the invocation - final IActionInvokeStatus status = actionInvoker.invokeAction( actionBean, actionUser, getSerializableMap( params ) ); - - // Status may not be available for remote execution, which is expected - if ( status == null ) { - if ( log.isWarnEnabled() ) { - log.warn( Messages.getInstance().getErrorString( - "ActionAdapterQuartzJob.WARN_0002_NO_STATUS", //$NON-NLS-1$ - getActionIdentifier( actionBean, actionClassName, actionId ), StringUtil.getMapAsPrettyString( params ) ) ); - } - return; - } - - // Some of the ktr/kjb execution failures are not thrown as exception as scheduler might try them again. - // To resolve this, the errors are flagged. If the execution status returns false, then it throws the - // exception - if ( !status.isExecutionSuccessful() ) { - // throw job exception - throw new JobExecutionException( Messages.getInstance().getActionFailedToExecute( actionBean //$NON-NLS-1$ - .getClass().getName() ) ); - } - - final boolean requiresUpdate = status.requiresUpdate(); - final Throwable throwable = status.getThrowable(); - Object objsp = status.getStreamProvider(); - IBackgroundExecutionStreamProvider sp = null; - if ( objsp != null && IBackgroundExecutionStreamProvider.class.isAssignableFrom( objsp.getClass() ) ) { - sp = (IBackgroundExecutionStreamProvider) objsp; - } - final IBackgroundExecutionStreamProvider streamProvider = sp; - - - final Map jobParams = new HashMap( params ); // shallow copy - - final IScheduler scheduler = PentahoSystem.getObjectFactory().get( IScheduler.class, "IScheduler2", null ); - if ( throwable != null ) { - Object restartFlag = jobParams.get( QuartzScheduler.RESERVEDMAPKEY_RESTART_FLAG ); - if ( restartFlag == null ) { - final SimpleJobTrigger trigger = new SimpleJobTrigger( new Date(), null, 0, 0 ); - final Class iaction = (Class) actionBean.getClass(); - // recreate the job in the context of the original creator - SecurityHelper.getInstance().runAsUser( actionUser, new Callable() { - @Override - public Void call() throws Exception { - if ( streamProvider != null ) { - streamProvider.setStreamingAction( null ); // remove generated content - } - QuartzJobKey jobKey = QuartzJobKey.parse( context.getJobDetail().getName() ); - String jobName = jobKey.getJobName(); - jobParams.put( QuartzScheduler.RESERVEDMAPKEY_RESTART_FLAG, Boolean.TRUE ); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.RESTARTED ); - scheduler.createJob( jobName, iaction, jobParams, trigger, streamProvider ); - log.warn( "New RunOnce job created for " + jobName + " -> possible startup synchronization error" ); - return null; - } - } ); - } else { - log.warn( "RunOnce already created, skipping" ); - } - throw new JobExecutionException( throwable ); - } - - scheduler.fireJobCompleted( actionBean, actionUser, params, streamProvider ); - - if ( requiresUpdate ) { - log.warn( "Output path for job: " + context.getJobDetail().getName() + " has changed. Job requires update" ); - try { - final IJobTrigger trigger = scheduler.getJob( context.getJobDetail().getName() ).getJobTrigger(); - final Class iaction = (Class) actionBean.getClass(); - - // remove job with outdated/invalid output path - scheduler.removeJob( context.getJobDetail().getName() ); - - // recreate the job in the context of the original creator - SecurityHelper.getInstance().runAsUser( actionUser, new Callable() { - @Override - public Void call() throws Exception { - streamProvider.setStreamingAction( null ); // remove generated content - QuartzJobKey jobKey = QuartzJobKey.parse( context.getJobDetail().getName() ); - String jobName = jobKey.getJobName(); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.RESTARTED ); - org.pentaho.platform.api.scheduler2.Job j = - scheduler.createJob( jobName, iaction, jobParams, trigger, streamProvider ); - log.warn( "New Job: " + j.getJobId() + " created" ); - return null; - } - } ); - } catch ( Exception e ) { - log.error( e.getMessage(), e ); - } - } - - if ( log.isDebugEnabled() ) { - log.debug( MessageFormat.format( - "Scheduling system successfully invoked action {0} as user {1} with params [ {2} ]", actionBean //$NON-NLS-1$ - .getClass().getName(), actionUser, QuartzScheduler.prettyPrintMap( params ) ) ); - } - } - - class LoggingJobExecutionException extends JobExecutionException { - private static final long serialVersionUID = -4124907454208034326L; - - public LoggingJobExecutionException( String msg ) { - super( msg ); - log.error( msg ); - } - - public LoggingJobExecutionException( String msg, Throwable t ) { - super( msg, t ); - log.error( msg, t ); - } - - } - - public IActionInvoker getActionInvoker() { - return actionInvoker; - } - - public void setActionInvoker( IActionInvoker actionInvoker ) { - this.actionInvoker = actionInvoker; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJob.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJob.java deleted file mode 100644 index 3ab312e4702..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJob.java +++ /dev/null @@ -1,132 +0,0 @@ -/*! - * - * 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-2020 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.engine.core.audit.AuditHelper; -import org.pentaho.platform.engine.core.audit.MDCUtil; -import org.pentaho.platform.engine.core.audit.MessageTypes; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.scheduler2.blockout.BlockoutAction; -import org.pentaho.platform.scheduler2.blockout.PentahoBlockoutManager; -import org.quartz.Job; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.quartz.SchedulerException; - -/** - * A Quartz job that checks if execution is currently suspended before passing on to the underlying job - * - * @author kwalker - */ -public class BlockingQuartzJob implements Job { - public void execute( final JobExecutionContext jobExecutionContext ) throws JobExecutionException { - JobDataMap jobDataMap = null; - if ( jobExecutionContext.getJobDetail() != null && jobExecutionContext.getJobDetail().getJobDataMap() != null ) { - jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); - } - boolean jobRestarted = false; - if ( jobDataMap != null ) { - MDCUtil.setupSchedulerMDC( jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ), jobDataMap.get( - "lineage-id" ) ); - jobRestarted = jobDataMap.getBooleanValue( QuartzScheduler.RESERVEDMAPKEY_RESTART_FLAG ); - } - String messageType = jobRestarted ? MessageTypes.RECREATED_INSTANCE_START : MessageTypes.INSTANCE_START; - long start = System.currentTimeMillis(); - long end = start; - try { - if ( getBlockoutManager().shouldFireNow() || isBlockoutAction( jobExecutionContext ) ) { // We should always let the blockouts fire //$NON-NLS-1$ - makeAuditRecord( 0, messageType, jobExecutionContext ); - createUnderlyingJob().execute( jobExecutionContext ); - end = System.currentTimeMillis(); - messageType = jobRestarted ? MessageTypes.RECREATED_INSTANCE_END : MessageTypes.INSTANCE_END; - } else { - getLogger().warn( - "Job '" + jobExecutionContext.getJobDetail().getName() - + "' attempted to run during a blockout period. This job was not executed" ); - } - } catch ( ActionAdapterQuartzJob.LoggingJobExecutionException le ) { - // thrown by the execution code - if execution fails, there only thing we do is to write to pro_audit table failing message, - // no point in trying to execute the job again - end = System.currentTimeMillis(); - messageType = jobRestarted ? MessageTypes.RECREATED_INSTANCE_FAILED : MessageTypes.INSTANCE_FAILED; - } catch ( SchedulerException e ) { - end = System.currentTimeMillis(); - messageType = jobRestarted ? MessageTypes.RECREATED_INSTANCE_FAILED : MessageTypes.INSTANCE_FAILED; - getLogger().warn( - "Got Exception retrieving the Blockout Manager for job '" + jobExecutionContext.getJobDetail().getName() - + "'. Executing the underlying job anyway", e ); - createUnderlyingJob().execute( jobExecutionContext ); - end = System.currentTimeMillis(); - messageType = jobRestarted ? MessageTypes.RECREATED_INSTANCE_END : MessageTypes.INSTANCE_END; - } finally { - makeAuditRecord( ( (float) ( end - start ) / 1000 ), messageType, jobExecutionContext ); - } - } - - IBlockoutManager getBlockoutManager() throws SchedulerException { - return new PentahoBlockoutManager(); - } - - Job createUnderlyingJob() { - return new ActionAdapterQuartzJob(); - } - - Log getLogger() { - return LogFactory.getLog( BlockingQuartzJob.class ); - } - - protected boolean isBlockoutAction( JobExecutionContext ctx ) { - try { - String actionClass = ctx.getJobDetail().getJobDataMap().getString( QuartzScheduler.RESERVEDMAPKEY_ACTIONCLASS ); - return BlockoutAction.class.getName().equals( actionClass ); - } catch ( Throwable t ) { - getLogger().warn( t.getMessage(), t ); - return false; - } - } - - protected void makeAuditRecord( final float time, final String messageType, - final JobExecutionContext jobExecutionContext ) { - if ( jobExecutionContext != null && jobExecutionContext.getJobDetail() != null ) { - final JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); - - if ( null == jobDataMap || null == jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ) || null == jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ) ) { - //it's an action, no need to log - return; - } - - AuditHelper.audit( PentahoSessionHolder.getSession() != null ? PentahoSessionHolder.getSession().getId() : "", - jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ) != null ? jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER ).toString() : "", - jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ) != null ? jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER ).toString() : "", - jobExecutionContext.getJobDetail().getJobClass() != null ? jobExecutionContext.getJobDetail().getJobClass().getName() : "", - jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ) != null ? jobDataMap.get( QuartzScheduler.RESERVEDMAPKEY_ACTIONID ).toString() : "", - messageType, - jobDataMap.get( "lineage-id" ) != null ? jobDataMap.get( "lineage-id" ).toString() : "", - null, - time, - null ); //$NON-NLS-1$ - } - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java deleted file mode 100644 index c64f117f73b..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java +++ /dev/null @@ -1,287 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.data.DBDatasourceServiceException; -import org.pentaho.platform.api.data.IDBDatasourceService; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.engine.ObjectFactoryException; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.quartz.SchedulerException; - -public class EmbeddedQuartzSystemListener implements IPentahoSystemListener { - - /* - * This is re-use by Copy and Paste to avoid a dependency on the bi-platform-scheduler project (which will eventually - * be phased out). - * - * The only difference between this and the other class is that this system listener will initialize the quartz - * database if it hasn't been created yet. - */ - - private static final String DEFAULT_QUARTZ_PROPERTIES_FILE = "quartz/quartz.properties"; //$NON-NLS-1$ - - Properties quartzProperties; - - String quartzPropertiesFile = DEFAULT_QUARTZ_PROPERTIES_FILE; - - private static final Log logger = LogFactory.getLog( EmbeddedQuartzSystemListener.class ); - - private static boolean useNewDatasourceService = false; - - public synchronized void setUseNewDatasourceService( boolean useNewService ) { - // - // The platform should not be calling this method. But, in case someone really - // really wants to use the new datasource service features to talk to - // a core service like Quartz, this is now toggle-able. - // - useNewDatasourceService = useNewService; - } - - public boolean startup( final IPentahoSession session ) { - boolean result = true; - Properties quartzProps = null; - if ( quartzPropertiesFile != null ) { - quartzProps = PentahoSystem.getSystemSettings().getSystemSettingsProperties( quartzPropertiesFile ); - } else if ( quartzProperties != null ) { - quartzProps = quartzProperties; - } - try { - if ( quartzProps == null ) { - quartzProps = findPropertiesInClasspath(); - } - if ( quartzProps == null ) { - result = false; - } else { - String dsName = quartzProps.getProperty( "org.quartz.dataSource.myDS.jndiURL" ); //$NON-NLS-1$ - if ( dsName != null ) { - IDBDatasourceService datasourceService = getQuartzDatasourceService( session ); - String boundDsName = datasourceService.getDSBoundName( dsName ); - - if ( boundDsName != null ) { - quartzProps.setProperty( "org.quartz.dataSource.myDS.jndiURL", boundDsName ); //$NON-NLS-1$ - } - - DataSource ds = datasourceService.getDataSource( dsName ); - result = verifyQuartzIsConfigured( ds ); - } - QuartzScheduler scheduler = (QuartzScheduler) PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - if ( logger.isDebugEnabled() ) { - logger.debug( "Quartz configured with properties" ); //$NON-NLS-1$ - quartzProps.store( System.out, "debugging" ); //$NON-NLS-1$ - } - scheduler.setQuartzSchedulerFactory( new org.quartz.impl.StdSchedulerFactory( quartzProps ) ); - if ( logger.isDebugEnabled() ) { - logger.debug( scheduler.getQuartzScheduler().getSchedulerName() ); - } - scheduler.start(); - } - } catch ( IOException ex ) { - result = false; - logger.error( Messages.getInstance().getErrorString( - "EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH" ), ex ); //$NON-NLS-1$ - } catch ( ObjectFactoryException objface ) { - logger - .error( - Messages - .getInstance() - .getErrorString( - "EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT", EmbeddedQuartzSystemListener.class.getName() ), objface ); //$NON-NLS-1$ - result = false; - } catch ( DBDatasourceServiceException dse ) { - logger - .error( - Messages - .getInstance() - .getErrorString( - "EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE", EmbeddedQuartzSystemListener.class.getName() ), dse ); //$NON-NLS-1$ - result = false; - } catch ( SQLException sqle ) { - logger.error( "EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR", sqle ); //$NON-NLS-1$ - result = false; - } catch ( SchedulerException e ) { - logger - .error( - Messages - .getInstance() - .getErrorString( - "EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized", EmbeddedQuartzSystemListener.class.getName() ), e ); //$NON-NLS-1$ - result = false; - } catch ( org.pentaho.platform.api.scheduler2.SchedulerException e ) { - logger - .error( - Messages - .getInstance() - .getErrorString( - "EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized", EmbeddedQuartzSystemListener.class.getName() ), e ); //$NON-NLS-1$ - result = false; - } - return result; - } - - protected boolean verifyQuartzIsConfigured( DataSource ds ) throws SQLException { - boolean quartzIsConfigured = false; - Connection conn = ds.getConnection(); - - try { - DatabaseMetaData databaseMetaData = conn.getMetaData(); - String tableNamePattern; - if ( databaseMetaData.storesLowerCaseIdentifiers() ) { - tableNamePattern = "%qrtz%"; - } else { - tableNamePattern = "%QRTZ%"; - } - ResultSet rs = conn.getMetaData().getTables( null, null, tableNamePattern, null ); - try { - quartzIsConfigured = rs.next(); - } finally { - rs.close(); - } - if ( !quartzIsConfigured ) { - // If we're here, then tables need creating - String quartzInitializationScriptPath = - PentahoSystem.getApplicationContext() - .getSolutionPath( "system/quartz/h2-quartz-schema-updated.sql" ).replace( '\\', '/' ); - File f = new File( quartzInitializationScriptPath ); - if ( f.exists() ) { - try ( Statement stmt = conn.createStatement() ) { - // We know now that there's an initialization script - stmt.executeUpdate( "RUNSCRIPT FROM '" + quartzInitializationScriptPath + "'" ); - // Tables should now exist. - quartzIsConfigured = true; - } - } - } - } finally { - conn.close(); - } - return quartzIsConfigured; - } - - private IDBDatasourceService getQuartzDatasourceService( IPentahoSession session ) throws ObjectFactoryException { - // - // Our new datasource stuff is provided for running queries and acquiring data. It is - // NOT there for the inner workings of the platform. So, the Quartz datasource should ALWAYS - // be provided by JNDI. However, the class could be twiddled so that it will use the factory. - // - // And, since the default shipping condition should be to NOT use the factory (and force JNDI), - // I've reversed the logic in the class to have the negative condition first (the default execution - // path). - // - // Marc - BISERVER-2004 - // - if ( !useNewDatasourceService ) { - return new JndiDatasourceService(); - } else { - IDBDatasourceService datasourceService = - PentahoSystem.getObjectFactory().get( IDBDatasourceService.class, session ); - return datasourceService; - } - } - - private Properties findPropertiesInClasspath() throws IOException { - // Do my best to find the properties file... - File propFile = new File( "quartz.properties" ); //$NON-NLS-1$ - if ( !propFile.canRead() ) { - InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream( "quartz.properties" ); //$NON-NLS-1$ - if ( in != null ) { - try { - Properties props = new Properties(); - props.load( in ); - return props; - } finally { - in.close(); - } - } - return null; // Couldn't find properties file. - } else { - InputStream iStream = new BufferedInputStream( new FileInputStream( propFile ) ); - try { - Properties props = new Properties(); - props.load( iStream ); - return props; - } finally { - try { - iStream.close(); - } catch ( IOException ignored ) { - boolean ignore = true; // close quietly - } - } - } - } - - /* - * (non-Javadoc) - * - * @see org.pentaho.core.system.IPentahoSystemListener#shutdown() - */ - public void shutdown() { - try { - QuartzScheduler scheduler = (QuartzScheduler) PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.getQuartzScheduler().shutdown(); - } catch ( SchedulerException e ) { - e.printStackTrace(); - } - } - - public Properties getQuartzProperties() { - return quartzProperties; - } - - public void setQuartzProperties( Properties quartzProperties ) { - this.quartzProperties = quartzProperties; - if ( quartzProperties != null ) { - quartzPropertiesFile = null; - } - } - - public String getQuartzPropertiesFile() { - return quartzPropertiesFile; - } - - public void setQuartzPropertiesFile( String quartzPropertiesFile ) { - this.quartzPropertiesFile = quartzPropertiesFile; - if ( quartzPropertiesFile != null ) { - quartzProperties = null; - } - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzCronStringFactory.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzCronStringFactory.java deleted file mode 100644 index 5792cbd8371..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzCronStringFactory.java +++ /dev/null @@ -1,153 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import java.util.List; - -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfMonth; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeekQualifier; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -public class QuartzCronStringFactory { - public static String createCronString( ComplexJobTrigger jobTrigger ) { - StringBuffer stringBuffer = new StringBuffer(); - String secondRecurrence = getRecurrenceString( jobTrigger.getSecondRecurrences(), "*" ); //$NON-NLS-1$ - String minuteRecurrence = getRecurrenceString( jobTrigger.getMinuteRecurrences(), "*" ); //$NON-NLS-1$ - String hourlyRecurrence = getRecurrenceString( jobTrigger.getHourlyRecurrences(), "*" ); //$NON-NLS-1$ - String dayOfMonthRecurrence = getRecurrenceString( jobTrigger.getDayOfMonthRecurrences(), "*" ); //$NON-NLS-1$ - String monthlyRecurrence = getRecurrenceString( jobTrigger.getMonthlyRecurrences(), "*" ); //$NON-NLS-1$ - String dayOfWeekRecurrence = getRecurrenceString( jobTrigger.getDayOfWeekRecurrences(), "*" ); //$NON-NLS-1$ - String yearlyRecurrence = getRecurrenceString( jobTrigger.getYearlyRecurrences(), "*" ); //$NON-NLS-1$ - if ( dayOfWeekRecurrence.equals( "*" ) && dayOfMonthRecurrence.equals( "*" ) ) { //$NON-NLS-1$ //$NON-NLS-2$ - dayOfWeekRecurrence = "?"; //$NON-NLS-1$ - } else if ( !dayOfMonthRecurrence.equals( "*" ) ) { //$NON-NLS-1$ - dayOfWeekRecurrence = "?"; //$NON-NLS-1$ - } else if ( !dayOfWeekRecurrence.equals( "*" ) ) { //$NON-NLS-1$ - dayOfMonthRecurrence = "?"; //$NON-NLS-1$ - } - stringBuffer.append( secondRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( minuteRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( hourlyRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( dayOfMonthRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( monthlyRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( dayOfWeekRecurrence ); - stringBuffer.append( " " ); //$NON-NLS-1$ - stringBuffer.append( yearlyRecurrence ); - return stringBuffer.toString(); - } - - private static String getRecurrenceString( ITimeWrapper recurrences, String defaultString ) { - String aString = ""; //$NON-NLS-1$ - StringBuffer stringBuffer = new StringBuffer(); - for ( Object recurrence : recurrences.getRecurrences() ) { - if ( recurrence instanceof RecurrenceList ) { - aString = getRecurrenceString( (RecurrenceList) recurrence ); - } else if ( recurrence instanceof SequentialRecurrence ) { - aString = getRecurrenceString( (SequentialRecurrence) recurrence ); - } else if ( recurrence instanceof IncrementalRecurrence ) { - aString = getRecurrenceString( (IncrementalRecurrence) recurrence ); - } else if ( recurrence instanceof QualifiedDayOfWeek ) { - aString = getRecurrenceString( (QualifiedDayOfWeek) recurrence ); - } else if ( recurrence instanceof QualifiedDayOfMonth ) { - aString = getRecurrenceString( (QualifiedDayOfMonth) recurrence ); - } - if ( aString.length() > 0 ) { - stringBuffer.append( aString ).append( "," ); //$NON-NLS-1$ - } - } - - if ( stringBuffer.length() != 0 ) { - // Delete the last comma. - stringBuffer.deleteCharAt( stringBuffer.length() - 1 ); - } else { - stringBuffer.append( defaultString ); - } - return stringBuffer.toString(); - } - - private static String getRecurrenceString( QualifiedDayOfWeek qualifiedDayOfWeek ) { - String aString = ""; //$NON-NLS-1$ - if ( ( qualifiedDayOfWeek.getQualifier() != null ) && ( qualifiedDayOfWeek.getDayOfWeek() != null ) ) { - if ( qualifiedDayOfWeek.getQualifier() == DayOfWeekQualifier.LAST ) { - aString = Integer.toString( qualifiedDayOfWeek.getDayOfWeek().ordinal() + 1 ) + "L"; //$NON-NLS-1$ - } else { - aString = - Integer.toString( qualifiedDayOfWeek.getDayOfWeek().ordinal() + 1 ) - + "#" + ( qualifiedDayOfWeek.getQualifier().ordinal() + 1 ); //$NON-NLS-1$ - } - } - return aString; - } - - private static String getRecurrenceString( QualifiedDayOfMonth qualifiedDayOfMonth ) { - return qualifiedDayOfMonth.toString(); - } - - private static String getRecurrenceString( RecurrenceList recurrenceList ) { - StringBuffer stringBuffer = new StringBuffer(); - if ( recurrenceList.getValues().size() > 0 ) { - for ( Integer recurrence : recurrenceList.getValues() ) { - if ( recurrence != null ) { - stringBuffer.append( recurrence.toString() ).append( "," ); //$NON-NLS-1$ - } - } - } - - if ( stringBuffer.length() != 0 ) { - // Delete the last comma. - stringBuffer.deleteCharAt( stringBuffer.length() - 1 ); - } - return stringBuffer.toString(); - } - - private static String getRecurrenceString( SequentialRecurrence sequentialRecurrence ) { - String aString = ""; //$NON-NLS-1$ - if ( ( sequentialRecurrence.getFirstValue() != null ) && ( sequentialRecurrence.getLastValue() != null ) ) { - aString = sequentialRecurrence.getFirstValue().toString() + "-" + sequentialRecurrence.getLastValue(); //$NON-NLS-1$ - } else if ( sequentialRecurrence.getFirstValue() != null ) { - aString = sequentialRecurrence.getFirstValue().toString(); - } else if ( sequentialRecurrence.getLastValue() != null ) { - aString = sequentialRecurrence.getLastValue().toString(); - } - return aString; - } - - private static String getRecurrenceString( IncrementalRecurrence incrementalRecurrence ) { - String aString = ""; //$NON-NLS-1$ - if ( ( incrementalRecurrence.getStartingValue() != null ) && ( incrementalRecurrence.getIncrement() != null ) ) { - aString = incrementalRecurrence.getStartingValue() + "/" + incrementalRecurrence.getIncrement(); //$NON-NLS-1$ - } else if ( incrementalRecurrence.getStartingValue() != null ) { - aString = incrementalRecurrence.getStartingValue(); - } - return aString; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzJobKey.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzJobKey.java deleted file mode 100644 index 0ae7de361d6..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzJobKey.java +++ /dev/null @@ -1,102 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import java.text.MessageFormat; - -import org.apache.commons.lang.StringUtils; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.util.UUIDUtil; - -/** - * This class is the key by which we identify a quartz job. It provides the means to create a new key or derive a key - * from an existing job. This should be the only place in the Quartz scheduler that knows exactly how a jobId is - * constructed. - * - * @author aphillips - */ -public class QuartzJobKey { - private String userName; - private String jobName; - // BACKLOG-22942, changing timInMillis from long to randomUUID - private String randomUuid; - - /** - * Use this constructor when you wish to create a new unique job key. - * - * @param jobName - * the user-provided job name - * @param username - * the user who is executing this job - * @throws SchedulerException - */ - public QuartzJobKey( String jobName, String username ) throws SchedulerException { - if ( StringUtils.isEmpty( jobName ) ) { - throw new SchedulerException( Messages.getInstance().getErrorString( "QuartzJobKey.ERROR_0000" ) ); //$NON-NLS-1$ - } - if ( StringUtils.isEmpty( username ) ) { - throw new SchedulerException( Messages.getInstance().getErrorString( "QuartzJobKey.ERROR_0001" ) ); //$NON-NLS-1$ - } - userName = username; - this.jobName = jobName; - randomUuid = UUIDUtil.getUUIDAsString(); - } - - private QuartzJobKey() { - } - - /** - * Parses an existing jobId into a {@link QuartzJobKey} - * - * @param jobId - * an existing jobId - * @return a quartz job key - * @throws SchedulerException - */ - public static QuartzJobKey parse( String jobId ) throws SchedulerException { - String delimiter = jobId.contains( "\t" ) || jobId.isEmpty() ? "\t" : ":"; - String[] elements = jobId.split( delimiter ); //$NON-NLS-1$ - if ( elements == null || elements.length < 3 ) { - throw new SchedulerException( MessageFormat.format( Messages.getInstance().getErrorString( - "QuartzJobKey.ERROR_0002" ), jobId ) ); //$NON-NLS-1$ - } - QuartzJobKey key = new QuartzJobKey(); - key.userName = elements[0]; - key.jobName = elements[1]; - key.randomUuid = elements[2]; - - return key; - } - - public String getUserName() { - return userName; - } - - public String getJobName() { - return jobName; - } - - @Override - public String toString() { - return userName + "\t" + jobName + "\t" + randomUuid; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java deleted file mode 100644 index c762a1e72fa..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java +++ /dev/null @@ -1,939 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IJobResult; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduleSubject; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.ISchedulerListener; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.Job.JobState; -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.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfMonth; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeek; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeekQualifier; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; -import org.pentaho.platform.util.ActionUtil; -import org.quartz.Calendar; -import org.quartz.CronExpression; -import org.quartz.CronTrigger; -import org.quartz.JobDataMap; -import org.quartz.JobDetail; -import org.quartz.Scheduler; -import org.quartz.SchedulerFactory; -import org.quartz.SimpleTrigger; -import org.quartz.Trigger; -import org.quartz.impl.StdSchedulerFactory; - -import java.io.Serializable; -import java.security.Principal; -import java.text.MessageFormat; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.UUID; -import java.util.regex.Pattern; - -/** - * A Quartz implementation of {@link IScheduler} - * - * @author aphillips - */ -public class QuartzScheduler implements IScheduler { - - public static final String RESERVEDMAPKEY_ACTIONCLASS = ActionUtil.QUARTZ_ACTIONCLASS; - - public static final String RESERVEDMAPKEY_ACTIONUSER = ActionUtil.QUARTZ_ACTIONUSER; - - public static final String RESERVEDMAPKEY_ACTIONID = ActionUtil.QUARTZ_ACTIONID; - - public static final String RESERVEDMAPKEY_STREAMPROVIDER = ActionUtil.QUARTZ_STREAMPROVIDER; - - public static final String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; - - public static final String RESERVEDMAPKEY_UIPASSPARAM = ActionUtil.QUARTZ_UIPASSPARAM; - - public static final String RESERVEDMAPKEY_LINEAGE_ID = ActionUtil.QUARTZ_LINEAGE_ID; - - public static final String RESERVEDMAPKEY_RESTART_FLAG = ActionUtil.QUARTZ_RESTART_FLAG; - - public static final String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = ActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; - - public static final String RESERVEDMAPKEY_APPEND_DATE_FORMAT = ActionUtil.QUARTZ_APPEND_DATE_FORMAT; - - private static final Log logger = LogFactory.getLog( QuartzScheduler.class ); - - private SchedulerFactory quartzSchedulerFactory; - - private Scheduler quartzScheduler; - - private ArrayList listeners = new ArrayList(); - - private static final Pattern listPattern = Pattern.compile( "\\d+" ); //$NON-NLS-1$ - - private static final Pattern dayOfWeekRangePattern = Pattern.compile( ".*\\-.*" ); //$NON-NLS-1$ - - private static final Pattern sequencePattern = Pattern.compile( "\\d+\\-\\d+" ); //$NON-NLS-1$ - - private static final Pattern intervalPattern = Pattern.compile( "[\\d*]+/[\\d]+" ); //$NON-NLS-1$ - - private static final Pattern qualifiedDayPattern = Pattern.compile( "\\d+#\\d+" ); //$NON-NLS-1$ - - private static final Pattern lastDayPattern = Pattern.compile( "\\d+L" ); //$NON-NLS-1$ - - public QuartzScheduler( SchedulerFactory schedulerFactory ) { - this.quartzSchedulerFactory = schedulerFactory; - } - - public QuartzScheduler() { - this.quartzSchedulerFactory = new StdSchedulerFactory(); - } - - /** - * Overrides the default Quartz {@link SchedulerFactory}. Note: depending on the type of scheduler you are setting - * here, there may be initializing required prior to this setter being called. Only the - * {@link SchedulerFactory#getScheduler()} will be called later, so the factory set here must already be in a state - * where that invocation will be successful. - * - * @param quartzSchedulerFactory - * the quartz factory to use for generating scheduler instances - */ - public void setQuartzSchedulerFactory( SchedulerFactory quartzSchedulerFactory ) throws SchedulerException { - this.quartzSchedulerFactory = quartzSchedulerFactory; - if ( quartzScheduler != null ) { - this.shutdown(); - quartzScheduler = null; - } - } - - public Scheduler getQuartzScheduler() throws org.quartz.SchedulerException { - if ( quartzScheduler == null ) { - /* - * Currently, quartz will always give you the same scheduler object when any factory instance is asked for a - * scheduler. In other words there is no such thing as scheduler-level isolation. If we really need multiple - * isolated scheduler instances, we should investigate named schedulers, but this API getScheduler() will not help - * us in that regard. - */ - quartzScheduler = quartzSchedulerFactory.getScheduler(); - } - - logger.debug( "Using quartz scheduler " + quartzScheduler ); //$NON-NLS-1$ - return quartzScheduler; - } - - private void setQuartzScheduler( Scheduler quartzScheduler ) { - this.quartzScheduler = quartzScheduler; - } - - /** {@inheritDoc} */ - public Job createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger ) - throws SchedulerException { - return createJob( jobName, actionId, jobParams, trigger, null ); - } - - /** {@inheritDoc} */ - public Job createJob( String jobName, Class action, Map jobParams, - IJobTrigger trigger ) throws SchedulerException { - return createJob( jobName, action, jobParams, trigger, null ); - } - - /** {@inheritDoc} */ - public Job createJob( String jobName, Class action, Map jobParams, - IJobTrigger trigger, IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException { - - if ( action == null ) { - throw new SchedulerException( Messages.getInstance().getString( "QuartzScheduler.ERROR_0003_ACTION_IS_NULL" ) ); //$NON-NLS-1$ - } - - if ( jobParams == null ) { - jobParams = new HashMap(); - } - - jobParams.put( RESERVEDMAPKEY_ACTIONCLASS, action.getName() ); - Job ret = createJob( jobName, jobParams, trigger, outputStreamProvider ); - ret.setSchedulableClass( action.getName() ); - return ret; - } - - /** {@inheritDoc} */ - public Job createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger, - IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException { - if ( StringUtils.isEmpty( actionId ) ) { - throw new SchedulerException( Messages.getInstance().getString( "QuartzScheduler.ERROR_0003_ACTION_IS_NULL" ) ); //$NON-NLS-1$ - } - - if ( jobParams == null ) { - jobParams = new HashMap(); - } - - jobParams.put( RESERVEDMAPKEY_ACTIONID, actionId ); - Job ret = createJob( jobName, jobParams, trigger, outputStreamProvider ); - ret.setSchedulableClass( "" ); //$NON-NLS-1$ - return ret; - } - - public static Trigger createQuartzTrigger( IJobTrigger jobTrigger, QuartzJobKey jobId ) throws SchedulerException { - Trigger quartzTrigger = null; - if ( jobTrigger instanceof ComplexJobTrigger ) { - try { - quartzTrigger = - new CronTrigger( jobId.toString(), jobId.getUserName(), jobTrigger.getCronString() != null ? jobTrigger - .getCronString() : QuartzCronStringFactory.createCronString( (ComplexJobTrigger) jobTrigger ) ); - } catch ( ParseException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB", jobId.getJobName() ), e ); //$NON-NLS-1$ - } - } else if ( jobTrigger instanceof SimpleJobTrigger ) { - SimpleJobTrigger simpleTrigger = (SimpleJobTrigger) jobTrigger; - long interval = simpleTrigger.getRepeatInterval(); - if ( interval > 0 ) { - interval *= 1000; - } - int repeatCount = - simpleTrigger.getRepeatCount() < 0 ? SimpleTrigger.REPEAT_INDEFINITELY : simpleTrigger.getRepeatCount(); - quartzTrigger = - new SimpleTrigger( jobId.toString(), jobId.getUserName(), simpleTrigger.getStartTime(), simpleTrigger - .getEndTime(), repeatCount, interval ); - } else { - throw new SchedulerException( Messages.getInstance().getString( "QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE" ) ); //$NON-NLS-1$ - } - quartzTrigger.setMisfireInstruction( SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW ); - if ( quartzTrigger instanceof SimpleTrigger ) { - if ( ( (SimpleTrigger) quartzTrigger ).getRepeatCount() != 0 ) { - quartzTrigger.setMisfireInstruction( SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT ); - } - } - return quartzTrigger; - } - - private JobDetail createJobDetails( QuartzJobKey jobId, Map jobParams ) { - JobDetail jobDetail = new JobDetail( jobId.toString(), jobId.getUserName(), BlockingQuartzJob.class ); - jobParams.put( RESERVEDMAPKEY_ACTIONUSER, jobId.getUserName() ); - JobDataMap jobDataMap = new JobDataMap( jobParams ); - jobDetail.setJobDataMap( jobDataMap ); - return jobDetail; - } - - private Calendar createQuartzCalendar( ComplexJobTrigger complexJobTrigger ) { - Calendar triggerCalendar = null; - if ( ( complexJobTrigger.getStartTime() != null ) || ( complexJobTrigger.getEndTime() != null ) ) { - triggerCalendar = - new QuartzSchedulerAvailability( complexJobTrigger.getStartTime(), complexJobTrigger.getEndTime() ); - } - return triggerCalendar; - } - - /** {@inheritDoc} */ - protected Job createJob( String jobName, Map jobParams, IJobTrigger trigger, - IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException { - - String curUser = getCurrentUser(); - - // determine if the job params tell us who owns the job - Serializable jobOwner = jobParams.get( RESERVEDMAPKEY_ACTIONUSER ); - if ( jobOwner != null && jobOwner.toString().length() > 0 ) { - curUser = jobOwner.toString(); - } - - QuartzJobKey jobId = new QuartzJobKey( jobName, curUser ); - logger.debug( " QuartzScheduler has received a request to createJob with jobId " + jobId ); - - Trigger quartzTrigger = createQuartzTrigger( trigger, jobId ); - - if ( trigger.getEndTime() != null ) { - quartzTrigger.setEndTime( trigger.getEndTime() ); - } - - Calendar triggerCalendar = - quartzTrigger instanceof CronTrigger ? createQuartzCalendar( (ComplexJobTrigger) trigger ) : null; - - if ( outputStreamProvider != null ) { - jobParams.put( RESERVEDMAPKEY_STREAMPROVIDER, outputStreamProvider ); - } - - if ( trigger.getUiPassParam() != null ) { - jobParams.put( RESERVEDMAPKEY_UIPASSPARAM, trigger.getUiPassParam() ); - } - - if ( !jobParams.containsKey( RESERVEDMAPKEY_LINEAGE_ID ) ) { - String uuid = UUID.randomUUID().toString(); - jobParams.put( RESERVEDMAPKEY_LINEAGE_ID, uuid ); - } - - JobDetail jobDetail = createJobDetails( jobId, jobParams ); - - try { - Scheduler scheduler = getQuartzScheduler(); - if ( triggerCalendar != null ) { - scheduler.addCalendar( jobId.toString(), triggerCalendar, false, false ); - quartzTrigger.setCalendarName( jobId.toString() ); - } - logger - .debug( MessageFormat - .format( - "Scheduling job {0} with trigger {1} and job parameters [ {2} ]", jobId.toString(), trigger, prettyPrintMap( jobParams ) ) ); //$NON-NLS-1$ - - if ( quartzTrigger instanceof CronTrigger ) { - Serializable timezone = jobParams.get( "timezone" ); - if ( timezone != null ) { - setTimezone( (CronTrigger) quartzTrigger, timezone.toString() ); - } - } - - scheduler.scheduleJob( jobDetail, quartzTrigger ); - - logger.debug( MessageFormat.format( "Scheduled job {0} successfully", jobId.toString() ) ); //$NON-NLS-1$ - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB", jobName ), e ); //$NON-NLS-1$ - } - - Job job = new Job(); - job.setJobParams( jobParams ); - job.setJobTrigger( (JobTrigger) trigger ); - job.setNextRun( quartzTrigger.getNextFireTime() ); - job.setLastRun( quartzTrigger.getPreviousFireTime() ); - job.setJobId( jobId.toString() ); - job.setJobName( jobName ); - job.setUserName( curUser ); - job.setState( JobState.NORMAL ); - - return job; - } - - @Override - public void updateJob( String jobId, Map jobParams, IJobTrigger trigger ) - throws SchedulerException { - QuartzJobKey jobKey = QuartzJobKey.parse( jobId ); - - Trigger quartzTrigger = createQuartzTrigger( trigger, jobKey ); - quartzTrigger.setJobName( jobId ); - quartzTrigger.setJobGroup( jobKey.getUserName() ); - - Calendar triggerCalendar = - quartzTrigger instanceof CronTrigger ? createQuartzCalendar( (ComplexJobTrigger) trigger ) : null; - - try { - Scheduler scheduler = getQuartzScheduler(); - // int triggerState = scheduler.getTriggerState(jobId, jobKey.getUserName()); - // if (triggerState != Trigger.STATE_PAUSED) { - // scheduler.pauseTrigger(jobId, jobKey.getUserName()); - // } - JobDetail origJobDetail = scheduler.getJobDetail( jobId, jobKey.getUserName() ); - if ( origJobDetail.getJobDataMap().containsKey( RESERVEDMAPKEY_ACTIONCLASS ) ) { - jobParams.put( RESERVEDMAPKEY_ACTIONCLASS, origJobDetail.getJobDataMap().get( RESERVEDMAPKEY_ACTIONCLASS ) - .toString() ); - } else if ( origJobDetail.getJobDataMap().containsKey( RESERVEDMAPKEY_ACTIONID ) ) { - jobParams - .put( RESERVEDMAPKEY_ACTIONID, origJobDetail.getJobDataMap().get( RESERVEDMAPKEY_ACTIONID ).toString() ); - } - - if ( origJobDetail.getJobDataMap().containsKey( RESERVEDMAPKEY_STREAMPROVIDER ) ) { - jobParams.put( RESERVEDMAPKEY_STREAMPROVIDER, (Serializable) origJobDetail.getJobDataMap().get( - RESERVEDMAPKEY_STREAMPROVIDER ) ); - } - if ( origJobDetail.getJobDataMap().containsKey( RESERVEDMAPKEY_UIPASSPARAM ) ) { - jobParams.put( RESERVEDMAPKEY_UIPASSPARAM, (Serializable) origJobDetail.getJobDataMap().get( - RESERVEDMAPKEY_UIPASSPARAM ) ); - } - - JobDetail jobDetail = createJobDetails( jobKey, jobParams ); - scheduler.addJob( jobDetail, true ); - if ( triggerCalendar != null ) { - scheduler.addCalendar( jobId.toString(), triggerCalendar, true, true ); - quartzTrigger.setCalendarName( jobId.toString() ); - } - - if ( quartzTrigger instanceof CronTrigger ) { - Serializable timezone = jobParams.get( "timezone" ); - if ( timezone != null ) { - setTimezone( (CronTrigger) quartzTrigger, timezone.toString() ); - } - } - - scheduler.rescheduleJob( jobId, jobKey.getUserName(), quartzTrigger ); - // if (triggerState != Trigger.STATE_PAUSED) { - // scheduler.resumeTrigger(jobId, jobKey.getUserName()); - // } - logger - .debug( MessageFormat - .format( - "Scheduling job {0} with trigger {1} and job parameters [ {2} ]", jobId.toString(), trigger, prettyPrintMap( jobParams ) ) ); //$NON-NLS-1$ - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB", jobKey.getJobName() ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - public Map getAvailabilityWindows() { - // TODO Auto-generated method stub - return null; - } - - /** {@inheritDoc} */ - public List getJobHistory( String jobId ) { - // TODO Auto-generated method stub - return null; - } - - /** {@inheritDoc} */ - public void triggerNow( String jobId ) throws SchedulerException { - try { - QuartzJobKey jobKey = QuartzJobKey.parse( jobId ); - Scheduler scheduler = getQuartzScheduler(); - String groupName = jobKey.getUserName(); - for ( Trigger trigger : scheduler.getTriggersOfJob( jobId, groupName ) ) { - if ( "MANUAL_TRIGGER".equals( trigger.getGroup() ) ) { - continue; - } - if ( trigger instanceof SimpleTrigger ) { - ( (SimpleTrigger) trigger ).setPreviousFireTime( new Date() ); - } else if ( trigger instanceof CronTrigger ) { - ( (CronTrigger) trigger ).setPreviousFireTime( new Date() ); - } - // force the trigger to be updated with the previous fire time - scheduler.rescheduleJob( jobId, jobKey.getUserName(), trigger ); - } - - scheduler.triggerJob( jobId, jobKey.getUserName() ); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB", jobId ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - @SuppressWarnings( "unchecked" ) - public Job getJob( String jobId ) throws SchedulerException { - try { - Scheduler scheduler = getQuartzScheduler(); - QuartzJobKey jobKey = QuartzJobKey.parse( jobId ); - String groupName = jobKey.getUserName(); - for ( Trigger trigger : scheduler.getTriggersOfJob( jobId, groupName ) ) { - Job job = new Job(); - JobDetail jobDetail = scheduler.getJobDetail( jobId, groupName ); - if ( jobDetail != null ) { - JobDataMap jobDataMap = jobDetail.getJobDataMap(); - if ( jobDataMap != null ) { - Map wrappedMap = jobDataMap.getWrappedMap(); - job.setJobParams( wrappedMap ); - } - } - - job.setJobId( jobId ); - setJobTrigger( scheduler, job, trigger ); - job.setUserName( jobDetail.getGroup() ); - return job; - } - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB", jobId ), e ); //$NON-NLS-1$ - } - return null; - } - - /** {@inheritDoc} */ - @SuppressWarnings( "unchecked" ) - public List getJobs( IJobFilter filter ) throws SchedulerException { - ArrayList jobs = new ArrayList(); - try { - Scheduler scheduler = getQuartzScheduler(); - for ( String groupName : scheduler.getJobGroupNames() ) { - for ( String jobId : scheduler.getJobNames( groupName ) ) { - for ( Trigger trigger : scheduler.getTriggersOfJob( jobId, groupName ) ) { - if ( "MANUAL_TRIGGER".equals( trigger.getGroup() ) ) { - continue; - } - Job job = new Job(); - job.setGroupName( groupName ); - JobDetail jobDetail = scheduler.getJobDetail( jobId, groupName ); - if ( jobDetail != null ) { - job.setUserName( jobDetail.getGroup() ); - JobDataMap jobDataMap = jobDetail.getJobDataMap(); - if ( jobDataMap != null ) { - Map wrappedMap = jobDataMap.getWrappedMap(); - job.setJobParams( wrappedMap ); - } - } - - job.setJobId( jobId ); - setJobTrigger( scheduler, job, trigger ); - job.setJobName( QuartzJobKey.parse( jobId ).getJobName() ); - setJobNextRun( job, trigger ); - job.setLastRun( trigger.getPreviousFireTime() ); - if ( ( filter == null ) || filter.accept( job ) ) { - jobs.add( job ); - } - } - } - } - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( - Messages.getInstance().getString( "QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS" ), e ); //$NON-NLS-1$ - } - return jobs; - } - - protected void setJobNextRun( Job job, Trigger trigger ) { - //if getNextFireTime() is in the future, then we use it - //if it is in past, we call getFireTimeAfter( new Date() ) to get the correct next date from today on - Date nextFire = trigger.getNextFireTime(); - job.setNextRun( nextFire != null && ( nextFire.getTime() < new Date().getTime() ) - ? trigger.getFireTimeAfter( new Date() ) - : nextFire ); - } - - private void setJobTrigger( Scheduler scheduler, Job job, Trigger trigger ) throws SchedulerException, - org.quartz.SchedulerException { - QuartzJobKey jobKey = QuartzJobKey.parse( job.getJobId() ); - String groupName = jobKey.getUserName(); - - if ( trigger instanceof SimpleTrigger ) { - SimpleTrigger simpleTrigger = (SimpleTrigger) trigger; - SimpleJobTrigger simpleJobTrigger = new SimpleJobTrigger(); - simpleJobTrigger.setStartTime( simpleTrigger.getStartTime() ); - simpleJobTrigger.setEndTime( simpleTrigger.getEndTime() ); - simpleJobTrigger.setUiPassParam( (String) job.getJobParams().get( RESERVEDMAPKEY_UIPASSPARAM ) ); - long interval = simpleTrigger.getRepeatInterval(); - if ( interval > 0 ) { - interval /= 1000; - } - simpleJobTrigger.setRepeatInterval( interval ); - simpleJobTrigger.setRepeatCount( simpleTrigger.getRepeatCount() ); - job.setJobTrigger( simpleJobTrigger ); - } else if ( trigger instanceof CronTrigger ) { - CronTrigger cronTrigger = (CronTrigger) trigger; - ComplexJobTrigger complexJobTrigger = createComplexTrigger( cronTrigger.getCronExpression() ); - complexJobTrigger.setUiPassParam( (String) job.getJobParams().get( RESERVEDMAPKEY_UIPASSPARAM ) ); - complexJobTrigger.setCronString( ( (CronTrigger) trigger ).getCronExpression() ); - List timeRecurrences = parseRecurrence(complexJobTrigger.getCronString(), 3); - if(timeRecurrences != null && timeRecurrences.size() > 0 ) { - ITimeRecurrence recurrence = timeRecurrences.get(0); - if( recurrence instanceof IncrementalRecurrence ) { - IncrementalRecurrence incrementalRecurrence = (IncrementalRecurrence) recurrence; - complexJobTrigger.setRepeatInterval(incrementalRecurrence.getIncrement() * 86400); - } - } - job.setJobTrigger( complexJobTrigger ); - if ( trigger.getCalendarName() != null ) { - Calendar calendar = scheduler.getCalendar( trigger.getCalendarName() ); - if ( calendar instanceof QuartzSchedulerAvailability ) { - QuartzSchedulerAvailability quartzSchedulerAvailability = (QuartzSchedulerAvailability) calendar; - complexJobTrigger.setStartTime( quartzSchedulerAvailability.getStartTime() ); - complexJobTrigger.setEndTime( quartzSchedulerAvailability.getEndTime() ); - } - } - complexJobTrigger.setCronString( ( (CronTrigger) trigger ).getCronExpression() ); - } - - int triggerState = scheduler.getTriggerState( job.getJobId(), groupName ); - switch ( triggerState ) { - case Trigger.STATE_NORMAL: - job.setState( JobState.NORMAL ); - break; - case Trigger.STATE_BLOCKED: - job.setState( JobState.BLOCKED ); - break; - case Trigger.STATE_COMPLETE: - job.setState( JobState.COMPLETE ); - break; - case Trigger.STATE_ERROR: - job.setState( JobState.ERROR ); - break; - case Trigger.STATE_PAUSED: - job.setState( JobState.PAUSED ); - break; - default: - job.setState( JobState.UNKNOWN ); - break; - } - - job.setJobName( QuartzJobKey.parse( job.getJobId() ).getJobName() ); - job.setNextRun( trigger.getNextFireTime() ); - job.setLastRun( trigger.getPreviousFireTime() ); - - } - - /** {@inheritDoc} */ - public Integer getMinScheduleInterval( IScheduleSubject subject ) { - // TODO Auto-generated method stub - return 0; - } - - /** {@inheritDoc} */ - public ComplexJobTrigger getSubjectAvailabilityWindow( IScheduleSubject subject ) { - // TODO Auto-generated method stub - return null; - } - - /** {@inheritDoc} */ - public void pause() throws SchedulerException { - try { - getQuartzScheduler().standby(); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( e ); - } - } - - /** {@inheritDoc} */ - public void pauseJob( String jobId ) throws SchedulerException { - try { - Scheduler scheduler = getQuartzScheduler(); - scheduler.pauseJob( jobId, QuartzJobKey.parse( jobId ).getUserName() ); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance() - .getString( "QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOBS" ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - public void removeJob( String jobId ) throws SchedulerException { - try { - Scheduler scheduler = getQuartzScheduler(); - scheduler.deleteJob( jobId, QuartzJobKey.parse( jobId ).getUserName() ); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance() - .getString( "QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOBS" ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - public void start() throws SchedulerException { - try { - getQuartzScheduler().start(); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( e ); - } - } - - /** {@inheritDoc} */ - public void resumeJob( String jobId ) throws SchedulerException { - try { - Scheduler scheduler = getQuartzScheduler(); - scheduler.resumeJob( jobId, QuartzJobKey.parse( jobId ).getUserName() ); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOBS" ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - public void setAvailabilityWindows( Map availability ) { - // TODO Auto-generated method stub - - } - - /** {@inheritDoc} */ - public void setMinScheduleInterval( IScheduleSubject subject, int intervalInSeconds ) { - // TODO Auto-generated method stub - - } - - /** {@inheritDoc} */ - public void setSubjectAvailabilityWindow( IScheduleSubject subject, ComplexJobTrigger availability ) { - // TODO Auto-generated method stub - - } - - /** - * @return - */ - protected String getCurrentUser() { - IPentahoSession session = PentahoSessionHolder.getSession(); - if ( session == null ) { - return null; - } - Principal p = SecurityHelper.getInstance().getAuthentication(); - return ( p == null ) ? null : p.getName(); - } - - public static ComplexJobTrigger createComplexTrigger( String cronExpression ) { - ComplexJobTrigger complexJobTrigger = new ComplexJobTrigger(); - complexJobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); - complexJobTrigger.setMinuteRecurrence( (ITimeRecurrence) null ); - complexJobTrigger.setSecondRecurrence( (ITimeRecurrence) null ); - - for ( ITimeRecurrence recurrence : parseRecurrence( cronExpression, 6 ) ) { - complexJobTrigger.addYearlyRecurrence( recurrence ); - } - for ( ITimeRecurrence recurrence : parseRecurrence( cronExpression, 4 ) ) { - complexJobTrigger.addMonthlyRecurrence( recurrence ); - } - List dayOfWeekRecurrences = parseDayOfWeekRecurrences( cronExpression ); - List dayOfMonthRecurrences = parseRecurrence( cronExpression, 3 ); - if ( ( dayOfWeekRecurrences.size() > 0 ) && ( dayOfMonthRecurrences.size() == 0 ) ) { - for ( ITimeRecurrence recurrence : dayOfWeekRecurrences ) { - complexJobTrigger.addDayOfWeekRecurrence( recurrence ); - } - } else if ( ( dayOfWeekRecurrences.size() == 0 ) && ( dayOfMonthRecurrences.size() > 0 ) ) { - for ( ITimeRecurrence recurrence : dayOfMonthRecurrences ) { - complexJobTrigger.addDayOfMonthRecurrence( recurrence ); - } - } - for ( ITimeRecurrence recurrence : parseRecurrence( cronExpression, 2 ) ) { - complexJobTrigger.addHourlyRecurrence( recurrence ); - } - for ( ITimeRecurrence recurrence : parseRecurrence( cronExpression, 1 ) ) { - complexJobTrigger.addMinuteRecurrence( recurrence ); - } - for ( ITimeRecurrence recurrence : parseRecurrence( cronExpression, 0 ) ) { - complexJobTrigger.addSecondRecurrence( recurrence ); - } - return complexJobTrigger; - } - - private static List parseDayOfWeekRecurrences( String cronExpression ) { - List dayOfWeekRecurrence = new ArrayList(); - String delims = "[ ]+"; //$NON-NLS-1$ - String[] tokens = cronExpression.split( delims ); - if ( tokens.length >= 6 ) { - String dayOfWeekTokens = tokens[5]; - tokens = dayOfWeekTokens.split( "," ); //$NON-NLS-1$ - if ( ( tokens.length > 1 ) || !( tokens[0].equals( "*" ) || tokens[0].equals( "?" ) ) ) { //$NON-NLS-1$ //$NON-NLS-2$ - RecurrenceList dayOfWeekList = null; - for ( String token : tokens ) { - if ( listPattern.matcher( token ).matches() ) { - if ( dayOfWeekList == null ) { - dayOfWeekList = new RecurrenceList(); - } - dayOfWeekList.getValues().add( Integer.parseInt( token ) ); - } else { - if ( dayOfWeekList != null ) { - dayOfWeekRecurrence.add( dayOfWeekList ); - dayOfWeekList = null; - } - if ( sequencePattern.matcher( token ).matches() ) { - String[] days = token.split( "-" ); //$NON-NLS-1$ - dayOfWeekRecurrence.add( new SequentialRecurrence( Integer.parseInt( days[0] ), Integer - .parseInt( days[1] ) ) ); - } else if ( intervalPattern.matcher( token ).matches() ) { - String[] days = token.split( "/" ); //$NON-NLS-1$ - dayOfWeekRecurrence.add( new IncrementalRecurrence( days[0], Integer - .parseInt( days[1] ) ) ); - } else if ( qualifiedDayPattern.matcher( token ).matches() ) { - String[] days = token.split( "#" ); //$NON-NLS-1$ - dayOfWeekRecurrence - .add( new QualifiedDayOfWeek( Integer.parseInt( days[1] ), Integer.parseInt( days[0] ) ) ); - } else if ( lastDayPattern.matcher( token ).matches() ) { - DayOfWeek dayOfWeek = - DayOfWeek.values()[( Integer.parseInt( token.substring( 0, token.length() - 1 ) ) - 1 ) % 7]; - dayOfWeekRecurrence.add( new QualifiedDayOfWeek( DayOfWeekQualifier.LAST, dayOfWeek ) ); - } else if ( dayOfWeekRangePattern.matcher( token ).matches() ) { - String[] days = token.split( "-" ); //$NON-NLS-1$ - int start = DayOfWeek.valueOf( days[0] ).ordinal(); - int finish = DayOfWeek.valueOf( days[1] ).ordinal(); - dayOfWeekRecurrence.add( new SequentialRecurrence( start, finish ) ); - } else { - dayOfWeekList = new RecurrenceList(); - dayOfWeekList.getValues().add( DayOfWeek.valueOf( token ).ordinal() ); - dayOfWeekRecurrence.add( dayOfWeekList ); - dayOfWeekList = null; - // } else { - // throw new IllegalArgumentException(Messages.getInstance().getErrorString( - // "ComplexJobTrigger.ERROR_0001_InvalidCronExpression")); //$NON-NLS-1$ - } - } - - } - if ( dayOfWeekList != null ) { - dayOfWeekRecurrence.add( dayOfWeekList ); - } - } - } else { - throw new IllegalArgumentException( Messages.getInstance().getErrorString( - "ComplexJobTrigger.ERROR_0001_InvalidCronExpression" ) ); //$NON-NLS-1$ - } - return dayOfWeekRecurrence; - } - - private static List parseRecurrence( String cronExpression, int tokenIndex ) { - List timeRecurrence = new ArrayList(); - String delims = "[ ]+"; //$NON-NLS-1$ - String[] tokens = cronExpression.split( delims ); - if ( tokens.length > tokenIndex ) { - String timeTokens = tokens[tokenIndex]; - tokens = timeTokens.split( "," ); //$NON-NLS-1$ - if ( ( tokens.length > 1 ) || !( tokens[0].equals( "*" ) || tokens[0].equals( "?" ) ) ) { //$NON-NLS-1$ //$NON-NLS-2$ - RecurrenceList timeList = null; - for ( String token : tokens ) { - if ( listPattern.matcher( token ).matches() ) { - if ( timeList == null ) { - timeList = new RecurrenceList(); - } - timeList.getValues().add( Integer.parseInt( token ) ); - } else { - if ( timeList != null ) { - timeRecurrence.add( timeList ); - timeList = null; - } - if ( sequencePattern.matcher( token ).matches() ) { - String[] days = token.split( "-" ); //$NON-NLS-1$ - timeRecurrence.add( new SequentialRecurrence( Integer.parseInt( days[0] ), - Integer.parseInt( days[ 1 ] ) ) ); - } else if ( intervalPattern.matcher( token ).matches() ) { - String[] days = token.split( "/" ); //$NON-NLS-1$ - - timeRecurrence - .add( new IncrementalRecurrence( days[ 0 ] , Integer.parseInt( days[ 1 ] ) ) ); - } else if ( "L".equalsIgnoreCase( token ) ) { - timeRecurrence.add( new QualifiedDayOfMonth() ); - } else { - throw new IllegalArgumentException( Messages.getInstance().getErrorString( - "ComplexJobTrigger.ERROR_0001_InvalidCronExpression" ) ); //$NON-NLS-1$ - } - } - - } - if ( timeList != null ) { - timeRecurrence.add( timeList ); - } - } - } else { - throw new IllegalArgumentException( Messages.getInstance().getErrorString( - "ComplexJobTrigger.ERROR_0001_InvalidCronExpression" ) ); //$NON-NLS-1$ - } - return timeRecurrence; - } - - /** - * Update cronTrigger's timezone based on the info from caller - * - * @param cronTrigger the cron trigger to update - * @param timezone the timezone to set - */ - void setTimezone( CronTrigger cronTrigger, String timezone ) throws SchedulerException { - try { - CronExpression cronEx = new CronExpression( cronTrigger.getCronExpression() ); - cronEx.setTimeZone( TimeZone.getTimeZone( timezone ) ); - cronTrigger.setCronExpression( cronEx ); - } catch ( ParseException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "ComplexJobTrigger.ERROR_0001_InvalidCronExpression" ), e ); //$NON-NLS-1$ - } - } - - /** {@inheritDoc} */ - public SchedulerStatus getStatus() throws SchedulerException { - SchedulerStatus schedulerStatus = SchedulerStatus.STOPPED; - try { - if ( getQuartzScheduler().isInStandbyMode() ) { - schedulerStatus = SchedulerStatus.PAUSED; - } else if ( getQuartzScheduler().isStarted() ) { - schedulerStatus = SchedulerStatus.RUNNING; - } - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS" ), e ); //$NON-NLS-1$ - } - return schedulerStatus; - } - - /** {@inheritDoc} */ - public void shutdown() throws SchedulerException { - try { - boolean waitForJobsToComplete = true; - getQuartzScheduler().shutdown( waitForJobsToComplete ); - setQuartzScheduler( null ); - } catch ( org.quartz.SchedulerException e ) { - throw new SchedulerException( e ); - } - } - - public static String prettyPrintMap( Map map ) { - StringBuilder b = new StringBuilder(); - for ( Map.Entry entry : map.entrySet() ) { - b.append( entry.getKey() ); - b.append( "=" ); //$NON-NLS-1$ - b.append( entry.getValue() ); - b.append( "; " ); //$NON-NLS-1$ - } - return b.toString(); - } - - public void addListener( ISchedulerListener listener ) { - listeners.add( listener ); - } - - public void setListeners( Collection listeners ) { - this.listeners.addAll( listeners ); - } - - public void fireJobCompleted( IAction actionBean, String actionUser, Map params, - IBackgroundExecutionStreamProvider streamProvider ) { - for ( ISchedulerListener listener : listeners ) { - listener.jobCompleted( actionBean, actionUser, params, streamProvider ); - } - } - - /** - * Checks if the text configuration for the input/output files is present. - * If not - silently returns. If present checks if the input file is allowed to be scheduled. - * @param jobParams scheduling job parameters - * @throws SchedulerException the configuration is recognized but the file can't be scheduled, is a folder or doesn't exist. - */ - @Override public void validateJobParams( Map jobParams ) throws SchedulerException { - final Object streamProviderObj = jobParams.get( RESERVEDMAPKEY_STREAMPROVIDER ); - if ( streamProviderObj instanceof String ) { - String inputFilePath = null; - final String inputOutputString = (String) streamProviderObj; - final String[] tokens = inputOutputString.split( ":" ); - if ( !ArrayUtils.isEmpty( tokens ) && tokens.length == 2 ) { - inputFilePath = tokens[ 0 ].split( "=" )[ 1 ].trim(); - if ( StringUtils.isNotBlank( inputFilePath ) ) { - final IUnifiedRepository repository = PentahoSystem.get( IUnifiedRepository.class ); - final RepositoryFile repositoryFile = repository.getFile( inputFilePath ); - if ( ( repositoryFile == null ) || repositoryFile.isFolder() || !repositoryFile.isSchedulable() ) { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED" ) ); - } - } - } - } - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerAvailability.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerAvailability.java deleted file mode 100644 index 24ab3126dae..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerAvailability.java +++ /dev/null @@ -1,97 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import java.util.Date; - -import org.quartz.impl.calendar.BaseCalendar; - -/** - * Implementation of a Quartz calendar. Note that unlike typical Quartz calendars in which you specify when the trigger - * is not allowed to fire, when constructing this calendar you specify when the trigger is allowed to fire. - * - * @author arodriguez - */ -public class QuartzSchedulerAvailability extends BaseCalendar { - private static final long serialVersionUID = 8419843512264409846L; - Date startTime; - Date endTime; - - /** - * Creates a quartz calender which is used to indicate when a trigger is allowed to fire. The trigger will be allowed - * to fire between the start date and end date. - * - * @param startTime - * the earliest time at which the trigger may fire. If null the trigger may fire immediately. - * @param endTime - * the last date at which the trigger may fire. If null the trigger may fire indefinitely. - */ - public QuartzSchedulerAvailability( Date startTime, Date endTime ) { - this.startTime = startTime; - this.endTime = endTime; - } - - /** {@inheritDoc} */ - public long getNextIncludedTime( long arg0 ) { - long nextIncludedDate = 0; - Date date = new Date( arg0 ); - if ( ( startTime != null ) && ( endTime != null ) ) { - if ( !date.before( startTime ) && date.before( endTime ) ) { - nextIncludedDate = arg0 + 1; - } else if ( date.before( startTime ) ) { - nextIncludedDate = startTime.getTime(); - } - } else if ( startTime != null ) { - if ( date.before( startTime ) ) { - nextIncludedDate = startTime.getTime(); - } else { - nextIncludedDate = arg0 + 1; - } - } else if ( endTime != null ) { - if ( date.before( endTime ) ) { - nextIncludedDate = arg0 + 1; - } - } - return nextIncludedDate; - } - - /** {@inheritDoc} */ - public boolean isTimeIncluded( long arg0 ) { - boolean isIncluded = false; - Date date = new Date( arg0 ); - if ( ( startTime != null ) && ( endTime != null ) ) { - isIncluded = !date.before( startTime ) && !date.after( endTime ); - } else if ( startTime != null ) { - isIncluded = !date.before( startTime ); - } else if ( endTime != null ) { - isIncluded = !date.after( endTime ); - } - return isIncluded; - } - - public Date getStartTime() { - return startTime; - } - - public Date getEndTime() { - return endTime; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/recur/ITimeRecurrence.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java similarity index 95% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/recur/ITimeRecurrence.java rename to scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java index de1b09f4b8d..819ac6d8429 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/recur/ITimeRecurrence.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.api.scheduler2.recur; +package org.pentaho.platform.scheduler2.recur; /** * A marker interface used to identify classes that can be used to specify the time (hour/minute) recurrence of job diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java index da8c93cf5f9..f6ac06d9dad 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java @@ -22,8 +22,6 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - /** * Used to specify incremental dates or times. For example an incremental recurrence with 1 as a starting value and 3 as * an increment translates to 1, 4, 7, etc. The time units may represent years, or days of month or hours, etc. The diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java index 5a8674bf3f9..60c4b36a5cf 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java @@ -22,8 +22,6 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - @XmlRootElement public class QualifiedDayOfMonth implements ITimeRecurrence { diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java index be0abbc2189..102533504fd 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java @@ -22,8 +22,6 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - @XmlRootElement public class QualifiedDayOfWeek implements ITimeRecurrence { public enum DayOfWeek { diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java index 0e5873bc53a..60c794677e5 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java @@ -26,8 +26,6 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - /** * Used to specify a list of recurrences representing dates or times. The list may represent years, or days of month or * hours, etc. The method to which this class is passed will determine the meaning of the integers within the list. diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java index 1157e2e09e4..45b0b68577f 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java @@ -22,8 +22,6 @@ import javax.xml.bind.annotation.XmlRootElement; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; - /** * Used to specify a sequence of dates or times from first value through and including the last value. The sequence may * represent years, or days of month or hours, etc. The method to which this class is passed will determine the meaning diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java index d18df257d5d..fb3a68dc532 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java @@ -20,25 +20,24 @@ package org.pentaho.platform.scheduler2.versionchecker; -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; +import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobFilter; +import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; -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.engine.core.system.PentahoSystem; import org.pentaho.platform.util.versionchecker.PentahoVersionCheckReflectHelper; +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListener { /** @@ -112,23 +111,19 @@ protected void scheduleJob( final int versionRequestFlags, final int repeatSecon Map parms = new HashMap(); parms.put( VersionCheckerAction.VERSION_REQUEST_FLAGS, new Integer( versionRequestFlags ) ); - JobTrigger trigger = new SimpleJobTrigger( new Date(), null, -1, repeatSeconds ); - scheduler.createJob( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME, VersionCheckerAction.class, parms, - trigger ); + IJobTrigger trigger = scheduler.createSimpleJobTrigger( new Date(), null, -1, repeatSeconds ); +// scheduler.createJob( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME, VersionCheckerAction.class, parms, +// trigger ); } protected void deleteJobIfNecessary() throws SchedulerException { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - IJobFilter filter = new IJobFilter() { - public boolean accept( Job job ) { - return job.getJobName().contains( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ); - } - }; + IJobFilter filter = job -> job.getJobName().contains( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ); // Like old code - remove the existing job and replace it - List matchingJobs = scheduler.getJobs( filter ); + List matchingJobs = scheduler.getJobs( filter ); if ( ( matchingJobs != null ) && ( matchingJobs.size() > 0 ) ) { - for ( Job verCkJob : matchingJobs ) { + for ( IJob verCkJob : matchingJobs ) { scheduler.removeJob( verCkJob.getJobId() ); } } diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java deleted file mode 100644 index 794a8c4810a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java +++ /dev/null @@ -1,184 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import javax.jws.WebService; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IScheduler; -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.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; - -/** - * The default implementation of the {@link ISchedulerService} which acts as a proxy to the {@link IScheduler} - * - * @author aphillips - */ -@WebService( endpointInterface = "org.pentaho.platform.scheduler2.ws.ISchedulerService", name = "Scheduler", - serviceName = "Scheduler", portName = "SchedulerPort", targetNamespace = "http://www.pentaho.org/ws/1.0" ) -public class DefaultSchedulerService implements ISchedulerService { - - private static Log logger = LogFactory.getLog( DefaultSchedulerService.class ); - - private static final String ADMIN_PERM = "org.pentaho.security.administerSecurity"; - - private String defaultActionId; // for testing only - - public void setDefaultActionId( String defaultActionId ) { - this.defaultActionId = defaultActionId; - } - - private String getDefaultActionId() { - return defaultActionId == null ? "PdiAction" : defaultActionId; //$NON-NLS-1$ - } - - /** {@inheritDoc} */ - public String createSimpleJob( String jobName, Map jobParams, SimpleJobTrigger trigger ) - throws SchedulerException { - return createJob( jobName, jobParams, trigger ); - } - - /** {@inheritDoc} */ - public String createComplexJob( String jobName, Map jobParams, ComplexJobTrigger trigger ) - throws SchedulerException { - return createJob( jobName, jobParams, trigger ); - } - - private String createJob( String jobName, Map jobParams, JobTrigger trigger ) - throws SchedulerException { - - logger.debug( "Creating job with schedule " + trigger.toString() ); //$NON-NLS-1$ - - Job job = null; - try { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - Map properJobParams = toProperMap( jobParams ); - scheduler.validateJobParams( properJobParams ); - job = scheduler.createJob( jobName, getDefaultActionId(), properJobParams, trigger ); - } catch ( SchedulerException e ) { - logger.error( e.getMessage(), e ); // temporary error logging.. this needs to become an aspect - throw e; - } - return job.getJobId(); - } - - private void updateJob( String jobId, Map jobParams, JobTrigger trigger ) - throws SchedulerException { - logger.debug( "Creating job with schedule " + trigger.toString() ); //$NON-NLS-1$ - try { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - Map properJobParams = toProperMap( jobParams ); - scheduler.updateJob( jobId, properJobParams, trigger ); - } catch ( SchedulerException e ) { - logger.error( e.getMessage(), e ); // temporary error logging.. this needs to become an aspect - throw e; - } - } - - /** {@inheritDoc} */ - public Job[] getJobs() throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - IPentahoSession session = PentahoSessionHolder.getSession(); - String principalName = session.getName(); - Boolean canAdminister = PentahoSystem.get( IAuthorizationPolicy.class ).isAllowed( ADMIN_PERM ); - - return scheduler.getJobs( job -> { - if ( canAdminister ) { - return !IBlockoutManager.BLOCK_OUT_JOB_NAME.equals( job.getJobName() ); - } - return principalName.equals( job.getUserName() ); - } ).toArray( new Job[0] ); - } - - /** {@inheritDoc} */ - public void pause() throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.pause(); - } - - /** {@inheritDoc} */ - public void pauseJob( String jobId ) throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.pauseJob( jobId ); - } - - /** {@inheritDoc} */ - public void removeJob( String jobId ) throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.removeJob( jobId ); - } - - /** {@inheritDoc} */ - public void start() throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.start(); - } - - /** {@inheritDoc} */ - public void resumeJob( String jobId ) throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - scheduler.resumeJob( jobId ); - } - - /** {@inheritDoc} */ - public int getSchedulerStatus() throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - return scheduler.getStatus().ordinal(); - } - - /** {@inheritDoc} */ - public void updateJobToUseSimpleTrigger( String jobId, Map jobParams, SimpleJobTrigger trigger ) - throws SchedulerException { - updateJob( jobId, jobParams, trigger ); - } - - /** {@inheritDoc} */ - public void updateJobToUseComplexTrigger( String jobId, Map jobParams, ComplexJobTrigger trigger ) - throws SchedulerException { - updateJob( jobId, jobParams, trigger ); - } - - private Map toProperMap( Map liteMap ) { - Map ret = new HashMap(); - for ( Map.Entry entry : liteMap.entrySet() ) { - ParamValue val = entry.getValue(); - if ( val instanceof StringParamValue ) { - ret.put( entry.getKey(), val.toString() ); - } else { - ret.put( entry.getKey(), (Serializable) val ); - } - } - return ret; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ISchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ISchedulerService.java deleted file mode 100644 index 6d79ef8222a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ISchedulerService.java +++ /dev/null @@ -1,97 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.util.Map; -import javax.jws.WebService; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; - -/** - * A service interface used for exposing scheduling capabilities as JAXWS or other endpoints. - *

- * WARNING: If you change this interface or any of the objects related to this API, you are effectively changing - * the WSDL which is generated by JAXWS from this interface. Changing the WSDL means you are changing the contract by - * which clients talk to the scheduling service. - *

- * Currently {@link SimpleJobTrigger} and {@link ComplexJobTrigger} are natively JAXB marshallable. Each trigger class - * contains JAXB annotations to allow us to use the real trigger object model and not to use a XmlJavaTypeAdapter class. - * For the {@link Job} object, we are using the {@link JobAdapter} to send the {@link Job} over the wire. We realize - * that two different approaches were taken here and perhaps a unified approach is best, but each object model was taken - * on and the best approach to JAXB compatibility assessed based on their own merits. In any case, the JAXB compliance - * unit tests in this project will provide assurance that each type transported over the WS remains functional. - * - * @author aphillips - */ -@WebService -public interface ISchedulerService { - /** @see IScheduler#createJob(String, Class, java.util.Map, org.pentaho.platform.api.scheduler2.JobTrigger) */ - public String createSimpleJob( String jobName, - @XmlJavaTypeAdapter( JobParamsAdapter.class ) Map jobParams, SimpleJobTrigger trigger ) - throws SchedulerException; - - /** @see IScheduler#createJob(String, Class, java.util.Map, org.pentaho.platform.api.scheduler2.JobTrigger) */ - public String createComplexJob( String jobName, - @XmlJavaTypeAdapter( JobParamsAdapter.class ) Map jobParams, ComplexJobTrigger trigger ) - throws SchedulerException; - - /** @see IScheduler#updateJob(String, java.util.Map, org.pentaho.platform.api.scheduler2.JobTrigger) */ - public void updateJobToUseSimpleTrigger( String jobId, - @XmlJavaTypeAdapter( JobParamsAdapter.class ) Map jobParams, SimpleJobTrigger trigger ) - throws SchedulerException; - - /** @see IScheduler#updateJob(String, java.util.Map, org.pentaho.platform.api.scheduler2.JobTrigger) */ - public void updateJobToUseComplexTrigger( String jobId, - @XmlJavaTypeAdapter( JobParamsAdapter.class ) Map jobParams, ComplexJobTrigger trigger ) - throws SchedulerException; - - /** @see IScheduler#removeJob(String) */ - public void removeJob( String jobId ) throws SchedulerException; - - /** @see IScheduler#pauseJob(String) */ - public void pauseJob( String jobId ) throws SchedulerException; - - /** @see IScheduler#resumeJob(String) */ - public void resumeJob( String jobId ) throws SchedulerException; - - /** @see IScheduler#pause() */ - public void pause() throws SchedulerException; - - /** @see IScheduler#start() */ - public void start() throws SchedulerException; - - /** @see IScheduler#getJobs(org.pentaho.platform.api.scheduler2.IJobFilter) */ - @XmlJavaTypeAdapter( JobAdapter.class ) - public Job[] getJobs() throws SchedulerException; - - /** - * Returns the scheduler status. - * - * @return the ordinal value of the current scheduler state - * @see IScheduler#getStatus() - */ - public int getSchedulerStatus() throws SchedulerException; - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JaxBSafeMap.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JaxBSafeMap.java deleted file mode 100644 index 9c9f1fecdbd..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JaxBSafeMap.java +++ /dev/null @@ -1,131 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.xml.bind.annotation.XmlRootElement; - -import org.pentaho.platform.scheduler2.messsages.Messages; - -/* - * 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 2010 - 2017 Hitachi Vantara. All rights reserved. - * - */ - -@XmlRootElement -public class JaxBSafeMap { - public List entry = new ArrayList(); - - public JaxBSafeMap( Map map ) { - for ( Map.Entry e : map.entrySet() ) { - entry.add( new JaxBSafeEntry( e ) ); - } - } - - public JaxBSafeMap() { - } - - public static class JaxBSafeEntry { - public String key; - - private StringParamValue stringValue; - - public boolean listValueIsEmptyList; - private ListParamValue listValue; - - private MapParamValue mapValue; - - public JaxBSafeEntry() { - } - - public JaxBSafeEntry( Map.Entry e ) { - key = e.getKey(); - ParamValue v = e.getValue(); - if ( v instanceof StringParamValue ) { - stringValue = (StringParamValue) v; - } else if ( v instanceof ListParamValue ) { - listValue = (ListParamValue) v; - /* - * To overcome JAXB nulling out empty lists, we set a flag here so when we read back the value on the receiving - * side we can properly construct an empty list. - */ - if ( listValue.size() == 0 ) { - listValueIsEmptyList = true; - } - } else if ( v instanceof MapParamValue ) { - mapValue = (MapParamValue) v; - } else { - throw new UnsupportedOperationException( MessageFormat.format( Messages.getInstance().getErrorString( - "JobParamsAdapter.ERROR_0001" ), v.getClass(), //$NON-NLS-1$ - this.getClass() ) ); - } - } - - /* - * See comments above regarding JAXBs faulty handling of empty lists - */ - public ListParamValue getListValue() { - if ( listValue == null && listValueIsEmptyList ) { - return new ListParamValue(); - } - if ( listValue != null ) { - return listValue; - } - return listValue; // (which is null) - } - - public void setListValue( ListParamValue v ) { - listValue = v; - } - - public StringParamValue getStringValue() { - return stringValue; - } - - public void setStringValue( StringParamValue v ) { - stringValue = v; - } - - public MapParamValue getMapValue() { - return mapValue; - } - - public void setMapValue( MapParamValue v ) { - mapValue = v; - } - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobAdapter.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobAdapter.java deleted file mode 100644 index 261463293a5..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobAdapter.java +++ /dev/null @@ -1,172 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.Job.JobState; -import org.pentaho.platform.api.scheduler2.JobTrigger; -import org.pentaho.platform.scheduler2.ws.JaxBSafeMap.JaxBSafeEntry; - -/** - * Handles the sending of {@link Job} objects over JAXWS webservices by utilizing {@link JaxbSafeJob} as a transport - * type. - * - * @author aphillips - */ -public class JobAdapter extends XmlAdapter { - - private static final Log logger = LogFactory.getLog( JobAdapter.class ); - - public JaxbSafeJob marshal( Job job ) throws Exception { - if ( job == null ) { - return null; - } - - JaxbSafeJob jaxbSafeJob = new JaxbSafeJob(); - try { - if ( !( job.getJobTrigger() instanceof JobTrigger ) ) { - throw new IllegalArgumentException(); - - } - jaxbSafeJob.jobTrigger = job.getJobTrigger(); - jaxbSafeJob.jobParams = new JaxBSafeMap( toParamValueMap( job.getJobParams() ) ); - jaxbSafeJob.lastRun = job.getLastRun(); - jaxbSafeJob.nextRun = job.getNextRun(); - jaxbSafeJob.schedulableClass = job.getSchedulableClass(); - jaxbSafeJob.jobId = job.getJobId(); - jaxbSafeJob.userName = job.getUserName(); - jaxbSafeJob.jobName = job.getJobName(); - jaxbSafeJob.state = job.getState(); - } catch ( Throwable t ) { - // no message bundle since this is a development error case - logger.error( "Error marshalling job", t ); //$NON-NLS-1$ - return null; - } - return jaxbSafeJob; - } - - @SuppressWarnings( "unchecked" ) - private Map toParamValueMap( Map unsafeMap ) { - Map paramValueMap = new HashMap(); - for ( Map.Entry entry : unsafeMap.entrySet() ) { - if ( entry.getValue() instanceof Map ) { - // convert the inner map - MapParamValue map = new MapParamValue(); - Map innerMap = (Map) entry.getValue(); - Set entrySet = innerMap.entrySet(); - for ( Map.Entry innerEntry : entrySet ) { - map.put( innerEntry.getKey().toString(), ( innerEntry.getValue() == null ) ? null : innerEntry.getValue() - .toString() ); - } - // add the converted map the the top-level map - paramValueMap.put( entry.getKey(), map ); - } else if ( entry.getValue() instanceof List ) { - ListParamValue list = new ListParamValue(); - List innerList = (List) entry.getValue(); - list.addAll( innerList ); - paramValueMap.put( entry.getKey(), list ); - } else { - paramValueMap.put( entry.getKey(), new StringParamValue( ( entry.getValue() == null ) ? null : entry.getValue() - .toString() ) ); - } - } - return paramValueMap; - } - - private Map toProperMap( JaxBSafeMap safeMap ) { - Map unsafeMap = new HashMap(); - for ( JaxBSafeEntry safeEntry : safeMap.entry ) { - if ( safeEntry.getStringValue() != null ) { - unsafeMap.put( safeEntry.key, ( safeEntry.getStringValue() == null ) ? null : safeEntry.getStringValue() - .toString() ); - continue; - } - if ( safeEntry.getListValue() != null ) { - unsafeMap.put( safeEntry.key, safeEntry.getListValue() ); - continue; - } - if ( safeEntry.getMapValue() != null ) { - unsafeMap.put( safeEntry.key, safeEntry.getMapValue() ); - continue; - } - } - return unsafeMap; - } - - public Job unmarshal( JaxbSafeJob jaxbSafeJob ) throws Exception { - if ( jaxbSafeJob == null ) { - return null; - } - - Job job = new Job(); - try { - job.setJobTrigger( jaxbSafeJob.jobTrigger ); - job.setJobParams( toProperMap( jaxbSafeJob.jobParams ) ); - job.setLastRun( jaxbSafeJob.lastRun ); - job.setNextRun( jaxbSafeJob.nextRun ); - job.setSchedulableClass( jaxbSafeJob.schedulableClass ); - job.setJobId( jaxbSafeJob.jobId ); - job.setUserName( jaxbSafeJob.userName ); - job.setJobName( jaxbSafeJob.jobName ); - job.setState( jaxbSafeJob.state ); - } catch ( Throwable t ) { - // no message bundle since this is a development error case - logger.error( "Error unmarshalling job", t ); //$NON-NLS-1$ - return null; - } - return job; - - } - - @XmlRootElement - public static class JaxbSafeJob { - public JobTrigger jobTrigger; - - public JaxBSafeMap jobParams; - - public Date lastRun; - - public Date nextRun; - - public String schedulableClass; - - public String jobId; - - public String userName; - - public String jobName; - - public JobState state; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobParamsAdapter.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobParamsAdapter.java deleted file mode 100644 index 0519e2cafd8..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/JobParamsAdapter.java +++ /dev/null @@ -1,72 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.util.HashMap; -import java.util.Map; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.scheduler2.ws.JaxBSafeMap.JaxBSafeEntry; - -/** - * Converts a Map used to pass {@link ISchedulerService} job parameters to a JAXB marshallable type - * and back. See this JAXB reference - * - * @author aphillips - * - */ -public class JobParamsAdapter extends XmlAdapter> { - - private static final Log logger = LogFactory.getLog( JobParamsAdapter.class ); - - public JaxBSafeMap marshal( Map unsafeMap ) throws Exception { - try { - JaxBSafeMap safeMap = new JaxBSafeMap( unsafeMap ); - return safeMap; - } catch ( Throwable t ) { - logger.error( t ); - } - return null; - } - - public Map unmarshal( JaxBSafeMap safeMap ) throws Exception { - Map unsafeMap = null; - try { - unsafeMap = new HashMap(); - for ( JaxBSafeEntry safeEntry : safeMap.entry ) { - ParamValue v = safeEntry.getStringValue(); - if ( v == null ) { - v = safeEntry.getListValue(); - } - if ( v == null ) { - v = safeEntry.getMapValue(); - } - unsafeMap.put( safeEntry.key, v ); - } - return unsafeMap; - } catch ( Throwable t ) { - logger.error( t ); - } - return null; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ListParamValue.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ListParamValue.java deleted file mode 100644 index 0f91e3f921a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ListParamValue.java +++ /dev/null @@ -1,29 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.util.ArrayList; -import javax.xml.bind.annotation.XmlRootElement; - -@SuppressWarnings( "serial" ) -@XmlRootElement -public class ListParamValue extends ArrayList implements ParamValue { -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/MapParamValue.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/MapParamValue.java deleted file mode 100644 index 7f39fc93b99..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/MapParamValue.java +++ /dev/null @@ -1,29 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import java.util.HashMap; -import javax.xml.bind.annotation.XmlRootElement; - -@SuppressWarnings( "serial" ) -@XmlRootElement -public class MapParamValue extends HashMap implements ParamValue { -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ParamValue.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ParamValue.java deleted file mode 100644 index 3c838c62336..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/ParamValue.java +++ /dev/null @@ -1,29 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -/** - * Marker interface for legal job parameter values for use in {@link ISchedulerService} - * - * @author aphillips - */ -public interface ParamValue { -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/StringParamValue.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/StringParamValue.java deleted file mode 100644 index c2f3677de59..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/StringParamValue.java +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws; - -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class StringParamValue implements ParamValue { - private String stringValue = null; - - public StringParamValue() { - } - - public StringParamValue( String value ) { - this.stringValue = value; - } - - public void setStringValue( String value ) { - this.stringValue = value; - } - - public String getStringValue() { - return stringValue; - } - - public String toString() { - return stringValue; - } -} diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties deleted file mode 100644 index 52a96b5bfb7..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties +++ /dev/null @@ -1,46 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have been run \ - remotely: {1} - -QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing -QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing -QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=You don't have scheduling permissions for this file.\nContact your administrator for assistance. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Due to user/role changes, job "{0}" is not able to be executed by "{1}" -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} - -schedulerEmailFromName=Pentaho Scheduler -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger - -Unknown=Unknown - -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Running action "{0}" in background locally: {1} - -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} - -ActionInvoker.ERROR_0004_ACTION_FAILED=Action "{0}" failed to execute -ActionInvoker.ERROR_0005_ACTION_NULL=Action is null, cannot invoke -ActionInvoker.ERROR_0006_ACTION_NULL=Action "{0}" is not supported -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Map is null, cannot return stream provider -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Cannot get repository file "{0}": {1} diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties deleted file mode 100644 index 86c334439b8..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Ung\u00fcltiger Cron-Ausdruck. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Eigenschaft "{0}" oder "{1}" muss in der Aufgabendatenzuordnung festgesetzt werden, -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Fehler beim Erstellen einer Instanz der Aktion "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=Klasse {0} muss eine Instanz von "{1}" sein -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Aktion "{0}" als Quartz-Aufgabe ausf\u00fchren fehlgeschlagen -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status f\ufffdr Aktion "{0}" ist nicht verf\ufffdgbar; Die Aktion kann \ -# remote ausgef\ufffdhrt worden sein: {1} -# -QuartzJobKey.ERROR_0000=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, jobName nicht vorhanden -QuartzJobKey.ERROR_0001=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, Benutzername nicht vorhanden -QuartzJobKey.ERROR_0002=In jobId "{0}" fehlen Daten -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz konnte f\u00fcr Aufgabe "{0}" keinen Zeitplan festlegen -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Ausl\u00f6ser ist ein unzul\u00e4ssiger Typ -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Aktion darf nicht Null sein -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz konnte die Aufgaben nicht auflisten. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz konnte die Aufgabe nicht anhalten. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz konnte die Aufgaben nicht fortsetzen. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Quartz-Zeitplanstatus kann nicht abgerufen werden. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Aufgabe "{0}" kann nicht abgerufen werden -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Planer wurde beim Starten nicht ordnungsgem\u00e4\u00df initialisiert -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Laden von Quartz.properties von Klassenpfad fehlgeschlagen. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Instanziieren von Objekt nicht m\u00f6glich -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Datenquellobjekt nicht abrufbar -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Beim Erstellen der Quartz-Tabellen ist ein SQL-Fehler aufgetreten -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Quartz-Initialisierungsskript system/quartz/quartzinit.sql kann nicht gefunden werden -JobParamsAdapter.ERROR_0001=Typ {0} wird von {1} nicht unterst\u00fctzt -# -schedulerEmailFromName=Pentaho-Planer -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Es wurde versucht, ein IBlockOutTrigger-Objekt hinzuzuf\u00fcgen, das keine Instanz des Ausl\u00f6sers ist -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Sperre "{0}" konnte nicht gesucht werden -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Es kann kein g\u00fcltiger Wiederholungsintervall vom bereitgestellten Ausl\u00f6ser analysiert werden -# -Unknown=Unbekannt -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Sie haben keine Berechtigungen, um diese Datei zu planen.\nWenden Sie sich wegen Unterst\u00fctzung an den Administrator. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Aufgrund Benutzer- oder Rollen\u00e4nderungen kann Job {0} nicht von {1} ausgef\u00fchrt werden. -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Aktion {0} wird im Hintergrund lokal ausgef\u00fchrt: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=Ausf\u00fchren der Aktion {0} fehlgeschlagen -ActionInvoker.ERROR_0005_ACTION_NULL=Aktion ist null, Fortfahren nicht m\u00f6glich ... -ActionInvoker.ERROR_0006_ACTION_NULL=Aktion {0} wird nicht unterst\u00fctzt -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Zuordnung ist null, Stream-Anbieter kann nicht zur\u00fcckgegeben werden -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Repository-Datei {0} nicht abrufbar: {1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties deleted file mode 100644 index 41a9d7e312f..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Expression cron non valide. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=La propri\u00e9t\u00e9 {0} ou {1} doit \u00eatre d\u00e9finie dans le mappage des donn\u00e9es de t\u00e2che. -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Impossible de cr\u00e9er une instance de l'action {0}: {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=la classe {0} doit \u00eatre une instance de {1} -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u00c9chec d'ex\u00e9cution de l'action {0} en tant que t\u00e2che quartz -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=L'\ufffdtat de l'action "{0}" n'est pas disponible; L'action peut avoir \ufffdt\ufffd \ -# ex\ufffdcut\ufffde \ufffd distance: {1} -# -QuartzJobKey.ERROR_0000=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, jobName est manquant -QuartzJobKey.ERROR_0001=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, username est manquant -QuartzJobKey.ERROR_0002=Donn\u00e9es manquantes dans jobId {0}. -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=\u00c9chec de la planification de la t\u00e2che {0} par quartz -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=D\u00e9clencheur est un type non conforme -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=L'action ne peut pas \u00eatre nulle -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Impossible pour Quartz de lister les t\u00e2ches -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Impossible pour Quartz de mettre les t\u00e2ches en pause -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Impossible pour Quartz de reprendre les t\u00e2ches -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Impossible d'obtenir le statut du planificateur Quartz. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Impossible d'obtenir la t\u00e2che {0} -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Le planificateur n'a pas \u00e9t\u00e9 correctement initialis\u00e9 lors du d\u00e9marrage. -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u00c9chec du chargement de quartz.properties depuis le Classpath. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Impossible d'instancier l'objet -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Impossible d'obtenir l'objet de la source de donn\u00e9es -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Erreur SQL lors de la cr\u00e9ation des tables Quartz -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Impossible de trouver le script d'initialisation Quartz system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} non pris en charge par {1} -# -schedulerEmailFromName=Planificateur Pentaho -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Tentative d'ajout d'un objet IBlockOutTrigger qui n'est pas une instance de d\u00e9clencheur -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Impossible de localiser le blocage avec le nom : {0} -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Impossible d'analyser un intervalle de p\u00e9riodicit\u00e9 valide \u00e0 partir du d\u00e9clencheur fourni. -# -Unknown=Inconnu -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Vous n'\u00eates pas autoris\u00e9 \u00e0 planifier ce fichier.\nPour obtenir de l'aide, contactez votre administrateur. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=En raison de changements d'utilisateur/de r\u00f4le, la t\u00e2che \u00ab\u00a0{0}\u00a0\u00bb ne peut pas \u00eatre ex\u00e9cut\u00e9e par \u00ab\u00a0{1}\u00a0\u00bb -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb en arri\u00e8re-plan localement\u00a0: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=\u00c9chec de l'ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb -ActionInvoker.ERROR_0005_ACTION_NULL=L'action est nulle, impossible de l'appeler -ActionInvoker.ERROR_0006_ACTION_NULL=L'action \u00ab\u00a0{0}\u00a0\u00bb n'est pas prise en charge -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Le mappage est nul, impossible de revenir au fournisseur de flux -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Impossible d'obtenir le fichier du r\u00e9f\u00e9rentiel \u00ab\u00a0{0}\u00a0\u00bb\u00a0:{1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties deleted file mode 100644 index 7463353f5cb..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have \ -# been run remotely: {1} -# -QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing -QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing -QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} -# -schedulerEmailFromName=Pentaho\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30fc -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger -# -Unknown=Unknown -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30ea\u30f3\u30b0\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n\u7ba1\u7406\u8005\u306b\u554f\u3044\u5408\u308f\u305b\u3066\u304f\u3060\u3055\u3044\u3002 -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u30e6\u30fc\u30b6\u30fc/\u30ed\u30fc\u30eb\u306e\u5909\u66f4\u306b\u3088\u308a\u3001\u30b8\u30e7\u30d6 "{0}" \u306f "{1}" \u3067\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u3092\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u30ed\u30fc\u30ab\u30eb\u3067\u5b9f\u884c\u3057\u3066\u3044\u307e\u3059: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306e\u5b9f\u884c\u306b\u5931\u6557\u3057\u307e\u3057\u305f -ActionInvoker.ERROR_0005_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3\u304cnull\u3067\u3001\u547c\u3073\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.ERROR_0006_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093 -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u30de\u30c3\u30d7\u304cnull\u3067\u3059\u3002\u30b9\u30c8\u30ea\u30fc\u30e0\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8fd4\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u30ea\u30dd\u30b8\u30c8\u30ea\u30d5\u30a1\u30a4\u30eb "{0}" \u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093: {1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties deleted file mode 100644 index 8cd2eb3fd00..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties +++ /dev/null @@ -1,46 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=cron \u8868\u8fbe\u5f0f\u65e0\u6548\u3002 -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=\u5fc5\u987b\u5728\u4f5c\u4e1a\u6570\u636e\u6620\u5c04\u4e2d\u8bbe\u7f6e\u5c5e\u6027 "{0}" \u6216 "{1}" -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=\u521b\u5efa\u64cd\u4f5c "{0}" \u7684\u5b9e\u4f8b\u5931\u8d25\uff1a{1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=\u7c7b {0} \u5fc5\u987b\u662f "{1}" \u7684\u5b9e\u4f8b -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u4f5c\u4e3a quartz \u4f5c\u4e1a\u8fd0\u884c\u5931\u8d25 -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=\u64cd\u4f5c\u72b6\u6001 "{0}" \u4e0d\u53ef\u7528\uff1b\u8be5\u64cd\u4f5c\u53ef\u80fd\u5df2\u8fdc\u7a0b\u8fd0\u884c #\uff1a{1} -# -QuartzJobKey.ERROR_0000=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0cjobName \u4e22\u5931 -QuartzJobKey.ERROR_0001=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0c\u7528\u6237\u540d\u4e22\u5931 -QuartzJobKey.ERROR_0002=jobId "{0}" \u4e2d\u7684\u6570\u636e\u4e22\u5931\u3002 -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz \u672a\u80fd\u5b89\u6392\u4f5c\u4e1a "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=\u89e6\u53d1\u5668\u4e3a\u975e\u6cd5\u7c7b\u578b -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=\u64cd\u4f5c\u4e0d\u80fd\u4e3a\u7a7a\u503c -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz \u5217\u51fa\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz \u6682\u505c\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz \u7ee7\u7eed\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=\u65e0\u6cd5\u83b7\u53d6 Quartz \u8c03\u5ea6\u7a0b\u5e8f\u72b6\u6001\u3002 -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=\u83b7\u53d6\u4f5c\u4e1a "{0}" \u5931\u8d25 -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u60a8\u6ca1\u6709\u6b64\u6587\u4ef6\u7684\u8c03\u5ea6\u6743\u9650\u3002\n\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u4ee5\u83b7\u53d6\u5e2e\u52a9\u3002 -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u7531\u4e8e\u7528\u6237/\u89d2\u8272\u7684\u66f4\u6539\uff0c\u4f5c\u4e1a "{0}" \u4e0d\u80fd\u7531 "{1}" \u6267\u884c -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=\u5728\u542f\u52a8\u65f6\u672a\u6b63\u786e\u521d\u59cb\u5316\u8c03\u5ea6\u7a0b\u5e8f -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u4ece\u7c7b\u8def\u5f84\u52a0\u8f7d quartz.properties \u5931\u8d25\u3002 -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=\u65e0\u6cd5\u5b9e\u4f8b\u5316\u5bf9\u8c61 -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=\u65e0\u6cd5\u83b7\u53d6\u6570\u636e\u6e90\u5bf9\u8c61 -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=\u521b\u5efa Quartz \u8868\u65f6\u51fa\u73b0 SQL \u9519\u8bef -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=\u627e\u4e0d\u5230 Quartz \u521d\u59cb\u5316\u811a\u672c system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001={1} \u4e0d\u652f\u6301\u7c7b\u578b {0} -# -schedulerEmailFromName=Pentaho \u8ba1\u5212\u7a0b\u5e8f -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=\u5df2\u5c1d\u8bd5\u6dfb\u52a0\u975e\u89e6\u53d1\u5668\u5b9e\u4f8b\u7684 IBlockOutTrigger \u5bf9\u8c61 -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=\u65e0\u6cd5\u4f7f\u7528\u540d\u79f0 "{0}" \u627e\u5230\u963b\u6b62 -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=\u65e0\u6cd5\u4ece\u63d0\u4f9b\u7684\u89e6\u53d1\u5668\u89e3\u6790\u6709\u6548\u7684\u5b9a\u671f\u95f4\u9694 -# -Unknown=\u672a\u77e5 -# -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u5728\u540e\u53f0\u672c\u5730\u8fd0\u884c\u64cd\u4f5c "{0}"\uff1a{1} -# -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} -# -ActionInvoker.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u6267\u884c\u5931\u8d25 -ActionInvoker.ERROR_0005_ACTION_NULL=\u64cd\u4f5c\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8c03\u7528 -ActionInvoker.ERROR_0006_ACTION_NULL=\u4e0d\u652f\u6301\u64cd\u4f5c "{0}" -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u6620\u5c04\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8fd4\u56de\u6d41\u63d0\u4f9b\u7a0b\u5e8f -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u65e0\u6cd5\u83b7\u53d6\u5b58\u50a8\u5e93\u6587\u4ef6 "{0}"\uff1a{1} -# diff --git a/scheduler/src/test/java/org/pentaho/platform/api/scheduler2/JobParamsAdapterTest.java b/scheduler/src/test/java/org/pentaho/platform/api/scheduler2/JobParamsAdapterTest.java deleted file mode 100644 index 2422bbfd0a4..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/api/scheduler2/JobParamsAdapterTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.api.scheduler2; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class JobParamsAdapterTest { - @Test - public void testMarshal() throws Exception { - JobParamsAdapter adapter = new JobParamsAdapter(); - - Map dataMap = new HashMap(); - dataMap.put( "a", "A" ); - dataMap.put( "bb", "[B]" ); - dataMap.put( "ccc", "[C].[CCC]" ); - dataMap.put( "dddd", "[D].[DDD,ddd]" ); - dataMap.put( "eeeee", null ); - dataMap.put( null, "FFFFFF" ); - JobParams expectedJobParams = createJobParams( new JobParam[]{ - createJobParam( "a", "A" ), - createJobParam( "bb", "[B]" ), - createJobParam( "ccc", "[C].[CCC]" ), - createJobParam( "dddd", "[D].[DDD,ddd]" ) - } ); - - final JobParams resultJobParams = adapter.marshal( dataMap ); - - assertNotNull( resultJobParams ); - assertNotNull( resultJobParams.jobParams ); - java.util.Arrays.sort( resultJobParams.jobParams, new JobParamWholeComparator() ); - assertJobParamArrayEquals( "", expectedJobParams.jobParams, resultJobParams.jobParams ); - } - - @Test - public void testMarshalMultiValue() throws Exception { - JobParamsAdapter adapter = new JobParamsAdapter(); - - Map dataMap = new HashMap(); - dataMap.put( "a", "A" ); - dataMap.put( "bb", "[B]" ); - ArrayList cValue = castAsArrayList( new String[] { "[C].[CCC]", "[D].[DDD,ddd]" } ); - dataMap.put( "ccc", cValue ); - ArrayList eValue = castAsArrayList( new String[] { null, "FFFFFF" } ); - dataMap.put( "eeeee", eValue ); - JobParams expectedJobParams = createJobParams( new JobParam[]{ - createJobParam( "a", "A" ), - createJobParam( "bb", "[B]" ), - createJobParam( "ccc", "[C].[CCC]" ), - createJobParam( "ccc", "[D].[DDD,ddd]" ), - createJobParam( "eeeee", "FFFFFF" ) - } ); - - final JobParams resultJobParams = adapter.marshal( dataMap ); - - assertNotNull( resultJobParams ); - assertNotNull( resultJobParams.jobParams ); - Arrays.sort( resultJobParams.jobParams, new JobParamWholeComparator() ); - assertJobParamArrayEquals( "", expectedJobParams.jobParams, resultJobParams.jobParams ); - } - - @Test - public void testMarshalRemovesVariableDuplicate() throws Exception { - JobParamsAdapter adapter = new JobParamsAdapter(); - - Map dataMap = new HashMap(); - HashMap variables = new HashMap<>(); - variables.put( "test1", "val1" ); - variables.put( "test2", "val2" ); - HashMap parameters = new HashMap<>(); - parameters.put( "test2", "val2Updated" ); - - dataMap.put( "variables", variables ); - dataMap.put( "parameters", parameters ); - dataMap.put( "test3", "val3" ); - - - JobParams expectedJobParams = createJobParams( new JobParam[]{ - createJobParam( "test1", "val1" ), - createJobParam( "test2", "val2Updated" ), - createJobParam( "test3", "val3" ) - } ); - - final JobParams resultJobParams = adapter.marshal( dataMap ); - - assertNotNull( resultJobParams ); - assertNotNull( resultJobParams.jobParams ); - - Arrays.sort( resultJobParams.jobParams, new JobParamWholeComparator() ); - assertJobParamArrayEquals( "", expectedJobParams.jobParams, resultJobParams.jobParams ); - } - - private void assertJobParamArrayEquals( String msg, JobParam[] expected, final JobParam[] actual ) { - Assert.assertNotNull( msg + " null", actual ); - Assert.assertEquals( msg + " length", expected.length, actual.length ); - for ( int i = 0; i < expected.length; i++ ) { - assertJobParamEquals( msg + " [" + i + "]", expected[i], actual[i] ); - } - } - - private void assertJobParamEquals( String msg, final JobParam expected, final JobParam actual ) { - Assert.assertEquals( msg + " .name", expected.name, actual.name ); - Assert.assertEquals( msg + " .value", expected.value, actual.value ); - } - - @Test - public void testUnmarshal() throws Exception { - JobParamsAdapter adapter = new JobParamsAdapter(); - - Map expectedDataMap = new HashMap(); - expectedDataMap.put( "a", "A" ); - expectedDataMap.put( "bb", "[B]" ); - expectedDataMap.put( "ccc", "[C].[CCC]" ); - expectedDataMap.put( "dddd", "[D].[DDD,ddd]" ); - JobParams dataJobParams = createJobParams( new JobParam[]{ - createJobParam( "a", "A" ), - createJobParam( "bb", "[B]" ), - createJobParam( "ccc", "[C].[CCC]" ), - createJobParam( "dddd", "[D].[DDD,ddd]" ) - } ); - - Map resultMap = adapter.unmarshal( dataJobParams ); - - Assert.assertNotNull( "resultMap", resultMap ); - Assert.assertEquals( "resultMap.size", expectedDataMap.size(), resultMap.size() ); - for ( String key : expectedDataMap.keySet() ) { - assertEquals( "resultMap[" + key + "]", expectedDataMap.get( key ), resultMap.get( key ) ); - } - } - - @Test - public void testUnmarshalMultiValue() throws Exception { - JobParamsAdapter adapter = new JobParamsAdapter(); - - Map expectedDataMap = new HashMap(); - expectedDataMap.put( "a", "A" ); - expectedDataMap.put( "bb", "[B]" ); - final ArrayList cValue = castAsArrayList( new String[] { "[C].[CCC]", "[D].[DDD,ddd]" } ); - expectedDataMap.put( "ccc", cValue ); - JobParams dataJobParams = createJobParams( new JobParam[]{ - createJobParam( "a", "A" ), - createJobParam( "bb", "[B]" ), - createJobParam( "ccc", "[C].[CCC]" ), - createJobParam( "ccc", "[D].[DDD,ddd]" ) - } ); - - Map resultMap = adapter.unmarshal( dataJobParams ); - - Assert.assertNotNull( "resultMap", resultMap ); - Assert.assertEquals( "resultMap.size", expectedDataMap.size(), resultMap.size() ); - for ( String key : new String[] { "a", "bb" } ) { - assertEquals( "resultMap[" + key + "]", expectedDataMap.get( key ), resultMap.get( key ) ); - } - - String key = "ccc"; - assertTrue( "resultMap[" + key + "] is collection", resultMap.get( key ) instanceof Collection ); - Collection actualCValue = (Collection) resultMap.get( key ); - assertEquals( "resultMap[" + key + "].size", cValue.size(), actualCValue.size() ); - assertTrue( "resultMap[" + key + "] all expected values", cValue.containsAll( actualCValue ) ); - - } - - JobParam createJobParam( String n, String v ) { - JobParam r = new JobParam(); - r.name = n; - r.value = v; - return r; - } - - JobParams createJobParams( JobParam[] v ) { - JobParams r = new JobParams(); - r.jobParams = v; - return r; - } - - static class JobParamWholeComparator implements Comparator { - - @Override - public int compare( JobParam arg0, JobParam arg1 ) { - int r = arg0.name.compareTo( arg1.name ); - if ( r != 0 ) { - return r; - } - return arg0.value.compareTo( arg1.value ); - } - - } - ArrayList castAsArrayList( String[] values ) { - if ( values == null ) { - return null; - } - ArrayList list = new ArrayList( values.length ); - for ( String v: values ) { - list.add( v ); - } - return list; - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/ActionRunnerTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/ActionRunnerTest.java deleted file mode 100644 index e1b9e1526bf..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/ActionRunnerTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.action; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.pentaho.platform.api.action.ActionInvocationException; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.ISecurityHelper; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.engine.services.actions.TestVarArgsAction; -import org.pentaho.platform.scheduler2.quartz.SchedulerOutputPathResolver; -import org.pentaho.platform.util.bean.TestAction; -import org.pentaho.platform.util.messages.LocaleHelper; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.isA; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.powermock.reflect.Whitebox.setInternalState; - -@RunWith( PowerMockRunner.class ) -@PowerMockIgnore( "jdk.internal.reflect.*" ) -@PrepareForTest( PentahoSystem.class ) -public class ActionRunnerTest { - - @Test - public void testCallInvokesExecute() throws Exception { - Map paramsMap = createMapWithUserLocale(); - IAction actionBeanSpy = Mockito.spy( new TestAction() ); - ActionRunner actionRunner = new ActionRunner( actionBeanSpy, "actionUser", paramsMap, null ); - actionRunner.call(); - Mockito.verify( actionBeanSpy ).execute(); - - // Verify that, by default the isExecutionSuccessful returns true - Assert.assertTrue( actionBeanSpy.isExecutionSuccessful() ); - } - - - @Test - public void testCallWithStreamProvider() throws Exception { - Map paramsMap = createMapWithUserLocale(); - IAction actionBeanSpy = Mockito.spy( new TestAction() ); - IBackgroundExecutionStreamProvider mockStreamProvider = Mockito.mock( IBackgroundExecutionStreamProvider.class ); - InputStream mockInputStream = Mockito.mock( InputStream.class ); - OutputStream mockOutputStream = Mockito.mock( OutputStream.class ); - when( mockStreamProvider.getInputStream() ).thenReturn( mockInputStream ); - String mockOutputPath = "/someUser/someOutput"; - when( mockStreamProvider.getOutputPath() ).thenReturn( mockOutputPath ); - when( mockStreamProvider.getOutputStream() ).thenReturn( mockOutputStream ); - ISecurityHelper mockSecurityHelper = Mockito.mock( ISecurityHelper.class ); - SecurityHelper.setMockInstance( mockSecurityHelper ); - when( mockSecurityHelper.runAsUser( Mockito.anyString(), Mockito.any() ) ).thenReturn( mockOutputPath ); - PowerMockito.mockStatic( PentahoSystem.class ); - IUnifiedRepository mockRepository = Mockito.mock( IUnifiedRepository.class ); - when( PentahoSystem.get( isA( IUnifiedRepository.class.getClass() ), Mockito.any() ) ) - .thenReturn( mockRepository ); - IAuthorizationPolicy mockAuthorizationPolicy = Mockito.mock( IAuthorizationPolicy.class ); - when( PentahoSystem.get( isA( IAuthorizationPolicy.class.getClass() ), Mockito.any() ) ) - .thenReturn( mockAuthorizationPolicy ); - when( mockAuthorizationPolicy.isAllowed( SchedulerOutputPathResolver.SCHEDULER_ACTION_NAME ) ).thenReturn( true ); - String repoId = "SOME_REPO_ID"; - Map dummyMetaData = new HashMap<>(); - dummyMetaData.put( RepositoryFile.SCHEDULABLE_KEY, true ); - when( mockRepository.getFileMetadata( repoId ) ).thenReturn( dummyMetaData ); - RepositoryFile mockRepoFile = Mockito.mock( RepositoryFile.class ); - when( mockRepoFile.isFolder() ).thenReturn( true ); - when( mockRepoFile.getId() ).thenReturn( repoId ); - ActionRunner actionRunner = new ActionRunner( actionBeanSpy, "actionUser", paramsMap, mockStreamProvider ); - actionRunner.call(); - Mockito.verify( actionBeanSpy ).execute(); - } - - @Test - public void testCallWithStreamProviderAndVarargsAction() throws Exception { - Map paramsMap = createMapWithUserLocale(); - TestVarArgsAction testVarArgsAction = new TestVarArgsAction(); - IBackgroundExecutionStreamProvider mockStreamProvider = Mockito.mock( IBackgroundExecutionStreamProvider.class ); - InputStream mockInputStream = Mockito.mock( InputStream.class ); - OutputStream mockOutputStream = Mockito.mock( OutputStream.class ); - when( mockStreamProvider.getInputStream() ).thenReturn( mockInputStream ); - String mockOutputPath = "/someUser/someOutput"; - when( mockStreamProvider.getOutputPath() ).thenReturn( mockOutputPath ); - when( mockStreamProvider.getOutputStream() ).thenReturn( mockOutputStream ); - ISecurityHelper mockSecurityHelper = Mockito.mock( ISecurityHelper.class ); - SecurityHelper.setMockInstance( mockSecurityHelper ); - when( mockSecurityHelper.runAsUser( Mockito.anyString(), Mockito.any() ) ).thenReturn( mockOutputPath ); - PowerMockito.mockStatic( PentahoSystem.class ); - IUnifiedRepository mockRepository = Mockito.mock( IUnifiedRepository.class ); - when( PentahoSystem.get( isA( IUnifiedRepository.class.getClass() ), Mockito.any() ) ) - .thenReturn( mockRepository ); - IAuthorizationPolicy mockAuthorizationPolicy = Mockito.mock( IAuthorizationPolicy.class ); - when( PentahoSystem.get( isA( IAuthorizationPolicy.class.getClass() ), Mockito.any() ) ) - .thenReturn( mockAuthorizationPolicy ); - when( mockAuthorizationPolicy.isAllowed( SchedulerOutputPathResolver.SCHEDULER_ACTION_NAME ) ).thenReturn( true ); - String repoId = "SOME_REPO_ID"; - Map dummyMetaData = new HashMap<>(); - dummyMetaData.put( RepositoryFile.SCHEDULABLE_KEY, true ); - when( mockRepository.getFileMetadata( repoId ) ).thenReturn( dummyMetaData ); - RepositoryFile mockRepoFile = Mockito.mock( RepositoryFile.class ); - when( mockRepoFile.isFolder() ).thenReturn( true ); - when( mockRepoFile.getId() ).thenReturn( repoId ); - ActionRunner actionRunner = new ActionRunner( testVarArgsAction, "actionUser", paramsMap, mockStreamProvider ); - actionRunner.call(); - assertThat( testVarArgsAction.isExecuteWasCalled(), is( true ) ); - } - - @Rule - public final ExpectedException exception = ExpectedException.none(); - - @Test - public void testCallThrowsException() throws Exception { - Map paramsMap = createMapWithUserLocale(); - IAction actionBeanSpy = Mockito.spy( new TestAction() ); - IBackgroundExecutionStreamProvider mockStreamProvider = Mockito.mock( IBackgroundExecutionStreamProvider.class ); - when( mockStreamProvider.getInputStream() ).thenThrow( new Exception( "something went wrong" ) ); - ActionRunner actionRunner = new ActionRunner( actionBeanSpy, "actionUser", paramsMap, mockStreamProvider ); - exception.expect( ActionInvocationException.class ); - actionRunner.call(); - } - - private Map createMapWithUserLocale() { - Map paramsMap = new HashMap<>(); - paramsMap.put( LocaleHelper.USER_LOCALE_PARAM, Locale.US ); - return paramsMap; - } - - @Test - public void deleteFileIfEmpty() { - PowerMockito.mockStatic( PentahoSystem.class ); - IUnifiedRepository mockRepository = Mockito.mock( IUnifiedRepository.class ); - when( PentahoSystem.get( isA( IUnifiedRepository.class.getClass() ), Mockito.any() ) ) - .thenReturn( mockRepository ); - - Map paramsMap = createMapWithUserLocale(); - IAction actionBeanSpy = Mockito.spy( new TestAction() ); - ActionRunner actionRunner = new ActionRunner( actionBeanSpy, "actionUser", paramsMap, null ); - setInternalState( actionRunner, "outputFilePath", null, ActionRunner.class ); - actionRunner.deleteFileIfEmpty(); - - verify( mockRepository, times( 0 ) ).getFile( anyObject() ); - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/DefaultActionInvokerTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/DefaultActionInvokerTest.java deleted file mode 100644 index dddb9d7a5f6..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/action/DefaultActionInvokerTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.action; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.pentaho.platform.api.action.ActionInvocationException; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; -import org.pentaho.platform.util.bean.TestAction; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.reflect.Whitebox; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -@RunWith( PowerMockRunner.class ) -@PowerMockIgnore( "jdk.internal.reflect.*" ) -public class DefaultActionInvokerTest -{ - @Test - public void testGetStreamProvider() throws Exception { - final DefaultActionInvoker ai = new DefaultActionInvoker(); - final Map params = new HashMap<>(); - - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( "foo", "bar" ); - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, null ); - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, 1 ); - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, true ); - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "streamProviderFoo" ); - Assert.assertNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - - params.put( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, Mockito.mock( IBackgroundExecutionStreamProvider.class ) ); - Assert.assertNotNull( Whitebox.invokeMethod( ai,"getStreamProvider", params ) ); - } - - @Test - public void testValidate() throws Exception { - final DefaultActionInvoker ai = new DefaultActionInvoker(); - ai.validate( new TestAction(), "user", new HashMap() ); - } - - @Test( expected = ActionInvocationException.class ) - public void testValidateNullAction() throws Exception { - final DefaultActionInvoker ai = new DefaultActionInvoker(); - ai.validate( null, "user", new HashMap() ); - } - - @Test( expected = ActionInvocationException.class ) - public void testValidateNullParams() throws Exception { - final DefaultActionInvoker ai = new DefaultActionInvoker(); - ai.validate( new TestAction(), "user", null ); - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/email/MockMail.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/email/MockMail.java deleted file mode 100644 index d6c4b45614d..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/email/MockMail.java +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.email; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.URLName; -import java.util.ArrayList; - -public class MockMail extends Transport { - - private static ArrayList MESSAGES = new ArrayList<>(); - - public static void clear() { - MESSAGES = new ArrayList<>(); - } - - public static Message get( final int i ) { - return MESSAGES.get( i ); - } - - public static int size() { - return MESSAGES.size(); - } - - - public MockMail( Session session, URLName urlname ) { - super( session, urlname ); - } - - public void connect( String host, int port, String user, String password ) throws MessagingException { - } - - @Override public void sendMessage( Message message, Address[] addresses ) throws MessagingException { - MESSAGES.add( message ); - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJobTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJobTest.java deleted file mode 100644 index 978e7832b61..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/BlockingQuartzJobTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/*! - * - * 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-2020 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz; - -import static org.junit.Assert.assertEquals; - -import org.apache.commons.logging.Log; -import org.jmock.Expectations; -import org.jmock.Mockery; -import org.jmock.lib.legacy.ClassImposteriser; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.engine.core.audit.MDCUtil; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.StandaloneSession; -import org.quartz.Job; -import org.quartz.JobDetail; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.quartz.SchedulerException; - -/** - * Unit tests for BlockingQuartzJob - * - * @author kwalker - */ -public class BlockingQuartzJobTest { - private Job underlyingJob; - - private JobExecutionContext context; - - private IBlockoutManager blockoutManager; - - private Mockery mockery; - - private Log logger; - - private SchedulerException schedulerException = new SchedulerException( "something bad happened" ); - - @Before - public void setUp() throws Exception { - mockery = new Mockery() { - { - setImposteriser( ClassImposteriser.INSTANCE ); - } - }; - underlyingJob = mockery.mock( Job.class ); - context = mockery.mock( JobExecutionContext.class ); - blockoutManager = mockery.mock( IBlockoutManager.class ); - logger = mockery.mock( Log.class ); - } - - @After - public void tearDown() throws Exception { - mockery.assertIsSatisfied(); - } - - /** - * Verify that MDC context contains the sessionName, sessionId and instanceId for scheduler jobs. - * - * @throws JobExecutionException - */ - @Test - public void testMDCContext() throws JobExecutionException { - PentahoSessionHolder.setSession( new StandaloneSession( "test user", "SESSION_ID_123" ) ); - JobDetail jobDetail = new JobDetail( "myjob", BlockingQuartzJob.class ); - jobDetail.getJobDataMap().put( QuartzScheduler.RESERVEDMAPKEY_ACTIONUSER, "test user" ); - jobDetail.getJobDataMap().put( "lineage-id", "INSTANCE_ID_123" ); - - // Verify we start with empty MDC context - MDCUtil mdc = new MDCUtil(); - Assert.assertTrue( mdc.getContextMap().isEmpty() ); - - BlockingQuartzJob blockingJob = createTestBlockingJob( false ); - mockery.checking( new Expectations() { - { - one( blockoutManager ).shouldFireNow(); - will( returnValue( false ) ); - one( logger ).warn( "Job 'myjob' attempted to run during a blockout period. This job was not executed" ); - allowing( context ).getJobDetail(); - will( returnValue( jobDetail ) ); - } - } ); - blockingJob.execute( context ); - - // Verify MDC context is now populated - mdc = new MDCUtil(); - assertEquals( "SESSION_ID_123", mdc.getContextMap().get( MDCUtil.SESSION_ID ) ); - assertEquals( "INSTANCE_ID_123", mdc.getContextMap().get( MDCUtil.INSTANCE_ID ) ); - assertEquals( "test user", mdc.getContextMap().get( MDCUtil.SESSION_NAME ) ); - } - - @Test - public void testJobIsBlockedDuringABlockout() throws JobExecutionException { - BlockingQuartzJob blockingJob = createTestBlockingJob( false ); - mockery.checking( new Expectations() { - { - one( blockoutManager ).shouldFireNow(); - will( returnValue( false ) ); - one( logger ).warn( "Job 'myjob' attempted to run during a blockout period. This job was not executed" ); - allowing( context ).getJobDetail(); - will( returnValue( new JobDetail( "myjob", BlockingQuartzJob.class ) ) ); - } - } ); - blockingJob.execute( context ); - } - - @Test - public void testJobIsRunWhenNoBlockout() throws JobExecutionException { - BlockingQuartzJob blockingJob = createTestBlockingJob( false ); - try { - mockery.checking( new Expectations() { - { - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - one( blockoutManager ).shouldFireNow(); - will( returnValue( true ) ); - one( underlyingJob ).execute( with( same( context ) ) ); - } - } ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - blockingJob.execute( context ); - } - - @Test - public void testJobIsRunWhenThereIsAnExceptionRetrievingTheBlockoutManager() throws JobExecutionException { - BlockingQuartzJob blockingJob = createTestBlockingJob( true ); - mockery.checking( new Expectations() { - { - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - oneOf( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - one( underlyingJob ).execute( with( same( context ) ) ); - one( context ).getJobDetail(); - will( returnValue( new JobDetail( "somejob", BlockingQuartzJob.class ) ) ); - one( logger ).warn( "Got Exception retrieving the Blockout Manager for job 'somejob'." - + " Executing the underlying job anyway", schedulerException ); - } - } ); - blockingJob.execute( context ); - } - - private BlockingQuartzJob createTestBlockingJob( final boolean throwSchedulerException ) { - return new BlockingQuartzJob() { - @Override - Job createUnderlyingJob() { - return underlyingJob; - } - - @Override - IBlockoutManager getBlockoutManager() throws SchedulerException { - - if ( throwSchedulerException ) { - throw schedulerException; - } else { - return blockoutManager; - } - } - - @Override - Log getLogger() { - return logger; - } - - @Override - protected void makeAuditRecord( float time, String messageType, JobExecutionContext jobExecutionContext ) { - - } - }; - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerTest.java deleted file mode 100644 index 7713681de55..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/QuartzSchedulerTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/*! - * - * 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-2019 Hitachi Vantara. All rights reserved. - * - */ - - -package org.pentaho.platform.scheduler2.quartz; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.mockito.Mockito; -import static org.mockito.Matchers.any; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.quartz.CronExpression; -import org.quartz.CronTrigger; -import org.quartz.Trigger; - -import java.text.ParseException; -import java.util.Collections; -import java.util.Date; -import java.util.TimeZone; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class QuartzSchedulerTest { - - - private static IUnifiedRepository repo; - private static IUnifiedRepository oldRepo; - - - @BeforeClass - public static void setUp() throws Exception { - - oldRepo = PentahoSystem.get( IUnifiedRepository.class ); - repo = Mockito.mock( IUnifiedRepository.class ); - Mockito.when( repo.getFile( Mockito.anyString() ) ).then( new Answer() { - @Override public Object answer( InvocationOnMock invocationOnMock ) throws Throwable { - final RepositoryFile repositoryFile = Mockito.mock( RepositoryFile.class ); - final String param = (String) invocationOnMock.getArguments()[ 0 ]; - if ( "/home/admin/notexist.ktr".equals( param ) ) { - return null; - } - if ( "/home/admin".equals( param ) ) { - Mockito.when( repositoryFile.isFolder() ).thenReturn( true ); - } - if ( "/home/admin/notallowed.ktr".equals( param ) ) { - Mockito.when( repositoryFile.isFolder() ).thenReturn( false ); - Mockito.when( repositoryFile.isSchedulable() ).thenReturn( false ); - } - if ( "/home/admin/allowed.ktr".equals( param ) ) { - Mockito.when( repositoryFile.isFolder() ).thenReturn( false ); - Mockito.when( repositoryFile.isSchedulable() ).thenReturn( true ); - } - return repositoryFile; - } - } ); - PentahoSystem.registerObject( repo, IUnifiedRepository.class ); - } - - @AfterClass - public static void tearDown() throws Exception { - repo = null; - if ( oldRepo != null ) { - PentahoSystem.registerObject( oldRepo, IUnifiedRepository.class ); - } - } - - @Test - public void testValidateParamsNoStreamProviderParam() throws SchedulerException { - new QuartzScheduler().validateJobParams( Collections.emptyMap() ); - } - - @Test - public void testValidateParamsNoStringConf() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, 1L ) ); - } - - @Test - public void testValidateParamsNoInputFile() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "someinputfile" ) ); - } - - @Test( expected = SchedulerException.class ) - public void testValidateParamsFileNotFound() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, - "input = /home/admin/notexist.ktr : output = /home/admin/notexist" ) ); - } - - @Test( expected = SchedulerException.class ) - public void testValidateParamsFileIsFolder() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, - "input = /home/admin : output = /home/admin/notexist" ) ); - } - - @Test( expected = SchedulerException.class ) - public void testValidateParamsSchedulingNotAllowed() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, - "input = /home/admin/notallowed.ktr : output = /home/admin/notallowed" ) ); - } - - @Test - public void testValidateParamsSchedulingAllowed() throws SchedulerException { - new QuartzScheduler() - .validateJobParams( Collections.singletonMap( QuartzScheduler.RESERVEDMAPKEY_STREAMPROVIDER, - "input = /home/admin/allowed.ktr : output = /home/admin/allowed." ) ); - } - - @Test - public void testSetTimezone() throws Exception { - - CronTrigger cronTrigger = new CronTrigger(); - cronTrigger.setCronExpression( new CronExpression( "0 15 10 ? * 6L 2002-2018" ) ); - String currentTimezoneId = TimeZone.getDefault().getID(); - - new QuartzScheduler().setTimezone( cronTrigger, currentTimezoneId ); - - assertNotNull( cronTrigger.getTimeZone() ); - assertEquals( currentTimezoneId, cronTrigger.getTimeZone().getID() ); - } - - @Test - public void testSetJobNextRunToTheFuture() { - - Trigger trigger = Mockito.mock( Trigger.class ); - Job job = new Job(); - QuartzScheduler quartzScheduler = new QuartzScheduler(); - long nowDate = new Date().getTime(); - long futureDate = nowDate+1000000000; - - Mockito.when( trigger.getNextFireTime() ).thenReturn( new Date( futureDate ) ); - Mockito.when( trigger.getFireTimeAfter( any() ) ).thenReturn( new Date( nowDate ) ); - - quartzScheduler.setJobNextRun( job, trigger ); - - assertEquals( new Date( futureDate ), job.getNextRun() ); - } - - @Test - public void testSetJobNextRunToThePast() { - - Trigger trigger = Mockito.mock( Trigger.class ); - Job job = new Job(); - QuartzScheduler quartzScheduler = new QuartzScheduler(); - long nowDate = new Date().getTime(); - long pastDate = nowDate-1000000000; - - Mockito.when( trigger.getNextFireTime() ).thenReturn( new Date( pastDate ) ); - Mockito.when( trigger.getFireTimeAfter( any() ) ).thenReturn( new Date( nowDate ) ); - - quartzScheduler.setJobNextRun( job, trigger ); - - assertEquals( new Date( nowDate ), job.getNextRun() ); - } - - @Test - public void testSetJobNextRunToNullDate() { - - Trigger trigger = Mockito.mock( Trigger.class ); - Job job = new Job(); - QuartzScheduler quartzScheduler = new QuartzScheduler(); - long nowDate = new Date().getTime(); - - Mockito.when( trigger.getNextFireTime() ).thenReturn( null ); - Mockito.when( trigger.getFireTimeAfter( any() ) ).thenReturn( new Date( nowDate ) ); - - quartzScheduler.setJobNextRun( job, trigger ); - - assertEquals( null, job.getNextRun() ); - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/ComplexTriggerTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/ComplexTriggerTest.java deleted file mode 100644 index 805c08149bc..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/ComplexTriggerTest.java +++ /dev/null @@ -1,523 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import org.junit.Assert; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeek; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeekQualifier; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -@SuppressWarnings( "nls" ) -public class ComplexTriggerTest { - - @Test - public void timeSliceTest() { - ComplexJobTrigger trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH ); - trigger.addDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY ); - trigger.addHourlyRecurrence( 12 ); - trigger.addMinuteRecurrence( 15 ); - trigger.addSecondRecurrence( 1 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0,1 0,15 0,12 ? 3 7 2010" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH ); - trigger.setDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY ); - trigger.setHourlyRecurrence( 12 ); - trigger.setMinuteRecurrence( 15 ); - trigger.setSecondRecurrence( 1 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "1 15 12 ? 3 7 2010" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH ); - trigger.addDayOfMonthRecurrence( 10 ); - trigger.addHourlyRecurrence( 12 ); - trigger.addMinuteRecurrence( 15 ); - trigger.addSecondRecurrence( 1 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0,1 0,15 0,12 10 3 ? 2010" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH ); - trigger.setDayOfMonthRecurrence( 10 ); - trigger.setHourlyRecurrence( 12 ); - trigger.setMinuteRecurrence( 15 ); - trigger.setSecondRecurrence( 1 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "1 15 12 10 3 ? 2010" ); - - trigger = new ComplexJobTrigger( 2010, ComplexJobTrigger.MARCH, null, ComplexJobTrigger.SATURDAY, 12 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0 12 ? 3 7 2010" ); - - trigger = new ComplexJobTrigger( 2010, ComplexJobTrigger.MARCH, 10, null, 12 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0 12 10 3 ? 2010" ); - - trigger = QuartzScheduler.createComplexTrigger( "5 15 12 ? 3 7 2010" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getYearlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 2010 ) ); - - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( ComplexJobTrigger.MARCH ) ); - - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 0 ); - - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getDayOfWeekRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfWeekRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfWeekRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 7 ) ); - - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getHourlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 12 ) ); - - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMinuteRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 15 ) ); - - Assert.assertEquals( trigger.getSecondRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getSecondRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getSecondRecurrences().get( 0 ) ).getValues().size(), 1 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getSecondRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 5 ) ); - - trigger = QuartzScheduler.createComplexTrigger( "* * * * * ? *" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getSecondRecurrences().size(), 0 ); - - trigger = QuartzScheduler.createComplexTrigger( "* * * ? * * *" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 0 ); - Assert.assertEquals( trigger.getSecondRecurrences().size(), 0 ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addDayOfMonthRecurrence( 3, 10 ); - trigger.addHourlyRecurrence( 12, 15 ); - trigger.addMinuteRecurrence( 30, 45 ); - trigger.addSecondRecurrence( 1, 2 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0,1,2 0,30,45 0,12,15 3,10 3,5 ? 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.setDayOfMonthRecurrence( 3, 10 ); - trigger.setHourlyRecurrence( 12, 15 ); - trigger.setMinuteRecurrence( 30, 45 ); - trigger.setSecondRecurrence( 1, 2 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "1,2 30,45 12,15 3,10 3,5 ? 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addDayOfMonthRecurrence( 3, 10 ); - trigger.addHourlyRecurrence( 12, 15 ); - trigger.addMinuteRecurrence( 30, 45 ); - trigger.addSecondRecurrence( 1, 2 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0,1,2 0,30,45 0,12,15 3,10 3,5 ? 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.setDayOfMonthRecurrence( 3, 10 ); - trigger.setHourlyRecurrence( 12, 15 ); - trigger.setMinuteRecurrence( 30, 45 ); - trigger.setSecondRecurrence( 1, 2 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "1,2 30,45 12,15 3,10 3,5 ? 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY, ComplexJobTrigger.SUNDAY ); - trigger.addHourlyRecurrence( 12, 15 ); - trigger.addMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0,30,45 0,12,15 ? 3,5 1,7 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.setDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY, ComplexJobTrigger.SUNDAY ); - trigger.setHourlyRecurrence( 12, 15 ); - trigger.setMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 30,45 12,15 ? 3,5 1,7 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY, ComplexJobTrigger.SUNDAY ); - trigger.addHourlyRecurrence( 12, 15 ); - trigger.addMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0,30,45 0,12,15 ? 3,5 1,7 2010,2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.setDayOfWeekRecurrence( ComplexJobTrigger.SATURDAY, ComplexJobTrigger.SUNDAY ); - trigger.setHourlyRecurrence( 12, 15 ); - trigger.setMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 30,45 12,15 ? 3,5 1,7 2010,2013" ); - - trigger = QuartzScheduler.createComplexTrigger( "0 30,45 12,15 3,10 3,5 ? 2010,2013" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getYearlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 2010 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 2013 ) ); - - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( ComplexJobTrigger.MARCH ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( ComplexJobTrigger.MAY ) ); - - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getDayOfMonthRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 3 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 10 ) ); - - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 0 ); - - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getHourlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 12 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 15 ) ); - - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMinuteRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 30 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 45 ) ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( new SequentialRecurrence( 2010, 2013 ) ); - trigger.addMonthlyRecurrence( new SequentialRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ) ); - trigger.addDayOfMonthRecurrence( new SequentialRecurrence( 15, 20 ) ); - trigger.addHourlyRecurrence( new SequentialRecurrence( 12, 15 ) ); - trigger.addMinuteRecurrence( new SequentialRecurrence( 30, 45 ) ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0,30-45 0,12-15 15-20 3-5 ? 2010-2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( new SequentialRecurrence( 2010, 2013 ) ); - trigger.setMonthlyRecurrence( new SequentialRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ) ); - trigger.setDayOfMonthRecurrence( new SequentialRecurrence( 15, 20 ) ); - trigger.setHourlyRecurrence( new SequentialRecurrence( 12, 15 ) ); - trigger.setMinuteRecurrence( new SequentialRecurrence( 30, 45 ) ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 30-45 12-15 15-20 3-5 ? 2010-2013" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2011, 2012, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.APRIL, ComplexJobTrigger.MAY ); - trigger.addDayOfMonthRecurrence( 15, 16, 17, 18, 19, 20 ); - trigger.addHourlyRecurrence( 12, 13, 14, 15 ); - trigger.addMinuteRecurrence( 30, 31, 32, 33, 34, 35, 36 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0,30-36 0,12-15 15-20 3-5 ? 2010-2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2011, 2012, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.APRIL, ComplexJobTrigger.MAY ); - trigger.setDayOfMonthRecurrence( 15, 16, 17, 18, 19, 20 ); - trigger.setHourlyRecurrence( 12, 13, 14, 15 ); - trigger.setMinuteRecurrence( 30, 31, 32, 33, 34, 35, 36 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 30-36 12-15 15-20 3-5 ? 2010-2013" ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2011, 2012, 2013 ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.APRIL, ComplexJobTrigger.MAY ); - trigger.addDayOfWeekRecurrence( ComplexJobTrigger.SUNDAY, ComplexJobTrigger.MONDAY, ComplexJobTrigger.TUESDAY, - ComplexJobTrigger.WEDNESDAY, ComplexJobTrigger.THURSDAY, ComplexJobTrigger.FRIDAY, ComplexJobTrigger.SATURDAY ); - trigger.addHourlyRecurrence( 12, 13, 14, 15 ); - trigger.addMinuteRecurrence( 30, 31, 32, 33, 34, 35, 36 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0,30-36 0,12-15 ? 3-5 1-7 2010-2013" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2011, 2012, 2013 ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.APRIL, ComplexJobTrigger.MAY ); - trigger.setDayOfWeekRecurrence( ComplexJobTrigger.SUNDAY, ComplexJobTrigger.MONDAY, ComplexJobTrigger.TUESDAY, - ComplexJobTrigger.WEDNESDAY, ComplexJobTrigger.THURSDAY, ComplexJobTrigger.FRIDAY, ComplexJobTrigger.SATURDAY ); - trigger.setHourlyRecurrence( 12, 13, 14, 15 ); - trigger.setMinuteRecurrence( 30, 31, 32, 33, 34, 35, 36 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 30-36 12-15 ? 3-5 1-7 2010-2013" ); - - trigger = QuartzScheduler.createComplexTrigger( "0 30-45 12-15 ? 3-5 1-7 2010-2013" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getYearlyRecurrences().get( 0 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getYearlyRecurrences().get( 0 ) ).getFirstValue(), - new Integer( 2010 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getYearlyRecurrences().get( 0 ) ).getLastValue(), - new Integer( 2013 ) ); - - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 0 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMonthlyRecurrences().get( 0 ) ).getFirstValue(), - new Integer( ComplexJobTrigger.MARCH ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMonthlyRecurrences().get( 0 ) ).getLastValue(), - new Integer( ComplexJobTrigger.MAY ) ); - - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 0 ); - - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getDayOfWeekRecurrences().get( 0 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getDayOfWeekRecurrences().get( 0 ) ).getFirstValue(), - new Integer( ComplexJobTrigger.SUNDAY ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getDayOfWeekRecurrences().get( 0 ) ).getLastValue(), - new Integer( ComplexJobTrigger.SATURDAY ) ); - - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getHourlyRecurrences().get( 0 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getHourlyRecurrences().get( 0 ) ).getFirstValue(), - new Integer( 12 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getHourlyRecurrences().get( 0 ) ).getLastValue(), - new Integer( 15 ) ); - - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMinuteRecurrences().get( 0 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMinuteRecurrences().get( 0 ) ).getFirstValue(), - new Integer( 30 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMinuteRecurrences().get( 0 ) ).getLastValue(), - new Integer( 45 ) ); - - trigger = new ComplexJobTrigger(); - trigger.addDayOfWeekRecurrence( new QualifiedDayOfWeek( DayOfWeekQualifier.LAST, DayOfWeek.FRI ) ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0 0 ? * 6L *" ); - - trigger = new ComplexJobTrigger(); - trigger.addDayOfWeekRecurrence( new QualifiedDayOfWeek( DayOfWeekQualifier.LAST, DayOfWeek.FRI ) ); - trigger.addDayOfWeekRecurrence( new QualifiedDayOfWeek( DayOfWeekQualifier.THIRD, DayOfWeek.SUN ) ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "0 0 0 ? * 6L,1#3 *" ); - - trigger = QuartzScheduler.createComplexTrigger( "* 0 0 ? * 6L,1#3 *" ); - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 2 ); - Assert.assertTrue( trigger.getDayOfWeekRecurrences().get( 0 ) instanceof QualifiedDayOfWeek ); - Assert.assertEquals( ( (QualifiedDayOfWeek) trigger.getDayOfWeekRecurrences().get( 0 ) ).getQualifier(), - DayOfWeekQualifier.LAST ); - Assert.assertEquals( ( (QualifiedDayOfWeek) trigger.getDayOfWeekRecurrences().get( 0 ) ).getDayOfWeek(), - DayOfWeek.FRI ); - Assert.assertTrue( trigger.getDayOfWeekRecurrences().get( 1 ) instanceof QualifiedDayOfWeek ); - Assert.assertEquals( ( (QualifiedDayOfWeek) trigger.getDayOfWeekRecurrences().get( 1 ) ).getQualifier(), - DayOfWeekQualifier.THIRD ); - Assert.assertEquals( ( (QualifiedDayOfWeek) trigger.getDayOfWeekRecurrences().get( 1 ) ).getDayOfWeek(), - DayOfWeek.SUN ); - - trigger = new ComplexJobTrigger(); - trigger.addYearlyRecurrence( 2010, 2013 ); - trigger.addYearlyRecurrence( new SequentialRecurrence( 2015, 2020 ) ); - trigger.addYearlyRecurrence( new IncrementalRecurrence( 2025, 5 ) ); - trigger.addMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addMonthlyRecurrence( new SequentialRecurrence( ComplexJobTrigger.JULY, ComplexJobTrigger.SEPTEMBER ) ); - trigger.addMonthlyRecurrence( new IncrementalRecurrence( ComplexJobTrigger.JANUARY, 3 ) ); - trigger.addDayOfMonthRecurrence( 3, 10 ); - trigger.addDayOfMonthRecurrence( new SequentialRecurrence( 15, 20 ) ); - trigger.addDayOfMonthRecurrence( new IncrementalRecurrence( 21, 3 ) ); - trigger.addHourlyRecurrence( 12, 15 ); - trigger.addHourlyRecurrence( new SequentialRecurrence( 25, 30 ) ); - trigger.addHourlyRecurrence( new IncrementalRecurrence( 10, 5 ) ); - trigger.addMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), - "0 0,30,45 0,12,15,25-30,10/5 3,10,15-20,21/3 3,5,7-9,1/3 ? 2010,2013,2015-2020,2025/5" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( 2010, 2013 ); - trigger.addYearlyRecurrence( new SequentialRecurrence( 2015, 2020 ) ); - trigger.addYearlyRecurrence( new IncrementalRecurrence( 2025, 5 ) ); - trigger.setMonthlyRecurrence( ComplexJobTrigger.MARCH, ComplexJobTrigger.MAY ); - trigger.addMonthlyRecurrence( new SequentialRecurrence( ComplexJobTrigger.JULY, ComplexJobTrigger.SEPTEMBER ) ); - trigger.addMonthlyRecurrence( new IncrementalRecurrence( ComplexJobTrigger.JANUARY, 3 ) ); - trigger.setDayOfWeekRecurrence( ComplexJobTrigger.THURSDAY, ComplexJobTrigger.FRIDAY ); - trigger.addDayOfWeekRecurrence( new SequentialRecurrence( ComplexJobTrigger.SUNDAY, ComplexJobTrigger.MONDAY ) ); - trigger.setHourlyRecurrence( 12, 15 ); - trigger.addHourlyRecurrence( new SequentialRecurrence( 25, 30 ) ); - trigger.addHourlyRecurrence( new IncrementalRecurrence( 10, 5 ) ); - trigger.setMinuteRecurrence( 30, 45 ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), - "0 30,45 12,15,25-30,10/5 ? 3,5,7-9,1/3 5,6,1-2 2010,2013,2015-2020,2025/5" ); - - trigger = new ComplexJobTrigger(); - trigger.setYearlyRecurrence( new SequentialRecurrence( 2015, 2020 ) ); - trigger.setMonthlyRecurrence( new SequentialRecurrence( ComplexJobTrigger.JULY, ComplexJobTrigger.SEPTEMBER ) ); - trigger.setDayOfWeekRecurrence( new SequentialRecurrence( ComplexJobTrigger.SUNDAY, ComplexJobTrigger.MONDAY ) ); - trigger.setHourlyRecurrence( new SequentialRecurrence( 25, 30 ) ); - trigger.setMinuteRecurrence( new SequentialRecurrence( 5, 10 ) ); - trigger.setSecondRecurrence( new SequentialRecurrence( 30, 35 ) ); - System.out.println( trigger.toString() ); - Assert.assertEquals( trigger.toString(), "30-35 5-10 25-30 ? 7-9 1-2 2015-2020" ); - - trigger = - QuartzScheduler - .createComplexTrigger( "0 30,45 12,15,25-30,10/5 3,10,15-20,21/3 3,5,7-9," - + "1/3 ? 2010,2013,2015-2020,2025/5" ); - Assert.assertEquals( trigger.getYearlyRecurrences().size(), 3 ); - Assert.assertTrue( trigger.getYearlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 2010 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getYearlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 2013 ) ); - - Assert.assertTrue( trigger.getYearlyRecurrences().get( 1 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getYearlyRecurrences().get( 1 ) ).getFirstValue(), - new Integer( 2015 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getYearlyRecurrences().get( 1 ) ).getLastValue(), - new Integer( 2020 ) ); - - Assert.assertTrue( trigger.getYearlyRecurrences().get( 2 ) instanceof IncrementalRecurrence ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getYearlyRecurrences().get( 2 ) ).getStartingValue(), - - "2025" ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getYearlyRecurrences().get( 2 ) ).getIncrement(), - new Integer( 5 ) ); - - Assert.assertEquals( trigger.getMonthlyRecurrences().size(), 3 ); - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( ComplexJobTrigger.MARCH ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMonthlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( ComplexJobTrigger.MAY ) ); - - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 1 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMonthlyRecurrences().get( 1 ) ).getFirstValue(), - new Integer( ComplexJobTrigger.JULY ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getMonthlyRecurrences().get( 1 ) ).getLastValue(), - new Integer( ComplexJobTrigger.SEPTEMBER ) ); - - Assert.assertTrue( trigger.getMonthlyRecurrences().get( 2 ) instanceof IncrementalRecurrence ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getMonthlyRecurrences().get( 2 ) ).getStartingValue(), - String.valueOf(ComplexJobTrigger.JANUARY) ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getMonthlyRecurrences().get( 2 ) ).getIncrement(), - new Integer( 3 ) ); - - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 3 ); - Assert.assertTrue( trigger.getDayOfMonthRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 3 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getDayOfMonthRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 10 ) ); - - Assert.assertTrue( trigger.getDayOfMonthRecurrences().get( 1 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getDayOfMonthRecurrences().get( 1 ) ).getFirstValue(), - new Integer( 15 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getDayOfMonthRecurrences().get( 1 ) ).getLastValue(), - new Integer( 20 ) ); - - Assert.assertTrue( trigger.getDayOfMonthRecurrences().get( 2 ) instanceof IncrementalRecurrence ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getDayOfMonthRecurrences().get( 2 ) ).getStartingValue(), - "21" ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getDayOfMonthRecurrences().get( 2 ) ).getIncrement(), - new Integer( 3 ) ); - Assert.assertEquals( trigger.getDayOfMonthRecurrences().size(), 3 ); - - Assert.assertEquals( trigger.getDayOfWeekRecurrences().size(), 0 ); - - Assert.assertEquals( trigger.getHourlyRecurrences().size(), 3 ); - Assert.assertTrue( trigger.getHourlyRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 12 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getHourlyRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 15 ) ); - - Assert.assertTrue( trigger.getHourlyRecurrences().get( 1 ) instanceof SequentialRecurrence ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getHourlyRecurrences().get( 1 ) ).getFirstValue(), - new Integer( 25 ) ); - Assert.assertEquals( ( (SequentialRecurrence) trigger.getHourlyRecurrences().get( 1 ) ).getLastValue(), - new Integer( 30 ) ); - - Assert.assertTrue( trigger.getHourlyRecurrences().get( 2 ) instanceof IncrementalRecurrence ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getHourlyRecurrences().get( 2 ) ).getStartingValue(), - "10" ); - Assert.assertEquals( ( (IncrementalRecurrence) trigger.getHourlyRecurrences().get( 2 ) ).getIncrement(), - new Integer( 5 ) ); - - Assert.assertEquals( trigger.getMinuteRecurrences().size(), 1 ); - Assert.assertTrue( trigger.getMinuteRecurrences().get( 0 ) instanceof RecurrenceList ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().size(), 2 ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().get( 0 ), - new Integer( 30 ) ); - Assert.assertEquals( ( (RecurrenceList) trigger.getMinuteRecurrences().get( 0 ) ).getValues().get( 1 ), - new Integer( 45 ) ); - - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/QuartzJobKeyTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/QuartzJobKeyTest.java deleted file mode 100644 index 7a9a9207103..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/QuartzJobKeyTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import org.junit.Test; -import org.junit.Ignore; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.scheduler2.quartz.QuartzJobKey; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -import static junit.framework.Assert.assertEquals; - -@SuppressWarnings( "nls" ) -public class QuartzJobKeyTest { - - static final String TEST_USER = "testUser"; - static final String TEST_JOBNAME = "testJobName"; - - @Test - public void testHappyPathKey() throws SchedulerException { - // - // Generate a new key based on client-provided job name and username - // - QuartzJobKey key = new QuartzJobKey( TEST_JOBNAME, TEST_USER ); - assertEquals( "Quartz job group is wrong", TEST_JOBNAME, key.getJobName() ); - assertEquals( "Username is wrong", TEST_USER, key.getUserName() ); - - // - // Now parse the jobId back into the key object - // - String jobId = key.toString(); - QuartzJobKey parsedKey = QuartzJobKey.parse( jobId ); - assertEquals( "Quartz job group is wrong", TEST_JOBNAME, parsedKey.getJobName() ); - assertEquals( "Username is wrong", TEST_USER, parsedKey.getUserName() ); - } - - @Test( expected = SchedulerException.class ) - public void testKeyMissingJobName() throws SchedulerException { - new QuartzJobKey( null, TEST_USER ); - } - - @Test( expected = SchedulerException.class ) - public void testKeyMissingUsername() throws SchedulerException { - new QuartzJobKey( TEST_JOBNAME, null ); - } - - @Test( expected = SchedulerException.class ) - public void testKeyBadJobIdParse() throws SchedulerException { - QuartzJobKey.parse( "toofewelements:1234567890" ); - } - - @Test - public void testKeyWithColonValues() throws SchedulerException { - testFromId( "user", "jobName with a (:) Colon", "\t" ); - } - - @Test - public void testOldFormat() throws SchedulerException { - testFromId( "user", "jobName can't have a colon", ":" ); - } - - @Test( expected = SchedulerException.class ) - public void testKeyBadJobIdParse2() throws SchedulerException { - QuartzJobKey.parse( "" ); - } - - private void testFromId (String user, String jobName, String delimiter) throws SchedulerException { - assert(delimiter.equals("\t") || delimiter.equals( ":" )); - - // - // Generate a new key based on client-provided job name and username - // - QuartzJobKey jobKey = QuartzJobKey.parse( user + delimiter + jobName + delimiter + "1234567890" ); - assertEquals( "Incorrect User", user, jobKey.getUserName() ); - assertEquals( "Incorrect Job Name", jobName, jobKey.getJobName() ); - - // - // Now parse the jobId back into the key object (should always be tab delimited) - // - String jobId = jobKey.toString(); - assertEquals( "Incorrect Returned Job Id", user + "\t" + jobName + "\t" + "1234567890" , jobId); - } - - static class FakeJob implements Job { - - public void execute( JobExecutionContext arg0 ) throws JobExecutionException { - // TODO Auto-generated method stub - - } - - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/SimpleTriggerTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/SimpleTriggerTest.java deleted file mode 100644 index f26133eb966..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/SimpleTriggerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import java.util.Calendar; - -import org.junit.Assert; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; - -@SuppressWarnings( "nls" ) -public class SimpleTriggerTest { - - @Test - public void defaultValidTest() { - SimpleJobTrigger trigger = new SimpleJobTrigger(); - Assert.assertNull( trigger.getStartTime() ); - Assert.assertNull( trigger.getEndTime() ); - Assert.assertFalse( trigger.getRepeatCount() != 0 && trigger.getRepeatInterval() < 1 ); - } - - @Test - public void defaultParamsNoDatesTest() { - SimpleJobTrigger trigger = new SimpleJobTrigger(); - Assert.assertEquals( trigger.toString(), "repeatCount=0, repeatInterval=0, startTime=null, endTime=null" ); - } - - @Test - public void defaultParamsDatesTest() { - Calendar now = Calendar.getInstance(); - Calendar nextMonth = Calendar.getInstance(); - nextMonth.add( Calendar.MONTH, 1 ); - SimpleJobTrigger trigger = new SimpleJobTrigger( now.getTime(), nextMonth.getTime(), 1, 1000 ); - Assert.assertEquals( trigger.toString(), "repeatCount=1, repeatInterval=1000, startTime=" - + now.getTime().toString() + ", endTime=" + nextMonth.getTime().toString() ); - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserDetailsService.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserDetailsService.java deleted file mode 100644 index 6246a75bef1..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserDetailsService.java +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import org.springframework.dao.DataAccessException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - -import java.util.Arrays; - -public class StubUserDetailsService implements UserDetailsService { - - @Override - public UserDetails loadUserByUsername( String username ) throws UsernameNotFoundException, DataAccessException { - GrantedAuthority[] auths = new GrantedAuthority[2]; - auths[0] = new SimpleGrantedAuthority( "Authenticated" ); - auths[1] = new SimpleGrantedAuthority( "Administrator" ); - - UserDetails user = new User( "admin", "password", true, true, true, true, Arrays.asList( auths ) ); - - return user; - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserRoleListService.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserRoleListService.java deleted file mode 100644 index 0866ea52965..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/quartz/test/StubUserRoleListService.java +++ /dev/null @@ -1,84 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.quartz.test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.pentaho.platform.api.engine.IUserRoleListService; -import org.pentaho.platform.api.mt.ITenant; - -@SuppressWarnings( { "nls", "unchecked" } ) -public class StubUserRoleListService implements IUserRoleListService { - - public List getAllRoles() { - // TODO Auto-generated method stub - return null; - } - - public List getAllUsers() { - // TODO Auto-generated method stub - return null; - } - - public List getUsersInRole( String role ) { - // TODO Auto-generated method stub - return null; - } - - public List getRolesForUser( String userName ) { - return Arrays.asList( "FL_GATOR", "FS_SEMINOLE" ); - } - - @Override - public List getAllRoles( ITenant tenant ) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getAllUsers( ITenant tenant ) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getUsersInRole( ITenant tenant, String role ) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getRolesForUser( ITenant tenant, String username ) { - List roles = new ArrayList(); - roles.add( "Admin" ); - roles.add( "Authenticated" ); - return roles; - } - - @Override - public List getSystemRoles() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplexTriggerJAXBTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplexTriggerJAXBTest.java deleted file mode 100644 index 419eb869d2e..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplexTriggerJAXBTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import javax.xml.bind.JAXBException; - -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; -import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; -import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; - -import junit.framework.Assert; - -@SuppressWarnings( "nls" ) -public class ComplexTriggerJAXBTest { - - ComplexJobTrigger trigger; - - IncrementalRecurrence inc = new IncrementalRecurrence( "2010", 5 ); - - SequentialRecurrence seq = new SequentialRecurrence( 5, 12 ); - - QualifiedDayOfWeek qday = new QualifiedDayOfWeek( QualifiedDayOfWeek.DayOfWeekQualifier.FIFTH, - QualifiedDayOfWeek.DayOfWeek.MON ); - - Integer[] list = { 7, 11 }; - - @Before - public void init() { - trigger = new ComplexJobTrigger(); - } - - private ComplexJobTrigger process( ComplexJobTrigger t ) throws JAXBException { - return JaxBUtil.outin( t, ComplexJobTrigger.class, SequentialRecurrence.class, IncrementalRecurrence.class, - RecurrenceList.class, QualifiedDayOfWeek.class ); - } - - @Test - public void testYearlDimension() throws JAXBException { - trigger.addYearlyRecurrence( inc ); - trigger.addYearlyRecurrence( seq ); - trigger.addYearlyRecurrence( list ); - - assertRecurrencesCorrect( "YEAR", 3, process( trigger ).getYearlyRecurrences() ); - } - - @Test - public void testMonthDimension() throws JAXBException { - trigger.addMonthlyRecurrence( inc ); - trigger.addMonthlyRecurrence( seq ); - trigger.addMonthlyRecurrence( list ); - assertRecurrencesCorrect( "MONTH", 3, process( trigger ).getMonthlyRecurrences() ); - } - - @Test - public void testHourDimension() throws JAXBException { - trigger.setHourlyRecurrence( inc ); - trigger.addHourlyRecurrence( seq ); - trigger.addHourlyRecurrence( list ); - assertRecurrencesCorrect( "MINUTE", 3, process( trigger ).getHourlyRecurrences() ); - } - - @Test - public void testMinuteDimension() throws JAXBException { - trigger.setMinuteRecurrence( inc ); - trigger.addMinuteRecurrence( seq ); - trigger.addMinuteRecurrence( list ); - assertRecurrencesCorrect( "MINUTE", 3, process( trigger ).getMinuteRecurrences() ); - } - - @Test - public void testDayOfMonthDimension() throws JAXBException { - trigger.addDayOfMonthRecurrence( inc ); - trigger.addDayOfMonthRecurrence( seq ); - trigger.addDayOfMonthRecurrence( list ); - assertRecurrencesCorrect( "DAYOFMONTH", 3, process( trigger ).getDayOfMonthRecurrences() ); - } - - @Test - public void testDayOfWeekDimension() throws JAXBException { - trigger.addDayOfWeekRecurrence( qday ); - trigger.addDayOfWeekRecurrence( inc ); - trigger.addDayOfWeekRecurrence( seq ); - trigger.addDayOfWeekRecurrence( list ); - assertRecurrencesCorrect( "DAYOFWEEK", 4, process( trigger ).getDayOfWeekRecurrences() ); - } - - private void assertRecurrencesCorrect( String dimension, int expectedCount, ITimeWrapper recurrences ) { - int count = 0; - for ( ITimeRecurrence rec : recurrences.getRecurrences() ) { - if ( rec instanceof IncrementalRecurrence ) { - count++; - IncrementalRecurrence i = (IncrementalRecurrence) rec; - Assert.assertEquals( "Wrong starting value for dimension " + dimension, inc.getStartingValue(), i - .getStartingValue() ); - Assert.assertEquals( "Wrong increment for dimension " + dimension, inc.getIncrement(), i.getIncrement() ); - } - if ( rec instanceof SequentialRecurrence ) { - count++; - SequentialRecurrence s = (SequentialRecurrence) rec; - Assert.assertEquals( "Wrong first value for dimension " + dimension, seq.getFirstValue(), s.getFirstValue() ); - Assert.assertEquals( "Wrong last value for dimension " + dimension, seq.getLastValue(), s.getLastValue() ); - } - if ( rec instanceof RecurrenceList ) { - count++; - RecurrenceList l = (RecurrenceList) rec; - Assert.assertEquals( "Wrong first value for dimension " + dimension, list[0], l.getValues().get( 0 ) ); - Assert.assertEquals( "Wrong second value for dimension " + dimension, list[1], l.getValues().get( 1 ) ); - } - if ( rec instanceof QualifiedDayOfWeek ) { - count++; - QualifiedDayOfWeek q = (QualifiedDayOfWeek) rec; - Assert.assertEquals( "Wrong day of week for dimension " + dimension, qday.getDayOfWeek(), q.getDayOfWeek() ); - Assert.assertEquals( "Wrong qualifier for dimension " + dimension, qday.getQualifier(), q.getQualifier() ); - } - } - Assert.assertEquals( "A recurrence type was expected but not found", expectedCount, count ); - } - -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplianceJaxBTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplianceJaxBTest.java deleted file mode 100644 index a55bce721a2..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/ComplianceJaxBTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import java.util.Date; -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.TreeMap; -import javax.xml.bind.JAXBException; - -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; -import org.pentaho.platform.scheduler2.ws.JaxBSafeMap; -import org.pentaho.platform.scheduler2.ws.JaxBSafeMap.JaxBSafeEntry; -import org.pentaho.platform.scheduler2.ws.JobAdapter; -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 junit.framework.Assert; - -@SuppressWarnings( "nls" ) -public class ComplianceJaxBTest { - - @Test - public void testJaxbSafeMap() throws JAXBException { - HashMap params = new HashMap(); - ListParamValue listValue = new ListParamValue(); - listValue.add( "testListVal0" ); - listValue.add( "testListVal1" ); - MapParamValue mapValue = new MapParamValue(); - mapValue.put( "testMapValueKey", "testMapVal" ); - - params.put( "testStringkey", new StringParamValue( "testStringVal" ) ); - params.put( "testListKey", listValue ); - params.put( "testMapKey", mapValue ); - - // TreeMap implements java.util.SortedMap; applies a natural ordering of its keys; - Map sortedParams = new TreeMap( params ); - List paramsList = java.util.Arrays.asList( sortedParams.keySet().toArray() ); - - JaxBSafeMap map = new JaxBSafeMap( sortedParams ); - - JaxBSafeMap unmarshalled = JaxBUtil.outin( map, JaxBSafeMap.class, JaxBSafeEntry.class, StringParamValue.class ); - - Assert.assertEquals( "testStringVal", unmarshalled.entry.get( paramsList.indexOf( "testStringkey" ) ).getStringValue().toString() ); - Assert.assertEquals( "testListVal0", unmarshalled.entry.get( paramsList.indexOf( "testListKey" ) ).getListValue().get( 0 ) ); - Assert.assertEquals( "testMapVal", unmarshalled.entry.get( paramsList.indexOf( "testMapKey" ) ).getMapValue().get( "testMapValueKey" ) ); - } - - @Test - public void testParamValue() throws JAXBException { - ParamValue val = new StringParamValue( "testval" ); - - ParamValue unmarshalled = JaxBUtil.outin( val, StringParamValue.class ); - Assert.assertEquals( "testval", unmarshalled.toString() ); - } - - @Test - public void testJaxbSafeJob() throws JAXBException { - JobAdapter.JaxbSafeJob job = new JobAdapter.JaxbSafeJob(); - final Date NOW = new Date(); - job.lastRun = NOW; - job.nextRun = NOW; - job.jobName = "testName"; - job.jobId = "testId"; - job.schedulableClass = "test.schedulable.class"; - job.state = Job.JobState.COMPLETE; - job.userName = "testUsername"; - - HashMap params = new HashMap(); - params.put( "testStringkey", new StringParamValue( "testStringVal" ) ); - - JaxBSafeMap safeMap = new JaxBSafeMap( params ); - job.jobParams = safeMap; - - JobAdapter.JaxbSafeJob unmarshalledJob = JaxBUtil.outin( job, JobAdapter.JaxbSafeJob.class ); - Assert.assertEquals( job.lastRun, unmarshalledJob.lastRun ); - Assert.assertEquals( job.nextRun, unmarshalledJob.nextRun ); - Assert.assertEquals( job.jobName, unmarshalledJob.jobName ); - Assert.assertEquals( job.jobId, unmarshalledJob.jobId ); - Assert.assertEquals( job.schedulableClass, unmarshalledJob.schedulableClass ); - Assert.assertEquals( job.userName, unmarshalledJob.userName ); - Assert.assertEquals( job.state, unmarshalledJob.state ); - Assert.assertEquals( job.jobTrigger, unmarshalledJob.jobTrigger ); - Assert.assertTrue( "testStringkey".equals( unmarshalledJob.jobParams.entry.get( 0 ).key ) ); - Assert.assertTrue( "testStringVal".equals( unmarshalledJob.jobParams.entry.get( 0 ).getStringValue().toString() ) ); - } - - @Test - public void testSimpleTrigger() throws JAXBException { - SimpleJobTrigger orig = new SimpleJobTrigger(); - Date STARTTIME = new Date(); - orig.setStartTime( STARTTIME ); - - SimpleJobTrigger unmarshalled = JaxBUtil.outin( orig, SimpleJobTrigger.class ); - - Assert.assertEquals( orig.getStartTime(), unmarshalled.getStartTime() ); - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/DefaultSchedulerServiceTest.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/DefaultSchedulerServiceTest.java deleted file mode 100644 index 06f3ba2b288..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/DefaultSchedulerServiceTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.Spy; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.Job; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.scheduler2.ws.DefaultSchedulerService; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.verify; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -@RunWith( PowerMockRunner.class ) -@PowerMockIgnore( "jdk.internal.reflect.*" ) -@PrepareForTest( { PentahoSystem.class, PentahoSessionHolder.class } ) -public class DefaultSchedulerServiceTest { - - @Spy - DefaultSchedulerService defaultSchedulerService = new DefaultSchedulerService(); - @Mock - IScheduler iSchedulerMock; - @Mock - IPentahoSession iPentahoSessionMock; - @Mock - IAuthorizationPolicy policy; - @Captor - ArgumentCaptor filterCaptor; - - @Before - public void setup() { - mockStatic( PentahoSystem.class ); - mockStatic( PentahoSessionHolder.class ); - when( PentahoSystem.get( IScheduler.class, "IScheduler2", null ) ).thenReturn( iSchedulerMock ); - when( PentahoSessionHolder.getSession() ).thenReturn( iPentahoSessionMock ); - when( PentahoSystem.get( IAuthorizationPolicy.class ) ).thenReturn( policy ); - } - - @Test - public void testGetJobsNonAdminUser() throws Exception { - when( policy.isAllowed( anyString() ) ).thenReturn( false ); - when( iPentahoSessionMock.getName() ).thenReturn( "testUser1" ); - defaultSchedulerService.getJobs(); - verify( iSchedulerMock ).getJobs( (IJobFilter) filterCaptor.capture() ); - IJobFilter filter = (IJobFilter) filterCaptor.getValue(); - assertNotNull( filter ); - List testJobs = getJobs(); - List filteredJobs = new ArrayList<>(); - for ( Job job : testJobs ) { - if ( filter.accept( job ) ) { - filteredJobs.add( job ); - } - } - assertEquals( 1, filteredJobs.size() ); - assertEquals( "testJobName1", filteredJobs.get( 0 ).getJobName() ); - assertEquals( "testUser1", filteredJobs.get( 0 ).getUserName() ); - } - - @Test - public void testGetJobsAdminUser() throws Exception { - when( policy.isAllowed( anyString() ) ).thenReturn( true ); - when( iPentahoSessionMock.getName() ).thenReturn( "admin" ); - defaultSchedulerService.getJobs(); - verify( iSchedulerMock ).getJobs( (IJobFilter) filterCaptor.capture() ); - IJobFilter filter = (IJobFilter) filterCaptor.getValue(); - assertNotNull( filter ); - List testJobs = getJobs(); - List filteredJobs = new ArrayList<>(); - for ( Job job : testJobs ) { - if ( filter.accept( job ) ) { - filteredJobs.add( job ); - assertNotEquals( "BlockoutAction", job.getJobName() ); - } - } - assertEquals( 10, filteredJobs.size() ); - } - - private List getJobs() { - List jobs = new ArrayList<>(); - for ( int i = 0; i < 10; i++ ) { - jobs.add( mockJob( "testUser" + i, "testJobName" + i ) ); - } - jobs.add( mockJob( "system", "BlockoutAction" ) ); - return jobs; - } - - private Job mockJob( String userName, String jobName ) { - Job job = mock( Job.class ); - when( job.getUserName() ).thenReturn( userName ); - when( job.getJobName() ).thenReturn( jobName ); - return job; - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/JaxBUtil.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/JaxBUtil.java deleted file mode 100644 index cba67b62aa9..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/JaxBUtil.java +++ /dev/null @@ -1,79 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.namespace.QName; - -public class JaxBUtil { - - /** - * Returns an object that should match the in object value-wise, but is actually created by JAXB. JAXB - * will marshall the in object to XML, print it to stdout, and hydrate an object of the same type from - * the XML. - * - * @param - * the type to marshall and unmarshall to and from XML - * @param in - * the object to marshall to XML - * @param classes - * additional classes referred to by the in object - * @return a JAXB-created object that should be value-wise equal to the in object - * @throws JAXBException - * if something goes wrong - */ - @SuppressWarnings( "unchecked" ) - public static T outin( T in, Class... classes ) throws JAXBException { - // - // marshal and unmarshall back into a new object - // - JAXBContext jc = JAXBContext.newInstance( classes ); - Marshaller m = jc.createMarshaller(); - m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - m.marshal( in, bos ); - System.out.println( new String( bos.toByteArray() ) ); - Unmarshaller u = jc.createUnmarshaller(); - T unmarshalled = (T) u.unmarshal( new ByteArrayInputStream( bos.toByteArray() ) ); - return unmarshalled; - } - - @SuppressWarnings( "unchecked" ) - /** - * @param wrapInRootElement false means the class is not required to be annotated with @XmlRootElement - */ - public static void out( boolean wrapInRootElement, T in, Class... classes ) throws JAXBException { - JAXBContext jc = JAXBContext.newInstance( classes ); - Marshaller m = jc.createMarshaller(); - m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - if ( wrapInRootElement ) { - m.marshal( new JAXBElement( new QName( in.getClass().getSimpleName() ), in.getClass(), in ), bos ); - } - System.out.println( new String( bos.toByteArray() ) ); - } -} diff --git a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/TestQuartzScheduler.java b/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/TestQuartzScheduler.java deleted file mode 100644 index b1ae2655ca3..00000000000 --- a/scheduler/src/test/java/org/pentaho/platform/scheduler2/ws/test/TestQuartzScheduler.java +++ /dev/null @@ -1,35 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.ws.test; - -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; - -public class TestQuartzScheduler extends QuartzScheduler { - - static final String TEST_USER = "TestUser"; - - @Override - protected String getCurrentUser() { - SecurityHelper.getInstance().becomeUser( TEST_USER ); - return super.getCurrentUser(); - } -} diff --git a/scheduler/src/test/resources/META-INF/javamail.providers b/scheduler/src/test/resources/META-INF/javamail.providers deleted file mode 100644 index dfe12f3911c..00000000000 --- a/scheduler/src/test/resources/META-INF/javamail.providers +++ /dev/null @@ -1,2 +0,0 @@ -protocol=smtp; type=transport; class=org.pentaho.platform.scheduler2.email.MockMail; - From 78421e85cf5e240d691fb6d805d65be969a76452 Mon Sep 17 00:00:00 2001 From: aramos Date: Mon, 26 Jun 2023 11:38:02 -0400 Subject: [PATCH 07/59] [BACKLOG-37772] Scheduler plugin POC code changes. --- .../platform/web/servlet/JAXRSServlet.java | 1 + scheduler/pom.xml | 23 +++++++++++++++ .../quartz/EmbeddedQuartzSystemListener.java | 28 ++++++++++++++----- .../scheduler2/quartz/QuartzScheduler.java | 6 ++++ .../EmbeddedVersionCheckSystemListener.java | 22 ++++++++++++--- .../ws/DefaultSchedulerService.java | 6 ++++ .../http/api/resources/SchedulerResource.java | 7 +++-- .../resources/proxies/BlockStatusProxy.java | 0 .../resources/services/SchedulerService.java | 0 9 files changed, 80 insertions(+), 13 deletions(-) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java (99%) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java (100%) rename {extensions => scheduler}/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java (100%) diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java index 8b1967569e3..12cb768eb41 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java @@ -181,6 +181,7 @@ protected Resource getResourceByPath( String path ) { String springFile = PentahoSystem.getApplicationContext() .getSolutionPath( "system" + File.separator + "pentahoServices.spring.xml" ); //$NON-NLS-1$ //$NON-NLS-2$ + //wac.setConfigLocations( new String[] { springFile, "/Users/aramos/Documents/Hitachi/REPOS/BUILDS/pentaho-server/pentaho-solutions/system/scheduler-plugin/plugin.spring.xml" } ); wac.setConfigLocations( new String[] { springFile } ); wac.addBeanFactoryPostProcessor( new PentahoBeanScopeValidatorPostProcessor() ); wac.refresh(); diff --git a/scheduler/pom.xml b/scheduler/pom.xml index a315401fce9..9ce9d38187d 100644 --- a/scheduler/pom.xml +++ b/scheduler/pom.xml @@ -184,6 +184,29 @@ ${hamcrest-core.version} test + + org.codehaus.enunciate + enunciate-jersey-rt + ${enunciate-jersey-rt.version} + compile + + + com.sun.xml.bind + jaxb-impl + + + org.codehaus.jackson + jackson-mapper-asl + + + + + + pentaho + pentaho-platform-extensions + 9.6.0.0-SNAPSHOT + compile + diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java index c64f117f73b..700afb24373 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/EmbeddedQuartzSystemListener.java @@ -38,16 +38,15 @@ import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.data.DBDatasourceServiceException; import org.pentaho.platform.api.data.IDBDatasourceService; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.engine.ObjectFactoryException; +import org.pentaho.platform.api.engine.*; import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; import org.pentaho.platform.scheduler2.messsages.Messages; import org.quartz.SchedulerException; -public class EmbeddedQuartzSystemListener implements IPentahoSystemListener { +public class EmbeddedQuartzSystemListener implements IPluginLifecycleListener { /* * This is re-use by Copy and Paste to avoid a dependency on the bi-platform-scheduler project (which will eventually @@ -76,7 +75,19 @@ public synchronized void setUseNewDatasourceService( boolean useNewService ) { useNewDatasourceService = useNewService; } - public boolean startup( final IPentahoSession session ) { + public EmbeddedQuartzSystemListener() { + System.out.println("***************************************************************"); + System.out.println("EmbeddedQuartzSystemListener initialized."); + System.out.println("***************************************************************"); + } + + @Override + public void init() throws PluginLifecycleException { + } + + @Override + public void loaded() throws PluginLifecycleException { + IPentahoSession session = PentahoSessionHolder.getSession(); boolean result = true; Properties quartzProps = null; if ( quartzPropertiesFile != null ) { @@ -154,7 +165,9 @@ public boolean startup( final IPentahoSession session ) { "EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized", EmbeddedQuartzSystemListener.class.getName() ), e ); //$NON-NLS-1$ result = false; } - return result; + if ( !result ) { + throw new PluginLifecycleException(" Failed to start EmbeddedQuartzSystemListener"); + } } protected boolean verifyQuartzIsConfigured( DataSource ds ) throws SQLException { @@ -253,7 +266,8 @@ private Properties findPropertiesInClasspath() throws IOException { * * @see org.pentaho.core.system.IPentahoSystemListener#shutdown() */ - public void shutdown() { + @Override + public void unLoaded() throws PluginLifecycleException { try { QuartzScheduler scheduler = (QuartzScheduler) PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ scheduler.getQuartzScheduler().shutdown(); diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java index c762a1e72fa..b833c1667f7 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/quartz/QuartzScheduler.java @@ -128,10 +128,16 @@ public class QuartzScheduler implements IScheduler { public QuartzScheduler( SchedulerFactory schedulerFactory ) { this.quartzSchedulerFactory = schedulerFactory; + System.out.println("***************************************************************"); + System.out.println("QuartzScheduler initialized."); + System.out.println("***************************************************************"); } public QuartzScheduler() { this.quartzSchedulerFactory = new StdSchedulerFactory(); + System.out.println("***************************************************************"); + System.out.println("QuartzScheduler initialized."); + System.out.println("***************************************************************"); } /** diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java index d18df257d5d..7e0a3d289d1 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java @@ -30,6 +30,8 @@ import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; +import org.pentaho.platform.api.engine.IPluginLifecycleListener; +import org.pentaho.platform.api.engine.PluginLifecycleException; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.Job; @@ -39,7 +41,7 @@ import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.versionchecker.PentahoVersionCheckReflectHelper; -public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListener { +public class EmbeddedVersionCheckSystemListener implements IPluginLifecycleListener { /** * This is a direct copy of VersionCheckSystemListener except that the mechanism for talking to quartz goes through @@ -55,7 +57,18 @@ public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListene private String requestedReleases = "minor, ga"; //$NON-NLS-1$ private boolean disableVersionCheck = false; - public boolean startup( final IPentahoSession session ) { + public EmbeddedVersionCheckSystemListener() { + System.out.println("***************************************************************"); + System.out.println("EmbeddedVersionCheckSystemListener initialized."); + System.out.println("***************************************************************"); + } + + @Override + public void init() throws PluginLifecycleException { + } + + @Override + public void loaded() throws PluginLifecycleException { if ( isVersionCheckAvailable() ) { // register version check job try { @@ -84,7 +97,7 @@ public boolean startup( final IPentahoSession session ) { } } } - return true; +// return true; } public int calculateRepeatSeconds() { @@ -138,7 +151,8 @@ protected boolean isVersionCheckAvailable() { return PentahoVersionCheckReflectHelper.isVersionCheckerAvailable(); } - public void shutdown() { + @Override + public void unLoaded() throws PluginLifecycleException { } public int getRepeatIntervalSeconds() { diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java index 794a8c4810a..d64e457891b 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/ws/DefaultSchedulerService.java @@ -54,6 +54,12 @@ public class DefaultSchedulerService implements ISchedulerService { private String defaultActionId; // for testing only + public DefaultSchedulerService() { + System.out.println("***************************************************************"); + System.out.println("DefaultSchedulerService initialized."); + System.out.println("***************************************************************"); + } + public void setDefaultActionId( String defaultActionId ) { this.defaultActionId = defaultActionId; } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java similarity index 99% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java index 5cfea213baf..614d1008e70 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java +++ b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java @@ -62,8 +62,8 @@ /** * The SchedulerResource service provides the means to create, read, update, delete, and list schedules and blockout periods. Also provides the ability to control the status of schedules and the scheduler. */ -@Path ( "/scheduler" ) -public class SchedulerResource extends AbstractJaxRSResource { +@Path ( "/scheduler-plugin/api/scheduler" ) +public class SchedulerResource { protected SchedulerService schedulerService; @@ -71,6 +71,9 @@ public class SchedulerResource extends AbstractJaxRSResource { public SchedulerResource() { schedulerService = new SchedulerService(); + System.out.println("-----------------------------------------------------------------------"); + System.out.println("SchedulerResource was initialized."); + System.out.println("-----------------------------------------------------------------------"); } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java similarity index 100% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java b/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java similarity index 100% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java rename to scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java From 92dccb85bf76d9f8a9740491db33c453dfbf9fd6 Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Wed, 12 Jul 2023 15:29:56 -0400 Subject: [PATCH 08/59] Moving scheduling code into a plugin --- assemblies/pentaho-server/pom.xml | 1 + .../commands/RefreshSchedulesCommand.java | 80 -- .../mantle/client/ui/column/HtmlColumn.java | 45 - .../mantle/client/ui/xul/MantleModel.java | 15 +- .../mantle/client/workspace/CellTable.css | 145 -- .../workspace/ClickableSafeHtmlCell.java | 71 - .../mantle/client/workspace/FilterDialog.java | 262 ---- .../mantle/client/workspace/IJobFilter.java | 25 - .../client/workspace/SchedulesPanel.java | 1259 ----------------- .../workspace/SchedulesPerspectivePanel.java | 148 -- .../workspace/cellTableSortAscending.png | Bin 175 -> 0 bytes .../workspace/cellTableSortDescending.png | Bin 166 -> 0 bytes 12 files changed, 9 insertions(+), 2042 deletions(-) delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png diff --git a/assemblies/pentaho-server/pom.xml b/assemblies/pentaho-server/pom.xml index 7c8127ea267..d4ee3f23d70 100644 --- a/assemblies/pentaho-server/pom.xml +++ b/assemblies/pentaho-server/pom.xml @@ -55,6 +55,7 @@ org.hsqldb hsqldb ${hsqldb.version} + jdk8 mysql diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java deleted file mode 100644 index 1558a386284..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RefreshSchedulesCommand.java +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.commands; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.RunAsyncCallback; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.user.client.Window; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; - -public class RefreshSchedulesCommand extends AbstractCommand { - - public RefreshSchedulesCommand() { - } - - protected void performOperation() { - performOperation( true ); - } - - protected void performOperation( boolean feedback ) { - try { - final String url = GWT.getHostPageBaseURL() + "api/repo/files/canAdminister"; //$NON-NLS-1$ - RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.GET, url ); - requestBuilder.setHeader( "accept", "text/plain" ); - requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); - requestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - GWT.runAsync( new RunAsyncCallback() { - - public void onSuccess() { - SchedulesPerspectivePanel.getInstance().refresh(); - } - - public void onFailure( Throwable reason ) { - } - } ); - } - - public void onResponseReceived( Request request, final Response response ) { - GWT.runAsync( new RunAsyncCallback() { - - public void onSuccess() { - SchedulesPerspectivePanel.getInstance().refresh(); - } - - public void onFailure( Throwable reason ) { - } - } ); - } - - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - } - -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java deleted file mode 100644 index 44b8adc3fcf..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/column/HtmlColumn.java +++ /dev/null @@ -1,45 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.ui.column; - -import com.google.gwt.cell.client.Cell; -import com.google.gwt.cell.client.SafeHtmlCell; -import com.google.gwt.safehtml.shared.OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.user.cellview.client.Column; - -public abstract class HtmlColumn extends Column { - - public HtmlColumn() { - super( new SafeHtmlCell() ); - } - - public HtmlColumn( Cell cell ) { - super( cell ); - } - - @Override - public SafeHtml getValue( T t ) { - return new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml( getStringValue( t ) ); - } - - public abstract String getStringValue( T t ); -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java index e5360451c37..db4567cfcb8 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java @@ -33,7 +33,7 @@ import org.pentaho.mantle.client.commands.OpenKettleStatusCommand; import org.pentaho.mantle.client.commands.PrintCommand; import org.pentaho.mantle.client.commands.RefreshRepositoryCommand; -import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; +//import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; import org.pentaho.mantle.client.commands.SaveCommand; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ISolutionBrowserEvent; @@ -297,14 +297,15 @@ public void onFailure( Throwable reason ) { @Bindable public void refreshContent() { - if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() - .getId() ) ) { - Command cmd = new RefreshSchedulesCommand(); - cmd.execute(); - } else { + // TODO Need to delegate this refresh to plugins as well + //if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() + // .getId() ) ) { + // Command cmd = new RefreshSchedulesCommand(); + //cmd.execute(); + //} else { Command cmd = new RefreshRepositoryCommand(); cmd.execute(); - } + //} } @Bindable diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css b/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css deleted file mode 100644 index a4b45fa3017..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/CellTable.css +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -@def selectionBorderWidth 2px; - -/* - Add the @external flag to tell GWT compiler to NOT obfuscate the cellTable* classes (all of them). - This allows for theme-driven overrides in external CSS files. Treat these styles as defaults. - Themed overrides should be set in mantleCrystal.css/mantleOnyx.css/... -*/ -@external .cellTable*; - -.cellTableWidget { - background-color: white; - font-size: .7em; - border-bottom: 1px solid #6f7277; -} - -.cellTableFirstColumn { - -} - -.cellTableLastColumn { - -} - -.cellTableFooter { - border-top: 2px solid #6f7277; - padding: 3px 15px; - text-align: left; - color: #4b4a4a; - text-shadow: #ddf 1px 1px 0; - overflow: hidden; -} - -.cellTableHeader { - padding: 3px 15px; - text-align: left; - color: white; - overflow: hidden; -} - -.cellTableCell { - padding: 2px 10px; - overflow: hidden; - text-align: left; -} - -.cellTableFirstColumnFooter { - -} - -.cellTableFirstColumnHeader { - -} - -.cellTableLastColumnFooter { - -} - -.cellTableLastColumnHeader { - -} - -.cellTableSortableHeader { - cursor: pointer; - cursor: hand; -} - -.cellTableSortableHeader:hover { - color: #dfdfdf; -} - -.cellTableSortedHeaderAscending { - -} - -.cellTableSortedHeaderDescending { - -} - -.cellTableEvenRow { - background: #ffffff; -} - -.cellTableEvenRowCell { - border: selectionBorderWidth solid #ffffff; -} - -.cellTableOddRow { - background: #f0f0f0; -} - -.cellTableOddRowCell { - border: selectionBorderWidth solid #f0f0f0; -} - -.cellTableHoveredRow { - background: #cbefa3; -} - -.cellTableHoveredRowCell { - border: selectionBorderWidth solid #cbefa3; -} - -.cellTableKeyboardSelectedRow { - background: #BEBEBE; -} - -.cellTableKeyboardSelectedRowCell { - border: selectionBorderWidth solid #BEBEBE; -} - -.cellTableSelectedRow { - background: #BEBEBE; - color: white; - height: auto; - overflow: auto; -} - -.cellTableSelectedRowCell { - border: selectionBorderWidth solid #BEBEBE; -} - -/** - * The keyboard selected cell is visible over selection. - */ -.cellTableKeyboardSelectedCell { -} - -.cellTableLoading { - margin: 30px; -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java deleted file mode 100644 index 0f9dc7f341f..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/ClickableSafeHtmlCell.java +++ /dev/null @@ -1,71 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.cell.client.AbstractCell; -import com.google.gwt.cell.client.ValueUpdater; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.EventTarget; -import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; - -/** - * @author Rowell Belen - */ -public class ClickableSafeHtmlCell extends AbstractCell { - - public ClickableSafeHtmlCell() { - super( "click" ); - } - - @Override - public void onBrowserEvent( Context context, Element parent, SafeHtml value, NativeEvent event, - ValueUpdater valueUpdater ) { - - // use default implementation for all events other than the click event - super.onBrowserEvent( context, parent, value, event, valueUpdater ); - - if ( "click".equals( event.getType() ) ) { - - // Ignore clicks that occur outside of the outermost element. - EventTarget eventTarget = event.getEventTarget(); - if ( parent.getFirstChildElement().isOrHasChild( Element.as( eventTarget ) ) ) { - onEnterKeyDown( context, parent, value, event, valueUpdater ); - } - } - } - - @Override - protected void onEnterKeyDown( Context context, Element parent, SafeHtml value, NativeEvent event, - ValueUpdater valueUpdater ) { - if ( valueUpdater != null ) { - valueUpdater.update( value ); - } - } - - @Override - public void render( Context context, SafeHtml value, SafeHtmlBuilder sb ) { - if ( value != null ) { - sb.append( value ); - } - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java deleted file mode 100644 index 879344000a3..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/FilterDialog.java +++ /dev/null @@ -1,262 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.core.client.JsArray; -import com.google.gwt.dom.client.Style; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.event.logical.shared.ValueChangeHandler; -import com.google.gwt.user.client.ui.CaptionPanel; -import com.google.gwt.user.client.ui.CheckBox; -import com.google.gwt.user.client.ui.FlexTable; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.ListBox; -import com.google.gwt.user.client.ui.MultiWordSuggestOracle; -import com.google.gwt.user.client.ui.SuggestBox; -import org.pentaho.gwt.widgets.client.controls.DateTimePicker; -import org.pentaho.gwt.widgets.client.controls.DateTimePicker.Layout; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.mantle.client.messages.Messages; - -import java.util.Date; -import java.util.HashSet; - -public class FilterDialog extends PromptDialogBox { - - private MultiWordSuggestOracle resourceOracle = new MultiWordSuggestOracle(); - private SuggestBox resourceSuggestBox = new SuggestBox( resourceOracle ); - - private CheckBox afterCheckBox = new CheckBox( Messages.getString( "after" ) ); - private CheckBox beforeCheckBox = new CheckBox( Messages.getString( "before" ) ); - private DateTimePicker afterDateBox = new DateTimePicker( Layout.HORIZONTAL ); - private DateTimePicker beforeDateBox = new DateTimePicker( Layout.HORIZONTAL ); - - private ListBox userListBox = new ListBox( false ); - private ListBox scheduleStateListBox = new ListBox( false ); - private ListBox scheduleTypeListBox = new ListBox( false ); - - private enum ScheduleStateEnum { - - SHOWALL( Messages.getString( "showAll" ) ), - NORMAL( "Normal" ), - PAUSED( "Paused" ), - COMPLETE( "Complete" ), - ERROR( "Error" ), - BLOCKED( "Blocked" ), - UNKNOWN( "Unknown" ); - - private final String value; - - ScheduleStateEnum( String value ) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } - } - - private enum ScheduleTypeEnum { - - SHOWALL( Messages.getString( "showAll" ) ), - DAILY( "Daily" ), - WEEKLY( "Weekly" ), - MONTHLY( "Monthly" ), - YEARLY( "Yearly" ); - - private final String value; - - ScheduleTypeEnum( String value ) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } - } - - public FilterDialog() { - super( - Messages.getString( "filterSchedules" ), Messages.getString( "ok" ), Messages.getString( "cancel" ), false, - true ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public FilterDialog( JsArray jobs, IDialogCallback callback ) { - super( - Messages.getString( "filterSchedules" ), Messages.getString( "ok" ), Messages.getString( "cancel" ), false, - true ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - initUI( jobs ); - // setSize("800px", "500px"); - setCallback( callback ); - } - - /** - * @param jobs - */ - public void initUI( JsArray jobs ) { - if ( jobs != null ) { - for ( int i = 0; i < jobs.length(); i++ ) { - resourceOracle.add( jobs.get( i ).getShortResourceName() ); - } - } - - resourceSuggestBox.setWidth( "240px" ); - userListBox.setWidth( "200px" ); - userListBox.getElement().getStyle().setTextTransform( Style.TextTransform.CAPITALIZE ); - scheduleStateListBox.setWidth( "200px" ); - scheduleTypeListBox.setWidth( "200px" ); - - // next execution filter - CaptionPanel executionFilterCaptionPanel = new CaptionPanel( Messages.getString( "executionTime" ) ); - FlexTable executionFilterPanel = new FlexTable(); - executionFilterPanel.setWidget( 0, 0, beforeCheckBox ); - executionFilterPanel.setWidget( 0, 1, beforeDateBox ); - executionFilterPanel.setWidget( 1, 0, afterCheckBox ); - executionFilterPanel.setWidget( 1, 1, afterDateBox ); - executionFilterCaptionPanel.add( executionFilterPanel ); - - afterCheckBox.addValueChangeHandler( new ValueChangeHandler() { - public void onValueChange( ValueChangeEvent event ) { - afterDateBox.setEnabled( event.getValue() ); - } - } ); - - beforeCheckBox.addValueChangeHandler( new ValueChangeHandler() { - public void onValueChange( ValueChangeEvent event ) { - beforeDateBox.setEnabled( event.getValue() ); - } - } ); - beforeDateBox.setEnabled( beforeCheckBox.getValue() ); - afterDateBox.setEnabled( afterCheckBox.getValue() ); - - final String showAll = Messages.getString( "showAll" ); - // user filter - int selectedIndex = getSelectedIndex( userListBox ); - userListBox.clear(); - userListBox.addItem( showAll ); - HashSet uniqueUsers = new HashSet(); - if ( jobs != null ) { - for ( int i = 0; i < jobs.length(); i++ ) { - uniqueUsers.add( jobs.get( i ).getUserName() ); - } - } - for ( String user : uniqueUsers ) { - userListBox.addItem( user ); - } - userListBox.setSelectedIndex( selectedIndex ); - - // state filter - scheduleStateListBox.setVisibleItemCount( 1 ); - selectedIndex = getSelectedIndex( scheduleStateListBox ); - scheduleStateListBox.clear(); - // NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN - scheduleStateListBox.addItem( showAll, ScheduleStateEnum.SHOWALL.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "normal" ), ScheduleStateEnum.NORMAL.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "paused" ), ScheduleStateEnum.PAUSED.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "complete" ), ScheduleStateEnum.COMPLETE.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "error" ), ScheduleStateEnum.ERROR.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "blocked" ), ScheduleStateEnum.BLOCKED.getValue() ); - scheduleStateListBox.addItem( Messages.getString( "unknown" ), ScheduleStateEnum.UNKNOWN.getValue() ); - scheduleStateListBox.setSelectedIndex( selectedIndex ); - - // state filter - scheduleTypeListBox.setVisibleItemCount( 1 ); - selectedIndex = getSelectedIndex( scheduleTypeListBox ); - scheduleTypeListBox.clear(); - // DAILY, WEEKLY, MONTHLY, YEARLY - scheduleTypeListBox.addItem( showAll, ScheduleStateEnum.SHOWALL.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.daily" ), ScheduleTypeEnum.DAILY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.weekly" ), ScheduleTypeEnum.WEEKLY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.monthly" ), ScheduleTypeEnum.MONTHLY.getValue() ); - scheduleTypeListBox.addItem( Messages.getString( "schedule.yearly" ), ScheduleTypeEnum.YEARLY.getValue() ); - scheduleTypeListBox.setSelectedIndex( selectedIndex ); - - FlexTable filterPanel = new FlexTable(); - filterPanel.setWidget( 0, 0, new Label( Messages.getString( "scheduledResource" ) ) ); - filterPanel.setWidget( 1, 0, resourceSuggestBox ); - - filterPanel.setWidget( 2, 0, new Label( Messages.getString( "_user" ) ) ); - filterPanel.setWidget( 3, 0, userListBox ); - - filterPanel.setWidget( 4, 0, new Label( Messages.getString( "scheduleState" ) ) ); - filterPanel.setWidget( 5, 0, scheduleStateListBox ); - - filterPanel.setWidget( 6, 0, new Label( Messages.getString( "scheduleType" ) ) ); - filterPanel.setWidget( 7, 0, scheduleTypeListBox ); - - filterPanel.setWidget( 8, 0, executionFilterCaptionPanel ); - - setContent( filterPanel ); - } - - public String getUserFilter() { - return userListBox.getItemText( userListBox.getSelectedIndex() ); - } - - public String getTypeFilter() { - return scheduleTypeListBox.getValue( scheduleTypeListBox.getSelectedIndex() ); - } - - public String getStateFilter() { - return scheduleStateListBox.getValue( scheduleStateListBox.getSelectedIndex() ); - } - - public Date getBeforeDate() { - if ( beforeCheckBox.getValue() ) { - return beforeDateBox.getDate(); - } - return null; - } - - public Date getAfterDate() { - if ( afterCheckBox.getValue() ) { - return afterDateBox.getDate(); - } - return null; - } - - public String getResourceName() { - return resourceSuggestBox.getText(); - } - - public CheckBox getAfterCheckBox() { - return afterCheckBox; - } - - private int getSelectedIndex( ListBox listBox ) { - int selectedIndex = listBox.getSelectedIndex(); - if ( selectedIndex == -1 ) { - selectedIndex = 0; - } - return selectedIndex; - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java deleted file mode 100644 index 65737b7ed52..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/IJobFilter.java +++ /dev/null @@ -1,25 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -public interface IJobFilter { - public boolean accept( JsJob job ); -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java deleted file mode 100644 index b113c547364..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPanel.java +++ /dev/null @@ -1,1259 +0,0 @@ -/*! - * 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-2023 Hitachi Vantara. All rights reserved. - */ -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.cell.client.FieldUpdater; -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.core.client.JsonUtils; -import com.google.gwt.dom.client.BrowserEvents; -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.dom.client.TableCellElement; -import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestBuilder.Method; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.http.client.URL; -import com.google.gwt.i18n.client.DateTimeFormat; -import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; -import com.google.gwt.json.client.JSONArray; -import com.google.gwt.json.client.JSONObject; -import com.google.gwt.json.client.JSONString; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.AbstractCellTable; -import com.google.gwt.user.cellview.client.AbstractHeaderOrFooterBuilder; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; -import com.google.gwt.user.cellview.client.SimplePager; -import com.google.gwt.user.cellview.client.SimplePager.TextLocation; -import com.google.gwt.user.cellview.client.TextColumn; -import com.google.gwt.user.client.Command; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.HasHorizontalAlignment; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.view.client.CellPreviewEvent; -import com.google.gwt.view.client.ListDataProvider; -import com.google.gwt.view.client.MultiSelectionModel; -import com.google.gwt.view.client.ProvidesKey; -import com.google.gwt.view.client.Range; -import com.google.gwt.view.client.SelectionChangeEvent; -import com.google.gwt.view.client.SelectionChangeEvent.Handler; -import org.apache.http.protocol.HTTP; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.gwt.widgets.client.toolbar.Toolbar; -import org.pentaho.gwt.widgets.client.toolbar.ToolbarButton; -import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.mantle.client.EmptyRequestCallback; -import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; -import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -import org.pentaho.mantle.client.dialogs.scheduling.NewScheduleDialog; -import org.pentaho.mantle.client.dialogs.scheduling.OutputLocationUtils; -import org.pentaho.mantle.client.events.EventBusUtil; -import org.pentaho.mantle.client.events.GenericEvent; -import org.pentaho.mantle.client.images.ImageUtil; -import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; -import org.pentaho.mantle.client.ui.PerspectiveManager; -import org.pentaho.mantle.client.ui.column.HtmlColumn; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.CellTableResources; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.PAGE_SIZE; - -public class SchedulesPanel extends SimplePanel { - - private static final String JOB_STATE_NORMAL = "NORMAL"; - private static final String SCHEDULER_STATE_RUNNING = "RUNNING"; - - private static final String HTTP_ACCEPT_HEADER = "Accept"; - private static final String JSON_CONTENT_TYPE = "application/json"; - private static final String IF_MODIFIED_SINCE = "01 Jan 1970 00:00:00 GMT"; - - private static final String ICON_SMALL_STYLE = "icon-small"; - private static final String ICON_RUN_STYLE = "icon-run"; - - private static final String BLANK_VALUE = "-"; - - private static final int READ_PERMISSION = 0; - - private static final int OUTPUT_PATH_COLUMN = 3; - - private ToolbarButton controlScheduleButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, ICON_RUN_STYLE ) ); - private ToolbarButton editButton = new ToolbarButton( ImageUtil.getThemeableImage( "pentaho-editbutton" ) ); - private ToolbarButton triggerNowButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-execute" ) ); - private ToolbarButton scheduleRemoveButton = new ToolbarButton( ImageUtil.getThemeableImage( - "pentaho-deletebutton" ) ); - private ToolbarButton filterButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-filter-add" ) ); - private ToolbarButton filterRemoveButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-filter-remove" ) ); - - private JsArray allJobs; - - private ArrayList filters = new ArrayList(); - - private CellTable table = new CellTable( PAGE_SIZE, (CellTableResources) GWT.create( CellTableResources.class ) ); - - private ListDataProvider dataProvider = new ListDataProvider(); - - private SimplePager pager; - - private FilterDialog filterDialog; - - private IDialogCallback filterDialogCallback = new IDialogCallback() { - public void okPressed() { - filters.clear(); - // create filters - if ( filterDialog.getAfterDate() != null ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getNextRun().after( filterDialog.getAfterDate() ); - } - } ); - } - if ( filterDialog.getBeforeDate() != null ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getNextRun().before( filterDialog.getBeforeDate() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getResourceName() ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getShortResourceName().toLowerCase().contains( filterDialog.getResourceName().toLowerCase() ); - } - } ); - } - final String showAll = Messages.getString( "showAll" ); - if ( !StringUtils.isEmpty( filterDialog.getUserFilter() ) && !filterDialog.getUserFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getUserName().equalsIgnoreCase( filterDialog.getUserFilter() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getStateFilter() ) && !filterDialog.getStateFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getState().toLowerCase().equalsIgnoreCase( filterDialog.getStateFilter() ); - } - } ); - } - if ( !StringUtils.isEmpty( filterDialog.getTypeFilter() ) && !filterDialog.getTypeFilter().equals( showAll ) ) { - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return job.getJobTrigger().getScheduleType().equalsIgnoreCase( filterDialog.getTypeFilter() ); - } - } ); - } - filterRemoveButton.setEnabled( !filters.isEmpty() ); - filterAndShowData(); - } - - public void cancelPressed() { - } - }; - - @SuppressWarnings( "unchecked" ) - private Set getSelectedJobs() { - return ( (MultiSelectionModel) table.getSelectionModel() ).getSelectedSet(); - } - - private IDialogCallback scheduleDialogCallback = new IDialogCallback() { - public void okPressed() { - refresh(); - - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "scheduleUpdatedTitle" ), - Messages.getString( "scheduleUpdatedMessage" ), false, false, true ); - - dialogBox.center(); - } - - public void cancelPressed() { - } - }; - - public SchedulesPanel( final boolean isAdmin, final boolean isScheduler ) { - createUI( isAdmin, isScheduler ); - refresh(); - } - - public void refresh() { - String moduleBaseURL = GWT.getModuleBaseURL(); - String moduleName = GWT.getModuleName(); - String contextURL = moduleBaseURL.substring( 0, moduleBaseURL.lastIndexOf( moduleName ) ); - - final String apiEndpoint = "api/scheduler/getJobs"; - - RequestBuilder executableTypesRequestBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint, contextURL ); - executableTypesRequestBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - executableTypesRequestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - allJobs = parseJson( JsonUtils.escapeJsonForEval( response.getText() ) ); - filterAndShowData(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void filterAndShowData() { - - filters.add( new IJobFilter() { - public boolean accept( JsJob job ) { - return !job.getFullResourceName().equals( "GeneratedContentCleaner" ); - } - } ); - - ArrayList filteredList = new ArrayList(); - for ( int i = 0; i < allJobs.length(); i++ ) { - filteredList.add( allJobs.get( i ) ); - // filter if needed - for ( IJobFilter filter : filters ) { - if ( !filter.accept( allJobs.get( i ) ) ) { - filteredList.remove( allJobs.get( i ) ); - } - } - } - List list = dataProvider.getList(); - list.clear(); - list.addAll( filteredList ); - pager.setVisible( filteredList.size() > PAGE_SIZE ); - for ( JsJob job : filteredList ) { - table.getSelectionModel().setSelected( job, false ); - } - editButton.setEnabled( false ); - controlScheduleButton.setEnabled( false ); - scheduleRemoveButton.setEnabled( false ); - triggerNowButton.setEnabled( false ); - table.setPageStart( 0 ); - - table.setKeyboardSelectedRow( 0, false ); - table.setKeyboardSelectedColumn( 0, false ); - - table.redraw(); - } - - private void updateControlSchedulerButtonState( final ToolbarButton controlSchedulerButton, - final boolean isScheduler ) { - RequestBuilder builder = createRequestBuilder( RequestBuilder.GET, "api/scheduler/state" ); - - try { - builder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - updateControlSchedulerButtonStyle( controlSchedulerButton, response.getText() ); - - controlSchedulerButton.setEnabled( isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - - private void updateControlSchedulerButtonStyle( ToolbarButton controlSchedulerButton, String state ) { - boolean isRunning = SCHEDULER_STATE_RUNNING.equalsIgnoreCase( state ); - - final String tooltip = isRunning ? Messages.getString( "stopScheduler" ) : Messages.getString( "startScheduler" ); - controlSchedulerButton.setToolTip( tooltip ); - - final String buttonIconCss = isRunning ? "icon-stop-scheduler" : "icon-start-scheduler"; - controlSchedulerButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, buttonIconCss ) ); - } - - private void updateJobScheduleButtonStyle( String state ) { - boolean isRunning = JOB_STATE_NORMAL.equalsIgnoreCase( state ); - - String controlButtonCss = isRunning ? "icon-stop" : ICON_RUN_STYLE; - controlScheduleButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, controlButtonCss ) ); - - String controlButtonTooltip = isRunning ? Messages.getString( "stop" ) : Messages.getString( "start" ); - controlScheduleButton.setToolTip( controlButtonTooltip ); - - } - - private void toggleSchedulerOnOff( final ToolbarButton controlSchedulerButton, final boolean isScheduler ) { - RequestBuilder builder = createRequestBuilder( RequestBuilder.GET, "api/scheduler/state" ); - - try { - builder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - boolean isRunning = SCHEDULER_STATE_RUNNING.equalsIgnoreCase( response.getText() ); - - final String action = isRunning ? "pause" : "start"; - controlScheduler( controlSchedulerButton, action, isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void createUI( boolean isAdmin, final boolean isScheduler ) { - - table.getElement().setId( "schedule-table" ); - table.setStylePrimaryName( "pentaho-table" ); - table.setWidth( "100%", true ); - - // BISERVER-9331 Column sort indicators should be to the right of header text in the Manage Schedules table. - if ( table.getHeaderBuilder() instanceof AbstractHeaderOrFooterBuilder ) { - ( (AbstractHeaderOrFooterBuilder) table.getHeaderBuilder() ).setSortIconStartOfLine( false ); - } - - final MultiSelectionModel selectionModel = new MultiSelectionModel( new ProvidesKey() { - public Object getKey( JsJob item ) { - return item.getJobId(); - } - } ); - table.setSelectionModel( selectionModel ); - - Label noDataLabel = new Label( Messages.getString( "noSchedules" ) ); - noDataLabel.setStyleName( "noDataForScheduleTable" ); - table.setEmptyTableWidget( noDataLabel ); - - TextColumn idColumn = new TextColumn() { - public String getValue( JsJob job ) { - return job.getJobId(); - } - }; - idColumn.setSortable( true ); - - TextColumn nameColumn = new TextColumn() { - public String getValue( JsJob job ) { - return job.getJobName(); - } - }; - nameColumn.setSortable( true ); - - HtmlColumn resourceColumn = new HtmlColumn() { - @Override - public String getStringValue( JsJob job ) { - String name = job.getFullResourceName().split( "\\." )[ 0 ]; - return name.replaceAll( "/", "/" ); - } - }; - resourceColumn.setSortable( true ); - - HtmlColumn outputPathColumn = new HtmlColumn( new ClickableSafeHtmlCell() ) { - @Override - public String getStringValue( JsJob jsJob ) { - try { - String outputPath = jsJob.getOutputPath(); - if ( StringUtils.isEmpty( outputPath ) ) { - return BLANK_VALUE; - } - - outputPath = new SafeHtmlBuilder().appendEscaped( outputPath ).toSafeHtml().asString(); - - return MessageFormat.format( - "{0}", outputPath ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - - outputPathColumn.setFieldUpdater( new FieldUpdater() { - @Override - public void update( final int index, final JsJob jsJob, final SafeHtml value ) { - if ( value != null && !BLANK_VALUE.equals( value.asString() ) ) { - - final Command errorCallback = new Command() { - @Override - public void execute() { - showValidateOutputLocationError(); - } - }; - - final Command successCallback = new Command() { - @Override - public void execute() { - openOutputLocation( jsJob.getOutputPath() ); - } - }; - - OutputLocationUtils.validateOutputLocation( jsJob.getOutputPath(), successCallback, errorCallback ); - } - } - } ); - - outputPathColumn.setSortable( true ); - - TextColumn scheduleColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - return job.getJobTrigger().getDescription(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - scheduleColumn.setSortable( true ); - - TextColumn userNameColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - return job.getUserName(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - userNameColumn.setSortable( true ); - - TextColumn stateColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - // BISERVER-9965 - final String jobState = "COMPLETE".equalsIgnoreCase( job.getState() ) ? "FINISHED" : job.getState(); - // not css text-transform because tooltip will use pure text from the cell - return jobState.substring( 0, 1 ).toUpperCase() + jobState.substring( 1 ).toLowerCase(); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - stateColumn.setSortable( true ); - - TextColumn nextFireColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - Date date = job.getNextRun(); - if ( date == null ) { - return BLANK_VALUE; - } - - DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM ); - - return format.format( date ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - nextFireColumn.setSortable( true ); - - TextColumn lastFireColumn = new TextColumn() { - public String getValue( JsJob job ) { - try { - Date date = job.getLastRun(); - if ( date == null ) { - return BLANK_VALUE; - } - - DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM ); - return format.format( date ); - } catch ( Throwable t ) { - return BLANK_VALUE; - } - } - }; - lastFireColumn.setSortable( true ); - - // table.addColumn(idColumn, "ID"); - table.addColumn( nameColumn, Messages.getString( "scheduleName" ) ); - table.addColumn( scheduleColumn, Messages.getString( "recurrence" ) ); - table.addColumn( resourceColumn, Messages.getString( "sourceFile" ) ); - table.addColumn( outputPathColumn, Messages.getString( "outputPath" ) ); - - table.addColumn( lastFireColumn, Messages.getString( "lastFire" ) ); - table.addColumn( nextFireColumn, Messages.getString( "nextFire" ) ); - if ( isAdmin ) { - table.addColumn( userNameColumn, Messages.getString( "user" ) ); - } - table.addColumn( stateColumn, Messages.getString( "state" ) ); - - table.addColumnStyleName( 0, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 1, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 2, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 3, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 4, "backgroundContentHeaderTableCell" ); - table.addColumnStyleName( 5, "backgroundContentHeaderTableCell" ); - if ( isAdmin ) { - table.addColumnStyleName( 6, "backgroundContentHeaderTableCell" ); - } - table.addColumnStyleName( isAdmin ? 7 : 6, "backgroundContentHeaderTableCell" ); - - table.setColumnWidth( nameColumn, 160, Unit.PX ); - table.setColumnWidth( resourceColumn, 200, Unit.PX ); - table.setColumnWidth( outputPathColumn, 180, Unit.PX ); - table.setColumnWidth( scheduleColumn, 170, Unit.PX ); - table.setColumnWidth( lastFireColumn, 120, Unit.PX ); - table.setColumnWidth( nextFireColumn, 120, Unit.PX ); - if ( isAdmin ) { - table.setColumnWidth( userNameColumn, 100, Unit.PX ); - } - table.setColumnWidth( stateColumn, 90, Unit.PX ); - - dataProvider.addDataDisplay( table ); - List list = dataProvider.getList(); - - ListHandler columnSortHandler = new ListHandler( list ); - - columnSortHandler.setComparator( idColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getJobId().compareTo( o2.getJobId() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( nameColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getJobName().compareTo( o2.getJobName() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( resourceColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - String r1 = o1.getShortResourceName(); - String r2 = null; - if ( o2 != null ) { - r2 = o2.getShortResourceName(); - } - - return ( o2 != null ) ? r1.compareTo( r2 ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( outputPathColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - String r1 = o1.getOutputPath(); - String r2 = null; - if ( o2 != null ) { - r2 = o2.getOutputPath(); - } - - return ( o2 != null ) ? r1.compareTo( r2 ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( scheduleColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - String s1 = o1.getJobTrigger().getDescription(); - String s2 = o2.getJobTrigger().getDescription(); - return s1.compareTo( s2 ); - } - } ); - columnSortHandler.setComparator( userNameColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getUserName().compareTo( o2.getUserName() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( stateColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 != null ) { - return ( o2 != null ) ? o1.getState().compareTo( o2.getState() ) : 1; - } - return -1; - } - } ); - columnSortHandler.setComparator( nextFireColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 == null || o1.getNextRun() == null ) { - return -1; - } - if ( o2 == null || o2.getNextRun() == null ) { - return 1; - } - - if ( o1.getNextRun() == o2.getNextRun() ) { - return 0; - } - - return o1.getNextRun().compareTo( o2.getNextRun() ); - } - } ); - columnSortHandler.setComparator( lastFireColumn, new Comparator() { - public int compare( JsJob o1, JsJob o2 ) { - if ( o1 == o2 ) { - return 0; - } - - if ( o1 == null || o1.getLastRun() == null ) { - return -1; - } - if ( o2 == null || o2.getLastRun() == null ) { - return 1; - } - - if ( o1.getLastRun() == o2.getLastRun() ) { - return 0; - } - - return o1.getLastRun().compareTo( o2.getLastRun() ); - } - } ); - table.addColumnSortHandler( columnSortHandler ); - - table.getColumnSortList().push( idColumn ); - table.getColumnSortList().push( resourceColumn ); - table.getColumnSortList().push( outputPathColumn ); - table.getColumnSortList().push( nameColumn ); - - table.getSelectionModel().addSelectionChangeHandler( new Handler() { - public void onSelectionChange( SelectionChangeEvent event ) { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob job = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - updateJobScheduleButtonStyle( job.getState() ); - - controlScheduleButton.setEnabled( isScheduler ); - editButton.setEnabled( isScheduler ); - controlScheduleButton.setEnabled( isScheduler ); - scheduleRemoveButton.setEnabled( isScheduler ); - triggerNowButton.setEnabled( isScheduler ); - } else { - editButton.setEnabled( false ); - controlScheduleButton.setEnabled( false ); - scheduleRemoveButton.setEnabled( false ); - triggerNowButton.setEnabled( false ); - } - } - } ); - - // BISERVER-9965 - table.addCellPreviewHandler( new CellPreviewEvent.Handler() { - @Override - public void onCellPreview( CellPreviewEvent event ) { - if ( "mouseover".equals( event.getNativeEvent().getType() ) ) { - final TableCellElement cell = table.getRowElement( event.getIndex() ).getCells().getItem( event.getColumn() ); - cell.setTitle( cell.getInnerText() ); - } - } - } ); - - /* - * For Left & Right, the below code is there to override the base class implementation i.e., - * navigates focus only amongst interactive cells, while our implementation navigates through all cells. - * - * For Enter, goes to the output path. - */ - table.setKeyboardSelectionHandler( new AbstractCellTable.CellTableKeyboardSelectionHandler( table ) { - @Override - public void onCellPreview( CellPreviewEvent event ) { - int keyboardSelectedColumn = table.getKeyboardSelectedColumn(); - if ( BrowserEvents.KEYDOWN.equals( event.getNativeEvent().getType() ) ) { - if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_RIGHT ) { - table.setKeyboardSelectedColumn( Math.min( keyboardSelectedColumn + 1, table.getColumnCount() - 1 ) ); - handledEvent( event ); - } else if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_LEFT ) { - table.setKeyboardSelectedColumn( Math.max( 0, keyboardSelectedColumn - 1 ) ); - handledEvent( event ); - } else if ( event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER && keyboardSelectedColumn == OUTPUT_PATH_COLUMN ) { - int index = event.getIndex(); - JsJob job = table.getVisibleItem( event.getIndex() ); - outputPathColumn.getFieldUpdater().update( index, job, outputPathColumn.getValue( job ) ); - } else if ( !event.getNativeEvent().getCtrlKey() && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_SPACE ) { - ( (MultiSelectionModel) table.getSelectionModel() ).clear(); - super.onCellPreview( event ); - } else { - super.onCellPreview( event ); - } - } else { - super.onCellPreview( event ); - } - } - - private void handledEvent( CellPreviewEvent event ) { - event.setCanceled( true ); - event.getNativeEvent().preventDefault(); - } - } ); - - SimplePager.Resources pagerResources = GWT.create( SimplePager.Resources.class ); - pager = new SimplePager( TextLocation.CENTER, pagerResources, false, 0, true ) { - @Override - public void setPageStart( int index ) { - if ( getDisplay() != null ) { - Range range = getDisplay().getVisibleRange(); - int pageSize = range.getLength(); - - index = Math.max( 0, index ); - if ( index != range.getStart() ) { - getDisplay().setVisibleRange( index, pageSize ); - } - } - } - }; - pager.setDisplay( table ); - - VerticalPanel tableAndPager = new VerticalPanel(); - tableAndPager.setHorizontalAlignment( HasHorizontalAlignment.ALIGN_CENTER ); - - Toolbar bar = new Toolbar(); - bar.addSpacer( 10 ); - - bar.add( Toolbar.GLUE ); - - // Add control scheduler button - if ( isAdmin ) { - final ToolbarButton controlSchedulerButton = new ToolbarButton( ImageUtil.getThemeableImage( - ICON_SMALL_STYLE, "icon-start-scheduler" ) ); - - controlSchedulerButton.setCommand( new Command() { - public void execute() { - toggleSchedulerOnOff( controlSchedulerButton, isScheduler ); - } - } ); - updateControlSchedulerButtonState( controlSchedulerButton, isScheduler ); - - bar.add( controlSchedulerButton ); - bar.addSpacer( 20 ); - } - - // Add filter button - filterButton.setCommand( new Command() { - public void execute() { - if ( filterDialog == null ) { - filterDialog = new FilterDialog( allJobs, filterDialogCallback ); - } else { - filterDialog.initUI( allJobs ); - } - - filterDialog.center(); - } - } ); - - filterButton.setToolTip( Messages.getString( "filterSchedules" ) ); - if ( isAdmin ) { - bar.add( filterButton ); - } - - // Add remove filters button - filterRemoveButton.setCommand( new Command() { - public void execute() { - filterDialog = null; - filters.clear(); - filterAndShowData(); - filterRemoveButton.setEnabled( false ); - filterButton.setImage( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, "icon-filter-add" ) ); - } - } ); - filterRemoveButton.setToolTip( Messages.getString( "removeFilters" ) ); - filterRemoveButton.setEnabled( !filters.isEmpty() ); - if ( isAdmin ) { - bar.add( filterRemoveButton ); - } - - // Add refresh button - ToolbarButton refresh = new ToolbarButton( ImageUtil.getThemeableImage( ICON_SMALL_STYLE, "icon-refresh" ) ); - refresh.setToolTip( Messages.getString( "refreshTooltip" ) ); - refresh.setCommand( new Command() { - public void execute() { - RefreshSchedulesCommand cmd = new RefreshSchedulesCommand(); - cmd.execute(); - } - } ); - bar.add( refresh ); - - bar.addSpacer( 20 ); - - // Add execute now button - triggerNowButton.setToolTip( Messages.getString( "executeNow" ) ); - triggerNowButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - if ( !selectedJobs.isEmpty() ) { - triggerExecuteNow( selectedJobs ); - } - } - } ); - triggerNowButton.setEnabled( false ); - bar.add( triggerNowButton ); - - // Add control schedule button - controlScheduleButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob job = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - - boolean isRunning = JOB_STATE_NORMAL.equalsIgnoreCase( job.getState() ); - - final String action = isRunning ? "pauseJob" : "resumeJob"; - controlJobs( selectedJobs, action, RequestBuilder.POST, false ); - } - } - } ); - controlScheduleButton.setEnabled( false ); - bar.add( controlScheduleButton ); - - bar.addSpacer( 20 ); - - // Add edit button - editButton.setCommand( new Command() { - public void execute() { - Set selectedJobs = getSelectedJobs(); - - if ( !selectedJobs.isEmpty() ) { - final JsJob editJob = selectedJobs.toArray( new JsJob[ 0 ] )[ 0 ]; - - canAccessJobRequest( editJob, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - promptForScheduleResourceError( Collections.singleton( editJob ) ); - } - - public void onResponseReceived( Request request, Response response ) { - boolean canEditJob = "true".equalsIgnoreCase( response.getText() ); - if ( !canEditJob ) { - promptForScheduleResourceError( Collections.singleton( editJob ) ); - return; - } - - editJob( editJob ); - } - } ); - } - } - } ); - - editButton.setEnabled( false ); - editButton.setToolTip( Messages.getString( "editTooltip" ) ); - bar.add( editButton ); - - // Add remove button - scheduleRemoveButton.setCommand( new Command() { - public void execute() { - final Set selectedJobs = getSelectedJobs(); - - int selectionSize = selectedJobs.size(); - if ( selectionSize > 0 ) { - final MessageDialogBox prompt = new MessageDialogBox( - Messages.getString( "warning" ), - Messages.getString( "deleteConfirmSchedles", "" + selectionSize ), - false, - Messages.getString( "yes" ), - Messages.getString( "no" ) ); - - prompt.setCallback( new IDialogCallback() { - public void okPressed() { - controlJobs( selectedJobs, "removeJob", RequestBuilder.DELETE, true ); - prompt.hide(); - } - - public void cancelPressed() { - prompt.hide(); - } - } ); - - prompt.center(); - } - } - } ); - scheduleRemoveButton.setToolTip( Messages.getString( "remove" ) ); - scheduleRemoveButton.setEnabled( false ); - bar.add( scheduleRemoveButton ); - - tableAndPager.add( bar ); - tableAndPager.add( table ); - tableAndPager.add( pager ); - - // Add it to the root panel. - setWidget( tableAndPager ); - } - - private void editJob( final JsJob editJob ) { - final String jobId = editJob.getJobId(); - final String apiEndpoint = "api/scheduler/jobinfo?jobId=" + URL.encodeQueryString( jobId ); - - RequestBuilder executableTypesRequestBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint ); - executableTypesRequestBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - executableTypesRequestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - final JsJob jsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); - - // check email is setup - final String checkEmailEndpoint = "api/emailconfig/isValid"; - RequestBuilder emailValidRequest = createRequestBuilder( RequestBuilder.GET, checkEmailEndpoint ); - - emailValidRequest.setHeader( "accept", "text/plain" ); - - try { - emailValidRequest.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "error" ), - exception.toString(), false, false, true ); - - dialogBox.center(); - } - - public void onResponseReceived( Request request, Response response ) { - if ( response.getStatusCode() == Response.SC_OK ) { - final boolean isEmailConfValid = Boolean.parseBoolean( response.getText() ); - final NewScheduleDialog scheduleDialog = new NewScheduleDialog( jsJob, - scheduleDialogCallback, isEmailConfValid ); - - scheduleDialog.center(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - - } else { - String message = Messages.getString( "serverErrorColon" ) + " " + response.getStatusCode(); - MessageDialogBox dialogBox = new MessageDialogBox( Messages.getString( "error" ), message, - false, false, true ); - - dialogBox.center(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void triggerExecuteNow( final Set jobs ) { - final Map> candidateJobs = new HashMap>( jobs.size() ); - for ( JsJob job : jobs ) { - List jobList = candidateJobs.get( job.getFullResourceName() ); - if ( null == jobList ) { - jobList = new ArrayList(); - candidateJobs.put( job.getFullResourceName(), jobList ); - } - jobList.add( job ); - } - - canAccessJobListRequest( jobs, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - promptForScheduleResourceError( jobs ); - } - - public void onResponseReceived( Request request, Response response ) { - final Set executeList = getExecutableJobs( candidateJobs, response ); - - // execute job schedules that can be executed - if ( !executeList.isEmpty() ) { - executeJobs( executeList ); - } - - final Set removeList = new HashSet(); - for ( JsJob job : jobs ) { - if ( !executeList.contains( job ) ) { - removeList.add( job ); - } - } - - // remove job schedules that no longer can be executed - if ( !removeList.isEmpty() ) { - promptForScheduleResourceError( removeList ); - } - } - } ); - } - - private void executeJobs( Set jobs ) { - final String title = Messages.getString( "executeNow" ); - final String message = Messages.getString( "executeNowStarted" - + ( jobs.size() > 1 ? "Multiple" : "" ) ); - - MessageDialogBox messageDialog = new MessageDialogBox( title, message, false, true, true ); - messageDialog.center(); - - controlJobs( jobs, "triggerNow", RequestBuilder.POST, true ); - } - - private Set getExecutableJobs( Map> candidateJobs, Response response ) { - final Set executeList = new HashSet(); - - try { - final List readableFiles = parseJsonAccessList( response.getText() ).getReadableFiles(); - - for ( String resourceName : readableFiles ) { - executeList.addAll( candidateJobs.get( resourceName ) ); - } - } catch ( Exception e ) { - // noop - } - - return executeList; - } - - private void promptForScheduleResourceError( final Set jobs ) { - final String promptContent = Messages.getString( - "editScheduleResourceDoesNotExist" + ( jobs.size() > 1 ? "Multiple" : "" ) ); - final MessageDialogBox prompt = new MessageDialogBox( - Messages.getString( "fileUnavailable" ), - promptContent, - true, - Messages.getString( "yesDelete" ), - Messages.getString( "no" ) ); - - prompt.setCallback( new IDialogCallback() { - public void okPressed() { - controlJobs( jobs, "removeJob", RequestBuilder.DELETE, true ); - prompt.hide(); - } - - public void cancelPressed() { - prompt.hide(); - } - } ); - - prompt.setWidth( "530px" ); - prompt.center(); - } - - private void controlJobs( final Set jobs, String function, final Method method, final boolean refreshData ) { - for ( final JsJob job : jobs ) { - RequestBuilder builder = createRequestBuilder( method, "api/scheduler/" + function ); - - builder.setHeader( HTTP.CONTENT_TYPE, JSON_CONTENT_TYPE ); - - JSONObject startJobRequest = new JSONObject(); - startJobRequest.put( "jobId", new JSONString( job.getJobId() ) ); - - try { - builder.sendRequest( startJobRequest.toString(), new RequestCallback() { - - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - final String jobState = response.getText(); - - job.setState( jobState ); - table.redraw(); - - updateJobScheduleButtonStyle( jobState ); - - if ( refreshData ) { - refresh(); - } - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - } - - private void controlScheduler( final ToolbarButton controlSchedulerButton, final String function, - final boolean isScheduler ) { - final RequestBuilder builder = createRequestBuilder( RequestBuilder.POST, "api/scheduler/" + function ); - - try { - builder.sendRequest( null, new RequestCallback() { - public void onError( Request request, Throwable exception ) { - // showError(exception); - } - - public void onResponseReceived( Request request, Response response ) { - updateControlSchedulerButtonStyle( controlSchedulerButton, response.getText() ); - - controlSchedulerButton.setEnabled( isScheduler ); - } - } ); - } catch ( RequestException e ) { - // showError(e); - } - } - - private void openOutputLocation( final String outputLocation ) { - - PerspectiveManager.getInstance().setPerspective( PerspectiveManager.BROWSER_PERSPECTIVE ); - - String url = GWT.getHostPageBaseURL() + "api/mantle/session-variable?key=scheduler_folder&value=" + outputLocation; - RequestBuilder executableTypesRequestBuilder = new CsrfRequestBuilder( RequestBuilder.POST, url ); - try { - executableTypesRequestBuilder.sendRequest( null, EmptyRequestCallback.getInstance() ); - } catch ( RequestException e ) { - // IGNORE - } - - GenericEvent event = new GenericEvent(); - event.setEventSubType( "RefreshFolderEvent" ); - event.setStringParam( outputLocation ); - EventBusUtil.EVENT_BUS.fireEvent( event ); - } - - private void showValidateOutputLocationError() { - String title = Messages.getString( "outputLocationErrorTitle" ); - String message = Messages.getString( "outputLocationErrorMessage" ); - String okText = Messages.getString( "close" ); - - MessageDialogBox dialogBox = new MessageDialogBox( title, message, - false, false, true, okText, null, null ); - - dialogBox.addStyleName( "pentaho-dialog-small" ); - dialogBox.center(); - } - - private void canAccessJobRequest( final JsJob job, RequestCallback callback ) { - final String jobId = SolutionBrowserPanel.pathToId( job.getFullResourceName() ); - - final String apiEndpoint = "api/repo/files/" + jobId + "/canAccess?cb=" + System.currentTimeMillis() - + "&permissions=" + READ_PERMISSION; - - final RequestBuilder accessBuilder = createRequestBuilder( RequestBuilder.GET, apiEndpoint ); - - try { - accessBuilder.sendRequest( null, callback ); - } catch ( RequestException re ) { - // noop - } - } - - private void canAccessJobListRequest( final Set jobs, RequestCallback callback ) { - final JSONArray jobNameList = new JSONArray(); - - int idx = 0; - for ( JsJob job : jobs ) { - jobNameList.set( idx++, new JSONString( job.getFullResourceName() ) ); - } - - final JSONObject payload = new JSONObject(); - payload.put( "strings", jobNameList ); - - final String accessListEndpoint = "api/repo/files/pathsAccessList?cb=" + System.currentTimeMillis(); - RequestBuilder accessListBuilder = createRequestBuilder( RequestBuilder.POST, accessListEndpoint ); - - accessListBuilder.setHeader( HTTP.CONTENT_TYPE, JSON_CONTENT_TYPE ); - accessListBuilder.setHeader( HTTP_ACCEPT_HEADER, JSON_CONTENT_TYPE ); - - try { - accessListBuilder.sendRequest( payload.toString(), callback ); - } catch ( RequestException re ) { - // noop - } - } - - private RequestBuilder createRequestBuilder( Method method, String apiEndpoint ) { - return createRequestBuilder( method, apiEndpoint, GWT.getHostPageBaseURL() ); - } - - private RequestBuilder createRequestBuilder( Method method, String apiEndpoint, String context ) { - final String url = context + apiEndpoint; - - RequestBuilder builder = new RequestBuilder( method, url ); - builder.setHeader( "If-Modified-Since", IF_MODIFIED_SINCE ); - - return builder; - } - - private native JsArray parseJson( String json ) /*-{ - var obj = JSON.parse(json); - - if (obj != null && obj.hasOwnProperty("job")) { - return obj.job; - } - - return []; - }-*/; - - private native JsJob parseJsonJob( String json ) /*-{ - return JSON.parse(json); - }-*/; - - private native JsPermissionsList parseJsonAccessList( String json ) /*-{ - return JSON.parse(json); - }-*/; -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java b/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java deleted file mode 100644 index adc2af361f5..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/workspace/SchedulesPerspectivePanel.java +++ /dev/null @@ -1,148 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.workspace; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -import com.google.gwt.resources.client.ImageResource; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import org.pentaho.mantle.client.messages.Messages; - -public class SchedulesPerspectivePanel extends SimplePanel { - static final int PAGE_SIZE = 25; - private static SchedulesPerspectivePanel instance = new SchedulesPerspectivePanel(); - - private VerticalPanel wrapperPanel; - private SchedulesPanel schedulesPanel; - private BlockoutPanel blockoutPanel; - - private boolean isScheduler; - private boolean isAdmin; - - public static SchedulesPerspectivePanel getInstance() { - return instance; - } - - public SchedulesPerspectivePanel() { - try { - final String url = GWT.getHostPageBaseURL() + "api/repo/files/canAdminister"; //$NON-NLS-1$ - RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.GET, url ); - requestBuilder.setHeader( "accept", "text/plain" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - isAdmin = false; - isScheduler = false; - } - - public void onResponseReceived( Request request, Response response ) { - isAdmin = "true".equalsIgnoreCase( response.getText() ); //$NON-NLS-1$ - - try { - final String url2 = GWT.getHostPageBaseURL() + "api/scheduler/canSchedule"; //$NON-NLS-1$ - RequestBuilder requestBuilder2 = new RequestBuilder( RequestBuilder.GET, url2 ); - requestBuilder2.setHeader( "accept", "application/json" ); //$NON-NLS-1$ //$NON-NLS-2$ - requestBuilder2.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); - requestBuilder2.sendRequest( null, new RequestCallback() { - - public void onError( Request request, Throwable caught ) { - isScheduler = false; - createUI(); - - } - - public void onResponseReceived( Request request, Response response ) { - isScheduler = "true".equalsIgnoreCase( response.getText() ); //$NON-NLS-1$ - createUI(); - } - - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - } - } ); - } catch ( RequestException e ) { - Window.alert( e.getMessage() ); - } - - } - - private void createUI() { - - this.setStyleName( "schedulerPerspective" ); //$NON-NLS-1$ - - wrapperPanel = new VerticalPanel(); - - String schedulesLabelStr = Messages.getString( "mySchedules" ); //$NON-NLS-1$ - if ( isAdmin ) { - schedulesLabelStr = Messages.getString( "manageSchedules" ); //$NON-NLS-1$ - } - - Label schedulesLabel = new Label( schedulesLabelStr ); - schedulesLabel.setStyleName( "workspaceHeading" ); //$NON-NLS-1$ - wrapperPanel.add( schedulesLabel ); - - schedulesPanel = new SchedulesPanel( isAdmin, isScheduler ); - schedulesPanel.setStyleName( "schedulesPanel" ); //$NON-NLS-1$ - schedulesPanel.addStyleName( "schedules-panel-wrapper" ); //$NON-NLS-1$ - wrapperPanel.add( schedulesPanel ); - - blockoutPanel = new BlockoutPanel( isAdmin ); - blockoutPanel.setStyleName( "schedulesPanel" ); //$NON-NLS-1$ - blockoutPanel.addStyleName( "blockout-schedules-panel-wrapper" ); //$NON-NLS-1$ - wrapperPanel.add( blockoutPanel ); - - SimplePanel sPanel = new SimplePanel(); - sPanel.add( wrapperPanel ); - sPanel.setStylePrimaryName( "schedulerPerspective-wrapper" ); //$NON-NLS-1$ - add( sPanel ); - - } - - public void refresh() { - schedulesPanel.refresh(); - blockoutPanel.refresh(); - } - - public interface CellTableResources extends CellTable.Resources { - @Override - public ImageResource cellTableSortAscending(); - - @Override - public ImageResource cellTableSortDescending(); - - /** - * The styles used in this widget. - */ - @Source( "org/pentaho/mantle/client/workspace/CellTable.css" ) - public CellTable.Style cellTableStyle(); - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png b/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortAscending.png deleted file mode 100644 index 06446f9d99c2ede0cab3917da60aaca3ebc06827..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gfu1goAr-fh{`~)M&#c+d+2~@xVseJ%(f^DJ(Jrn44aLNz z|7SRGM)K}r6VP)Hy3?rF@7t^(u)jIUv7}N==U)~75m5&nj?~2rZnKV?I5aRay!_wP UbUbU*44~l*p00i_>zopr09KnhAOHXW diff --git a/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png b/user-console/src/main/java/org/pentaho/mantle/client/workspace/cellTableSortDescending.png deleted file mode 100644 index 98c16ee36fe9b2155501f132cf414961af36a730..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G9-c0aAr-fh{`~)M&#c+d+34b6%A4sB(-+G2gxy4k Date: Tue, 18 Jul 2023 13:12:59 -0400 Subject: [PATCH 09/59] Getting the user-console module to a compiling state. --- .../client/admin/ContentCleanerPanel.java | 52 ++++++++++++------- .../commands/AdhocRunInBackgroundCommand.java | 8 +-- .../commands/RunInBackgroundCommand.java | 46 +++++++++------- .../solutionbrowser/ScheduleCallback.java | 6 ++- .../solutionbrowser/SolutionBrowserPanel.java | 9 ++-- .../solutionbrowser/filelist/FileCommand.java | 8 +-- 6 files changed, 79 insertions(+), 50 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java index 559612c53fd..e5b7e5de202 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java @@ -52,10 +52,12 @@ import org.pentaho.gwt.widgets.client.utils.string.StringUtils; import org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog; import org.pentaho.mantle.client.dialogs.WaitPopup; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.workspace.JsJob; -import org.pentaho.mantle.client.workspace.JsJobParam; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.workspace.JsJob; +//import org.pentaho.mantle.client.workspace.JsJobParam; import java.util.Date; @@ -104,7 +106,8 @@ public void onResponseReceived( Request request, Response response ) { nowTextBox.getElement().getStyle().setMarginRight( 5, Unit.PX ); final TextBox scheduleTextBox = new TextBox(); scheduleTextBox.setVisibleLength( 4 ); - + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /* JsJob tmpJsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); boolean fakeJob = false; @@ -131,7 +134,7 @@ public void onChange( ChangeEvent event ) { } } } - } ); + } );*/ Label settingsLabel = new Label( Messages.getString( "settings" ) ); settingsLabel.setStyleName( "pentaho-fieldgroup-major" ); @@ -190,27 +193,30 @@ public void cancelPressed() { scheduledPanel.add( deleteScheduleLabel ); Label descLabel; - if ( !fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*if ( !fakeJob ) { String desc = jsJob.getJobTrigger().getDescription(); descLabel = new Label( desc ); scheduledPanel.add( descLabel ); - } else { + } else {*/ descLabel = new Label( Messages.getString( "generatedFilesAreNotScheduledToBeDeleted" ) ); scheduledPanel.add( descLabel ); - } + //} descLabel.getElement().getStyle().setPaddingTop( 10, Unit.PX ); descLabel.getElement().getStyle().setPaddingBottom( 10, Unit.PX ); Button editScheduleButton = new Button( Messages.getString( "edit" ) ); - if ( fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*if ( fakeJob ) { editScheduleButton.setText( Messages.getString( "scheduleDeletion" ) ); - } + }*/ Button deleteScheduleButton = new Button( Messages.getString( "cancelSchedule" ) ); deleteScheduleButton.setStylePrimaryName( "pentaho-button" ); deleteScheduleButton.addStyleName( "last" ); deleteScheduleButton.addClickHandler( new ClickHandler() { public void onClick( ClickEvent event ) { - deleteContentCleaner( jsJob ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //deleteContentCleaner( jsJob ); } } ); editScheduleButton.setStylePrimaryName( "pentaho-button" ); @@ -219,7 +225,8 @@ public void onClick( ClickEvent event ) { public void onClick( ClickEvent event ) { IDialogCallback callback = new IDialogCallback() { public void okPressed() { - deleteContentCleaner( jsJob ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //deleteContentCleaner( jsJob ); } public void cancelPressed() { @@ -230,19 +237,21 @@ public void cancelPressed() { scheduleLabelPanel.add( new Label( Messages.getString( "deleteGeneratedFilesOlderThan" ), false ) ); scheduleLabelPanel.add( scheduleTextBox ); scheduleLabelPanel.add( new Label( Messages.getString( "daysUsingTheFollowingRules" ), false ) ); - ScheduleRecurrenceDialog editSchedule = + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*ScheduleRecurrenceDialog editSchedule = new ScheduleRecurrenceDialog( null, jsJob, callback, false, false, AbstractWizardDialog.ScheduleDialogType.SCHEDULER ); editSchedule.setShowSuccessDialog( false ); editSchedule.addCustomPanel( scheduleLabelPanel, DockPanel.NORTH ); - editSchedule.center(); + editSchedule.center();*/ } } ); HorizontalPanel scheduleButtonPanel = new HorizontalPanel(); scheduleButtonPanel.add( editScheduleButton ); - if ( !fakeJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //if ( !fakeJob ) { scheduleButtonPanel.add( deleteScheduleButton ); - } + //} scheduledPanel.add( scheduleButtonPanel ); add( scheduledPanel, DockPanel.NORTH ); @@ -335,7 +344,8 @@ public void onError( Request request, Throwable throwable ) { } } - private final native JsJob parseJsonJob( String json ) + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //private final native JsJob parseJsonJob( String json ) /*-{ window.parent.jobjson = json; if (null == json || "" == json) { @@ -345,7 +355,8 @@ private final native JsJob parseJsonJob( String json ) return obj; }-*/; - private final native JsJob createJsJob() + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //private final native JsJob createJsJob() /*-{ var jsJob = new Object(); jsJob.jobParams = new Object(); @@ -366,7 +377,8 @@ private final native JsJob createJsJob() return jsJob; }-*/; - private void deleteContentCleaner( JsJob jsJob ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*private void deleteContentCleaner( JsJob jsJob ) { if ( jsJob == null || StringUtils.isEmpty( jsJob.getJobId() ) ) { activate(); return; @@ -394,7 +406,7 @@ public void onResponseReceived( Request request, Response response ) { } catch ( RequestException re ) { Window.alert( re.getMessage() ); } - } + }*/ private static void showLoadingIndicator() { WaitPopup.getInstance().setVisible( true ); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java index 117f3e283ab..c255d48ff1a 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java @@ -34,7 +34,8 @@ import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -94,7 +95,8 @@ public void handle( RepositoryFile repositoryFile ) { @Override protected void showDialog( final boolean feedback ) { - final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { @Override protected void onSelect( final String name, final String outputPath, final boolean overwriteFile, final String dateFormat ) { setOutputName( name ); @@ -122,7 +124,7 @@ protected void onSelect( final String name, final String outputPath, final boole outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); outputLocationDialog.setScheduleNameText( Messages.getString( "scheduleNameColonReportviewer" ) ); - outputLocationDialog.center(); + outputLocationDialog.center();*/ } public static native void onCancel() diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index 36bd4d73970..29c6c41195d 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -40,10 +40,11 @@ import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.ScheduleCreateStatusDialog; @@ -196,7 +197,8 @@ protected JSONObject getJsonSimpleTrigger( int repeatCount, int interval, Date s } protected void showDialog( final boolean feedback ) { - final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { @Override protected void onSelect( final String name, final String outputLocationPath, final boolean overwriteFile, final String dateFormat ) { setOutputName( name ); @@ -205,7 +207,7 @@ protected void onSelect( final String name, final String outputLocationPath, fin setDateFormat( dateFormat ); performOperation( feedback ); } - }; + };*/ final String filePath = solutionPath; String urlPath = NameUtils.URLEncode( NameUtils.encodeRepositoryPath( filePath ) ); @@ -225,9 +227,11 @@ public void onResponseReceived( Request request, Response response ) { String responseMessage = response.getText(); boolean hasParams = hasParameters( responseMessage, isXAction ); if ( !hasParams ) { - outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); } - outputLocationDialog.center(); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //outputLocationDialog.center(); } else { MessageDialogBox dialogBox = new MessageDialogBox( @@ -379,18 +383,21 @@ public void onResponseReceived( Request request, Response response ) { // on final boolean isEmailConfValid = false; if ( hasParams ) { - ScheduleParamsDialog dialog = - new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); - dialog.center(); - dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleParamsDialog dialog = + // new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); + //dialog.center(); + //dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); } else if ( isEmailConfValid ) { - ScheduleEmailDialog scheduleEmailDialog = - new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); - scheduleEmailDialog.center(); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleEmailDialog scheduleEmailDialog = + // new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); + //scheduleEmailDialog.center(); } else { // Handle Schedule Parameters - JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); - scheduleRequest.put( "jobParameters", scheduleParams ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); + //scheduleRequest.put( "jobParameters", scheduleParams ); // just run it RequestBuilder scheduleFileRequestBuilder = @@ -459,7 +466,8 @@ public void onResponseReceived( Request request, Response response ) { } } - ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + /*ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { @Override public void onResponse( JSONValue rib ) { if ( rib != null && rib.isBoolean() != null && rib.isBoolean().booleanValue() ) { @@ -480,5 +488,5 @@ public void onResponse( JSONValue rib ) { dialogBox.center(); } } - }; + };*/ } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java index 290683bb129..6a66f9274bd 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java @@ -23,7 +23,8 @@ import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.messages.Messages; public class ScheduleCallback implements IDialogCallback { @@ -54,7 +55,8 @@ public void cancelPressed() { } }; - ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); } else { final MessageDialogBox dialogBox = new MessageDialogBox( diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index 0dc2091f911..b17d7b690d7 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -56,7 +56,8 @@ import org.pentaho.mantle.client.commands.ExecuteUrlInNewTabCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ShowDescriptionsEvent; import org.pentaho.mantle.client.events.ShowHiddenFilesEvent; @@ -336,7 +337,8 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga } $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - @org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //r@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); } $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES @@ -481,7 +483,8 @@ public void openFile( final RepositoryFile repositoryFile, final FileCommand.COM PerspectiveManager.getInstance().setPerspective( PerspectiveManager.OPENED_PERSPECTIVE ); editFile( repositoryFile ); } else if ( mode == FileCommand.COMMAND.SCHEDULE_NEW ) { - ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); return; } else if ( mode == FileCommand.COMMAND.SHARE ) { ShareFileCommand sfc = new ShareFileCommand(); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 4c1ff25bb3c..7f094f42c08 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -30,7 +30,8 @@ import org.pentaho.mantle.client.commands.NewFolderCommand; import org.pentaho.mantle.client.commands.RunInBackgroundCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; -import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; +//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui +//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.solutionbrowser.IRepositoryFileProvider; import org.pentaho.mantle.client.solutionbrowser.ScheduleCallback; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -97,8 +98,9 @@ public void execute() { } else if ( mode == COMMAND.BACKGROUND ) { new RunInBackgroundCommand( selectedItem ).execute( true ); } else if ( mode == COMMAND.SCHEDULE_NEW ) { - ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem - .getRepositoryFile() ) ); + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui + //ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem + // .getRepositoryFile() ) ); } else if ( mode == COMMAND.SHARE ) { new ShareFileCommand().execute(); } else if ( mode == COMMAND.IMPORT ) { From f8c10c85e519448dc6e52202f9abf767df71a34b Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Wed, 26 Jul 2023 16:12:34 -0400 Subject: [PATCH 10/59] [BACKLOG-38035] SCHEDULER - moving the scheduler UI into the new scheduler plugin --- user-console/pom.xml | 4 +- .../mantle/client/MantleEntryPoint.java | 1 + .../pentaho/mantle/client/MantleUtils.java | 91 ++++++++++++ .../client/admin/ContentCleanerPanel.java | 136 +++++------------- .../commands/AdhocRunInBackgroundCommand.java | 38 +---- .../commands/RunInBackgroundCommand.java | 116 +++++++-------- .../solutionbrowser/ScheduleCallback.java | 82 ----------- .../ScheduleCreateStatusDialog.java | 46 ------ .../solutionbrowser/SolutionBrowserPanel.java | 15 +- .../solutionbrowser/filelist/FileCommand.java | 12 +- .../mantle/client/ui/PerspectiveManager.java | 22 ++- .../org/pentaho/mantle/public/Mantle.jsp | 5 +- 12 files changed, 231 insertions(+), 337 deletions(-) create mode 100644 user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java delete mode 100644 user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java diff --git a/user-console/pom.xml b/user-console/pom.xml index 367a428f91e..41bf79677b0 100644 --- a/user-console/pom.xml +++ b/user-console/pom.xml @@ -374,9 +374,9 @@ org.pentaho.mantle.MantleApplication ${gwt.outputDirectory} -Xms512m -Xmx1024m - + - --> diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java index 14889ff0e99..09ef1974262 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java @@ -41,6 +41,7 @@ public void onModuleLoad() { "mantleMessages", true, MantleEntryPoint.this ); + new MantleUtils(); } public void bundleLoaded( String bundleName ) { diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java new file mode 100644 index 00000000000..cedfb4d991a --- /dev/null +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java @@ -0,0 +1,91 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.mantle.client; + +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestException; +import org.pentaho.mantle.client.events.EventBusUtil; +import org.pentaho.mantle.client.events.GenericEvent; +import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; +import org.pentaho.mantle.client.ui.PerspectiveManager; + +public class MantleUtils { + + static { + setupNativeHooks( new MantleUtils() ); + } + + + public void setSchedulesPerspective() { + PerspectiveManager.getInstance().setPerspective( PerspectiveManager.SCHEDULES_PERSPECTIVE ); + } + + public void setBrowserPerspective() { + PerspectiveManager.getInstance().setPerspective( PerspectiveManager.BROWSER_PERSPECTIVE ); + } + + public boolean containsExtension( String extension ) { + return SolutionBrowserPanel.getInstance().getExecutableFileExtensions().contains( extension ); + } + + public void sendRequest( RequestBuilder executableTypesRequestBuilder ) { + try { + executableTypesRequestBuilder.sendRequest( null, EmptyRequestCallback.getInstance() ); + } catch ( RequestException e ) { + // IGNORE + } + } + + public void fireRefreshFolderEvent( String outputLocation ) { + GenericEvent event = new GenericEvent(); + event.setEventSubType( "RefreshFolderEvent" ); + event.setStringParam( outputLocation ); + EventBusUtil.EVENT_BUS.fireEvent( event ); + } + + private static native void setupNativeHooks( MantleUtils utils ) + /*-{ + $wnd.mantle.setSchedulesPerspective = function() { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::setSchedulesPerspective()(); + } + + $wnd.mantle.setBrowserPerspective = function() { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::setBrowserPerspective()(); + } + + $wnd.mantle.containsExtension = function(extension) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + return utils.@org.pentaho.mantle.client.MantleUtils::containsExtension(Ljava/lang/String;)(extension); + } + + $wnd.mantle.sendRequest = function(executableTypesRequestBuilder) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::sendRequest(Lcom/google/gwt/http/client/RequestBuilder;)(executableTypesRequestBuilder); + } + + $wnd.mantle.fireRefreshFolderEvent = function(outputLocation) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + utils.@org.pentaho.mantle.client.MantleUtils::fireRefreshFolderEvent(Ljava/lang/String;)(outputLocation); + } + }-*/; +} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java index e5b7e5de202..3e68466f92a 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java @@ -21,11 +21,8 @@ package org.pentaho.mantle.client.admin; import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.Request; @@ -49,15 +46,8 @@ import com.google.gwt.user.client.ui.VerticalPanel; import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -import org.pentaho.gwt.widgets.client.wizards.AbstractWizardDialog; import org.pentaho.mantle.client.dialogs.WaitPopup; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleRecurrenceDialog; import org.pentaho.mantle.client.messages.Messages; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.workspace.JsJob; -//import org.pentaho.mantle.client.workspace.JsJobParam; import java.util.Date; @@ -106,35 +96,7 @@ public void onResponseReceived( Request request, Response response ) { nowTextBox.getElement().getStyle().setMarginRight( 5, Unit.PX ); final TextBox scheduleTextBox = new TextBox(); scheduleTextBox.setVisibleLength( 4 ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /* - JsJob tmpJsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) ); - - boolean fakeJob = false; - if ( tmpJsJob == null ) { - tmpJsJob = createJsJob(); - fakeJob = true; - } - final JsJob jsJob = tmpJsJob; - - if ( jsJob != null ) { - scheduleTextBox.setValue( "" + ( Long.parseLong( jsJob.getJobParamValue( "age" ) ) / DAY_IN_MILLIS ) ); - } else { - scheduleTextBox.setText( "180" ); - } - scheduleTextBox.addChangeHandler( new ChangeHandler() { - public void onChange( ChangeEvent event ) { - if ( jsJob != null ) { - JsArray params = jsJob.getJobParams(); - for ( int i = 0; i < params.length(); i++ ) { - if ( params.get( i ).getName().equals( "age" ) ) { - params.get( i ).setValue( "" + ( Long.parseLong( scheduleTextBox.getText() ) * DAY_IN_MILLIS ) ); - break; - } - } - } - } - } );*/ + processScheduleTextBox( JsonUtils.escapeJsonForEval( response.getText() ), scheduleTextBox ); Label settingsLabel = new Label( Messages.getString( "settings" ) ); settingsLabel.setStyleName( "pentaho-fieldgroup-major" ); @@ -193,30 +155,28 @@ public void cancelPressed() { scheduledPanel.add( deleteScheduleLabel ); Label descLabel; - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*if ( !fakeJob ) { - String desc = jsJob.getJobTrigger().getDescription(); + boolean fakeJob = isFakeJob(); + if ( !fakeJob ) { + String desc = getJobDescription(); descLabel = new Label( desc ); scheduledPanel.add( descLabel ); - } else {*/ + } else { descLabel = new Label( Messages.getString( "generatedFilesAreNotScheduledToBeDeleted" ) ); scheduledPanel.add( descLabel ); - //} + } descLabel.getElement().getStyle().setPaddingTop( 10, Unit.PX ); descLabel.getElement().getStyle().setPaddingBottom( 10, Unit.PX ); Button editScheduleButton = new Button( Messages.getString( "edit" ) ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*if ( fakeJob ) { + if ( fakeJob ) { editScheduleButton.setText( Messages.getString( "scheduleDeletion" ) ); - }*/ + } Button deleteScheduleButton = new Button( Messages.getString( "cancelSchedule" ) ); deleteScheduleButton.setStylePrimaryName( "pentaho-button" ); deleteScheduleButton.addStyleName( "last" ); deleteScheduleButton.addClickHandler( new ClickHandler() { public void onClick( ClickEvent event ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //deleteContentCleaner( jsJob ); + deleteContentCleaner(); } } ); editScheduleButton.setStylePrimaryName( "pentaho-button" ); @@ -225,8 +185,7 @@ public void onClick( ClickEvent event ) { public void onClick( ClickEvent event ) { IDialogCallback callback = new IDialogCallback() { public void okPressed() { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //deleteContentCleaner( jsJob ); + deleteContentCleaner(); } public void cancelPressed() { @@ -237,21 +196,14 @@ public void cancelPressed() { scheduleLabelPanel.add( new Label( Messages.getString( "deleteGeneratedFilesOlderThan" ), false ) ); scheduleLabelPanel.add( scheduleTextBox ); scheduleLabelPanel.add( new Label( Messages.getString( "daysUsingTheFollowingRules" ), false ) ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*ScheduleRecurrenceDialog editSchedule = - new ScheduleRecurrenceDialog( null, jsJob, callback, false, false, - AbstractWizardDialog.ScheduleDialogType.SCHEDULER ); - editSchedule.setShowSuccessDialog( false ); - editSchedule.addCustomPanel( scheduleLabelPanel, DockPanel.NORTH ); - editSchedule.center();*/ + createScheduleRecurrenceDialog( scheduleLabelPanel, callback ); } } ); HorizontalPanel scheduleButtonPanel = new HorizontalPanel(); scheduleButtonPanel.add( editScheduleButton ); - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //if ( !fakeJob ) { + if ( !fakeJob ) { scheduleButtonPanel.add( deleteScheduleButton ); - //} + } scheduledPanel.add( scheduleButtonPanel ); add( scheduledPanel, DockPanel.NORTH ); @@ -344,42 +296,8 @@ public void onError( Request request, Throwable throwable ) { } } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //private final native JsJob parseJsonJob( String json ) - /*-{ - window.parent.jobjson = json; - if (null == json || "" == json) { - return null; - } - var obj = JSON.parse(json); - return obj; - }-*/; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //private final native JsJob createJsJob() - /*-{ - var jsJob = new Object(); - jsJob.jobParams = new Object(); - jsJob.jobParams.jobParams = []; - jsJob.jobParams.jobParams[0] = new Object(); - jsJob.jobParams.jobParams[0].name = "ActionAdapterQuartzJob-ActionClass"; - jsJob.jobParams.jobParams[0].value = "org.pentaho.platform.admin.GeneratedContentCleaner"; - jsJob.jobParams.jobParams[1] = new Object(); - jsJob.jobParams.jobParams[1].name = "age"; - jsJob.jobParams.jobParams[1].value = "15552000000"; - jsJob.jobTrigger = new Object(); - jsJob.jobTrigger['@type'] = "simpleJobTrigger"; - jsJob.jobTrigger.repeatCount = -1; - jsJob.jobTrigger.repeatInterval = 86400; - jsJob.jobTrigger.scheduleType = "DAILY"; - //jsJob.jobTrigger.startTime = "2013-03-22T09:35:52.276-04:00"; - jsJob.jobName = "GeneratedContentCleaner"; - return jsJob; - }-*/; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*private void deleteContentCleaner( JsJob jsJob ) { - if ( jsJob == null || StringUtils.isEmpty( jsJob.getJobId() ) ) { + private void deleteContentCleaner() { + if ( getJobId() == null ) { activate(); return; } @@ -389,7 +307,7 @@ public void onError( Request request, Throwable throwable ) { builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ JSONObject startJobRequest = new JSONObject(); - startJobRequest.put( "jobId", new JSONString( jsJob.getJobId() ) ); //$NON-NLS-1$ + startJobRequest.put( "jobId", new JSONString( getJobId() ) ); //$NON-NLS-1$ try { builder.sendRequest( startJobRequest.toString(), new RequestCallback() { @@ -406,7 +324,7 @@ public void onResponseReceived( Request request, Response response ) { } catch ( RequestException re ) { Window.alert( re.getMessage() ); } - }*/ + } private static void showLoadingIndicator() { WaitPopup.getInstance().setVisible( true ); @@ -416,4 +334,24 @@ private static void hideLoadingIndicator() { WaitPopup.getInstance().setVisible( false ); } + private native void processScheduleTextBox( String jsonJobString, TextBox scheduleTextBox )/*-{ + $wnd.pho.processScheduleTextBox( jsonJobString, scheduleTextBox ); + }-*/; + + private native boolean isFakeJob()/*-{ + return $wnd.pho.isFakeJob(); + }-*/; + + private native String getJobDescription()/*-{ + return $wnd.pho.getJobDescription(); + }-*/; + + private native String getJobId()/*-{ + return $wnd.pho.getJobId(); + }-*/; + + private native void createScheduleRecurrenceDialog( HorizontalPanel scheduleLabelPanel, IDialogCallback callback )/*-{ + $wnd.pho.createScheduleRecurrenceDialog( scheduleLabelPanel, callback); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java index c255d48ff1a..35742945aa4 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/AdhocRunInBackgroundCommand.java @@ -34,8 +34,6 @@ import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -95,36 +93,7 @@ public void handle( RepositoryFile repositoryFile ) { @Override protected void showDialog( final boolean feedback ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( getSolutionPath() ) { - @Override - protected void onSelect( final String name, final String outputPath, final boolean overwriteFile, final String dateFormat ) { - setOutputName( name ); - setOutputLocationPath( outputPath ); - setOverwriteFile( String.valueOf( overwriteFile ) ); - setDateFormat( dateFormat ); - performOperation( feedback ); - } - - @Override protected void onCancel() { - super.onCancel(); - AdhocRunInBackgroundCommand.onCancel(); - } - - @Override protected void onOk() { - super.onOk(); - AdhocRunInBackgroundCommand.onOk( getOutputLocationPath() ); - } - - @Override protected void onAttach() { - super.onAttach(); - AdhocRunInBackgroundCommand.onAttach(); - } - }; - - outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); - outputLocationDialog.setScheduleNameText( Messages.getString( "scheduleNameColonReportviewer" ) ); - outputLocationDialog.center();*/ + createScheduleOutputLocationDialog( getSolutionPath(), getOutputLocationPath(), feedback ); } public static native void onCancel() @@ -243,4 +212,9 @@ private void onError( Throwable exception ) { true ); dialogBox.center(); } + + public native void createScheduleOutputLocationDialog(String solutionPath, String outputLocationPath, Boolean feedback) /*-{ + $wnd.pho.createScheduleOutputLocationDialog(solutionPath, outputLocationPath, feedback); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index 29c6c41195d..bf4e01f0007 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -28,26 +28,18 @@ import com.google.gwt.http.client.Response; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; -import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONBoolean; import com.google.gwt.json.client.JSONNull; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; -import com.google.gwt.json.client.JSONValue; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleEmailDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleOutputLocationDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsDialog; -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleParamsHelper; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.solutionbrowser.ScheduleCreateStatusDialog; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; import org.pentaho.mantle.client.solutionbrowser.filelist.FileItem; import org.pentaho.mantle.client.ui.PerspectiveManager; @@ -197,17 +189,9 @@ protected JSONObject getJsonSimpleTrigger( int repeatCount, int interval, Date s } protected void showDialog( final boolean feedback ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*final ScheduleOutputLocationDialog outputLocationDialog = new ScheduleOutputLocationDialog( solutionPath ) { - @Override - protected void onSelect( final String name, final String outputLocationPath, final boolean overwriteFile, final String dateFormat ) { - setOutputName( name ); - setOutputLocationPath( outputLocationPath ); - setOverwriteFile( String.valueOf( overwriteFile ) ); - setDateFormat( dateFormat ); - performOperation( feedback ); - } - };*/ + + createScheduleOutputLocationDialog( getSolutionPath(), feedback ); + final String filePath = solutionPath; String urlPath = NameUtils.URLEncode( NameUtils.encodeRepositoryPath( filePath ) ); @@ -227,11 +211,9 @@ public void onResponseReceived( Request request, Response response ) { String responseMessage = response.getText(); boolean hasParams = hasParameters( responseMessage, isXAction ); if ( !hasParams ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //outputLocationDialog.setOkButtonText( Messages.getString( "ok" ) ); + setOkButtonText(); } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //outputLocationDialog.center(); + centerScheduleOutputLocationDialog(); } else { MessageDialogBox dialogBox = new MessageDialogBox( @@ -383,21 +365,13 @@ public void onResponseReceived( Request request, Response response ) { // on final boolean isEmailConfValid = false; if ( hasParams ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleParamsDialog dialog = - // new ScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid ); - //dialog.center(); - //dialog.setAfterResponseCallback( scheduleParamsDialogCallback ); + boolean isSchedulesPerspectiveActive = !PerspectiveManager.getInstance().getActivePerspective().getId().equals(PerspectiveManager.SCHEDULES_PERSPECTIVE ); + createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid, isSchedulesPerspectiveActive ); } else if ( isEmailConfValid ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleEmailDialog scheduleEmailDialog = - // new ScheduleEmailDialog( null, filePath, scheduleRequest, null, null ); - //scheduleEmailDialog.center(); + crateScheduleEmailDialog( filePath, scheduleRequest ); } else { // Handle Schedule Parameters - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //JSONArray scheduleParams = ScheduleParamsHelper.getScheduleParams( scheduleRequest ); - //scheduleRequest.put( "jobParameters", scheduleParams ); + getScheduleParams( scheduleRequest ); // just run it RequestBuilder scheduleFileRequestBuilder = @@ -466,27 +440,55 @@ public void onResponseReceived( Request request, Response response ) { } } - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - /*ScheduleParamsDialog.IAfterResponse scheduleParamsDialogCallback = new ScheduleParamsDialog.IAfterResponse() { - @Override - public void onResponse( JSONValue rib ) { - if ( rib != null && rib.isBoolean() != null && rib.isBoolean().booleanValue() ) { - MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "runInBackground" ), Messages.getString( "backgroundExecutionStarted" ), //$NON-NLS-1$ //$NON-NLS-2$ - false, false, true ); - dialogBox.center(); - } else if ( !PerspectiveManager.getInstance().getActivePerspective().getId().equals( - PerspectiveManager.SCHEDULES_PERSPECTIVE ) ) { - ScheduleCreateStatusDialog successDialog = new ScheduleCreateStatusDialog(); - successDialog.center(); - } else { - MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "scheduleUpdatedTitle" ), Messages.getString( "scheduleUpdatedMessage" ), //$NON-NLS-1$ //$NON-NLS-2$ - false, false, true ); - dialogBox.center(); - } + private native void setupNativeHooks( RunInBackgroundCommand cmd ) + /*-{ + $wnd.mantle_runInBackgroundCommand.setOutputName = function(name) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(name); + } + + $wnd.mantle_runInBackgroundCommand.setOutputLocationPath = function(outputPath) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputPath); + } + + $wnd.mantle_runInBackgroundCommand.setOverwriteFile = function(overwriteFile) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOverwriteFile(Ljava/lang/String;)(overwriteFile); + } + + $wnd.mantle_runInBackgroundCommand.setDateFormat = function(dateFormat) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setDateFormat(Ljava/lang/String;)(dateFormat); } - };*/ + + $wnd.mantle_runInBackgroundCommand.performOperation = function(feedback) { + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Ljava/lang/Boolean;)(feedback); + } + }-*/; + + public native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ + $wnd.pho.createScheduleOutputLocationDialog(solutionPath, feedback); + }-*/; + + public native void setOkButtonText() /*-{ + $wnd.pho.setOkButtonText(); + }-*/; + + public native void centerScheduleOutputLocationDialog() /*-{ + $wnd.pho.centerScheduleOutputLocationDialog(); + }-*/; + + public native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ + $wnd.pho.createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfigValid, isSchedulesPerspectiveActive ); + }-*/; + + public native void crateScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ + $wnd.pho.crateScheduleEmailDialog( filePath, scheduleRequest ); + }-*/; + + public native void getScheduleParams( JSONObject scheduleRequest) /*-{ + $wnd.pho.getScheduleParams( scheduleRequest ); + }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java deleted file mode 100644 index 6a66f9274bd..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCallback.java +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.solutionbrowser; - -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; -import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; -import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; -import org.pentaho.mantle.client.messages.Messages; - -public class ScheduleCallback implements IDialogCallback { - private final RepositoryFile repositoryFile; - - public ScheduleCallback( RepositoryFile repositoryFile ) { - this.repositoryFile = repositoryFile; - } - - @Override - public void okPressed() { - String extension = ""; //$NON-NLS-1$ - if ( repositoryFile.getPath().lastIndexOf( "." ) > 0 ) { //$NON-NLS-1$ - extension = repositoryFile.getPath().substring( repositoryFile.getPath().lastIndexOf( "." ) + 1 ); //$NON-NLS-1$ - } - - if ( SolutionBrowserPanel.getInstance().getExecutableFileExtensions().contains( extension ) ) { - - IDialogCallback callback = new IDialogCallback() { - @Override - public void okPressed() { - ScheduleCreateStatusDialog dialog = new ScheduleCreateStatusDialog(); - dialog.center(); - } - - @Override - public void cancelPressed() { - } - }; - - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.showScheduleDialog( repositoryFile.getPath(), callback ); - } else { - final MessageDialogBox dialogBox = - new MessageDialogBox( - Messages.getString( "open" ), Messages.getString( "scheduleInvalidFileType", repositoryFile.getPath() ), false, false, true ); //$NON-NLS-1$ //$NON-NLS-2$ - - dialogBox.setCallback( new IDialogCallback() { - public void cancelPressed() { - } - - public void okPressed() { - dialogBox.hide(); - } - } ); - - dialogBox.center(); - return; - } - } - - @Override - public void cancelPressed() { - } -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java deleted file mode 100644 index 6569111fe22..00000000000 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/ScheduleCreateStatusDialog.java +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.mantle.client.solutionbrowser; - -import com.google.gwt.user.client.ui.HasHorizontalAlignment; -import com.google.gwt.user.client.ui.Label; -import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; -import org.pentaho.mantle.client.messages.Messages; -import org.pentaho.mantle.client.ui.PerspectiveManager; - -public class ScheduleCreateStatusDialog extends PromptDialogBox { - - public ScheduleCreateStatusDialog() { - super( Messages.getString( "scheduleCreated" ), Messages.getString( "yes" ), Messages.getString( "no" ), false, - true ); - Label label = new Label(); - label.setText( Messages.getString( "scheduleCreateSuccess" ) ); - label.setHorizontalAlignment( HasHorizontalAlignment.ALIGN_LEFT ); - setContent( label ); - setWidth( "400px" ); - } - - protected void onOk() { - super.onOk(); - PerspectiveManager.getInstance().setPerspective( PerspectiveManager.SCHEDULES_PERSPECTIVE ); - } - -} diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index b17d7b690d7..b332c7a2bea 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -47,6 +47,7 @@ import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.TreeListener; import com.google.gwt.user.client.ui.Widget; +import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; @@ -56,8 +57,6 @@ import org.pentaho.mantle.client.commands.ExecuteUrlInNewTabCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; import org.pentaho.mantle.client.csrf.CsrfRequestBuilder; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ShowDescriptionsEvent; import org.pentaho.mantle.client.events.ShowHiddenFilesEvent; @@ -336,9 +335,10 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga return solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::setNavigatorShowing(Z)(show); } $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { - //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //r@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); + //MAY NOT BE USED ANYMORE!!!!! + //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES + //@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); } $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES @@ -483,8 +483,7 @@ public void openFile( final RepositoryFile repositoryFile, final FileCommand.COM PerspectiveManager.getInstance().setPerspective( PerspectiveManager.OPENED_PERSPECTIVE ); editFile( repositoryFile ); } else if ( mode == FileCommand.COMMAND.SCHEDULE_NEW ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.createSchedule( repositoryFile, new ScheduleCallback( repositoryFile ) ); + createSchedule( repositoryFile ); return; } else if ( mode == FileCommand.COMMAND.SHARE ) { ShareFileCommand sfc = new ShareFileCommand(); @@ -836,4 +835,8 @@ public InfoDialog( String title, String message, boolean isHTML, boolean autoHid cancelButton.removeFromParent(); } } + + private native void createSchedule( final RepositoryFile repositoryFile )/*-{ + $wnd.pho.createSchedule( repositoryFile ); + }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 7f094f42c08..81be807abae 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -23,6 +23,7 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.PopupPanel; +import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.mantle.client.commands.ExportFileCommand; import org.pentaho.mantle.client.commands.FilePropertiesCommand; @@ -30,10 +31,7 @@ import org.pentaho.mantle.client.commands.NewFolderCommand; import org.pentaho.mantle.client.commands.RunInBackgroundCommand; import org.pentaho.mantle.client.commands.ShareFileCommand; -//TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui -//import org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper; import org.pentaho.mantle.client.solutionbrowser.IRepositoryFileProvider; -import org.pentaho.mantle.client.solutionbrowser.ScheduleCallback; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; import org.pentaho.mantle.client.solutionbrowser.filepicklist.FavoritePickList; @@ -98,9 +96,7 @@ public void execute() { } else if ( mode == COMMAND.BACKGROUND ) { new RunInBackgroundCommand( selectedItem ).execute( true ); } else if ( mode == COMMAND.SCHEDULE_NEW ) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //ScheduleHelper.createSchedule( selectedItem.getRepositoryFile(), new ScheduleCallback( selectedItem - // .getRepositoryFile() ) ); + createSchedule( selectedItem.getRepositoryFile() ); } else if ( mode == COMMAND.SHARE ) { new ShareFileCommand().execute(); } else if ( mode == COMMAND.IMPORT ) { @@ -118,4 +114,8 @@ public void execute() { } } + private native void createSchedule( final RepositoryFile repositoryFile )/*-{ + $wnd.pho.createSchedule( repositoryFile ); + }-*/; + } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 58ba876e263..4984dbe31b6 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -56,7 +56,6 @@ import org.pentaho.mantle.client.ui.xul.JsXulOverlay; import org.pentaho.mantle.client.ui.xul.MantleXul; import org.pentaho.gwt.widgets.client.menuitem.MenuCloner; -import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel; import org.pentaho.platform.api.engine.perspective.pojo.IPluginPerspective; import org.pentaho.platform.plugin.services.pluginmgr.perspective.pojo.DefaultPluginPerspective; import org.pentaho.ui.xul.XulOverlay; @@ -445,13 +444,12 @@ private void showSchedulesPerspective() { public void onSuccess() { DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); - if ( MantleApplication.getInstance().getContentDeck().getWidgetIndex( - SchedulesPerspectivePanel.getInstance() ) == -1 ) { - contentDeck.add( SchedulesPerspectivePanel.getInstance() ); + if ( getSchedulerPerspectivePanelIndex( contentDeck ) == -1 ) { + addSchedulesPerspectivePanel( contentDeck ); } else { - SchedulesPerspectivePanel.getInstance().refresh(); + refreshSchedulesPerspectivePanel(); } - contentDeck.showWidget( contentDeck.getWidgetIndex( SchedulesPerspectivePanel.getInstance() ) ); + contentDeck.showWidget( getSchedulerPerspectivePanelIndex( contentDeck ) ); } public void onFailure( Throwable reason ) { @@ -500,6 +498,18 @@ private void hijackContentArea( IPluginPerspective perspective ) { perspectiveActivated( frameElement ); } + public native int getSchedulerPerspectivePanelIndex( DeckPanel contentDeck ) /*-{ + return $wnd.pho.getSchedulerPerspectivePanelIndex( contentDeck ); + }-*/; + + public native void addSchedulesPerspectivePanel( DeckPanel contentDeck ) /*-{ + $wnd.pho.addSchedulesPerspectivePanel( contentDeck ); + }-*/; + + public native void refreshSchedulesPerspectivePanel() /*-{ + $wnd.pho.refreshSchedulesPerspectivePanel(); + }-*/; + private native void perspectiveActivated( Element frameElement ) /*-{ try { diff --git a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp index 121a0cdef10..ec8bf4ec1a4 100644 --- a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp +++ b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp @@ -262,7 +262,10 @@ <%if ( hasDataAccessPlugin ) {%> - + + <%}}}%> From b044f17468f1dba60705f035ad225732157d0fdc Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Fri, 4 Aug 2023 17:34:19 -0400 Subject: [PATCH 11/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../mantle/client/MantleEntryPoint.java | 4 +++ .../commands/RunInBackgroundCommand.java | 35 ++++++++++--------- .../solutionbrowser/SolutionBrowserPanel.java | 4 +-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java index 09ef1974262..634be15f24d 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleEntryPoint.java @@ -41,6 +41,10 @@ public void onModuleLoad() { "mantleMessages", true, MantleEntryPoint.this ); + initializeNativeHooks(); + } + + private void initializeNativeHooks() { new MantleUtils(); } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index bf4e01f0007..86d516b6051 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -65,6 +65,7 @@ public class RunInBackgroundCommand extends AbstractCommand { private FileItem repositoryFile; public RunInBackgroundCommand() { + setupNativeHooks( this ); } public RunInBackgroundCommand( FileItem fileItem ) { @@ -368,7 +369,7 @@ public void onResponseReceived( Request request, Response response ) { boolean isSchedulesPerspectiveActive = !PerspectiveManager.getInstance().getActivePerspective().getId().equals(PerspectiveManager.SCHEDULES_PERSPECTIVE ); createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfValid, isSchedulesPerspectiveActive ); } else if ( isEmailConfValid ) { - crateScheduleEmailDialog( filePath, scheduleRequest ); + createScheduleEmailDialog( filePath, scheduleRequest ); } else { // Handle Schedule Parameters getScheduleParams( scheduleRequest ); @@ -440,55 +441,55 @@ public void onResponseReceived( Request request, Response response ) { } } - private native void setupNativeHooks( RunInBackgroundCommand cmd ) + private static native void setupNativeHooks( RunInBackgroundCommand cmd ) /*-{ - $wnd.mantle_runInBackgroundCommand.setOutputName = function(name) { + $wnd.mantle_runInBackgroundCommand_setOutputName = function(outputName) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(name); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputName(Ljava/lang/String;)(outputName); } - $wnd.mantle_runInBackgroundCommand.setOutputLocationPath = function(outputPath) { + $wnd.mantle_runInBackgroundCommand_setOutputLocationPath = function(outputLocationPath) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputPath); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOutputLocationPath(Ljava/lang/String;)(outputLocationPath); } - $wnd.mantle_runInBackgroundCommand.setOverwriteFile = function(overwriteFile) { + $wnd.mantle_runInBackgroundCommand_setOverwriteFile = function(overwriteFile) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setOverwriteFile(Ljava/lang/String;)(overwriteFile); } - $wnd.mantle_runInBackgroundCommand.setDateFormat = function(dateFormat) { + $wnd.mantle_runInBackgroundCommand_setDateFormat = function(dateFormat) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::setDateFormat(Ljava/lang/String;)(dateFormat); } - $wnd.mantle_runInBackgroundCommand.performOperation = function(feedback) { + $wnd.mantle_runInBackgroundCommand_performOperation = function(feedback) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Ljava/lang/Boolean;)(feedback); + cmd.@org.pentaho.mantle.client.commands.RunInBackgroundCommand::performOperation(Z)(feedback); } }-*/; - public native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ + private native void createScheduleOutputLocationDialog(String solutionPath, Boolean feedback) /*-{ $wnd.pho.createScheduleOutputLocationDialog(solutionPath, feedback); }-*/; - public native void setOkButtonText() /*-{ + private native void setOkButtonText() /*-{ $wnd.pho.setOkButtonText(); }-*/; - public native void centerScheduleOutputLocationDialog() /*-{ + private native void centerScheduleOutputLocationDialog() /*-{ $wnd.pho.centerScheduleOutputLocationDialog(); }-*/; - public native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ + private native void createScheduleParamsDialog( String filePath, JSONObject scheduleRequest, Boolean isEmailConfigValid, Boolean isSchedulesPerspectiveActive ) /*-{ $wnd.pho.createScheduleParamsDialog( filePath, scheduleRequest, isEmailConfigValid, isSchedulesPerspectiveActive ); }-*/; - public native void crateScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ - $wnd.pho.crateScheduleEmailDialog( filePath, scheduleRequest ); + private native void createScheduleEmailDialog( String filePath, JSONObject scheduleRequest ) /*-{ + $wnd.pho.createScheduleEmailDialog( filePath, scheduleRequest ); }-*/; - public native void getScheduleParams( JSONObject scheduleRequest) /*-{ + private native void getScheduleParams( JSONObject scheduleRequest) /*-{ $wnd.pho.getScheduleParams( scheduleRequest ); }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index b332c7a2bea..bc605b551db 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -334,12 +334,12 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES return solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::setNavigatorShowing(Z)(show); } - $wnd.mantle_confirmBackgroundExecutionDialog = function (url) { + //$wnd.mantle_confirmBackgroundExecutionDialog = function (url) { //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui //MAY NOT BE USED ANYMORE!!!!! //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES //@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); - } + //} $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::openFile(Ljava/lang/String;Ljava/lang/String;)(pathToFile, mode); From b58aa258fffe201a7782e7cc78aa9ae803efec3f Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Tue, 29 Aug 2023 08:49:29 -0400 Subject: [PATCH 12/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../java/org/pentaho/platform/web/servlet/JAXRSServlet.java | 1 - .../mantle/client/solutionbrowser/filelist/FileCommand.java | 1 - .../main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java | 2 +- .../src/main/resources/org/pentaho/mantle/public/Mantle.jsp | 1 + 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java index 12cb768eb41..8b1967569e3 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java @@ -181,7 +181,6 @@ protected Resource getResourceByPath( String path ) { String springFile = PentahoSystem.getApplicationContext() .getSolutionPath( "system" + File.separator + "pentahoServices.spring.xml" ); //$NON-NLS-1$ //$NON-NLS-2$ - //wac.setConfigLocations( new String[] { springFile, "/Users/aramos/Documents/Hitachi/REPOS/BUILDS/pentaho-server/pentaho-solutions/system/scheduler-plugin/plugin.spring.xml" } ); wac.setConfigLocations( new String[] { springFile } ); wac.addBeanFactoryPostProcessor( new PentahoBeanScopeValidatorPostProcessor() ); wac.refresh(); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 81be807abae..0bb98a699e3 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -23,7 +23,6 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.PopupPanel; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.mantle.client.commands.ExportFileCommand; import org.pentaho.mantle.client.commands.FilePropertiesCommand; diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java index db4567cfcb8..31ae88eb618 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java @@ -33,7 +33,6 @@ import org.pentaho.mantle.client.commands.OpenKettleStatusCommand; import org.pentaho.mantle.client.commands.PrintCommand; import org.pentaho.mantle.client.commands.RefreshRepositoryCommand; -//import org.pentaho.mantle.client.commands.RefreshSchedulesCommand; import org.pentaho.mantle.client.commands.SaveCommand; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.ISolutionBrowserEvent; @@ -297,6 +296,7 @@ public void onFailure( Throwable reason ) { @Bindable public void refreshContent() { + //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui // TODO Need to delegate this refresh to plugins as well //if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() // .getId() ) ) { diff --git a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp index ec8bf4ec1a4..f39e7969378 100644 --- a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp +++ b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp @@ -265,6 +265,7 @@ + <%}}}%> From c9a22b1e4f604298094b74d632c05c1d87f572b7 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Tue, 29 Aug 2023 10:43:43 -0400 Subject: [PATCH 13/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java | 1 - .../mantle/client/solutionbrowser/filelist/FileCommand.java | 1 - 2 files changed, 2 deletions(-) diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java index 12cb768eb41..8b1967569e3 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSServlet.java @@ -181,7 +181,6 @@ protected Resource getResourceByPath( String path ) { String springFile = PentahoSystem.getApplicationContext() .getSolutionPath( "system" + File.separator + "pentahoServices.spring.xml" ); //$NON-NLS-1$ //$NON-NLS-2$ - //wac.setConfigLocations( new String[] { springFile, "/Users/aramos/Documents/Hitachi/REPOS/BUILDS/pentaho-server/pentaho-solutions/system/scheduler-plugin/plugin.spring.xml" } ); wac.setConfigLocations( new String[] { springFile } ); wac.addBeanFactoryPostProcessor( new PentahoBeanScopeValidatorPostProcessor() ); wac.refresh(); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 81be807abae..0bb98a699e3 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -23,7 +23,6 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.PopupPanel; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.mantle.client.commands.ExportFileCommand; import org.pentaho.mantle.client.commands.FilePropertiesCommand; From 9c7f4b0d2c932b5927a20c4ac89f0241e6c8f8d0 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Wed, 30 Aug 2023 12:39:53 -0400 Subject: [PATCH 14/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../system/default-plugin/plugin.xml | 4 --- .../solutionbrowser/SolutionBrowserPanel.java | 6 ---- .../mantle/client/ui/PerspectiveManager.java | 30 +++---------------- .../mantle/client/ui/xul/MantleModel.java | 17 ++++++----- .../org/pentaho/mantle/public/Mantle.jsp | 6 +--- 5 files changed, 14 insertions(+), 49 deletions(-) diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/default-plugin/plugin.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/default-plugin/plugin.xml index 287e99d3a8e..97428e89aff 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/default-plugin/plugin.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/default-plugin/plugin.xml @@ -29,10 +29,6 @@ - - - diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index bc605b551db..0c9bd208a40 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -334,12 +334,6 @@ private static native void setupNativeHooks( SolutionBrowserPanel solutionNaviga //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES return solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::setNavigatorShowing(Z)(show); } - //$wnd.mantle_confirmBackgroundExecutionDialog = function (url) { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - //MAY NOT BE USED ANYMORE!!!!! - //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES - //@org.pentaho.mantle.client.dialogs.scheduling.ScheduleHelper::confirmBackgroundExecutionDialog(Ljava/lang/String;)(url); - //} $wnd.mantle_openRepositoryFile = function (pathToFile, mode) { //CHECKSTYLE IGNORE LineLength FOR NEXT 1 LINES solutionNavigator.@org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel::openFile(Ljava/lang/String;Ljava/lang/String;)(pathToFile, mode); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 4984dbe31b6..40f851a4e47 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -439,22 +439,8 @@ private void showOpenedPerspective( boolean browserChecked, boolean schedulesChe } private void showSchedulesPerspective() { - - GWT.runAsync( new RunAsyncCallback() { - - public void onSuccess() { - DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); - if ( getSchedulerPerspectivePanelIndex( contentDeck ) == -1 ) { - addSchedulesPerspectivePanel( contentDeck ); - } else { - refreshSchedulesPerspectivePanel(); - } - contentDeck.showWidget( getSchedulerPerspectivePanelIndex( contentDeck ) ); - } - - public void onFailure( Throwable reason ) { - } - } ); + DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); + showSchedulesPerspective( contentDeck ); setCheckMMenuItem( false, true ); } @@ -498,16 +484,8 @@ private void hijackContentArea( IPluginPerspective perspective ) { perspectiveActivated( frameElement ); } - public native int getSchedulerPerspectivePanelIndex( DeckPanel contentDeck ) /*-{ - return $wnd.pho.getSchedulerPerspectivePanelIndex( contentDeck ); - }-*/; - - public native void addSchedulesPerspectivePanel( DeckPanel contentDeck ) /*-{ - $wnd.pho.addSchedulesPerspectivePanel( contentDeck ); - }-*/; - - public native void refreshSchedulesPerspectivePanel() /*-{ - $wnd.pho.refreshSchedulesPerspectivePanel(); + public native void showSchedulesPerspective( DeckPanel contentDeck ) /*-{ + return $wnd.pho.showSchedulesPerspective( contentDeck ); }-*/; private native void perspectiveActivated( Element frameElement ) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java index 31ae88eb618..48a209fd5a0 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/xul/MantleModel.java @@ -296,16 +296,13 @@ public void onFailure( Throwable reason ) { @Bindable public void refreshContent() { - //TODO REFACTOR-DEPENDENCY TO pentaho-scheduler-plugin/ui - // TODO Need to delegate this refresh to plugins as well - //if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() - // .getId() ) ) { - // Command cmd = new RefreshSchedulesCommand(); - //cmd.execute(); - //} else { + if ( PerspectiveManager.SCHEDULES_PERSPECTIVE.equals( PerspectiveManager.getInstance().getActivePerspective() + .getId() ) ) { + refreshSchedules(); + } else { Command cmd = new RefreshRepositoryCommand(); cmd.execute(); - //} + } } @Bindable @@ -484,4 +481,8 @@ public void setShowNavigatorSelected( boolean showNavigator ) { this.showNavigatorSelected = showNavigator; } + public native void refreshSchedules() /*-{ + $wnd.pho.refreshSchedules(); + }-*/; + } diff --git a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp index f39e7969378..121a0cdef10 100644 --- a/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp +++ b/user-console/src/main/resources/org/pentaho/mantle/public/Mantle.jsp @@ -262,11 +262,7 @@ <%if ( hasDataAccessPlugin ) {%> - - - + <%}}}%> From e5933160735ad2083daa448c417482ca65324d5c Mon Sep 17 00:00:00 2001 From: wilseyler Date: Wed, 30 Aug 2023 12:38:13 -0400 Subject: [PATCH 15/59] [BACKLOG-38036] - Fixed problems with plugin startup. (+1 squashed commit) Squashed commits: [3c8ef0f6c] BACKLOG-38036 - Changes to allow scheduler-plugin to startup --- .../pentaho-solutions/system/pentahoObjects.spring.xml | 7 ------- .../resources/pentaho-solutions/system/systemListeners.xml | 1 - 2 files changed, 8 deletions(-) diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml index 6171065d451..15752f0045f 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml @@ -50,13 +50,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - - - - - - - diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml index e8810acff36..6361b624395 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml @@ -32,7 +32,6 @@ - 86400 From 2f92abe44084be4f7745bd489ee348152bf9e69d Mon Sep 17 00:00:00 2001 From: wilseyler Date: Thu, 7 Sep 2023 10:46:20 -0400 Subject: [PATCH 16/59] BACKLOG-38036 - Moved classes to fix circular dependency problem between scheduler and extensions --- .../plugin/services/importer/SolutionImportHandler.java | 2 +- .../platform/web/http/api}/SchedulerResource.java | 9 ++++++--- .../platform/web/http/api}/proxies/BlockStatusProxy.java | 2 +- .../web/http/api/resources/services/FileService.java | 4 ++-- .../web/http/api}/services/SchedulerService.java | 6 ++++-- .../services/importer/SolutionImportHandlerTest.java | 2 +- .../web/http/api/resources/SchedulerResourceTest.java | 6 +++--- .../http/api/resources/proxies/BlockStatusProxyTest.java | 3 ++- .../api/resources/services/SchedulerServiceTest.java | 3 ++- scheduler/pom.xml | 8 -------- 10 files changed, 22 insertions(+), 23 deletions(-) rename {scheduler/src/main/java/org/pentaho/platform/web/http/api/resources => extensions/src/main/java/org/pentaho/platform/web/http/api}/SchedulerResource.java (99%) rename {scheduler/src/main/java/org/pentaho/platform/web/http/api/resources => extensions/src/main/java/org/pentaho/platform/web/http/api}/proxies/BlockStatusProxy.java (97%) rename {scheduler/src/main/java/org/pentaho/platform/web/http/api/resources => extensions/src/main/java/org/pentaho/platform/web/http/api}/services/SchedulerService.java (99%) diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 262bdf562f3..1a76f1b9f9d 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -81,10 +81,10 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; +import org.pentaho.platform.web.http.api.SchedulerResource; import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.SchedulerResource; import org.pentaho.platform.web.http.api.resources.services.FileService; public class SolutionImportHandler implements IPlatformImportHandler { diff --git a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java similarity index 99% rename from scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java index 9f8ec9a71a9..86d06bc2322 100644 --- a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api.resources; +package org.pentaho.platform.web.http.api; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.APPLICATION_XML; @@ -54,8 +54,11 @@ import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.services.SchedulerService; +import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; +import org.pentaho.platform.web.http.api.resources.JobRequest; +import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; +import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; +import org.pentaho.platform.web.http.api.services.SchedulerService; import org.pentaho.platform.web.http.messages.Messages; /** diff --git a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java similarity index 97% rename from scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java index 6aaa13e16e7..78b1133e2b5 100644 --- a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxy.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api.resources.proxies; +package org.pentaho.platform.web.http.api.proxies; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java index aae8b9daf1e..fa3203a941e 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java @@ -1547,8 +1547,8 @@ private List doGetGeneratedContentForUser( String pathId, Str * @throws FileNotFoundException * @private */ - protected List searchGeneratedContent( String userDir, String targetComparator, - String metadataConstant ) + public List searchGeneratedContent( String userDir, String targetComparator, + String metadataConstant ) throws FileNotFoundException { List content = new ArrayList(); diff --git a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java similarity index 99% rename from scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java index 7b39cbe3e5d..7156eb8afdf 100644 --- a/scheduler/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api.resources.services; +package org.pentaho.platform.web.http.api.services; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; @@ -48,6 +48,7 @@ import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; import org.pentaho.platform.util.ActionUtil; import org.pentaho.platform.util.messages.LocaleHelper; +import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; import org.pentaho.platform.web.http.api.resources.ComplexJobTriggerProxy; import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; @@ -56,7 +57,8 @@ import org.pentaho.platform.web.http.api.resources.SchedulerOutputPathResolver; import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; import org.pentaho.platform.web.http.api.resources.SessionResource; -import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; +import org.pentaho.platform.web.http.api.resources.services.FileService; + import java.io.FileNotFoundException; import java.io.IOException; diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java index 004ef084149..10edf01b627 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java @@ -55,7 +55,7 @@ import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetaStore; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.SchedulerResource; +import org.pentaho.platform.web.resources.SchedulerResource; import javax.ws.rs.core.Response; import java.io.File; diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java index cbf31b8ee4d..d55136cc894 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java @@ -28,9 +28,9 @@ import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener; -import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.services.SchedulerService; +import org.pentaho.platform.web.resources.SchedulerResource; +import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; +import org.pentaho.platform.web.resources.services.SchedulerService; import javax.ws.rs.core.Response; diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java index 94caa40bf09..dbf4332c2d4 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java @@ -20,10 +20,11 @@ package org.pentaho.platform.web.http.api.resources.proxies; +import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; import org.pentaho.test.BeanTester; public class BlockStatusProxyTest extends BeanTester { public BlockStatusProxyTest() { super( BlockStatusProxy.class ); } -} \ No newline at end of file +} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java index 36648c0aa0f..c1fbe78f8bd 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java @@ -74,7 +74,8 @@ import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.SchedulerOutputPathResolver; import org.pentaho.platform.web.http.api.resources.SessionResource; -import org.pentaho.platform.web.http.api.resources.proxies.BlockStatusProxy; +import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; +import org.pentaho.platform.web.resources.services.SchedulerService; @RunWith( MockitoJUnitRunner.class ) public class SchedulerServiceTest { diff --git a/scheduler/pom.xml b/scheduler/pom.xml index 9ce9d38187d..77142401c07 100644 --- a/scheduler/pom.xml +++ b/scheduler/pom.xml @@ -200,14 +200,6 @@ - - - pentaho - pentaho-platform-extensions - 9.6.0.0-SNAPSHOT - compile - - From 570ff10be001c739b3dbbeb2b854fad7d61d2876 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Thu, 7 Sep 2023 13:07:01 -0400 Subject: [PATCH 17/59] BACKLOG-38036 - Refactor of SchedulerResource --- .../plugin/services/importer/SolutionImportHandler.java | 2 +- .../web/http/api/{ => resources}/SchedulerResource.java | 7 ++----- .../api/{ => resources}/services/SchedulerService.java | 2 +- .../web/http/api/resources/SchedulerResourceTest.java | 6 +++--- 4 files changed, 7 insertions(+), 10 deletions(-) rename extensions/src/main/java/org/pentaho/platform/web/http/api/{ => resources}/SchedulerResource.java (99%) rename extensions/src/main/java/org/pentaho/platform/web/http/api/{ => resources}/services/SchedulerService.java (99%) diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 1a76f1b9f9d..7fb07ba224f 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -81,7 +81,7 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.SchedulerResource; +import org.pentaho.platform.web.http.api.resources.SchedulerResource; import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java similarity index 99% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java index 86d06bc2322..a1672183380 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api; +package org.pentaho.platform.web.http.api.resources; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.APPLICATION_XML; @@ -55,10 +55,7 @@ import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.JobRequest; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; -import org.pentaho.platform.web.http.api.services.SchedulerService; +import org.pentaho.platform.web.http.api.resources.services.SchedulerService; import org.pentaho.platform.web.http.messages.Messages; /** diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java similarity index 99% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java index 7156eb8afdf..172a6bedd6e 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api.services; +package org.pentaho.platform.web.http.api.resources.services; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java index d55136cc894..bd86b5e34e7 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java @@ -28,9 +28,9 @@ import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.web.resources.SchedulerResource; -import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; -import org.pentaho.platform.web.resources.services.SchedulerService; +import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; +import org.pentaho.platform.web.http.api.resources.services.SchedulerService; + import javax.ws.rs.core.Response; From 23cab95e54f55f71b77ae15af06f2cfc7d324145 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Thu, 7 Sep 2023 13:07:01 -0400 Subject: [PATCH 18/59] BACKLOG-38036 - Refactor of SchedulerResource --- .../system/pentahoObjects.spring.xml | 1 - .../system/pentahoServices.spring.xml | 2 - .../system/systemListeners.xml | 9 - .../platform/admin/GatherStatsListener.java | 4 +- .../exporter/PentahoPlatformExporter.java | 3 +- .../services/exporter/ScheduleExportUtil.java | 6 +- .../importer/SolutionImportHandler.java | 2 +- .../api/resources/JobScheduleRequest.java | 3 + .../{ => resources}/SchedulerResource.java | 494 +++++++++--------- .../api/resources/SchedulerResourceUtil.java | 62 ++- .../services/SchedulerService.java | 12 +- .../api/resources/SchedulerResourceTest.java | 6 +- .../api/scheduler2/IComplexJobTrigger.java | 32 +- .../api/scheduler2/ICronJobTrigger.java | 3 +- .../platform/api/scheduler2/IJobTrigger.java | 4 +- .../api/scheduler2/ISimpleJobTrigger.java | 13 +- .../wrappers/DayOfMonthWrapper.java | 44 ++ .../scheduler2/wrappers/DayOfWeekWrapper.java | 46 ++ .../scheduler2/wrappers/HourlyWrapper.java | 43 ++ .../scheduler2/wrappers/MinuteWrapper.java} | 32 +- .../scheduler2/wrappers/MonthlyWrapper.java | 42 ++ .../scheduler2/wrappers/SecondWrapper.java | 43 ++ .../scheduler2/wrappers/YearlyWrapper.java | 42 ++ .../RepositoryCleanerSystemListener.java | 22 +- .../scheduler2/blockout/BlockoutAction.java | 66 +++ .../EmbeddedVersionCheckSystemListener.java | 163 ------ .../versionchecker/VersionCheckerAction.java | 54 -- 27 files changed, 681 insertions(+), 572 deletions(-) rename extensions/src/main/java/org/pentaho/platform/web/http/api/{ => resources}/SchedulerResource.java (78%) rename extensions/src/main/java/org/pentaho/platform/web/http/api/{ => resources}/services/SchedulerService.java (98%) create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java rename scheduler/src/main/java/org/pentaho/platform/{scheduler2/blockout/IBlockoutAction.java => api/scheduler2/wrappers/MinuteWrapper.java} (50%) create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/VersionCheckerAction.java diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml index 15752f0045f..855244e75b6 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml @@ -50,7 +50,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml index cbda42e0351..23aaff7cdd3 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml @@ -128,8 +128,6 @@ - - diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml index 6361b624395..de6b26101c7 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/systemListeners.xml @@ -32,15 +32,6 @@ - - - 86400 - - - - false - - diff --git a/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java b/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java index e64d5610eb3..3af5683158a 100644 --- a/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java +++ b/extensions/src/main/java/org/pentaho/platform/admin/GatherStatsListener.java @@ -73,9 +73,9 @@ private void scheduleJob( int intervalInSeconds ) throws Exception { /* * protected Class resolveClass(String className) throws PluginBeanException { - * + * * Class clazz = null; - * + * * IPluginManager pluginManager = PentahoSystem.get(IPluginManager.class); clazz = pluginManager.loadClass(className); * if (clazz == null) { throw new PluginBeanException(); } return clazz; } */ diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java index 2102b12332e..03261f75605 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java @@ -61,7 +61,6 @@ import org.pentaho.platform.plugin.services.metadata.IPentahoMetadataDomainRepositoryExporter; import org.pentaho.platform.repository.solution.filebased.MondrianVfs; import org.pentaho.platform.repository2.ClientRepositoryPaths; -import org.pentaho.platform.scheduler2.versionchecker.EmbeddedVersionCheckSystemListener; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.slf4j.Logger; @@ -313,7 +312,7 @@ protected void exportSchedules() { try { List jobs = getScheduler().getJobs( null ); for ( IJob job : jobs ) { - if ( job.getJobName().equals( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ) ) { + if ( job.getJobName().equals( "PentahoSystemVersionCheck" ) ) { // don't bother exporting the Version Checker schedule, it gets created automatically on server start // if it doesn't exist and fails if you try to import it due to a null ActionClass continue; diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java index 8a408018ce1..c2d07ac5de8 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java @@ -31,6 +31,7 @@ import org.pentaho.platform.api.scheduler2.IBlockoutManager; import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; @@ -42,7 +43,7 @@ public class ScheduleExportUtil { - public static final String RUN_PARAMETERS_KEY = "parameters"; + public static final String RUN_PARAMETERS_KEY = "parameters"; public ScheduleExportUtil() { // to get 100% coverage @@ -50,7 +51,8 @@ public ScheduleExportUtil() { public static JobScheduleRequest createJobScheduleRequest( IJob job ) { if ( job == null ) { - throw new IllegalArgumentException( Messages.getInstance().getString( "ScheduleExportUtil.JOB_MUST_NOT_BE_NULL" ) ); + throw new IllegalArgumentException( + Messages.getInstance().getString( "ScheduleExportUtil.JOB_MUST_NOT_BE_NULL" ) ); } IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ assert scheduler != null; diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 1a76f1b9f9d..7fb07ba224f 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -81,7 +81,7 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.SchedulerResource; +import org.pentaho.platform.web.http.api.resources.SchedulerResource; import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java index ba3b54a158c..10834cd5f98 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Map; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.pentaho.platform.api.scheduler2.ICronJobTrigger; @@ -117,6 +118,7 @@ public void setOutputFile( String file ) { this.outputFile = file; } + @XmlElement(name = "data", type=Object.class) public ICronJobTrigger getCronJobTrigger() { return cronJobTrigger; } @@ -141,6 +143,7 @@ public void setComplexJobTrigger( ComplexJobTriggerProxy jobTrigger ) { this.complexJobTrigger = jobTrigger; } + @XmlElement(name = "data", type=Object.class) public ISimpleJobTrigger getSimpleJobTrigger() { return simpleJobTrigger; } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java similarity index 78% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java index 86d06bc2322..fc41efab818 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/SchedulerResource.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api; +package org.pentaho.platform.web.http.api.resources; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.APPLICATION_XML; @@ -55,16 +55,14 @@ import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.JobRequest; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; -import org.pentaho.platform.web.http.api.services.SchedulerService; +import org.pentaho.platform.web.http.api.resources.services.SchedulerService; import org.pentaho.platform.web.http.messages.Messages; /** - * The SchedulerResource service provides the means to create, read, update, delete, and list schedules and blockout periods. Also provides the ability to control the status of schedules and the scheduler. + * The SchedulerResource service provides the means to create, read, update, delete, and list schedules and blockout + * periods. Also provides the ability to control the status of schedules and the scheduler. */ -@Path ( "/scheduler-plugin/api/scheduler" ) +@Path( "/scheduler" ) public class SchedulerResource { protected SchedulerService schedulerService; @@ -73,9 +71,9 @@ public class SchedulerResource { public SchedulerResource() { schedulerService = new SchedulerService(); - System.out.println("-----------------------------------------------------------------------"); - System.out.println("SchedulerResource was initialized."); - System.out.println("-----------------------------------------------------------------------"); + System.out.println( "-----------------------------------------------------------------------" ); + System.out.println( "SchedulerResource was initialized." ); + System.out.println( "-----------------------------------------------------------------------" ); } @@ -83,10 +81,10 @@ public SchedulerResource() { * Creates a new scheduled job. * *

Example Request:
- * POST pentaho/api/scheduler/job + * POST pentaho/api/scheduler/job *

*
POST data: - *
+   * 
    *      <jobScheduleRequest>
    *      <jobName>JobName</jobName>
    *      <simpleJobTrigger>
@@ -108,7 +106,6 @@ public SchedulerResource() {
    * 

* * @param scheduleRequest A JobScheduleRequest object to define the parameters of the job being created. - * * @return A jax-rs Response object with the created jobId. * *

Example Response:

@@ -117,15 +114,15 @@ public SchedulerResource() { *
*/ @POST - @Path ( "/job" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Schedule created successfully." ), - @ResponseCode ( code = 401, condition = "User is not allowed to create schedules." ), - @ResponseCode ( code = 403, condition = "Cannot create schedules for the specified file." ), - @ResponseCode ( code = 500, condition = "An error occurred while creating a schedule." ) - } ) + @Path( "/job" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Schedule created successfully." ), + @ResponseCode( code = 401, condition = "User is not allowed to create schedules." ), + @ResponseCode( code = 403, condition = "Cannot create schedules for the specified file." ), + @ResponseCode( code = 500, condition = "An error occurred while creating a schedule." ) + } ) public Response createJob( JobScheduleRequest scheduleRequest ) { try { IJob job = schedulerService.createJob( scheduleRequest ); @@ -146,10 +143,10 @@ public Response createJob( JobScheduleRequest scheduleRequest ) { * removing the current instance. * *

Example Request:
- * POST pentaho/api/scheduler/job/edit + * POST pentaho/api/scheduler/job/edit *

*
POST data: - *
+   * 
    *      <jobScheduleRequest>
    *      <jobName>JobName</jobName>
    *      <simpleJobTrigger>
@@ -180,15 +177,15 @@ public Response createJob( JobScheduleRequest scheduleRequest ) {
    * 
*/ @POST - @Path ( "/job/update" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Schedule updated successfully." ), - @ResponseCode ( code = 401, condition = "User is not allowed to update schedules." ), - @ResponseCode ( code = 403, condition = "Cannot update schedules for the specified file." ), - @ResponseCode ( code = 500, condition = "An error occurred while updating a schedule." ) - } ) + @Path( "/job/update" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Schedule updated successfully." ), + @ResponseCode( code = 401, condition = "User is not allowed to update schedules." ), + @ResponseCode( code = 403, condition = "Cannot update schedules for the specified file." ), + @ResponseCode( code = 500, condition = "An error occurred while updating a schedule." ) + } ) public Response updateJob( JobScheduleRequest scheduleRequest ) { try { IJob job = schedulerService.updateJob( scheduleRequest ); @@ -208,10 +205,10 @@ public Response updateJob( JobScheduleRequest scheduleRequest ) { * Execute a previously scheduled job. * *

Example Request:
- * POST pentaho/api/scheduler/triggerNow + * POST pentaho/api/scheduler/triggerNow *

*
POST data: - *
+   * 
    *      <jobRequest>
    *      <jobId>admin  JobName 1410786491777</jobId>
    *      </jobRequest>
@@ -219,7 +216,6 @@ public Response updateJob( JobScheduleRequest scheduleRequest ) {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A Response object indicating the status of the scheduler. * *

Example Response:

@@ -228,14 +224,14 @@ public Response updateJob( JobScheduleRequest scheduleRequest ) { *
*/ @POST - @Path ( "/triggerNow" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Job triggered successfully." ), - @ResponseCode ( code = 400, condition = "Invalid input." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) - } ) + @Path( "/triggerNow" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Job triggered successfully." ), + @ResponseCode( code = 400, condition = "Invalid input." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) + } ) public Response triggerNow( JobRequest jobRequest ) { try { IJob job = schedulerService.triggerNow( jobRequest.getJobId() ); @@ -249,7 +245,7 @@ public Response triggerNow( JobRequest jobRequest ) { * Get the scheduled job created by the system for deleting generated files. * *

Example Request:
- * GET pentaho/api/scheduler/getContentCleanerJob + * GET pentaho/api/scheduler/getContentCleanerJob *

* * @return A Job object containing the definition of the content cleaner job. @@ -301,12 +297,12 @@ public Response triggerNow( JobRequest jobRequest ) { *
*/ @GET - @Path ( "/getContentCleanerJob" ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Content cleaner job successfully retrieved." ), - @ResponseCode ( code = 204, condition = "No content cleaner job exists." ), - } ) + @Path( "/getContentCleanerJob" ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Content cleaner job successfully retrieved." ), + @ResponseCode( code = 204, condition = "No content cleaner job exists." ), + } ) public IJob getContentCleanerJob() { try { return schedulerService.getContentCleanerJob(); @@ -319,7 +315,7 @@ public IJob getContentCleanerJob() { * Retrieve the all the job(s) visible to the current users. * *

Example Request:
- * GET pentaho/api/scheduler/jobs + * GET pentaho/api/scheduler/jobs *

* * @param asCronString Cron string (Unused). @@ -412,14 +408,14 @@ public IJob getContentCleanerJob() { */ @Deprecated @GET - @Path ( "/jobs" ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @Facet ( name = "Unsupported" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Jobs retrieved successfully." ), - @ResponseCode ( code = 500, condition = "Error while retrieving jobs." ) - } ) - public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString" ) Boolean asCronString ) { + @Path( "/jobs" ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @Facet( name = "Unsupported" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Jobs retrieved successfully." ), + @ResponseCode( code = 500, condition = "Error while retrieving jobs." ) + } ) + public List getJobs( @DefaultValue( "false" ) @QueryParam( "asCronString" ) Boolean asCronString ) { try { return schedulerService.getJobs(); } catch ( SchedulerException e ) { @@ -431,7 +427,7 @@ public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString * Retrieve the all the scheduled job(s) visible to the current users. * *

Example Request:
- * GET pentaho/api/scheduler/getJobs + * GET pentaho/api/scheduler/getJobs *

* * @return A list of jobs that are visible to the current users. @@ -522,12 +518,12 @@ public List getJobs( @DefaultValue ( "false" ) @QueryParam ( "asCronString *
*/ @GET - @Path ( "/getJobs" ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Jobs retrieved successfully." ), - @ResponseCode ( code = 500, condition = "Error while retrieving jobs." ), - } ) + @Path( "/getJobs" ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Jobs retrieved successfully." ), + @ResponseCode( code = 500, condition = "Error while retrieving jobs." ), + } ) public List getAllJobs() { try { return schedulerService.getJobs(); @@ -540,12 +536,12 @@ public List getAllJobs() { * Checks whether the current user may schedule a repository file in the platform. * *

Example Request:
- * GET pentaho/api/scheduler/isScheduleAllowed?id=b5f806b9-9f72-4814-b1e0-aa9e0ece7e1a + * GET pentaho/api/scheduler/isScheduleAllowed?id=b5f806b9-9f72-4814-b1e0-aa9e0ece7e1a *

* * @param id The repository file ID of the content to checked. - * - * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for the file. + * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for + * the file. * *

Example Response:

*
@@ -553,13 +549,13 @@ public List getAllJobs() {
    * 
*/ @GET - @Path ( "/isScheduleAllowed" ) - @Produces ( TEXT_PLAIN ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully retrieved scheduling ability of repository file." ), - @ResponseCode ( code = 500, condition = "Invalid repository file id." ), - } ) - public String isScheduleAllowed( @QueryParam ( "id" ) String id ) { + @Path( "/isScheduleAllowed" ) + @Produces( TEXT_PLAIN ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully retrieved scheduling ability of repository file." ), + @ResponseCode( code = 500, condition = "Invalid repository file id." ), + } ) + public String isScheduleAllowed( @QueryParam( "id" ) String id ) { return "" + schedulerService.isScheduleAllowed( id ); } @@ -567,10 +563,11 @@ public String isScheduleAllowed( @QueryParam ( "id" ) String id ) { * Checks whether the current user has authority to schedule any content in the platform. * *

Example Request:
- * GET pentaho/api/scheduler/canSchedule + * GET pentaho/api/scheduler/canSchedule *

* - * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for the user. + * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for + * the user. * *

Example Response:

*
@@ -578,12 +575,12 @@ public String isScheduleAllowed( @QueryParam ( "id" ) String id ) {
    * 
*/ @GET - @Path ( "/canSchedule" ) - @Produces ( APPLICATION_JSON ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successful retrieved the scheduling permission." ), - @ResponseCode ( code = 500, condition = "Unable to retrieve the scheduling permission." ) - } ) + @Path( "/canSchedule" ) + @Produces( APPLICATION_JSON ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successful retrieved the scheduling permission." ), + @ResponseCode( code = 500, condition = "Unable to retrieve the scheduling permission." ) + } ) public String doGetCanSchedule() { return schedulerService.doGetCanSchedule(); } @@ -592,7 +589,7 @@ public String doGetCanSchedule() { * Returns the state of the scheduler with the value of RUNNING or PAUSED. * *

Example Request:
- * GET pentaho/api/scheduler/state + * GET pentaho/api/scheduler/state *

* * @return status of the scheduler as RUNNING or PAUSED. @@ -603,12 +600,12 @@ public String doGetCanSchedule() { *
*/ @GET - @Path ( "/state" ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully retrieved the state of the scheduler." ), - @ResponseCode ( code = 500, condition = "An error occurred when getting the state of the scheduler." ) - } ) + @Path( "/state" ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully retrieved the state of the scheduler." ), + @ResponseCode( code = 500, condition = "An error occurred when getting the state of the scheduler." ) + } ) public Response getState() { try { String state = schedulerService.getState(); @@ -622,10 +619,10 @@ public Response getState() { * Resume the scheduler from a paused state. * *

Example Request:
- * POST pentaho/api/scheduler/start + * POST pentaho/api/scheduler/start *

*
POST data: - *
+   * 
    *    This POST body does not contain data.
    *  
*

@@ -638,12 +635,12 @@ public Response getState() { *
*/ @POST - @Path ( "/start" ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully started the server." ), - @ResponseCode ( code = 500, condition = "An error occurred when resuming the scheduler." ) - } ) + @Path( "/start" ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully started the server." ), + @ResponseCode( code = 500, condition = "An error occurred when resuming the scheduler." ) + } ) public Response start() { try { String status = schedulerService.start(); @@ -657,10 +654,10 @@ public Response start() { * Pause the scheduler from a running state. * *

Example Request:
- * POST pentaho/api/scheduler/pause + * POST pentaho/api/scheduler/pause *

*
POST data: - *
+   * 
    *    This POST body does not contain data.
    *  
*

@@ -673,12 +670,12 @@ public Response start() { *
*/ @POST - @Path ( "/pause" ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully paused the server." ), - @ResponseCode ( code = 500, condition = "An error occurred when pausing the scheduler." ) - } ) + @Path( "/pause" ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully paused the server." ), + @ResponseCode( code = 500, condition = "An error occurred when pausing the scheduler." ) + } ) public Response pause() { try { String status = schedulerService.pause(); @@ -692,10 +689,10 @@ public Response pause() { * Shuts down the scheduler. * *

Example Request:
- * POST pentaho/api/scheduler/shutdown + * POST pentaho/api/scheduler/shutdown *

*
POST data: - *
+   * 
    *    This POST body does not contain data.
    *  
*

@@ -708,12 +705,12 @@ public Response pause() { *
*/ @POST - @Path ( "/shutdown" ) - @Produces ( "text/plain" ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully shut down the server." ), - @ResponseCode ( code = 500, condition = "An error occurred when shutting down the scheduler." ) - } ) + @Path( "/shutdown" ) + @Produces( "text/plain" ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully shut down the server." ), + @ResponseCode( code = 500, condition = "An error occurred when shutting down the scheduler." ) + } ) public Response shutdown() { try { String status = schedulerService.shutdown(); @@ -727,10 +724,10 @@ public Response shutdown() { * Checks the state of the selected scheduled job. * *

Example Request:
- * POST pentaho/api/scheduler/jobState + * POST pentaho/api/scheduler/jobState *

*
POST data: - *
+   * 
    *      <jobRequest>
    *      <jobId>admin  JobName 1410786491777</jobId>
    *      </jobRequest>
@@ -738,7 +735,6 @@ public Response shutdown() {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A jax-rs Response object containing the status of the scheduled job. * *

Example Response:

@@ -747,13 +743,13 @@ public Response shutdown() { *
*/ @POST - @Path ( "/jobState" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully retrieved the state of the requested job." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) - } ) + @Path( "/jobState" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully retrieved the state of the requested job." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) + } ) public Response getJobState( JobRequest jobRequest ) { try { return buildPlainTextOkResponse( schedulerService.getJobState( jobRequest ).name() ); @@ -768,10 +764,10 @@ public Response getJobState( JobRequest jobRequest ) { * Pause the specified scheduled job. * *

Example Request:
- * POST pentaho/api/scheduler/pauseJob + * POST pentaho/api/scheduler/pauseJob *

*
POST data: - *
+   * 
    *    <jobRequest>
    *    <jobId>admin  JobName 1410786491777</jobId>
    *    </jobRequest>
@@ -779,7 +775,6 @@ public Response getJobState( JobRequest jobRequest ) {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A jax-rs Response object containing the status of the scheduled job. * *

Example Response:

@@ -788,13 +783,13 @@ public Response getJobState( JobRequest jobRequest ) { *
*/ @POST - @Path ( "/pauseJob" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully paused the job." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) - } ) + @Path( "/pauseJob" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully paused the job." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) + } ) public Response pauseJob( JobRequest jobRequest ) { try { IJob.JobState state = schedulerService.pauseJob( jobRequest.getJobId() ); @@ -808,10 +803,10 @@ public Response pauseJob( JobRequest jobRequest ) { * Resume the specified scheduled job. * *

Example Request:
- * POST pentaho/api/scheduler/resumeJob + * POST pentaho/api/scheduler/resumeJob *

*
POST data: - *
+   * 
    *    <jobRequest>
    *    <jobId>admin  JobName 1410786491777</jobId>
    *    </jobRequest>
@@ -819,7 +814,6 @@ public Response pauseJob( JobRequest jobRequest ) {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A jax-rs Response object containing the status of the scheduled job. * *

Example Response:

@@ -828,13 +822,13 @@ public Response pauseJob( JobRequest jobRequest ) { *
*/ @POST - @Path ( "/resumeJob" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully resumed the job." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) - } ) + @Path( "/resumeJob" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully resumed the job." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) + } ) public Response resumeJob( JobRequest jobRequest ) { try { IJob.JobState state = schedulerService.resumeJob( jobRequest.getJobId() ); @@ -848,10 +842,10 @@ public Response resumeJob( JobRequest jobRequest ) { * Delete the specified scheduled job from the platform. * *

Example Request:
- * DELETE pentaho/api/scheduler/removeJob + * DELETE pentaho/api/scheduler/removeJob *

*
DELETE data: - *
+   * 
    *    <jobRequest>
    *    <jobId>admin  BlockoutAction 1410786491503</jobId>
    *    </jobRequest>
@@ -859,7 +853,6 @@ public Response resumeJob( JobRequest jobRequest ) {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A jax-rs Response object containing the status of the scheduled job. * *

Example Response:

@@ -869,13 +862,13 @@ public Response resumeJob( JobRequest jobRequest ) { */ @Deprecated @DELETE - @Path ( "/removeJob" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully removed the job." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) - } ) + @Path( "/removeJob" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully removed the job." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) + } ) public Response removeJob( JobRequest jobRequest ) { return deleteJob( jobRequest ); } @@ -884,10 +877,10 @@ public Response removeJob( JobRequest jobRequest ) { * Delete the specified scheduled job from the platform. * *

Example Request:
- * PUT pentaho/api/scheduler/removeJob + * PUT pentaho/api/scheduler/removeJob *

*
PUT data: - *
+   * 
    *    <jobRequest>
    *    <jobId>admin  BlockoutAction 1410786491503</jobId>
    *    </jobRequest>
@@ -895,7 +888,6 @@ public Response removeJob( JobRequest jobRequest ) {
    * 

* * @param jobRequest A JobRequest object containing the jobId. - * * @return A jax-rs Response object containing the status of the scheduled job. * *

Example Response:

@@ -904,12 +896,12 @@ public Response removeJob( JobRequest jobRequest ) { *
*/ @PUT - @Path ( "/removeJob" ) - @Produces ( "text/plain" ) - @Consumes ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully removed the job." ), - @ResponseCode ( code = 500, condition = "Invalid jobId." ) + @Path( "/removeJob" ) + @Produces( "text/plain" ) + @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully removed the job." ), + @ResponseCode( code = 500, condition = "Invalid jobId." ) } ) public Response deleteJob( JobRequest jobRequest ) { try { @@ -927,12 +919,11 @@ public Response deleteJob( JobRequest jobRequest ) { * Return the information for a specified job. * *

Example Request:
- * GET pentaho/api/scheduler/jobinfo?jobId=admin%09JobName%091410786491777 + * GET pentaho/api/scheduler/jobinfo?jobId=admin%09JobName%091410786491777 *

* - * @param jobId The jobId of the job for which we are requesting information. + * @param jobId The jobId of the job for which we are requesting information. * @param asCronString Cron string (Unused) - * * @return A Job object containing the info for the specified job. * *

Example Response:

@@ -941,19 +932,19 @@ public Response deleteJob( JobRequest jobRequest ) { *
*/ @GET - @Path ( "/jobinfo" ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully retrieved the information for the requested job." ), - @ResponseCode ( code = 204, condition = "jobId is valid, but the job is either finished or does not exists." ), - @ResponseCode ( code = 500, condition = "Internal error or invalid jobId." ) - } ) + @Path( "/jobinfo" ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully retrieved the information for the requested job." ), + @ResponseCode( code = 204, condition = "jobId is valid, but the job is either finished or does not exists." ), + @ResponseCode( code = 500, condition = "Internal error or invalid jobId." ) + } ) public Response getJob( @QueryParam( "jobId" ) String jobId, - @DefaultValue( "false" ) @QueryParam( "asCronString" ) String asCronString ) { + @DefaultValue( "false" ) @QueryParam( "asCronString" ) String asCronString ) { try { IJob jobInfo = schedulerService.getJobInfo( jobId ); if ( jobInfo == null ) { - return buildStatusResponse( Status.NO_CONTENT ); + return buildStatusResponse( Status.NO_CONTENT ); } return buildOkResponse( jobInfo ); } catch ( SchedulerException e ) { @@ -963,9 +954,9 @@ public Response getJob( @QueryParam( "jobId" ) String jobId, @Deprecated @GET - @Path ( "/jobinfotest" ) - @Produces ( { APPLICATION_JSON } ) - @Facet ( name = "Unsupported" ) + @Path( "/jobinfotest" ) + @Produces( { APPLICATION_JSON } ) + @Facet( name = "Unsupported" ) public JobScheduleRequest getJobInfo() { return schedulerService.getJobInfo(); } @@ -973,11 +964,11 @@ public JobScheduleRequest getJobInfo() { /** * @return list of Job * @deprecated Method is deprecated as the name getBlockoutJobs is preferred over getJobs - * + *

* Retrieves all blockout jobs in the system */ @Deprecated - @Facet ( name = "Unsupported" ) + @Facet( name = "Unsupported" ) public List getJobs() { return getBlockoutJobs(); } @@ -987,7 +978,7 @@ public List getJobs() { * Get all the blockout jobs in the system. * *

Example Request:
- * GET pentaho/api/scheduler/blockout/blockoutjobs + * GET pentaho/api/scheduler/blockout/blockoutjobs *

* * @return A Response object that contains a list of blockout jobs. @@ -1070,11 +1061,11 @@ public List getJobs() { *
*/ @GET - @Path ( "/blockout/blockoutjobs" ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully retrieved blockout jobs." ), - } ) + @Path( "/blockout/blockoutjobs" ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully retrieved blockout jobs." ), + } ) public List getBlockoutJobs() { return schedulerService.getBlockOutJobs(); } @@ -1084,7 +1075,7 @@ public List getBlockoutJobs() { * Checks if there are blockouts in the system. * *

Example Request:
- * GET pentaho/api/scheduler/blockout/hasblockouts + * GET pentaho/api/scheduler/blockout/hasblockouts *

* * @return true or false whether there are blackouts or not. @@ -1095,11 +1086,11 @@ public List getBlockoutJobs() { *
*/ @GET - @Path ( "/blockout/hasblockouts" ) - @Produces ( { TEXT_PLAIN } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully determined whether or not the system contains blockouts." ), - } ) + @Path( "/blockout/hasblockouts" ) + @Produces( { TEXT_PLAIN } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully determined whether or not the system contains blockouts." ), + } ) public Response hasBlockouts() { Boolean hasBlockouts = schedulerService.hasBlockouts(); return buildOkResponse( hasBlockouts.toString() ); @@ -1109,10 +1100,10 @@ public Response hasBlockouts() { * Creates a new blockout for scheduled jobs. * *

Example Request:
- * POST pentaho/api/scheduler/blockout/add + * POST pentaho/api/scheduler/blockout/add *

*
POST data: - *
+   * 
    *    <jobScheduleRequest>
    *    <jobName>DAILY-1820438815:admin:7740000</jobName>
    *    <complexJobTrigger>
@@ -1134,7 +1125,6 @@ public Response hasBlockouts() {
    * 

* * @param jobScheduleRequest A JobScheduleRequest object defining the blockout job. - * * @return A Response object which contains the ID of the blockout which was created. * *

Example Response:

@@ -1143,21 +1133,17 @@ public Response hasBlockouts() { *
*/ @POST - @Path ( "/blockout/add" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successful operation." ), - @ResponseCode ( code = 401, condition = "User is not authorized to create blockout." ) - } ) + @Path( "/blockout/add" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successful operation." ), + @ResponseCode( code = 401, condition = "User is not authorized to create blockout." ) + } ) public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { try { IJob job = schedulerService.addBlockout( jobScheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); - } catch ( IOException e ) { - return buildStatusResponse( UNAUTHORIZED ); - } catch ( SchedulerException e ) { - return buildStatusResponse( UNAUTHORIZED ); - } catch ( IllegalAccessException e ) { + } catch ( IOException | SchedulerException | IllegalAccessException e ) { return buildStatusResponse( UNAUTHORIZED ); } } @@ -1166,10 +1152,10 @@ public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { * Update an existing blockout. * *

Example Request:
- * POST pentaho/api/scheduler/blockout/update?jobid=admin%09BlockoutAction%091410786491209 + * POST pentaho/api/scheduler/blockout/update?jobid=admin%09BlockoutAction%091410786491209 *

*
POST data: - *
+   * 
    *    <jobScheduleRequest>
    *    <jobName>DAILY-1820438815:admin:7740000</jobName>
    *    <complexJobTrigger>
@@ -1190,9 +1176,8 @@ public Response addBlockout( JobScheduleRequest jobScheduleRequest ) {
    *  
*

* - * @param jobId The jobId of the blockout we are editing. + * @param jobId The jobId of the blockout we are editing. * @param jobScheduleRequest The payload containing the definition of the blockout. - * * @return A Response object which contains the ID of the blockout which was created. * *

Example Response:

@@ -1201,13 +1186,13 @@ public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { *
*/ @POST - @Path ( "/blockout/update" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successful operation." ), - @ResponseCode ( code = 401, condition = "User is not authorized to update blockout." ) - } ) - public Response updateBlockout( @QueryParam ( "jobid" ) String jobId, JobScheduleRequest jobScheduleRequest ) { + @Path( "/blockout/update" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successful operation." ), + @ResponseCode( code = 401, condition = "User is not authorized to update blockout." ) + } ) + public Response updateBlockout( @QueryParam( "jobid" ) String jobId, JobScheduleRequest jobScheduleRequest ) { try { IJob job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); return buildPlainTextOkResponse( job.getJobId() ); @@ -1224,10 +1209,10 @@ public Response updateBlockout( @QueryParam ( "jobid" ) String jobId, JobSchedul * Checks if the selected blockout schedule will be fired. * *

Example Request:
- * POST pentaho/api/scheduler/blockout/willFire + * POST pentaho/api/scheduler/blockout/willFire *

*
POST data: - *
+   * 
    *    <jobScheduleRequest>
    *    <jobName>DAILY-1820438815:admin:7740000</jobName>
    *    <complexJobTrigger>
@@ -1249,7 +1234,6 @@ public Response updateBlockout( @QueryParam ( "jobid" ) String jobId, JobSchedul
    * 

* * @param jobScheduleRequest The payload containing the definition of the blockout. - * * @return true or false indicating whether or not the blockout will fire. * *

Example Response:

@@ -1258,13 +1242,13 @@ public Response updateBlockout( @QueryParam ( "jobid" ) String jobId, JobSchedul *
*/ @POST - @Path ( "/blockout/willFire" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces ( { TEXT_PLAIN } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successful operation." ), - @ResponseCode ( code = 500, condition = "An error occurred while determining blockouts being fired." ) - } ) + @Path( "/blockout/willFire" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @Produces( { TEXT_PLAIN } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successful operation." ), + @ResponseCode( code = 500, condition = "An error occurred while determining blockouts being fired." ) + } ) public Response blockoutWillFire( JobScheduleRequest jobScheduleRequest ) { Boolean willFire; try { @@ -1281,7 +1265,7 @@ public Response blockoutWillFire( JobScheduleRequest jobScheduleRequest ) { * Checks if the selected blockout schedule should be fired now. * *

Example Request:
- * GET pentaho/api/scheduler/blockout/shouldFireNow + * GET pentaho/api/scheduler/blockout/shouldFireNow *

* * @return true or false whether or not the blockout should fire now. @@ -1292,11 +1276,11 @@ public Response blockoutWillFire( JobScheduleRequest jobScheduleRequest ) { *
*/ @GET - @Path ( "/blockout/shouldFireNow" ) - @Produces ( { TEXT_PLAIN } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successful operation." ) - } ) + @Path( "/blockout/shouldFireNow" ) + @Produces( { TEXT_PLAIN } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successful operation." ) + } ) public Response shouldFireNow() { Boolean result = schedulerService.shouldFireNow(); return buildOkResponse( result.toString() ); @@ -1307,10 +1291,10 @@ public Response shouldFireNow() { * Check the status of the selected blockout schedule. * *

Example Request:
- * POST pentaho/api/scheduler/blockout/blockstatus + * POST pentaho/api/scheduler/blockout/blockstatus *

*
POST data: - *
+   * 
    *    <jobScheduleRequest>
    *    <jobName>DAILY-1820438815:admin:7740000</jobName>
    *    <complexJobTrigger>
@@ -1332,8 +1316,8 @@ public Response shouldFireNow() {
    * 

* * @param jobScheduleRequest The payload containing the definition of the blockout. - * - * @return A Response object which contains a BlockStatusProxy which contains totallyBlocked and partiallyBlocked flags. + * @return A Response object which contains a BlockStatusProxy which contains totallyBlocked and partiallyBlocked + * flags. * *

Example Response:

*
@@ -1344,13 +1328,13 @@ public Response shouldFireNow() {
    * 
*/ @POST - @Path ( "/blockout/blockstatus" ) - @Consumes ( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces ( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully got the blockout status." ), - @ResponseCode ( code = 401, condition = "User is not authorized to get the blockout status." ) - } ) + @Path( "/blockout/blockstatus" ) + @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) + @Produces( { APPLICATION_JSON, APPLICATION_XML } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully got the blockout status." ), + @ResponseCode( code = 401, condition = "User is not authorized to get the blockout status." ) + } ) public Response getBlockStatus( JobScheduleRequest jobScheduleRequest ) { try { BlockStatusProxy blockStatusProxy = schedulerService.getBlockStatus( jobScheduleRequest ); @@ -1364,11 +1348,11 @@ public Response getBlockStatus( JobScheduleRequest jobScheduleRequest ) { * Retrieve the list of execute content by lineage id. * *

Example Request:
- * GET pentaho/api/scheduler/generatedContentForSchedule?lineageId=:public:Steel%20Wheels:Inventory%20List%20(report).prpt + * GET pentaho/api/scheduler/generatedContentForSchedule?lineageId=:public:Steel%20Wheels:Inventory%20List%20 + * (report).prpt *

* * @param lineageId the path for the file. - * * @return A list of RepositoryFileDto objects. * *

Example Response:

@@ -1418,12 +1402,12 @@ public Response getBlockStatus( JobScheduleRequest jobScheduleRequest ) { *
*/ @GET - @Path ( "/generatedContentForSchedule" ) - @Produces ( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes ( { - @ResponseCode ( code = 200, condition = "Successfully got the generated content for schedule" ) - } ) - public List doGetGeneratedContentForSchedule( @QueryParam ( "lineageId" ) String lineageId ) { + @Path( "/generatedContentForSchedule" ) + @Produces( { APPLICATION_XML, APPLICATION_JSON } ) + @StatusCodes( { + @ResponseCode( code = 200, condition = "Successfully got the generated content for schedule" ) + } ) + public List doGetGeneratedContentForSchedule( @QueryParam( "lineageId" ) String lineageId ) { List repositoryFileDtoList = new ArrayList(); try { repositoryFileDtoList = schedulerService.doGetGeneratedContentForSchedule( lineageId ); @@ -1431,7 +1415,7 @@ public List doGetGeneratedContentForSchedule( @QueryParam ( " //return the empty list } catch ( Throwable t ) { logger - .error( Messages.getInstance().getString( "FileResource.GENERATED_CONTENT_FOR_USER_FAILED", lineageId ), t ); + .error( Messages.getInstance().getString( "FileResource.GENERATED_CONTENT_FOR_USER_FAILED", lineageId ), t ); } return repositoryFileDtoList; } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java index 5e1b0bc57a9..ca03f7fade1 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java @@ -57,7 +57,8 @@ public class SchedulerResourceUtil { private static final Log logger = LogFactory.getLog( SchedulerResourceUtil.class ); public static final String RESERVEDMAPKEY_LINEAGE_ID = "lineage-id"; - public static final String RESERVED_BACKGROUND_EXECUTION_ACTION_ID = ".backgroundExecution"; //$NON-NLS-1$ //$NON-NLS-2$ + public static final String RESERVED_BACKGROUND_EXECUTION_ACTION_ID = ".backgroundExecution"; + //$NON-NLS-1$ //$NON-NLS-2$ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest scheduleRequest, IScheduler scheduler ) @@ -71,7 +72,8 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest // add 10 seconds to the RIB to ensure execution (see PPP-3264) IJobTrigger jobTrigger = - runInBackground ? scheduler.createSimpleJobTrigger( new Date( System.currentTimeMillis() + 10000 ), null, 0, 0 ) + runInBackground ? + scheduler.createSimpleJobTrigger( new Date( System.currentTimeMillis() + 10000 ), null, 0, 0 ) : scheduleRequest.getSimpleJobTrigger(); if ( scheduleRequest.getSimpleJobTrigger() != null ) { @@ -87,14 +89,14 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest ComplexJobTriggerProxy proxyTrigger = scheduleRequest.getComplexJobTrigger(); String cronString = proxyTrigger.getCronString(); - IComplexJobTrigger complexJobTrigger = null; + IComplexJobTrigger complexJobTrigger; /** * We will have two options. Either it is a daily scehdule to ignore DST or any other * complex schedule */ - if(cronString != null && cronString.equals("TO_BE_GENERATED")) { - cronString = generateCronString((int)proxyTrigger.getRepeatInterval()/86400 - ,proxyTrigger.getStartTime()); + if ( cronString != null && cronString.equals( "TO_BE_GENERATED" ) ) { + cronString = generateCronString( (int) proxyTrigger.getRepeatInterval() / 86400 + , proxyTrigger.getStartTime() ); complexJobTrigger = scheduler.createComplexTrigger( cronString ); } else { complexJobTrigger = scheduler.createComplexJobTrigger(); @@ -119,8 +121,8 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest complexJobTrigger.addDayOfWeekRecurrence( dayOfWeek + 1 ); } } - } else if ( proxyTrigger.getDaysOfMonth().length > 0 ) { - + } else { + proxyTrigger.getDaysOfMonth(); for ( int dayOfMonth : proxyTrigger.getDaysOfMonth() ) { complexJobTrigger.addDayOfMonthRecurrence( dayOfMonth ); } @@ -161,7 +163,7 @@ public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest complexJobTrigger.setDuration( scheduleRequest.getCronJobTrigger().getDuration() ); complexJobTrigger.setUiPassParam( scheduleRequest.getCronJobTrigger().getUiPassParam() ); jobTrigger = complexJobTrigger; - } else { + } else { throw new IllegalArgumentException(); } } @@ -183,10 +185,10 @@ public static void updateStartDateForTimeZone( JobScheduleRequest request ) { request.getComplexJobTrigger().setStartTime( serverTimeZoneStartDate ); } } else if ( request.getCronJobTrigger() != null ) { - if ( request.getCronJobTrigger().getStartTime() != null ) { - Date origStartDate = request.getCronJobTrigger().getStartTime(); + if ( request.getSimpleJobTrigger().getStartTime() != null ) { + Date origStartDate = request.getSimpleJobTrigger().getStartTime(); Date serverTimeZoneStartDate = convertDateToServerTimeZone( origStartDate, request.getTimeZone() ); - request.getCronJobTrigger().setStartTime( serverTimeZoneStartDate ); + request.getSimpleJobTrigger().setStartTime( serverTimeZoneStartDate ); } } } @@ -195,7 +197,7 @@ 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 ); + logger.warn( "original defined time: " + userDefinedTime.getTime() + " 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 ) ); @@ -204,7 +206,7 @@ public static Date convertDateToServerTimeZone( Date dateTime, String timeZone ) 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() ); + logger.warn( "adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime() ); return quartzStartDate.getTime(); } else { return dateTime; @@ -213,7 +215,8 @@ public static Date convertDateToServerTimeZone( Date dateTime, String timeZone ) public static HashMap handlePDIScheduling( RepositoryFile file, - HashMap parameterMap, Map pdiParameters ) { + HashMap parameterMap, + Map pdiParameters ) { HashMap convertedParameterMap = new HashMap<>(); @@ -231,7 +234,7 @@ public static HashMap handlePDIScheduling( RepositoryFile while ( it.hasNext() ) { - String param = (String) it.next(); + String param = it.next(); if ( !StringUtils.isEmpty( param ) && parameterMap.containsKey( param ) ) { convertedParameterMap.put( param, parameterMap.get( param ).toString() ); @@ -276,20 +279,21 @@ public static String getExtension( final String filename ) { // unchanged logic, ported over from its original location ( SchedulerService ) into this SchedulerUtil class return RepositoryFilenameUtils.getExtension( filename ); } - private static String generateCronString(long interval, Date startDate) { + + private static String generateCronString( long interval, Date startDate ) { Calendar calendar = GregorianCalendar.getInstance(); // creates a new calendar instance - calendar.setTime(startDate); - int hour = calendar.get(Calendar.HOUR_OF_DAY); - int minute = calendar.get(Calendar.MINUTE); - - Cron cron = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ)) - .withYear(always()) - .withDoM(every((int)interval)) - .withMonth(always()) - .withDoW(questionMark()) - .withHour(on(hour)) - .withMinute(on(minute)) - .withSecond(on(0)).instance(); + calendar.setTime( startDate ); + int hour = calendar.get( Calendar.HOUR_OF_DAY ); + int minute = calendar.get( Calendar.MINUTE ); + + Cron cron = CronBuilder.cron( CronDefinitionBuilder.instanceDefinitionFor( CronType.QUARTZ ) ) + .withYear( always() ) + .withDoM( every( (int) interval ) ) + .withMonth( always() ) + .withDoW( questionMark() ) + .withHour( on( hour ) ) + .withMinute( on( minute ) ) + .withSecond( on( 0 ) ).instance(); return cron.asString(); } } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java similarity index 98% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java rename to extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java index 7156eb8afdf..71a7c0ea7f0 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/services/SchedulerService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java @@ -18,7 +18,7 @@ * */ -package org.pentaho.platform.web.http.api.services; +package org.pentaho.platform.web.http.api.resources.services; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; @@ -33,7 +33,6 @@ import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.scheduler2.blockout.IBlockoutAction; import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IJobTrigger; @@ -44,6 +43,7 @@ import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.security.SecurityHelper; import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; +import org.pentaho.platform.scheduler2.blockout.BlockoutAction; import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; import org.pentaho.platform.util.ActionUtil; @@ -57,7 +57,6 @@ import org.pentaho.platform.web.http.api.resources.SchedulerOutputPathResolver; import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; import org.pentaho.platform.web.http.api.resources.SessionResource; -import org.pentaho.platform.web.http.api.resources.services.FileService; import java.io.FileNotFoundException; @@ -123,7 +122,8 @@ public IJob createJob( JobScheduleRequest scheduleRequest ) if ( hasInputFile ) { if ( file == null ) { logger.error( "Cannot find input source file " + scheduleRequest.getInputFile() + " Aborting schedule..." ); - throw new SchedulerException( new ServiceException( "Cannot find input source file " + scheduleRequest.getInputFile() ) ); + throw new SchedulerException( + new ServiceException( "Cannot find input source file " + scheduleRequest.getInputFile() ) ); } Map metadata = getRepository().getFileMetadata( file.getId() ); if ( metadata.containsKey( RepositoryFile.SCHEDULABLE_KEY ) ) { @@ -159,7 +159,7 @@ public IJob createJob( JobScheduleRequest scheduleRequest ) String outputFile = outputPathResolver.resolveOutputFilePath(); String actionId = SchedulerResourceUtil.resolveActionId( scheduleRequest.getInputFile() ); final String inputFile = scheduleRequest.getInputFile(); - parameterMap.put( ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE, inputFile ); + parameterMap.put( ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE, inputFile ); job = getScheduler().createJob( scheduleRequest.getJobName(), actionId, parameterMap, jobTrigger, new RepositoryFileStreamProvider( inputFile, outputFile, @@ -375,7 +375,7 @@ public boolean shouldFireNow() { public IJob addBlockout( JobScheduleRequest jobScheduleRequest ) throws IOException, IllegalAccessException, SchedulerException { if ( canAdminister() ) { - jobScheduleRequest.setActionClass( IBlockoutAction.getCanonicalName() ); + jobScheduleRequest.setActionClass( BlockoutAction.class.getCanonicalName() ); jobScheduleRequest.getJobParameters().add( getJobScheduleParam( IBlockoutManager.DURATION_PARAM, jobScheduleRequest.getDuration() ) ); jobScheduleRequest.getJobParameters() diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java index d55136cc894..bd86b5e34e7 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java @@ -28,9 +28,9 @@ import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.web.resources.SchedulerResource; -import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; -import org.pentaho.platform.web.resources.services.SchedulerService; +import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; +import org.pentaho.platform.web.http.api.resources.services.SchedulerService; + import javax.ws.rs.core.Response; diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java index b54823d04cd..1ff302964f9 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java @@ -1,26 +1,40 @@ package org.pentaho.platform.api.scheduler2; -import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; +import org.pentaho.platform.api.scheduler2.wrappers.DayOfMonthWrapper; +import org.pentaho.platform.api.scheduler2.wrappers.DayOfWeekWrapper; +import org.pentaho.platform.api.scheduler2.wrappers.MonthlyWrapper; +import org.pentaho.platform.api.scheduler2.wrappers.YearlyWrapper; import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; -import java.util.List; - public interface IComplexJobTrigger extends IJobTrigger { - static final int SUNDAY = 1; + static int SUNDAY = 1; long getRepeatInterval(); + void setRepeatInterval( long repeatIntervalSeconds ); + void addYearlyRecurrence( Integer... recurrence ); + void addMonthlyRecurrence( Integer... recurrence ); + void addDayOfMonthRecurrence( Integer... recurrence ); + void addDayOfWeekRecurrence( ITimeRecurrence recurrence ); + void addDayOfWeekRecurrence( Integer... recurrence ); + void setHourlyRecurrence( Integer... recurrence ); + void addMinuteRecurrence( Integer... recurrence ); - void setCronString(String cronString); - List getDayOfMonthRecurrences(); - List getMonthlyRecurrences(); - List getYearlyRecurrences(); - List getDayOfWeekRecurrences(); + void setCronString( String cronString ); + + DayOfMonthWrapper getDayOfMonthRecurrences(); + + MonthlyWrapper getMonthlyRecurrences(); + + YearlyWrapper getYearlyRecurrences(); + + DayOfWeekWrapper getDayOfWeekRecurrences(); + } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java index b25d57eaba0..bb46cec0fb3 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java @@ -20,7 +20,8 @@ package org.pentaho.platform.api.scheduler2; -public interface ICronJobTrigger extends IJobTrigger { +public interface ICronJobTrigger extends IJobTrigger{ String getCronString(); + void setCronString( String crongString ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java index 6ff9d3820ef..940b5ea9e9b 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java @@ -86,12 +86,12 @@ public interface IJobTrigger { /** * @return a long that represents in milliseconds how long this trigger should be in effect once triggered */ - public long getDuration(); + long getDuration(); /** * @param duration * * Sets the length of time in milliseconds that this trigger should be in effect. */ - public void setDuration( long duration ); + void setDuration( long duration ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java index f2b8a045fbe..177626f4937 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java @@ -24,13 +24,16 @@ * A simple way of specifying a schedule on which a job will fire as opposed to {@link IComplexJobTrigger}. The * {@link ISimpleJobTrigger} can meet your needs if you are looking for a way to have a job start, execute a set number * of times on a regular interval and then end either after a specified number of runs or at an end date. - * + * * @author aphillips */ public interface ISimpleJobTrigger extends IJobTrigger { - public int getRepeatCount(); - public void setRepeatCount( int repeatCount ); - public long getRepeatInterval(); - public void setRepeatInterval( long repeatIntervalSeconds ); + int getRepeatCount(); + + void setRepeatCount( int repeatCount ); + + long getRepeatInterval(); + + void setRepeatInterval( long repeatIntervalSeconds ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java new file mode 100644 index 00000000000..9675fdb2b4b --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java @@ -0,0 +1,44 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.QualifiedDayOfMonth; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +public class DayOfMonthWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = QualifiedDayOfMonth.class ), + @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java new file mode 100644 index 00000000000..2294905dcf4 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java @@ -0,0 +1,46 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +public class DayOfWeekWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ), + @XmlElementRef( type = QualifiedDayOfWeek.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } + + +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java new file mode 100644 index 00000000000..c4d9ccefc83 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java @@ -0,0 +1,43 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.List; + +@XmlRootElement +public class HourlyWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } +} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java similarity index 50% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java rename to scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java index ec1bc302d74..06b03bee29a 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/IBlockoutAction.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java @@ -18,23 +18,25 @@ * */ -package org.pentaho.platform.scheduler2.blockout; +package org.pentaho.platform.api.scheduler2.wrappers; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IVarArgsAction; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import java.util.Date; -import java.util.Map; +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; -/** - * @author wseyler This is the job that executes when the a block out trigger fires. This job essentially does nothing - * more than logging the firing of the trigger. - */ -public interface IBlockoutAction { - public static String getCanonicalName() { - return "org.pentaho.platform.scheduler2.blockout.BlockoutAction"; +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +public class MinuteWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; } - public void execute() throws Exception; } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java new file mode 100644 index 00000000000..6953396ced4 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java @@ -0,0 +1,42 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +public class MonthlyWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java new file mode 100644 index 00000000000..8150e462a3a --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java @@ -0,0 +1,43 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.List; + +@XmlRootElement +public class SecondWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java new file mode 100644 index 00000000000..822ab4a51dc --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java @@ -0,0 +1,42 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2.wrappers; + + +import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; +import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; +import org.pentaho.platform.scheduler2.recur.RecurrenceList; +import org.pentaho.platform.scheduler2.recur.SequentialRecurrence; + +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +public class YearlyWrapper extends ITimeWrapper { + @XmlElementRefs( { @XmlElementRef( type = SequentialRecurrence.class ), + @XmlElementRef( type = IncrementalRecurrence.class ), @XmlElementRef( type = RecurrenceList.class ) } ) + @Override + public List getRecurrences() { + return recurrences; + } +} diff --git a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java index 032ec9aa0c0..10d84f364a8 100644 --- a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java +++ b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java @@ -25,12 +25,11 @@ import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoSystemListener; import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobFilter; 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.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.StringUtil; @@ -41,11 +40,11 @@ /** * This is a 5.4-only class. To use it, update systemListeners.xml by adding the following section: *
-  <bean id="repositoryCleanerSystemListener"
-        class="org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener">
-    <property name="gcEnabled" value="true"/>
-    <property name="execute" value="now"/>
-  </bean>
+ * <bean id="repositoryCleanerSystemListener"
+ * class="org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener">
+ * <property name="gcEnabled" value="true"/>
+ * <property name="execute" value="now"/>
+ * </bean>
  * 
* gcEnabled is a non-mandatory parameter, true by default. Use it to turn off the listener without * removing its description from the XML-file @@ -57,6 +56,7 @@ * * Note, that periodic executions will be planned to start at 0:00. If an execution was not started at that time, * e.g. the server was shut down, then it will be started as soon as the scheduler is restored. + * * @author Andrey Khayrutdinov */ public class RepositoryCleanerSystemListener implements IPentahoSystemListener, IJobFilter { @@ -67,7 +67,7 @@ enum Frequency { NOW( "now" ) { @Override public IJobTrigger createTrigger() { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - return scheduler.createSimpleJobTrigger(new Date(), + return (IJobTrigger) scheduler.createSimpleJobTrigger( new Date(), new Date( Long.MAX_VALUE ), 0, 1 ); } }, @@ -76,7 +76,7 @@ enum Frequency { @Override public IJobTrigger createTrigger() { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); // execute each first day of week at 0 hours - return scheduler.createComplexTrigger( null, null, null, IComplexJobTrigger.SUNDAY, 0 ); + return (IJobTrigger) scheduler.createComplexTrigger( null, null, null, IComplexJobTrigger.SUNDAY, 0 ); } }, @@ -85,7 +85,7 @@ enum Frequency { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); // execute each first day of month at 0 hours - return scheduler.createComplexTrigger( null, null, 1, null, 0 ); + return (IJobTrigger) scheduler.createComplexTrigger( null, null, 1, null, 0 ); } }; diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java new file mode 100644 index 00000000000..75cb536f77a --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java @@ -0,0 +1,66 @@ +/*! + * + * 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-2018 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.scheduler2.blockout; + +import java.util.Date; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.pentaho.platform.api.action.IVarArgsAction; +import org.pentaho.platform.api.scheduler2.IBlockoutManager; + +/** + * @author wseyler This is the job that executes when the a block out trigger fires. This job essentially does nothing + * more than logging the firing of the trigger. + */ +public class BlockoutAction implements IVarArgsAction { + + private static final Log logger = LogFactory.getLog( BlockoutAction.class ); + + long duration; + Date scheduledFireTime; + + @Override + public void execute() throws Exception { + Date startDate = new Date(); + long effectiveDuration = duration - ( startDate.getTime() - scheduledFireTime.getTime() ); + if ( effectiveDuration < 0 ) { + logger.warn( "Blocking Scheduled for " + scheduledFireTime + " for " + this.duration + + " milliseconds has already expired" ); + } else { + logger.warn( "Blocking Started at: " + startDate + " and will last: " + effectiveDuration + " milliseconds" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Thread.sleep( effectiveDuration ); + logger.warn( "Blockout that started at: " + startDate + " has ended at: " + new Date() ); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + @Override + public void setVarArgs( Map args ) { + if ( args.containsKey( IBlockoutManager.DURATION_PARAM ) ) { + this.duration = ( (Number) args.get( IBlockoutManager.DURATION_PARAM ) ).longValue(); + } + if ( args.containsKey( IBlockoutManager.SCHEDULED_FIRE_TIME ) ) { + this.scheduledFireTime = ( (Date) args.get( IBlockoutManager.SCHEDULED_FIRE_TIME ) ); + } + } + +} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java deleted file mode 100644 index fb3a68dc532..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/EmbeddedVersionCheckSystemListener.java +++ /dev/null @@ -1,163 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.versionchecker; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobFilter; -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.engine.core.system.PentahoSystem; -import org.pentaho.platform.util.versionchecker.PentahoVersionCheckReflectHelper; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class EmbeddedVersionCheckSystemListener implements IPentahoSystemListener { - - /** - * This is a direct copy of VersionCheckSystemListener except that the mechanism for talking to quartz goes through - * the PentahoSystem factory - */ - private static final Log logger = LogFactory.getLog( EmbeddedVersionCheckSystemListener.class ); - - public static final String VERSION_CHECK_JOBNAME = "PentahoSystemVersionCheck"; //$NON-NLS-1$ - private static int MIN_CHECK_INTERVAL = 43200; - private static int DEFAULT_CHECK_INTERVAL = 86400; - - private int repeatIntervalSeconds = DEFAULT_CHECK_INTERVAL; - private String requestedReleases = "minor, ga"; //$NON-NLS-1$ - private boolean disableVersionCheck = false; - - public boolean startup( final IPentahoSession session ) { - if ( isVersionCheckAvailable() ) { - // register version check job - try { - int repeatSeconds = calculateRepeatSeconds(); - int versionRequestFlags = calculateRequestFlags(); - - if ( !disableVersionCheck ) { - scheduleJob( versionRequestFlags, repeatSeconds ); - } else { - deleteJobIfNecessary(); - } - } catch ( Exception ignoredMainException ) { - // ignore errors by versioncheck requirements unless trace level - if ( logger.isTraceEnabled() ) { - logger.trace( "Exception in VersionCheck", ignoredMainException ); //$NON-NLS-1$ - } - } - - } else { - try { - deleteJobIfNecessary(); - } catch ( SchedulerException ignoredOnPurpose ) { - // By version checker requirement, we must not log unless it's trace - if ( logger.isTraceEnabled() ) { - logger.trace( "Exception in VersionCheck", ignoredOnPurpose ); //$NON-NLS-1$ - } - } - } - return true; - } - - public int calculateRepeatSeconds() { - return Math.max( MIN_CHECK_INTERVAL, repeatIntervalSeconds ); // Force maximum number of times to check in a day - } - - protected int calculateRequestFlags() { - boolean requestMajorReleases = requestedReleases.indexOf( "major" ) >= 0; //$NON-NLS-1$ - boolean requestMinorReleases = requestedReleases.indexOf( "minor" ) >= 0; //$NON-NLS-1$ - boolean requestRCReleases = requestedReleases.indexOf( "rc" ) >= 0; //$NON-NLS-1$ - boolean requestGAReleases = requestedReleases.indexOf( "ga" ) >= 0; //$NON-NLS-1$ - boolean requestMilestoneReleases = requestedReleases.indexOf( "milestone" ) >= 0; //$NON-NLS-1$ - - int versionRequestFlags = - ( requestMajorReleases ? 4 : 0 ) + ( requestMinorReleases ? 8 : 0 ) + ( requestRCReleases ? 16 : 0 ) - + ( requestGAReleases ? 32 : 0 ) + ( requestMilestoneReleases ? 64 : 0 ); - return versionRequestFlags; - } - - protected void scheduleJob( final int versionRequestFlags, final int repeatSeconds ) throws Exception { - - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - - deleteJobIfNecessary(); - - Map parms = new HashMap(); - parms.put( VersionCheckerAction.VERSION_REQUEST_FLAGS, new Integer( versionRequestFlags ) ); - IJobTrigger trigger = scheduler.createSimpleJobTrigger( new Date(), null, -1, repeatSeconds ); -// scheduler.createJob( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME, VersionCheckerAction.class, parms, -// trigger ); - } - - protected void deleteJobIfNecessary() throws SchedulerException { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - IJobFilter filter = job -> job.getJobName().contains( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ); - - // Like old code - remove the existing job and replace it - List matchingJobs = scheduler.getJobs( filter ); - if ( ( matchingJobs != null ) && ( matchingJobs.size() > 0 ) ) { - for ( IJob verCkJob : matchingJobs ) { - scheduler.removeJob( verCkJob.getJobId() ); - } - } - } - - protected boolean isVersionCheckAvailable() { - return PentahoVersionCheckReflectHelper.isVersionCheckerAvailable(); - } - - public void shutdown() { - } - - public int getRepeatIntervalSeconds() { - return repeatIntervalSeconds; - } - - public void setRepeatIntervalSeconds( int repeatIntervalSeconds ) { - this.repeatIntervalSeconds = repeatIntervalSeconds; - } - - public String getRequestedReleases() { - return requestedReleases; - } - - public void setRequestedReleases( String requestedReleases ) { - this.requestedReleases = requestedReleases; - } - - public boolean isDisableVersionCheck() { - return disableVersionCheck; - } - - public void setDisableVersionCheck( boolean disableVersionCheck ) { - this.disableVersionCheck = disableVersionCheck; - } - -} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/VersionCheckerAction.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/VersionCheckerAction.java deleted file mode 100644 index 09c0e5ff926..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/versionchecker/VersionCheckerAction.java +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.versionchecker; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.util.versionchecker.PentahoVersionCheckReflectHelper; - -public class VersionCheckerAction implements IAction { - - public static final String VERSION_REQUEST_FLAGS = "versionRequestFlags"; //$NON-NLS-1$ - - private int requestFlags; - - public Log getLogger() { - return LogFactory.getLog( VersionCheckerAction.class ); - } - - public void setVersionRequestFlags( int value ) { - this.requestFlags = value; - } - - public int getVersionRequestFlags() { - return this.requestFlags; - } - - public void execute() { - List results = PentahoVersionCheckReflectHelper.performVersionCheck( false, this.getVersionRequestFlags() ); - if ( results != null ) { - PentahoVersionCheckReflectHelper.logVersionCheck( results, getLogger() ); - } - } -} From a0c2911e1161da348fafb5224eed20e90d0c6859 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 12 Sep 2023 07:42:01 -0400 Subject: [PATCH 19/59] BACKLOG-38036 - Working checkpoint of scheduler plugin. SchedulerResource still in platform. --- .../system/pentahoServices.spring.xml | 2 + .../importer/SolutionImportHandler.java | 224 +++++++++--------- 2 files changed, 114 insertions(+), 112 deletions(-) diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml index 23aaff7cdd3..cbda42e0351 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml @@ -128,6 +128,8 @@ + + diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 7fb07ba224f..6cf0faca7f7 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -81,7 +81,7 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.resources.SchedulerResource; +//import org.pentaho.platform.web.http.api.resources.SchedulerResource; import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; @@ -289,16 +289,16 @@ public void importFile( IPlatformImportBundle bundle ) throws PlatformImportExce } if ( manifest != null ) { - importSchedules( manifest.getScheduleList() ); +// importSchedules( manifest.getScheduleList() ); } // Process locale files. localeFilesProcessor.processLocaleFiles( importer ); } - List getAllJobs( SchedulerResource schedulerResource ) { - return schedulerResource.getAllJobs(); - } +// List getAllJobs( SchedulerResource schedulerResource ) { +// return schedulerResource.getAllJobs(); +// } private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryFileBundle fileBundle ) { String repositoryFilePath = @@ -306,103 +306,103 @@ private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryF return repository.getFile( repositoryFilePath ); } - protected void importSchedules( List scheduleList ) throws PlatformImportException { - if ( CollectionUtils.isNotEmpty( scheduleList ) ) { - SchedulerResource schedulerResource = new SchedulerResource(); - schedulerResource.pause(); - for ( JobScheduleRequest jobScheduleRequest : scheduleList ) { - - boolean jobExists = false; - - List jobs = getAllJobs( schedulerResource ); - if ( jobs != null ) { - - //paramRequest to map - Map mapParamsRequest = new HashMap<>(); - for ( JobScheduleParam paramRequest : jobScheduleRequest.getJobParameters() ) { - mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() ); - } - - for ( IJob job : jobs ) { - - if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null ) - && ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) - .equals( job.getJobParams().get( RESERVEDMAPKEY_LINEAGE_ID ) ) ) ) { - jobExists = true; - } - - if ( overwriteFile && jobExists ) { - JobRequest jobRequest = new JobRequest(); - jobRequest.setJobId( job.getJobId() ); - schedulerResource.removeJob( jobRequest ); - jobExists = false; - break; - } - } - } - - if ( !jobExists ) { - try { - Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); - if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { - if ( response.getEntity() != null ) { - // get the schedule job id from the response and add it to the import session - ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); - } - } - } catch ( Exception e ) { - // there is a scenario where if the file scheduled has a space in the file name, that it won't work. the - // di server - - // replaces spaces with underscores and the export mechanism can't determine if it needs this to happen - // or not - // so, if we failed to import and there is a space in the path, try again but this time with replacing - // the space(s) - if ( jobScheduleRequest.getInputFile().contains( " " ) || jobScheduleRequest.getOutputFile() - .contains( " " ) ) { - getLogger().info( Messages.getInstance() - .getString( "SolutionImportHandler.SchedulesWithSpaces", jobScheduleRequest.getInputFile() ) ); - File inFile = new File( jobScheduleRequest.getInputFile() ); - File outFile = new File( jobScheduleRequest.getOutputFile() ); - String inputFileName = inFile.getParent() + RepositoryFile.SEPARATOR - + inFile.getName().replace( " ", "_" ); - String outputFileName = outFile.getParent() + RepositoryFile.SEPARATOR - + outFile.getName().replace( " ", "_" ); - jobScheduleRequest.setInputFile( inputFileName ); - jobScheduleRequest.setOutputFile( outputFileName ); - try { - if ( !File.separator.equals( RepositoryFile.SEPARATOR ) ) { - // on windows systems, the backslashes will result in the file not being found in the repository - jobScheduleRequest.setInputFile( inputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); - jobScheduleRequest - .setOutputFile( outputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); - } - Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); - if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { - if ( response.getEntity() != null ) { - // get the schedule job id from the response and add it to the import session - ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); - } - } - } catch ( Exception ex ) { - // log it and keep going. we should stop processing all schedules just because one fails. - getLogger().error( Messages.getInstance() - .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ), ex ); - } - } else { - // log it and keep going. we should stop processing all schedules just because one fails. - getLogger().error( Messages.getInstance() - .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) ); - } - } - } else { - getLogger().info( Messages.getInstance() - .getString( "DefaultImportHandler.ERROR_0009_OVERWRITE_CONTENT", jobScheduleRequest.toString() ) ); - } - } - schedulerResource.start(); - } - } +// protected void importSchedules( List scheduleList ) throws PlatformImportException { +// if ( CollectionUtils.isNotEmpty( scheduleList ) ) { +// SchedulerResource schedulerResource = new SchedulerResource(); +// schedulerResource.pause(); +// for ( JobScheduleRequest jobScheduleRequest : scheduleList ) { +// +// boolean jobExists = false; +// +// List jobs = getAllJobs( schedulerResource ); +// if ( jobs != null ) { +// +// //paramRequest to map +// Map mapParamsRequest = new HashMap<>(); +// for ( JobScheduleParam paramRequest : jobScheduleRequest.getJobParameters() ) { +// mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() ); +// } +// +// for ( IJob job : jobs ) { +// +// if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null ) +// && ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) +// .equals( job.getJobParams().get( RESERVEDMAPKEY_LINEAGE_ID ) ) ) ) { +// jobExists = true; +// } +// +// if ( overwriteFile && jobExists ) { +// JobRequest jobRequest = new JobRequest(); +// jobRequest.setJobId( job.getJobId() ); +// schedulerResource.removeJob( jobRequest ); +// jobExists = false; +// break; +// } +// } +// } +// +// if ( !jobExists ) { +// try { +// Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); +// if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { +// if ( response.getEntity() != null ) { +// // get the schedule job id from the response and add it to the import session +// ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); +// } +// } +// } catch ( Exception e ) { +// // there is a scenario where if the file scheduled has a space in the file name, that it won't work. the +// // di server +// +// // replaces spaces with underscores and the export mechanism can't determine if it needs this to happen +// // or not +// // so, if we failed to import and there is a space in the path, try again but this time with replacing +// // the space(s) +// if ( jobScheduleRequest.getInputFile().contains( " " ) || jobScheduleRequest.getOutputFile() +// .contains( " " ) ) { +// getLogger().info( Messages.getInstance() +// .getString( "SolutionImportHandler.SchedulesWithSpaces", jobScheduleRequest.getInputFile() ) ); +// File inFile = new File( jobScheduleRequest.getInputFile() ); +// File outFile = new File( jobScheduleRequest.getOutputFile() ); +// String inputFileName = inFile.getParent() + RepositoryFile.SEPARATOR +// + inFile.getName().replace( " ", "_" ); +// String outputFileName = outFile.getParent() + RepositoryFile.SEPARATOR +// + outFile.getName().replace( " ", "_" ); +// jobScheduleRequest.setInputFile( inputFileName ); +// jobScheduleRequest.setOutputFile( outputFileName ); +// try { +// if ( !File.separator.equals( RepositoryFile.SEPARATOR ) ) { +// // on windows systems, the backslashes will result in the file not being found in the repository +// jobScheduleRequest.setInputFile( inputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); +// jobScheduleRequest +// .setOutputFile( outputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); +// } +// Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); +// if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { +// if ( response.getEntity() != null ) { +// // get the schedule job id from the response and add it to the import session +// ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); +// } +// } +// } catch ( Exception ex ) { +// // log it and keep going. we should stop processing all schedules just because one fails. +// getLogger().error( Messages.getInstance() +// .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ), ex ); +// } +// } else { +// // log it and keep going. we should stop processing all schedules just because one fails. +// getLogger().error( Messages.getInstance() +// .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) ); +// } +// } +// } else { +// getLogger().info( Messages.getInstance() +// .getString( "DefaultImportHandler.ERROR_0009_OVERWRITE_CONTENT", jobScheduleRequest.toString() ) ); +// } +// } +// schedulerResource.start(); +// } +// } protected void importMetaStore( ExportManifestMetaStore manifestMetaStore, boolean overwrite ) { if ( manifestMetaStore != null ) { @@ -770,16 +770,16 @@ public IPlatformImportBundle build( RepositoryFileImportBundle.Builder builder ) // handlers that extend this class may override this method and perform operations // over the job prior to its creation at scheduler.createJob() - public Response createSchedulerJob( SchedulerResource scheduler, JobScheduleRequest jobScheduleRequest ) - throws IOException { - Response rs = scheduler != null ? scheduler.createJob( jobScheduleRequest ) : null; - if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) { - JobRequest jobRequest = new JobRequest(); - jobRequest.setJobId( rs.getEntity().toString() ); - scheduler.pauseJob( jobRequest ); - } - return rs; - } +// public Response createSchedulerJob( SchedulerResource scheduler, JobScheduleRequest jobScheduleRequest ) +// throws IOException { +// Response rs = scheduler != null ? scheduler.createJob( jobScheduleRequest ) : null; +// if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) { +// JobRequest jobRequest = new JobRequest(); +// jobRequest.setJobId( rs.getEntity().toString() ); +// scheduler.pauseJob( jobRequest ); +// } +// return rs; +// } public boolean isOverwriteFile() { return overwriteFile; From 327f3ad2502bc4b315884b26ce1971367c99c67a Mon Sep 17 00:00:00 2001 From: wilseyler Date: Wed, 13 Sep 2023 15:37:25 -0400 Subject: [PATCH 20/59] BACKLOG-38036 - Moved SchedulerResource out of pentaho-platform. --- .../system/pentahoServices.spring.xml | 4 +- .../http/api/resources/BlockoutResource.java | 24 - .../http/api/resources/SchedulerResource.java | 1450 ----------------- .../resources/services/SchedulerService.java | 596 ------- 4 files changed, 2 insertions(+), 2072 deletions(-) delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/BlockoutResource.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml index cbda42e0351..3254a80cfeb 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoServices.spring.xml @@ -128,8 +128,8 @@ - - + + diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/BlockoutResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/BlockoutResource.java deleted file mode 100644 index 0417d8f9acd..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/BlockoutResource.java +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -public class BlockoutResource { -} diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java deleted file mode 100644 index fc41efab818..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResource.java +++ /dev/null @@ -1,1450 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static javax.ws.rs.core.MediaType.APPLICATION_XML; -import static javax.ws.rs.core.MediaType.TEXT_PLAIN; -import static javax.ws.rs.core.Response.Status.FORBIDDEN; -import static javax.ws.rs.core.Response.Status.UNAUTHORIZED; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.codehaus.enunciate.Facet; -import org.codehaus.enunciate.jaxrs.ResponseCode; -import org.codehaus.enunciate.jaxrs.StatusCodes; -import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.services.SchedulerService; -import org.pentaho.platform.web.http.messages.Messages; - -/** - * The SchedulerResource service provides the means to create, read, update, delete, and list schedules and blockout - * periods. Also provides the ability to control the status of schedules and the scheduler. - */ -@Path( "/scheduler" ) -public class SchedulerResource { - - protected SchedulerService schedulerService; - - protected static final Log logger = LogFactory.getLog( SchedulerResource.class ); - - public SchedulerResource() { - schedulerService = new SchedulerService(); - System.out.println( "-----------------------------------------------------------------------" ); - System.out.println( "SchedulerResource was initialized." ); - System.out.println( "-----------------------------------------------------------------------" ); - } - - - /** - * Creates a new scheduled job. - * - *

Example Request:
- * POST pentaho/api/scheduler/job - *

- *
POST data: - *
-   *      <jobScheduleRequest>
-   *      <jobName>JobName</jobName>
-   *      <simpleJobTrigger>
-   *      <uiPassParam>MINUTES</uiPassParam>
-   *      <repeatInterval>1800</repeatInterval>
-   *      <repeatCount>-1</repeatCount>
-   *      <startTime>2014-08-14T11:46:00.000-04:00</startTime>
-   *      <endTime />
-   *      </simpleJobTrigger>
-   *      <inputFile>/public/Steel Wheels/Top Customers (report).prpt</inputFile>
-   *      <outputFile>/public/output</outputFile>
-   *      <jobParameters>
-   *      <name>ParameterName</name>
-   *      <type>string</type>
-   *      <stringValue>false</stringValue>
-   *      </jobParameters>
-   *      </jobScheduleRequest>
-   *  
- *

- * - * @param scheduleRequest A JobScheduleRequest object to define the parameters of the job being created. - * @return A jax-rs Response object with the created jobId. - * - *

Example Response:

- *
-   *   admin  JobName  1410786491777
-   * 
- */ - @POST - @Path( "/job" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Schedule created successfully." ), - @ResponseCode( code = 401, condition = "User is not allowed to create schedules." ), - @ResponseCode( code = 403, condition = "Cannot create schedules for the specified file." ), - @ResponseCode( code = 500, condition = "An error occurred while creating a schedule." ) - } ) - public Response createJob( JobScheduleRequest scheduleRequest ) { - try { - IJob job = schedulerService.createJob( scheduleRequest ); - return buildPlainTextOkResponse( job.getJobId() ); - } catch ( SchedulerException e ) { - return buildServerErrorResponse( e.getCause().getMessage() ); - } catch ( IOException e ) { - return buildServerErrorResponse( e.getCause().getMessage() ); - } catch ( SecurityException e ) { - return buildStatusResponse( UNAUTHORIZED ); - } catch ( IllegalAccessException e ) { - return buildStatusResponse( FORBIDDEN ); - } - } - - /** - * Changes an existing job by creating an instance with new content (picked from {@code scheduleRequest}) and - * removing the current instance. - * - *

Example Request:
- * POST pentaho/api/scheduler/job/edit - *

- *
POST data: - *
-   *      <jobScheduleRequest>
-   *      <jobName>JobName</jobName>
-   *      <simpleJobTrigger>
-   *      <uiPassParam>MINUTES</uiPassParam>
-   *      <repeatInterval>1800</repeatInterval>
-   *      <repeatCount>-1</repeatCount>
-   *      <startTime>2014-08-14T11:46:00.000-04:00</startTime>
-   *      <endTime />
-   *      </simpleJobTrigger>
-   *      <inputFile>/public/Steel Wheels/Top Customers (report).prpt</inputFile>
-   *      <outputFile>/public/output</outputFile>
-   *      <jobParameters>
-   *      <name>ParameterName</name>
-   *      <type>string</type>
-   *      <stringValue>false</stringValue>
-   *      </jobParameters>
-   *      </jobScheduleRequest>
-   *      </jobId>
-   *  
- *

- * - * @param scheduleRequest A JobScheduleRequest object to define the parameters of the job being updated. - * @return A jax-rs Response object with the created jobId. - * - *

Example Response:

- *
-   *  admin JobName 1410786491777
-   * 
- */ - @POST - @Path( "/job/update" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Schedule updated successfully." ), - @ResponseCode( code = 401, condition = "User is not allowed to update schedules." ), - @ResponseCode( code = 403, condition = "Cannot update schedules for the specified file." ), - @ResponseCode( code = 500, condition = "An error occurred while updating a schedule." ) - } ) - public Response updateJob( JobScheduleRequest scheduleRequest ) { - try { - IJob job = schedulerService.updateJob( scheduleRequest ); - return buildPlainTextOkResponse( job.getJobId() ); - } catch ( SchedulerException e ) { - return buildServerErrorResponse( e.getCause().getMessage() ); - } catch ( IOException e ) { - return buildServerErrorResponse( e.getCause().getMessage() ); - } catch ( SecurityException e ) { - return buildStatusResponse( UNAUTHORIZED ); - } catch ( IllegalAccessException e ) { - return buildStatusResponse( FORBIDDEN ); - } - } - - /** - * Execute a previously scheduled job. - * - *

Example Request:
- * POST pentaho/api/scheduler/triggerNow - *

- *
POST data: - *
-   *      <jobRequest>
-   *      <jobId>admin  JobName 1410786491777</jobId>
-   *      </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A Response object indicating the status of the scheduler. - * - *

Example Response:

- *
-   *      NORMAL
-   * 
- */ - @POST - @Path( "/triggerNow" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Job triggered successfully." ), - @ResponseCode( code = 400, condition = "Invalid input." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response triggerNow( JobRequest jobRequest ) { - try { - IJob job = schedulerService.triggerNow( jobRequest.getJobId() ); - return buildPlainTextOkResponse( job.getState().name() ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Get the scheduled job created by the system for deleting generated files. - * - *

Example Request:
- * GET pentaho/api/scheduler/getContentCleanerJob - *

- * - * @return A Job object containing the definition of the content cleaner job. - * - *

Example Response:

- *
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin  GeneratedContentCleaner 1408377444383</jobId>
-   *  <jobName>GeneratedContentCleaner</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>uiPassParam</name>
-   *  <value>DAILY</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>age</name>
-   *  <value>15552000</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>user_locale</name>
-   *  <value>en_US</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionClass</name>
-   *  <value>org.pentaho.platform.admin.GeneratedContentCleaner</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>c3cfbad4-2e34-4dbd-8071-a2f3c7e8fab9</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="simpleJobTrigger">
-   *  <duration>-1</duration>
-   *  <startTime>2014-08-18T11:57:00-04:00</startTime>
-   *  <uiPassParam>DAILY</uiPassParam>
-   *  <repeatCount>-1</repeatCount>
-   *  <repeatInterval>86400</repeatInterval>
-   *  </jobTrigger>
-   *  <lastRun>2014-08-18T11:57:00-04:00</lastRun>
-   *  <nextRun>2014-08-19T11:57:00-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   * 
- */ - @GET - @Path( "/getContentCleanerJob" ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Content cleaner job successfully retrieved." ), - @ResponseCode( code = 204, condition = "No content cleaner job exists." ), - } ) - public IJob getContentCleanerJob() { - try { - return schedulerService.getContentCleanerJob(); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Retrieve the all the job(s) visible to the current users. - * - *

Example Request:
- * GET pentaho/api/scheduler/jobs - *

- * - * @param asCronString Cron string (Unused). - * @return A list of jobs that are visible to the current users. - * - *

Example Response:

- *
-   *  <jobs>
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin  PentahoSystemVersionCheck 1408369303507</jobId>
-   *  <jobName>PentahoSystemVersionCheck</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionClass</name>
-   *  <value>org.pentaho.platform.scheduler2.versionchecker.VersionCheckerAction</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>1986cc90-cf87-43f6-8924-9d6e443e7d5d</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>versionRequestFlags</name>
-   *  <value>0</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="simpleJobTrigger">
-   *  <duration>-1</duration>
-   *  <startTime>2014-08-18T09:41:43.506-04:00</startTime>
-   *  <repeatCount>-1</repeatCount>
-   *  <repeatInterval>86400</repeatInterval>
-   *  </jobTrigger>
-   *  <lastRun>2014-08-18T11:37:31.412-04:00</lastRun>
-   *  <nextRun>2014-08-19T09:41:43.506-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin  UpdateAuditData 1408373019115</jobId>
-   *  <jobName>UpdateAuditData</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>autoCreateUniqueFilename</name>
-   *  <value>false</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>uiPassParam</name>
-   *  <value>MINUTES</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-StreamProvider</name>
-   *  <value>input file = /public/pentaho-operations-mart/update_audit_mart_data/UpdateAuditData.xaction:outputFile = /public/pentaho-operations-mart/generated_logs/UpdateAuditData.*</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>user_locale</name>
-   *  <value>en_US</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionId</name>
-   *  <value>xaction.backgroundExecution</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>1f2402c4-0a70-40e4-b428-0d328f504cb3</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="simpleJobTrigger">
-   *  <duration>-1</duration>
-   *  <startTime>2014-07-14T12:47:00-04:00</startTime>
-   *  <uiPassParam>MINUTES</uiPassParam>
-   *  <repeatCount>-1</repeatCount>
-   *  <repeatInterval>1800</repeatInterval>
-   *  </jobTrigger>
-   *  <lastRun>2014-08-18T12:47:00-04:00</lastRun>
-   *  <nextRun>2014-08-18T13:17:00-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   *  </jobs>
-   * 
- */ - @Deprecated - @GET - @Path( "/jobs" ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @Facet( name = "Unsupported" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Jobs retrieved successfully." ), - @ResponseCode( code = 500, condition = "Error while retrieving jobs." ) - } ) - public List getJobs( @DefaultValue( "false" ) @QueryParam( "asCronString" ) Boolean asCronString ) { - try { - return schedulerService.getJobs(); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Retrieve the all the scheduled job(s) visible to the current users. - * - *

Example Request:
- * GET pentaho/api/scheduler/getJobs - *

- * - * @return A list of jobs that are visible to the current users. - * - *

Example Response:

- *
-   *  <jobs>
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin  PentahoSystemVersionCheck 1408369303507</jobId>
-   *  <jobName>PentahoSystemVersionCheck</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionClass</name>
-   *  <value>org.pentaho.platform.scheduler2.versionchecker.VersionCheckerAction</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>1986cc90-cf87-43f6-8924-9d6e443e7d5d</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>versionRequestFlags</name>
-   *  <value>0</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="simpleJobTrigger">
-   *  <duration>-1</duration>
-   *  <startTime>2014-08-18T09:41:43.506-04:00</startTime>
-   *  <repeatCount>-1</repeatCount>
-   *  <repeatInterval>86400</repeatInterval>
-   *  </jobTrigger>
-   *  <lastRun>2014-08-18T11:37:31.412-04:00</lastRun>
-   *  <nextRun>2014-08-19T09:41:43.506-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin UpdateAuditData 1408373019115</jobId>
-   *  <jobName>UpdateAuditData</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>autoCreateUniqueFilename</name>
-   *  <value>false</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>uiPassParam</name>
-   *  <value>MINUTES</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-StreamProvider</name>
-   *  <value>input file = /public/pentaho-operations-mart/update_audit_mart_data/UpdateAuditData.xaction:outputFile = /public/pentaho-operations-mart/generated_logs/UpdateAuditData.*</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>user_locale</name>
-   *  <value>en_US</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionId</name>
-   *  <value>xaction.backgroundExecution</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>1f2402c4-0a70-40e4-b428-0d328f504cb3</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="simpleJobTrigger">
-   *  <duration>-1</duration>
-   *  <startTime>2014-07-14T12:47:00-04:00</startTime>
-   *  <uiPassParam>MINUTES</uiPassParam>
-   *  <repeatCount>-1</repeatCount>
-   *  <repeatInterval>1800</repeatInterval>
-   *  </jobTrigger>
-   *  <lastRun>2014-08-18T12:47:00-04:00</lastRun>
-   *  <nextRun>2014-08-18T13:17:00-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   *  </jobs>
-   * 
- */ - @GET - @Path( "/getJobs" ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Jobs retrieved successfully." ), - @ResponseCode( code = 500, condition = "Error while retrieving jobs." ), - } ) - public List getAllJobs() { - try { - return schedulerService.getJobs(); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Checks whether the current user may schedule a repository file in the platform. - * - *

Example Request:
- * GET pentaho/api/scheduler/isScheduleAllowed?id=b5f806b9-9f72-4814-b1e0-aa9e0ece7e1a - *

- * - * @param id The repository file ID of the content to checked. - * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for - * the file. - * - *

Example Response:

- *
-   *  true
-   * 
- */ - @GET - @Path( "/isScheduleAllowed" ) - @Produces( TEXT_PLAIN ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully retrieved scheduling ability of repository file." ), - @ResponseCode( code = 500, condition = "Invalid repository file id." ), - } ) - public String isScheduleAllowed( @QueryParam( "id" ) String id ) { - return "" + schedulerService.isScheduleAllowed( id ); - } - - /** - * Checks whether the current user has authority to schedule any content in the platform. - * - *

Example Request:
- * GET pentaho/api/scheduler/canSchedule - *

- * - * @return true or false. true indicates scheduling is allowed and false indicates scheduling is not allowed for - * the user. - * - *

Example Response:

- *
-   *  true
-   * 
- */ - @GET - @Path( "/canSchedule" ) - @Produces( APPLICATION_JSON ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successful retrieved the scheduling permission." ), - @ResponseCode( code = 500, condition = "Unable to retrieve the scheduling permission." ) - } ) - public String doGetCanSchedule() { - return schedulerService.doGetCanSchedule(); - } - - /** - * Returns the state of the scheduler with the value of RUNNING or PAUSED. - * - *

Example Request:
- * GET pentaho/api/scheduler/state - *

- * - * @return status of the scheduler as RUNNING or PAUSED. - * - *

Example Response:

- *
-   *  RUNNING
-   * 
- */ - @GET - @Path( "/state" ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully retrieved the state of the scheduler." ), - @ResponseCode( code = 500, condition = "An error occurred when getting the state of the scheduler." ) - } ) - public Response getState() { - try { - String state = schedulerService.getState(); - return buildPlainTextOkResponse( state ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Resume the scheduler from a paused state. - * - *

Example Request:
- * POST pentaho/api/scheduler/start - *

- *
POST data: - *
-   *    This POST body does not contain data.
-   *  
- *

- * - * @return A jax-rs Response object containing the status of the scheduler. - * - *

Example Response:

- *
-   *  RUNNING
-   * 
- */ - @POST - @Path( "/start" ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully started the server." ), - @ResponseCode( code = 500, condition = "An error occurred when resuming the scheduler." ) - } ) - public Response start() { - try { - String status = schedulerService.start(); - return buildPlainTextOkResponse( status ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Pause the scheduler from a running state. - * - *

Example Request:
- * POST pentaho/api/scheduler/pause - *

- *
POST data: - *
-   *    This POST body does not contain data.
-   *  
- *

- * - * @return A jax-rs Response object containing the status of the scheduler. - * - *

Example Response:

- *
-   *  PAUSED
-   * 
- */ - @POST - @Path( "/pause" ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully paused the server." ), - @ResponseCode( code = 500, condition = "An error occurred when pausing the scheduler." ) - } ) - public Response pause() { - try { - String status = schedulerService.pause(); - return buildPlainTextOkResponse( status ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Shuts down the scheduler. - * - *

Example Request:
- * POST pentaho/api/scheduler/shutdown - *

- *
POST data: - *
-   *    This POST body does not contain data.
-   *  
- *

- * - * @return A jax-rs Response object containing the status of the scheduler. - * - *

Example Response:

- *
-   *  PAUSED
-   * 
- */ - @POST - @Path( "/shutdown" ) - @Produces( "text/plain" ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully shut down the server." ), - @ResponseCode( code = 500, condition = "An error occurred when shutting down the scheduler." ) - } ) - public Response shutdown() { - try { - String status = schedulerService.shutdown(); - return buildPlainTextOkResponse( status ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Checks the state of the selected scheduled job. - * - *

Example Request:
- * POST pentaho/api/scheduler/jobState - *

- *
POST data: - *
-   *      <jobRequest>
-   *      <jobId>admin  JobName 1410786491777</jobId>
-   *      </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A jax-rs Response object containing the status of the scheduled job. - * - *

Example Response:

- *
-   *  NORMAL
-   * 
- */ - @POST - @Path( "/jobState" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully retrieved the state of the requested job." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response getJobState( JobRequest jobRequest ) { - try { - return buildPlainTextOkResponse( schedulerService.getJobState( jobRequest ).name() ); - } catch ( UnsupportedOperationException e ) { - return buildPlainTextStatusResponse( UNAUTHORIZED ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Pause the specified scheduled job. - * - *

Example Request:
- * POST pentaho/api/scheduler/pauseJob - *

- *
POST data: - *
-   *    <jobRequest>
-   *    <jobId>admin  JobName 1410786491777</jobId>
-   *    </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A jax-rs Response object containing the status of the scheduled job. - * - *

Example Response:

- *
-   *  PAUSED
-   * 
- */ - @POST - @Path( "/pauseJob" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully paused the job." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response pauseJob( JobRequest jobRequest ) { - try { - IJob.JobState state = schedulerService.pauseJob( jobRequest.getJobId() ); - return buildPlainTextOkResponse( state.name() ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Resume the specified scheduled job. - * - *

Example Request:
- * POST pentaho/api/scheduler/resumeJob - *

- *
POST data: - *
-   *    <jobRequest>
-   *    <jobId>admin  JobName 1410786491777</jobId>
-   *    </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A jax-rs Response object containing the status of the scheduled job. - * - *

Example Response:

- *
-   * NORMAL
-   * 
- */ - @POST - @Path( "/resumeJob" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully resumed the job." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response resumeJob( JobRequest jobRequest ) { - try { - IJob.JobState state = schedulerService.resumeJob( jobRequest.getJobId() ); - return buildPlainTextOkResponse( state.name() ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Delete the specified scheduled job from the platform. - * - *

Example Request:
- * DELETE pentaho/api/scheduler/removeJob - *

- *
DELETE data: - *
-   *    <jobRequest>
-   *    <jobId>admin  BlockoutAction 1410786491503</jobId>
-   *    </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A jax-rs Response object containing the status of the scheduled job. - * - *

Example Response:

- *
-   *  REMOVED
-   * 
- */ - @Deprecated - @DELETE - @Path( "/removeJob" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully removed the job." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response removeJob( JobRequest jobRequest ) { - return deleteJob( jobRequest ); - } - - /** - * Delete the specified scheduled job from the platform. - * - *

Example Request:
- * PUT pentaho/api/scheduler/removeJob - *

- *
PUT data: - *
-   *    <jobRequest>
-   *    <jobId>admin  BlockoutAction 1410786491503</jobId>
-   *    </jobRequest>
-   *  
- *

- * - * @param jobRequest A JobRequest object containing the jobId. - * @return A jax-rs Response object containing the status of the scheduled job. - * - *

Example Response:

- *
-   *  REMOVED
-   * 
- */ - @PUT - @Path( "/removeJob" ) - @Produces( "text/plain" ) - @Consumes( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully removed the job." ), - @ResponseCode( code = 500, condition = "Invalid jobId." ) - } ) - public Response deleteJob( JobRequest jobRequest ) { - try { - if ( schedulerService.removeJob( jobRequest.getJobId() ) ) { - return buildPlainTextOkResponse( "REMOVED" ); - } - IJob job = schedulerService.getJob( jobRequest.getJobId() ); - return buildPlainTextOkResponse( job.getState().name() ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - /** - * Return the information for a specified job. - * - *

Example Request:
- * GET pentaho/api/scheduler/jobinfo?jobId=admin%09JobName%091410786491777 - *

- * - * @param jobId The jobId of the job for which we are requesting information. - * @param asCronString Cron string (Unused) - * @return A Job object containing the info for the specified job. - * - *

Example Response:

- *
-   *  <?xml version="1.0" encoding="UTF-8" standalone="yes"?><job><jobId>admin JobName 1410786491777</jobId><jobName>JobName</jobName><jobParams><jobParams><name>uiPassParam</name><value>MINUTES</value></jobParams><jobParams><name>ActionAdapterQuartzJob-StreamProvider</name><value>input file = /public/Steel Wheels/Top Customers (report).prpt:outputFile = /home/admin/JobName.*</value></jobParams><jobParams><name>user_locale</name><value>en_US</value></jobParams><jobParams><name>ActionAdapterQuartzJob-ActionUser</name><value>admin</value></jobParams><jobParams><name>ActionAdapterQuartzJob-ActionId</name><value>prpt.backgroundExecution</value></jobParams><jobParams><name>ParameterName</name><value>false</value></jobParams><jobParams><name>lineage-id</name><value>5212a120-3294-49e8-9c5d-c755b9766c43</value></jobParams></jobParams><jobTrigger xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="simpleJobTrigger"><duration>-1</duration><startTime>2014-08-14T11:46:00-04:00</startTime><uiPassParam>MINUTES</uiPassParam><repeatCount>-1</repeatCount><repeatInterval>1800</repeatInterval></jobTrigger><nextRun>2014-08-14T11:46:00-04:00</nextRun><state>NORMAL</state><userName>admin</userName></job>
-   * 
- */ - @GET - @Path( "/jobinfo" ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully retrieved the information for the requested job." ), - @ResponseCode( code = 204, condition = "jobId is valid, but the job is either finished or does not exists." ), - @ResponseCode( code = 500, condition = "Internal error or invalid jobId." ) - } ) - public Response getJob( @QueryParam( "jobId" ) String jobId, - @DefaultValue( "false" ) @QueryParam( "asCronString" ) String asCronString ) { - try { - IJob jobInfo = schedulerService.getJobInfo( jobId ); - if ( jobInfo == null ) { - return buildStatusResponse( Status.NO_CONTENT ); - } - return buildOkResponse( jobInfo ); - } catch ( SchedulerException e ) { - throw new RuntimeException( e ); - } - } - - @Deprecated - @GET - @Path( "/jobinfotest" ) - @Produces( { APPLICATION_JSON } ) - @Facet( name = "Unsupported" ) - public JobScheduleRequest getJobInfo() { - return schedulerService.getJobInfo(); - } - - /** - * @return list of Job - * @deprecated Method is deprecated as the name getBlockoutJobs is preferred over getJobs - *

- * Retrieves all blockout jobs in the system - */ - @Deprecated - @Facet( name = "Unsupported" ) - public List getJobs() { - return getBlockoutJobs(); - } - - - /** - * Get all the blockout jobs in the system. - * - *

Example Request:
- * GET pentaho/api/scheduler/blockout/blockoutjobs - *

- * - * @return A Response object that contains a list of blockout jobs. - * - *

Example Response:

- *
-   *  <jobs>
-   *  <job>
-   *  <groupName>admin</groupName>
-   *  <jobId>admin  BlockoutAction  1408457558636</jobId>
-   *  <jobName>BlockoutAction</jobName>
-   *  <jobParams>
-   *  <jobParams>
-   *  <name>TIME_ZONE_PARAM</name>
-   *  <value>America/New_York</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>DURATION_PARAM</name>
-   *  <value>10080000</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>uiPassParam</name>
-   *  <value>DAILY</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>user_locale</name>
-   *  <value>en_US</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionUser</name>
-   *  <value>admin</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>ActionAdapterQuartzJob-ActionClass</name>
-   *  <value>org.pentaho.platform.scheduler2.blockout.BlockoutAction</value>
-   *  </jobParams>
-   *  <jobParams>
-   *  <name>lineage-id</name>
-   *  <value>0989726c-3247-4864-bc79-8e2a1dc60c58</value>
-   *  </jobParams>
-   *  </jobParams>
-   *  <jobTrigger xsi:type="complexJobTrigger">
-   *  <cronString>0 12 10 ? * 2,3,4,5,6 *</cronString>
-   *  <duration>10080000</duration>
-   *  <startTime>2014-08-19T10:12:00-04:00</startTime>
-   *  <uiPassParam>DAILY</uiPassParam>
-   *  <dayOfMonthRecurrences />
-   *  <dayOfWeekRecurrences>
-   *  <recurrenceList>
-   *  <values>2</values>
-   *  <values>3</values>
-   *  <values>4</values>
-   *  <values>5</values>
-   *  <values>6</values>
-   *  </recurrenceList>
-   *  </dayOfWeekRecurrences>
-   *  <hourlyRecurrences>
-   *  <recurrenceList>
-   *  <values>10</values>
-   *  </recurrenceList>
-   *  </hourlyRecurrences>
-   *  <minuteRecurrences>
-   *  <recurrenceList>
-   *  <values>12</values>
-   *  </recurrenceList>
-   *  </minuteRecurrences>
-   *  <monthlyRecurrences />
-   *  <secondRecurrences>
-   *  <recurrenceList>
-   *  <values>0</values>
-   *  </recurrenceList>
-   *  </secondRecurrences>
-   *  <yearlyRecurrences />
-   *  </jobTrigger>
-   *  <nextRun>2014-08-20T10:12:00-04:00</nextRun>
-   *  <state>NORMAL</state>
-   *  <userName>admin</userName>
-   *  </job>
-   *  </jobs>
-   * 
- */ - @GET - @Path( "/blockout/blockoutjobs" ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully retrieved blockout jobs." ), - } ) - public List getBlockoutJobs() { - return schedulerService.getBlockOutJobs(); - } - - - /** - * Checks if there are blockouts in the system. - * - *

Example Request:
- * GET pentaho/api/scheduler/blockout/hasblockouts - *

- * - * @return true or false whether there are blackouts or not. - * - *

Example Response:

- *
-   *  true
-   * 
- */ - @GET - @Path( "/blockout/hasblockouts" ) - @Produces( { TEXT_PLAIN } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully determined whether or not the system contains blockouts." ), - } ) - public Response hasBlockouts() { - Boolean hasBlockouts = schedulerService.hasBlockouts(); - return buildOkResponse( hasBlockouts.toString() ); - } - - /** - * Creates a new blockout for scheduled jobs. - * - *

Example Request:
- * POST pentaho/api/scheduler/blockout/add - *

- *
POST data: - *
-   *    <jobScheduleRequest>
-   *    <jobName>DAILY-1820438815:admin:7740000</jobName>
-   *    <complexJobTrigger>
-   *    <uiPassParam>DAILY</uiPassParam>
-   *    <daysOfWeek>1</daysOfWeek>
-   *    <daysOfWeek>2</daysOfWeek>
-   *    <daysOfWeek>3</daysOfWeek>
-   *    <daysOfWeek>4</daysOfWeek>
-   *    <daysOfWeek>5</daysOfWeek>
-   *    <startTime>2014-08-19T10:51:00.000-04:00</startTime>
-   *    <endTime />
-   *    </complexJobTrigger>
-   *    <inputFile></inputFile>
-   *    <outputFile></outputFile>
-   *    <duration>7740000</duration>
-   *    <timeZone>America/New_York</timeZone>
-   *    </jobScheduleRequest>
-   *  
- *

- * - * @param jobScheduleRequest A JobScheduleRequest object defining the blockout job. - * @return A Response object which contains the ID of the blockout which was created. - * - *

Example Response:

- *
-   * admin BlockoutAction 1410786491209
-   * 
- */ - @POST - @Path( "/blockout/add" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successful operation." ), - @ResponseCode( code = 401, condition = "User is not authorized to create blockout." ) - } ) - public Response addBlockout( JobScheduleRequest jobScheduleRequest ) { - try { - IJob job = schedulerService.addBlockout( jobScheduleRequest ); - return buildPlainTextOkResponse( job.getJobId() ); - } catch ( IOException | SchedulerException | IllegalAccessException e ) { - return buildStatusResponse( UNAUTHORIZED ); - } - } - - /** - * Update an existing blockout. - * - *

Example Request:
- * POST pentaho/api/scheduler/blockout/update?jobid=admin%09BlockoutAction%091410786491209 - *

- *
POST data: - *
-   *    <jobScheduleRequest>
-   *    <jobName>DAILY-1820438815:admin:7740000</jobName>
-   *    <complexJobTrigger>
-   *    <uiPassParam>DAILY</uiPassParam>
-   *    <daysOfWeek>1</daysOfWeek>
-   *    <daysOfWeek>2</daysOfWeek>
-   *    <daysOfWeek>3</daysOfWeek>
-   *    <daysOfWeek>4</daysOfWeek>
-   *    <daysOfWeek>5</daysOfWeek>
-   *    <startTime>2012-01-12T10:51:00.000-04:00</startTime>
-   *    <endTime />
-   *    </complexJobTrigger>
-   *    <inputFile></inputFile>
-   *    <outputFile></outputFile>
-   *    <duration>7740000</duration>
-   *    <timeZone>America/New_York</timeZone>
-   *    </jobScheduleRequest>
-   *  
- *

- * - * @param jobId The jobId of the blockout we are editing. - * @param jobScheduleRequest The payload containing the definition of the blockout. - * @return A Response object which contains the ID of the blockout which was created. - * - *

Example Response:

- *
-   * admin BlockoutAction 1410786491503
-   * 
- */ - @POST - @Path( "/blockout/update" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successful operation." ), - @ResponseCode( code = 401, condition = "User is not authorized to update blockout." ) - } ) - public Response updateBlockout( @QueryParam( "jobid" ) String jobId, JobScheduleRequest jobScheduleRequest ) { - try { - IJob job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); - return buildPlainTextOkResponse( job.getJobId() ); - } catch ( IOException e ) { - return buildStatusResponse( Status.UNAUTHORIZED ); - } catch ( SchedulerException e ) { - return buildStatusResponse( Status.UNAUTHORIZED ); - } catch ( IllegalAccessException e ) { - return buildStatusResponse( Status.UNAUTHORIZED ); - } - } - - /** - * Checks if the selected blockout schedule will be fired. - * - *

Example Request:
- * POST pentaho/api/scheduler/blockout/willFire - *

- *
POST data: - *
-   *    <jobScheduleRequest>
-   *    <jobName>DAILY-1820438815:admin:7740000</jobName>
-   *    <complexJobTrigger>
-   *    <uiPassParam>DAILY</uiPassParam>
-   *    <daysOfWeek>1</daysOfWeek>
-   *    <daysOfWeek>2</daysOfWeek>
-   *    <daysOfWeek>3</daysOfWeek>
-   *    <daysOfWeek>4</daysOfWeek>
-   *    <daysOfWeek>5</daysOfWeek>
-   *    <startTime>2014-08-19T10:51:00.000-04:00</startTime>
-   *    <endTime />
-   *    </complexJobTrigger>
-   *    <inputFile></inputFile>
-   *    <outputFile></outputFile>
-   *    <duration>7740000</duration>
-   *    <timeZone>America/New_York</timeZone>
-   *    </jobScheduleRequest>
-   *  
- *

- * - * @param jobScheduleRequest The payload containing the definition of the blockout. - * @return true or false indicating whether or not the blockout will fire. - * - *

Example Response:

- *
-   *  false
-   * 
- */ - @POST - @Path( "/blockout/willFire" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces( { TEXT_PLAIN } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successful operation." ), - @ResponseCode( code = 500, condition = "An error occurred while determining blockouts being fired." ) - } ) - public Response blockoutWillFire( JobScheduleRequest jobScheduleRequest ) { - Boolean willFire; - try { - willFire = schedulerService.willFire( convertScheduleRequestToJobTrigger( jobScheduleRequest ) ); - } catch ( UnifiedRepositoryException e ) { - return buildServerErrorResponse( e ); - } catch ( SchedulerException e ) { - return buildServerErrorResponse( e ); - } - return buildOkResponse( willFire.toString() ); - } - - /** - * Checks if the selected blockout schedule should be fired now. - * - *

Example Request:
- * GET pentaho/api/scheduler/blockout/shouldFireNow - *

- * - * @return true or false whether or not the blockout should fire now. - * - *

Example Response:

- *
-   *  true
-   * 
- */ - @GET - @Path( "/blockout/shouldFireNow" ) - @Produces( { TEXT_PLAIN } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successful operation." ) - } ) - public Response shouldFireNow() { - Boolean result = schedulerService.shouldFireNow(); - return buildOkResponse( result.toString() ); - } - - - /** - * Check the status of the selected blockout schedule. - * - *

Example Request:
- * POST pentaho/api/scheduler/blockout/blockstatus - *

- *
POST data: - *
-   *    <jobScheduleRequest>
-   *    <jobName>DAILY-1820438815:admin:7740000</jobName>
-   *    <complexJobTrigger>
-   *    <uiPassParam>DAILY</uiPassParam>
-   *    <daysOfWeek>1</daysOfWeek>
-   *    <daysOfWeek>2</daysOfWeek>
-   *    <daysOfWeek>3</daysOfWeek>
-   *    <daysOfWeek>4</daysOfWeek>
-   *    <daysOfWeek>5</daysOfWeek>
-   *    <startTime>2014-08-19T10:51:00.000-04:00</startTime>
-   *    <endTime />
-   *    </complexJobTrigger>
-   *    <inputFile></inputFile>
-   *    <outputFile></outputFile>
-   *    <duration>7740000</duration>
-   *    <timeZone>America/New_York</timeZone>
-   *    </jobScheduleRequest>
-   *  
- *

- * - * @param jobScheduleRequest The payload containing the definition of the blockout. - * @return A Response object which contains a BlockStatusProxy which contains totallyBlocked and partiallyBlocked - * flags. - * - *

Example Response:

- *
-   *  <blockStatusProxy>
-   *  <partiallyBlocked>true</partiallyBlocked>
-   *  <totallyBlocked>true</totallyBlocked>
-   *  </blockStatusProxy>
-   * 
- */ - @POST - @Path( "/blockout/blockstatus" ) - @Consumes( { APPLICATION_JSON, APPLICATION_XML } ) - @Produces( { APPLICATION_JSON, APPLICATION_XML } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully got the blockout status." ), - @ResponseCode( code = 401, condition = "User is not authorized to get the blockout status." ) - } ) - public Response getBlockStatus( JobScheduleRequest jobScheduleRequest ) { - try { - BlockStatusProxy blockStatusProxy = schedulerService.getBlockStatus( jobScheduleRequest ); - return buildOkResponse( blockStatusProxy ); - } catch ( SchedulerException e ) { - return buildStatusResponse( Status.UNAUTHORIZED ); - } - } - - /** - * Retrieve the list of execute content by lineage id. - * - *

Example Request:
- * GET pentaho/api/scheduler/generatedContentForSchedule?lineageId=:public:Steel%20Wheels:Inventory%20List%20 - * (report).prpt - *

- * - * @param lineageId the path for the file. - * @return A list of RepositoryFileDto objects. - * - *

Example Response:

- *
-   *  <List>
-   *  <repositoryFileDto>
-   *  <createdDate>1402911997019</createdDate>
-   *  <fileSize>3461</fileSize>
-   *  <folder>false</folder>
-   *  <hidden>false</hidden>
-   *  <id>ff11ac89-7eda-4c03-aab1-e27f9048fd38</id>
-   *  <lastModifiedDate>1406647160536</lastModifiedDate>
-   *  <locale>en</locale>
-   *  <localePropertiesMapEntries>
-   *  <localeMapDto>
-   *  <locale>default</locale>
-   *  <properties>
-   *  <stringKeyStringValueDto>
-   *  <key>file.title</key>
-   *  <value>myFile</value>
-   *  </stringKeyStringValueDto>
-   *  <stringKeyStringValueDto>
-   *  <key>jcr:primaryType</key>
-   *  <value>nt:unstructured</value>
-   *  </stringKeyStringValueDto>
-   *  <stringKeyStringValueDto>
-   *  <key>title</key>
-   *  <value>myFile</value>
-   *  </stringKeyStringValueDto>
-   *  <stringKeyStringValueDto>
-   *  <key>file.description</key>
-   *  <value>myFile Description</value>
-   *  </stringKeyStringValueDto>
-   *  </properties>
-   *  </localeMapDto>
-   *  </localePropertiesMapEntries>
-   *  <locked>false</locked>
-   *  <name>myFile.prpt</name></name>
-   *  <originalParentFolderPath>/public/admin</originalParentFolderPath>
-   *  <ownerType>-1</ownerType>
-   *  <path>/public/admin/ff11ac89-7eda-4c03-aab1-e27f9048fd38</path>
-   *  <title>myFile</title>
-   *  <versionId>1.9</versionId>
-   *  <versioned>true</versioned>
-   *  </repositoryFileAclDto>
-   *  </List>
-   * 
- */ - @GET - @Path( "/generatedContentForSchedule" ) - @Produces( { APPLICATION_XML, APPLICATION_JSON } ) - @StatusCodes( { - @ResponseCode( code = 200, condition = "Successfully got the generated content for schedule" ) - } ) - public List doGetGeneratedContentForSchedule( @QueryParam( "lineageId" ) String lineageId ) { - List repositoryFileDtoList = new ArrayList(); - try { - repositoryFileDtoList = schedulerService.doGetGeneratedContentForSchedule( lineageId ); - } catch ( FileNotFoundException e ) { - //return the empty list - } catch ( Throwable t ) { - logger - .error( Messages.getInstance().getString( "FileResource.GENERATED_CONTENT_FOR_USER_FAILED", lineageId ), t ); - } - return repositoryFileDtoList; - } - - protected Response buildOkResponse( Object entity ) { - return Response.ok( entity ).build(); - } - - protected Response buildPlainTextOkResponse( String msg ) { - return Response.ok( msg ).type( MediaType.TEXT_PLAIN ).build(); - } - - protected Response buildServerErrorResponse( Object entity ) { - return Response.serverError().entity( entity ).build(); - } - - protected Response buildStatusResponse( Status status ) { - return Response.status( status ).build(); - } - - protected Response buildPlainTextStatusResponse( Status status ) { - return Response.status( status ).type( MediaType.TEXT_PLAIN ).build(); - } - - protected JobRequest getJobRequest() { - return new JobRequest(); - } - - protected IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest request ) throws SchedulerException { - return SchedulerResourceUtil.convertScheduleRequestToJobTrigger( request, schedulerService.getScheduler() ); - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java deleted file mode 100644 index 71a7c0ea7f0..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/SchedulerService.java +++ /dev/null @@ -1,596 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources.services; - -import org.apache.commons.lang.BooleanUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.ISecurityHelper; -import org.pentaho.platform.api.engine.ServiceException; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.IJob.JobState; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.scheduler2.blockout.BlockoutAction; -import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; -import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.util.messages.LocaleHelper; -import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.ComplexJobTriggerProxy; -import org.pentaho.platform.web.http.api.resources.JobRequest; -import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; -import org.pentaho.platform.web.http.api.resources.SchedulerOutputPathResolver; -import org.pentaho.platform.web.http.api.resources.SchedulerResourceUtil; -import org.pentaho.platform.web.http.api.resources.SessionResource; - - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class SchedulerService { - - protected IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - - protected IAuthorizationPolicy policy; - - protected IUnifiedRepository repository; - - protected SessionResource sessionResource; - - protected FileService fileService; - - protected IBlockoutManager blockoutManager; - - private static final Log logger = LogFactory.getLog( FileService.class ); - - public IJob createJob( JobScheduleRequest scheduleRequest ) - throws IOException, SchedulerException, IllegalAccessException { - - // Used to determine if created by a RunInBackgroundCommand - boolean runInBackground = - scheduleRequest.getSimpleJobTrigger() == null && scheduleRequest.getComplexJobTrigger() == null - && scheduleRequest.getCronJobTrigger() == null; - - if ( !runInBackground && !getPolicy().isAllowed( SchedulerAction.NAME ) ) { - throw new SecurityException(); - } - - boolean hasInputFile = !StringUtils.isEmpty( scheduleRequest.getInputFile() ); - RepositoryFile file = null; - if ( hasInputFile ) { - try { - file = getRepository().getFile( scheduleRequest.getInputFile() ); - } catch ( UnifiedRepositoryException ure ) { - hasInputFile = false; - logger.warn( ure.getMessage(), ure ); - } - } - - // if we have an inputfile, generate job name based on that if the name is not passed in - if ( hasInputFile && StringUtils.isEmpty( scheduleRequest.getJobName() ) ) { - scheduleRequest.setJobName( file.getName().substring( 0, file.getName().lastIndexOf( "." ) ) ); //$NON-NLS-1$ - } else if ( !StringUtils.isEmpty( scheduleRequest.getActionClass() ) ) { - String actionClass = - scheduleRequest.getActionClass().substring( scheduleRequest.getActionClass().lastIndexOf( "." ) + 1 ); - scheduleRequest.setJobName( actionClass ); //$NON-NLS-1$ - } else if ( !hasInputFile && StringUtils.isEmpty( scheduleRequest.getJobName() ) ) { - // just make up a name - scheduleRequest.setJobName( "" + System.currentTimeMillis() ); //$NON-NLS-1$ - } - - if ( hasInputFile ) { - if ( file == null ) { - logger.error( "Cannot find input source file " + scheduleRequest.getInputFile() + " Aborting schedule..." ); - throw new SchedulerException( - new ServiceException( "Cannot find input source file " + scheduleRequest.getInputFile() ) ); - } - Map metadata = getRepository().getFileMetadata( file.getId() ); - if ( metadata.containsKey( RepositoryFile.SCHEDULABLE_KEY ) ) { - boolean schedulable = BooleanUtils.toBoolean( (String) metadata.get( RepositoryFile.SCHEDULABLE_KEY ) ); - if ( !schedulable ) { - throw new IllegalAccessException(); - } - } - } - - if ( scheduleRequest.getTimeZone() != null ) { - updateStartDateForTimeZone( scheduleRequest ); - } - - IJob job = null; - - IJobTrigger jobTrigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - - HashMap parameterMap = new HashMap<>(); - - for ( JobScheduleParam param : scheduleRequest.getJobParameters() ) { - parameterMap.put( param.getName(), param.getValue() ); - } - - if ( isPdiFile( file ) ) { - parameterMap = handlePDIScheduling( file, parameterMap, scheduleRequest.getPdiParameters() ); - } - - parameterMap.put( LocaleHelper.USER_LOCALE_PARAM, LocaleHelper.getLocale() ); - - if ( hasInputFile ) { - SchedulerOutputPathResolver outputPathResolver = getSchedulerOutputPathResolver( scheduleRequest ); - String outputFile = outputPathResolver.resolveOutputFilePath(); - String actionId = SchedulerResourceUtil.resolveActionId( scheduleRequest.getInputFile() ); - final String inputFile = scheduleRequest.getInputFile(); - parameterMap.put( ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE, inputFile ); - job = - getScheduler().createJob( scheduleRequest.getJobName(), actionId, parameterMap, jobTrigger, - new RepositoryFileStreamProvider( inputFile, outputFile, - getAutoCreateUniqueFilename( scheduleRequest ), getAppendDateFormat( scheduleRequest ) ) - ); - } else { - // need to locate actions from plugins if done this way too (but for now, we're just on main) - String actionClass = scheduleRequest.getActionClass(); - try { - @SuppressWarnings( "unchecked" ) - Class iaction = getAction( actionClass ); - job = getScheduler().createJob( scheduleRequest.getJobName(), iaction, parameterMap, jobTrigger ); - } catch ( ClassNotFoundException e ) { - throw new RuntimeException( e ); - } - } - - return job; - } - - public IJob updateJob( JobScheduleRequest scheduleRequest ) - throws IllegalAccessException, IOException, SchedulerException { - IJob job = getScheduler().getJob( scheduleRequest.getJobId() ); - if ( job != null ) { - scheduleRequest.getJobParameters() - .add( new JobScheduleParam( IScheduler.RESERVEDMAPKEY_ACTIONUSER, job.getUserName() ) ); - } - IJob newJob = createJob( scheduleRequest ); - removeJob( scheduleRequest.getJobId() ); - return newJob; - } - - public IJob triggerNow( String jobId ) throws SchedulerException { - IJob job = getScheduler().getJob( jobId ); - if ( getPolicy().isAllowed( SchedulerAction.NAME ) ) { - getScheduler().triggerNow( jobId ); - } else { - if ( getSession().getName().equals( job.getUserName() ) ) { - getScheduler().triggerNow( jobId ); - } - } - // udpate job state - job = getScheduler().getJob( jobId ); - - return job; - } - - public IJob getContentCleanerJob() throws SchedulerException { - IPentahoSession session = getSession(); - final String principalName = session.getName(); // this authentication wasn't matching with the job user name, - // changed to get name via the current session - final Boolean canAdminister = getPolicy().isAllowed( AdministerSecurityAction.NAME ); - - List jobs = getScheduler().getJobs( getJobFilter( canAdminister, principalName ) ); - - if ( jobs.size() > 0 ) { - return jobs.get( 0 ); - } - - return null; - } - - /** - * @param lineageId - * @return - * @throws java.io.FileNotFoundException - */ - public List doGetGeneratedContentForSchedule( String lineageId ) throws FileNotFoundException { - return getFileService().searchGeneratedContent( getSessionResource().doGetCurrentUserDir(), lineageId, - IScheduler.RESERVEDMAPKEY_LINEAGE_ID ); - } - - public IJob getJob( String jobId ) throws SchedulerException { - return getScheduler().getJob( jobId ); - } - - public boolean isScheduleAllowed() { - return getPolicy().isAllowed( SchedulerAction.NAME ); - } - - public boolean isScheduleAllowed( String id ) { - Boolean canSchedule = isScheduleAllowed(); - if ( canSchedule ) { - Map metadata = getRepository().getFileMetadata( id ); - if ( metadata.containsKey( RepositoryFile.SCHEDULABLE_KEY ) ) { - canSchedule = BooleanUtils.toBoolean( (String) metadata.get( RepositoryFile.SCHEDULABLE_KEY ) ); - } - } - return canSchedule; - } - - public IJobFilter getJobFilter( boolean canAdminister, String principalName ) { - return new JobFilter( canAdminister, principalName ); - } - - private class JobFilter implements IJobFilter { - - private boolean canAdminister; - private String principalName; - - public JobFilter( boolean canAdminister, String principalName ) { - this.canAdminister = canAdminister; - this.principalName = principalName; - } - - @Override - public boolean accept( IJob job ) { - String actionClass = (String) job.getJobParams().get( "ActionAdapterQuartzJob-ActionClass" ); - if ( canAdminister && "org.pentaho.platform.admin.GeneratedContentCleaner".equals( actionClass ) ) { - return true; - } - return principalName.equals( job.getUserName() ) - && "org.pentaho.platform.admin.GeneratedContentCleaner".equals( actionClass ); - } - } - - public String doGetCanSchedule() { - return String.valueOf( getPolicy().isAllowed( SchedulerAction.NAME ) ); - } - - public String getState() throws SchedulerException { - return getScheduler().getStatus().name(); - } - - public String start() throws SchedulerException { - if ( getPolicy().isAllowed( SchedulerAction.NAME ) ) { - getScheduler().start(); - } - return getScheduler().getStatus().name(); - } - - public String pause() throws SchedulerException { - if ( getPolicy().isAllowed( SchedulerAction.NAME ) ) { - getScheduler().pause(); - } - return getScheduler().getStatus().name(); - } - - public String shutdown() throws SchedulerException { - if ( getPolicy().isAllowed( SchedulerAction.NAME ) ) { - getScheduler().shutdown(); - } - return getScheduler().getStatus().name(); - } - - public JobState pauseJob( String jobId ) throws SchedulerException { - IJob job = getJob( jobId ); - if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { - getScheduler().pauseJob( jobId ); - } - job = getJob( jobId ); - return job.getState(); - } - - public JobState resumeJob( String jobId ) throws SchedulerException { - IJob job = getJob( jobId ); - if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { - getScheduler().resumeJob( jobId ); - } - job = getJob( jobId ); - return job.getState(); - } - - public boolean removeJob( String jobId ) throws SchedulerException { - IJob job = getJob( jobId ); - if ( isScheduleAllowed() || PentahoSessionHolder.getSession().getName().equals( job.getUserName() ) ) { - getScheduler().removeJob( jobId ); - return true; - } - return false; - } - - public IJob getJobInfo( String jobId ) throws SchedulerException { - IJob job = getJob( jobId ); - if ( job == null ) { - return null; - } - if ( canAdminister() || getSession().getName().equals( job.getUserName() ) ) { - for ( String key : job.getJobParams().keySet() ) { - Serializable value = job.getJobParams().get( key ); - if ( value != null && value.getClass() != null && value.getClass().isArray() ) { - String[] sa = ( new String[ 0 ] ).getClass().cast( value ); - ArrayList list = new ArrayList<>(); - for ( int i = 0; i < sa.length; i++ ) { - list.add( sa[ i ] ); - } - job.getJobParams().put( key, list ); - } - } - return job; - } else { - throw new RuntimeException( "Job not found or improper credentials for access" ); - } - } - - public List getBlockOutJobs() { - return getBlockoutManager().getBlockOutJobs(); - } - - public boolean hasBlockouts() { - List jobs = getBlockoutManager().getBlockOutJobs(); - return jobs != null && jobs.size() > 0; - } - - public boolean willFire( IJobTrigger trigger ) { - return getBlockoutManager().willFire( trigger ); - } - - public boolean shouldFireNow() { - return getBlockoutManager().shouldFireNow(); - } - - public IJob addBlockout( JobScheduleRequest jobScheduleRequest ) - throws IOException, IllegalAccessException, SchedulerException { - if ( canAdminister() ) { - jobScheduleRequest.setActionClass( BlockoutAction.class.getCanonicalName() ); - jobScheduleRequest.getJobParameters().add( getJobScheduleParam( IBlockoutManager.DURATION_PARAM, - jobScheduleRequest.getDuration() ) ); - jobScheduleRequest.getJobParameters() - .add( getJobScheduleParam( IBlockoutManager.TIME_ZONE_PARAM, jobScheduleRequest.getTimeZone() ) ); - return createJob( jobScheduleRequest ); - } - throw new IllegalAccessException(); - } - - protected JobScheduleParam getJobScheduleParam( String name, String value ) { - return new JobScheduleParam( name, value ); - } - - protected JobScheduleParam getJobScheduleParam( String name, long value ) { - return new JobScheduleParam( name, value ); - } - - protected void updateStartDateForTimeZone( JobScheduleRequest jobScheduleRequest ) { - SchedulerResourceUtil.updateStartDateForTimeZone( jobScheduleRequest ); - } - - public IJob updateBlockout( String jobId, JobScheduleRequest jobScheduleRequest ) - throws IllegalAccessException, SchedulerException, IOException { - if ( canAdminister() ) { - boolean isJobRemoved = removeJob( jobId ); - if ( isJobRemoved ) { - IJob job = addBlockout( jobScheduleRequest ); - return job; - } - } - throw new IllegalAccessException(); - } - - public BlockStatusProxy getBlockStatus( JobScheduleRequest jobScheduleRequest ) throws SchedulerException { - updateStartDateForTimeZone( jobScheduleRequest ); - IJobTrigger trigger = convertScheduleRequestToJobTrigger( jobScheduleRequest ); - Boolean totallyBlocked = false; - Boolean partiallyBlocked = getBlockoutManager().isPartiallyBlocked( trigger ); - if ( partiallyBlocked ) { - totallyBlocked = !getBlockoutManager().willFire( trigger ); - } - return getBlockStatusProxy( totallyBlocked, partiallyBlocked ); - } - - protected BlockStatusProxy getBlockStatusProxy( Boolean totallyBlocked, Boolean partiallyBlocked ) { - return new BlockStatusProxy( totallyBlocked, partiallyBlocked ); - } - - protected IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest jobScheduleRequest ) - throws SchedulerException { - return SchedulerResourceUtil.convertScheduleRequestToJobTrigger( jobScheduleRequest, scheduler ); - } - - public JobScheduleRequest getJobInfo() { - JobScheduleRequest jobRequest = new JobScheduleRequest(); - ComplexJobTriggerProxy proxyTrigger = new ComplexJobTriggerProxy(); - proxyTrigger.setDaysOfMonth( new int[] { 1, 2, 3 } ); - proxyTrigger.setDaysOfWeek( new int[] { 1, 2, 3 } ); - proxyTrigger.setMonthsOfYear( new int[] { 1, 2, 3 } ); - proxyTrigger.setYears( new int[] { 2012, 2013 } ); - proxyTrigger.setStartTime( new Date() ); - jobRequest.setComplexJobTrigger( proxyTrigger ); - jobRequest.setInputFile( "aaaaa" ); - jobRequest.setOutputFile( "bbbbb" ); - ArrayList jobParams = new ArrayList<>(); - jobParams.add( new JobScheduleParam( "param1", "aString" ) ); - jobParams.add( new JobScheduleParam( "param2", 1 ) ); - jobParams.add( new JobScheduleParam( "param3", true ) ); - jobParams.add( new JobScheduleParam( "param4", new Date() ) ); - jobRequest.setJobParameters( jobParams ); - return jobRequest; - } - - public JobState getJobState( JobRequest jobRequest ) throws SchedulerException { - IJob job = getJob( jobRequest.getJobId() ); - if ( isScheduleAllowed() || getSession().getName().equals( job.getUserName() ) ) { - return job.getState(); - } - - throw new UnsupportedOperationException(); - } - - protected IPentahoSession getSession() { - return PentahoSessionHolder.getSession(); - } - - public Class getAction( String actionClass ) throws ClassNotFoundException { - return ( (Class) Class.forName( actionClass ) ); - } - - public IUnifiedRepository getRepository() { - if ( repository == null ) { - repository = PentahoSystem.get( IUnifiedRepository.class ); - } - return repository; - } - - public IScheduler getScheduler() { - if ( scheduler == null ) { - scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - } - - return scheduler; - } - - public IAuthorizationPolicy getPolicy() { - if ( policy == null ) { - policy = PentahoSystem.get( IAuthorizationPolicy.class ); - } - - return policy; - } - - protected SchedulerOutputPathResolver getSchedulerOutputPathResolver( JobScheduleRequest scheduleRequest ) { - return new SchedulerOutputPathResolver( scheduleRequest ); - } - - protected boolean isPdiFile( RepositoryFile file ) { - return SchedulerResourceUtil.isPdiFile( file ); - } - - protected HashMap handlePDIScheduling( RepositoryFile file, - HashMap parameterMap, - Map pdiParameters ) { - return SchedulerResourceUtil.handlePDIScheduling( file, parameterMap, pdiParameters ); - } - - public boolean getAutoCreateUniqueFilename( final JobScheduleRequest scheduleRequest ) { - ArrayList jobParameters = scheduleRequest.getJobParameters(); - for ( JobScheduleParam jobParameter : jobParameters ) { - if ( IScheduler.RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME.equals( jobParameter.getName() ) && "boolean" - .equals( jobParameter.getType() ) ) { - return (Boolean) jobParameter.getValue(); - } - } - return true; - } - - public String getAppendDateFormat( final JobScheduleRequest scheduleRequest ) { - ArrayList jobParameters = scheduleRequest.getJobParameters(); - for ( JobScheduleParam jobParameter : jobParameters ) { - if ( IScheduler.RESERVEDMAPKEY_APPEND_DATE_FORMAT.equals( jobParameter.getName() ) && "string" - .equals( jobParameter.getType() ) ) { - return (String) jobParameter.getValue(); - } - } - return null; - } - - public List getJobs() throws SchedulerException { - IPentahoSession session = getSession(); - final String principalName = session.getName(); // this authentication wasn't matching with the job user name, - // changed to get name via the current session - final Boolean canAdminister = canAdminister( session ); - - List jobs = getScheduler().getJobs( new IJobFilter() { - @Override - public boolean accept( IJob job ) { - if ( canAdminister ) { - return !IBlockoutManager.BLOCK_OUT_JOB_NAME.equals( job.getJobName() ); - } - return principalName.equals( job.getUserName() ); - } - } ); - return jobs; - } - - protected Boolean canAdminister() { - return canAdminister( null ); - } - - protected Boolean canAdminister( IPentahoSession session ) { - if ( getPolicy().isAllowed( AdministerSecurityAction.NAME ) ) { - return true; - } - return false; - } - - protected String resolveActionId( final String inputFile ) { - return SchedulerResourceUtil.resolveActionId( inputFile ); - } - - protected String getExtension( String filename ) { - return SchedulerResourceUtil.getExtension( filename ); - } - - /** - * Gets an instance of SessionResource - * - * @return SessionResource - */ - protected SessionResource getSessionResource() { - if ( sessionResource == null ) { - sessionResource = new SessionResource(); - } - return sessionResource; - } - - protected FileService getFileService() { - if ( fileService == null ) { - fileService = new FileService(); - } - - return fileService; - } - - protected IBlockoutManager getBlockoutManager() { - if ( blockoutManager == null ) { - blockoutManager = PentahoSystem.get( IBlockoutManager.class, "IBlockoutManager", null ); //$NON-NLS-1$; - } - - return blockoutManager; - } - - protected ISecurityHelper getSecurityHelper() { - return SecurityHelper.getInstance(); - } -} From 8d67aa20a28406410ce24427f8d332b5d27597e8 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Sun, 17 Sep 2023 14:56:31 -0400 Subject: [PATCH 21/59] BACKLOG-38036 - Fixed Issues with Cron an Simple Triggers --- .../api/scheduler}/JobScheduleParam.java | 2 +- .../exporter/PentahoPlatformExporter.java | 4 +- .../services/exporter/ScheduleExportUtil.java | 13 +- .../importer/SolutionImportHandler.java | 10 - .../exportManifest/ExportManifest.java | 26 +- .../bindings/ExportManifestDto.java | 6 +- .../bindings/JobScheduleRequest.java | 2 + .../bindings/ObjectFactory.java | 2 + .../http/api/resources/JobScheduleParam.java | 4 +- .../api/resources/JobScheduleRequest.java | 228 ------------- .../SchedulerOutputPathResolver.java | 5 +- .../api/resources/SchedulerResourceUtil.java | 299 ------------------ .../exporter/ScheduleExportUtilTest.java | 10 +- .../api/scheduler2/IJobScheduleParam.java | 10 + .../api/scheduler2/IJobScheduleRequest.java | 40 +++ .../platform/api/scheduler2/IScheduler.java | 81 ++--- .../scheduler2/blockout/BlockoutAction.java | 66 ---- 17 files changed, 133 insertions(+), 675 deletions(-) rename {extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings => api/src/main/java/org/pentaho/platform/api/scheduler}/JobScheduleParam.java (97%) delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParam.java b/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java similarity index 97% rename from extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParam.java rename to api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java index 8dd066f94e0..0e267b12ba3 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParam.java +++ b/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java @@ -25,7 +25,7 @@ // Generated on: 2013.07.25 at 11:25:28 AM EDT // -package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; +package org.pentaho.platform.api.scheduler; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java index 03261f75605..84e92a2877c 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java @@ -34,6 +34,7 @@ import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.SchedulerException; @@ -62,7 +63,6 @@ import org.pentaho.platform.repository.solution.filebased.MondrianVfs; import org.pentaho.platform.repository2.ClientRepositoryPaths; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.userdetails.UserDetailsService; @@ -318,7 +318,7 @@ protected void exportSchedules() { continue; } try { - JobScheduleRequest scheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); + IJobScheduleRequest scheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); getExportManifest().addSchedule( scheduleRequest ); } catch ( IllegalArgumentException e ) { log.warn( e.getMessage(), e ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java index c2d07ac5de8..64556b7117d 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java @@ -31,14 +31,13 @@ import org.pentaho.platform.api.scheduler2.IBlockoutManager; import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobTrigger; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; public class ScheduleExportUtil { @@ -49,14 +48,14 @@ public ScheduleExportUtil() { // to get 100% coverage } - public static JobScheduleRequest createJobScheduleRequest( IJob job ) { + public static IJobScheduleRequest createJobScheduleRequest( IJob job ) { if ( job == null ) { throw new IllegalArgumentException( Messages.getInstance().getString( "ScheduleExportUtil.JOB_MUST_NOT_BE_NULL" ) ); } IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ assert scheduler != null; - JobScheduleRequest schedule = new JobScheduleRequest(); + IJobScheduleRequest schedule = scheduler.createJobScheduleRequest(); schedule.setJobName( job.getJobName() ); schedule.setDuration( job.getJobTrigger().getDuration() ); schedule.setJobState( job.getState() ); @@ -113,7 +112,7 @@ public static JobScheduleRequest createJobScheduleRequest( IJob job ) { } schedule.getPdiParameters().putAll( (Map) serializable ); } else { - JobScheduleParam param = null; + JobScheduleParam param = new JobScheduleParam(); if ( serializable instanceof String ) { String value = (String) serializable; if ( IScheduler.RESERVEDMAPKEY_ACTIONCLASS.equals( key ) ) { @@ -129,9 +128,7 @@ public static JobScheduleRequest createJobScheduleRequest( IJob job ) { } else if ( serializable instanceof Boolean ) { param = new JobScheduleParam( key, (Boolean) serializable ); } - if ( param != null ) { - schedule.getJobParameters().add( param ); - } + schedule.getJobParameters().add( param ); } } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 6cf0faca7f7..c142b56331c 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -25,7 +25,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -36,10 +35,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import javax.ws.rs.core.Response; - import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.pentaho.database.model.IDatabaseConnection; @@ -55,8 +51,6 @@ import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJob.JobState; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; @@ -81,10 +75,6 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -//import org.pentaho.platform.web.http.api.resources.SchedulerResource; -import org.pentaho.platform.web.http.api.resources.JobRequest; -import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.services.FileService; public class SolutionImportHandler implements IPlatformImportHandler { diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java index 888052a7dbb..f72f3104ed5 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java @@ -22,6 +22,7 @@ import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; import org.pentaho.platform.plugin.services.importexport.RoleExport; import org.pentaho.platform.plugin.services.importexport.UserExport; @@ -33,7 +34,7 @@ import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian; import org.pentaho.platform.util.StringUtil; import org.pentaho.platform.util.xml.XMLParserFactoryProducer; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; + import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; @@ -71,7 +72,7 @@ public class ExportManifest { private ExportManifestDto.ExportManifestInformation manifestInformation; private List metadataList = new ArrayList<>(); private List mondrianList = new ArrayList<>(); - private List scheduleList = new ArrayList<>(); + private List scheduleList = new ArrayList<>(); private List datasourceList = new ArrayList<>(); private List userExports = new ArrayList<>(); private List roleExports = new ArrayList<>(); @@ -81,23 +82,24 @@ public class ExportManifest { public ExportManifest() { this.exportManifestEntities = new HashMap<>(); this.manifestInformation = new ExportManifestDto.ExportManifestInformation(); + IJobScheduleRequest request; } public ExportManifest( ExportManifestDto exportManifestDto ) { this(); - this.manifestInformation = exportManifestDto.getExportManifestInformation(); + manifestInformation = exportManifestDto.getExportManifestInformation(); List exportManifestEntityList = exportManifestDto.getExportManifestEntity(); for ( ExportManifestEntityDto exportManifestEntityDto : exportManifestEntityList ) { exportManifestEntities .put( exportManifestEntityDto.getPath(), new ExportManifestEntity( exportManifestEntityDto ) ); } - this.mondrianList = exportManifestDto.getExportManifestMondrian(); - this.metadataList = exportManifestDto.getExportManifestMetadata(); - this.scheduleList = exportManifestDto.getExportManifestSchedule(); - this.datasourceList = exportManifestDto.getExportManifestDatasource(); - this.userExports = exportManifestDto.getExportManifestUser(); - this.roleExports = exportManifestDto.getExportManifestRole(); - this.globalUserSettings = exportManifestDto.getGlobalUserSettings(); + mondrianList = exportManifestDto.getExportManifestMondrian(); + metadataList = exportManifestDto.getExportManifestMetadata(); + scheduleList = exportManifestDto.getExportManifestSchedule(); + datasourceList = exportManifestDto.getExportManifestDatasource(); + userExports = exportManifestDto.getExportManifestUser(); + roleExports = exportManifestDto.getExportManifestRole(); + globalUserSettings = exportManifestDto.getGlobalUserSettings(); setMetaStore( exportManifestDto.getExportManifestMetaStore() ); } @@ -273,7 +275,7 @@ public void addMondrian( ExportManifestMondrian mondrian ) { this.mondrianList.add( mondrian ); } - public void addSchedule( JobScheduleRequest schedule ) { + public void addSchedule( IJobScheduleRequest schedule ) { this.scheduleList.add( schedule ); } @@ -289,7 +291,7 @@ public List getMondrianList() { return mondrianList; } - public List getScheduleList() { + public List getScheduleList() { return scheduleList; } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java index 0de52a801aa..4d9666946c9 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java @@ -27,10 +27,10 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; import org.pentaho.platform.plugin.services.importexport.RoleExport; import org.pentaho.platform.plugin.services.importexport.UserExport; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -93,7 +93,7 @@ public class ExportManifestDto { @XmlElement ( name = "ExportManifestMetadata" ) protected List exportManifestMetadata; @XmlElement ( name = "ExportManifestSchedule" ) - protected List exportManifestSchedule; + protected List exportManifestSchedule; @XmlElement ( name = "ExportManifestDatasource" ) protected List exportManifestDatasource; @XmlElement ( name = "ExportManifestEntity" ) @@ -210,7 +210,7 @@ public List getExportManifestMetadata() { *

* Objects of the following type(s) are allowed in the list {@link JobScheduleRequest } */ - public List getExportManifestSchedule() { + public List getExportManifestSchedule() { if ( exportManifestSchedule == null ) { exportManifestSchedule = new ArrayList<>(); } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java index bdd56e51efb..f5ba4f180ed 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java @@ -27,6 +27,8 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; +import org.pentaho.platform.api.scheduler.JobScheduleParam; + import java.util.ArrayList; import java.util.List; diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ObjectFactory.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ObjectFactory.java index 67e2e086d6c..eff9db01190 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ObjectFactory.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ObjectFactory.java @@ -27,6 +27,8 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; +import org.pentaho.platform.api.scheduler.JobScheduleParam; + import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java index 40b5ee20258..d98d3318c28 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java @@ -20,13 +20,15 @@ package org.pentaho.platform.web.http.api.resources; +import org.pentaho.platform.api.scheduler2.IJobScheduleParam; + import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; -public class JobScheduleParam implements Serializable { +public class JobScheduleParam implements Serializable, IJobScheduleParam { private static final long serialVersionUID = -4214459740606299083L; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java deleted file mode 100644 index 10834cd5f98..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleRequest.java +++ /dev/null @@ -1,228 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Map; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import org.pentaho.platform.api.scheduler2.ICronJobTrigger; -import org.pentaho.platform.api.scheduler2.IJob.JobState; -import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; - -@XmlRootElement -public class JobScheduleRequest implements Serializable { - - private static final long serialVersionUID = -485489832281790257L; - - public static final int SUNDAY = 0; - - public static final int MONDAY = 1; - - public static final int TUESDAY = 2; - - public static final int WEDNESDAY = 3; - - public static final int THURSDAY = 4; - - public static final int FRIDAY = 5; - - public static final int SATURDAY = 6; - - public static final int JANUARY = 0; - - public static final int FEBRUARY = 1; - - public static final int MARCH = 2; - - public static final int APRIL = 3; - - public static final int MAY = 4; - - public static final int JUNE = 5; - - public static final int JULY = 6; - - public static final int AUGUST = 7; - - public static final int SEPTEMBER = 8; - - public static final int OCTOBER = 9; - - public static final int NOVEMBER = 10; - - public static final int DECEMBER = 11; - - public static final int LAST_WEEK_OF_MONTH = 4; - - String jobName; - - String jobId; - - JobState jobState; - - String inputFile; - - String outputFile; - - String actionClass; - - ICronJobTrigger cronJobTrigger; - - ComplexJobTriggerProxy complexJobTrigger; - - ISimpleJobTrigger simpleJobTrigger; - - ArrayList jobParameters = new ArrayList(); - - Map pdiParameters; - - long duration; - - String timeZone; - - public String getInputFile() { - return inputFile; - } - - public void setInputFile( String file ) { - this.inputFile = file; - } - - public String getOutputFile() { - return outputFile; - } - - public void setOutputFile( String file ) { - this.outputFile = file; - } - - @XmlElement(name = "data", type=Object.class) - public ICronJobTrigger getCronJobTrigger() { - return cronJobTrigger; - } - - public void setCronJobTrigger( ICronJobTrigger jobTrigger ) { - if ( jobTrigger != null ) { - setComplexJobTrigger( null ); - setSimpleJobTrigger( null ); - } - this.cronJobTrigger = jobTrigger; - } - - public ComplexJobTriggerProxy getComplexJobTrigger() { - return complexJobTrigger; - } - - public void setComplexJobTrigger( ComplexJobTriggerProxy jobTrigger ) { - if ( jobTrigger != null ) { - setCronJobTrigger( null ); - setSimpleJobTrigger( null ); - } - this.complexJobTrigger = jobTrigger; - } - - @XmlElement(name = "data", type=Object.class) - public ISimpleJobTrigger getSimpleJobTrigger() { - return simpleJobTrigger; - } - - public void setSimpleJobTrigger( ISimpleJobTrigger jobTrigger ) { - if ( jobTrigger != null ) { - setCronJobTrigger( null ); - setComplexJobTrigger( null ); - } - this.simpleJobTrigger = jobTrigger; - } - - public ArrayList getJobParameters() { - return jobParameters; - } - - public void setJobParameters( ArrayList jobParameters ) { - if ( jobParameters != this.jobParameters ) { - this.jobParameters.clear(); - if ( jobParameters != null ) { - this.jobParameters.addAll( jobParameters ); - } - } - } - - public Map getPdiParameters() { - return pdiParameters; - } - - public void setPdiParameters( Map pdiParameters ) { - this.pdiParameters = pdiParameters; - } - - public String getJobName() { - return jobName; - } - - public void setJobName( String jobName ) { - this.jobName = jobName; - } - - public JobState getJobState() { - return jobState; - } - - public void setJobState( JobState jobState ) { - this.jobState = jobState; - } - - public String getActionClass() { - return actionClass; - } - - public void setActionClass( String actionClass ) { - this.actionClass = actionClass; - } - - public long getDuration() { - return duration; - } - - public void setDuration( long duration ) { - this.duration = duration; - } - - public String getTimeZone() { - return timeZone; - } - - public void setTimeZone( String timeZone ) { - this.timeZone = timeZone; - } - - public String getJobId() { - return jobId; - } - - public void setJobId( String jobId ) { - this.jobId = jobId; - } - -} diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java index 4a1acfdf960..6e937a052c0 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java @@ -26,6 +26,7 @@ import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; @@ -53,9 +54,9 @@ private IUserSettingService getSettingsService() { } private IUserSettingService settingsService; - private JobScheduleRequest scheduleRequest; + private IJobScheduleRequest scheduleRequest; - public SchedulerOutputPathResolver( JobScheduleRequest scheduleRequest ) { + public SchedulerOutputPathResolver( IJobScheduleRequest scheduleRequest ) { this.scheduleRequest = scheduleRequest; } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java deleted file mode 100644 index ca03f7fade1..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtil.java +++ /dev/null @@ -1,299 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import com.cronutils.builder.CronBuilder; -import com.cronutils.model.Cron; -import com.cronutils.model.CronType; -import com.cronutils.model.definition.CronDefinitionBuilder; -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.IComplexJobTrigger; -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.ISimpleJobTrigger; -import org.pentaho.platform.plugin.services.exporter.ScheduleExportUtil; -import org.pentaho.platform.repository.RepositoryFilenameUtils; -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; - -import static com.cronutils.model.field.expression.FieldExpressionFactory.*; - -public class SchedulerResourceUtil { - - private static final Log logger = LogFactory.getLog( SchedulerResourceUtil.class ); - - public static final String RESERVEDMAPKEY_LINEAGE_ID = "lineage-id"; - public static final String RESERVED_BACKGROUND_EXECUTION_ACTION_ID = ".backgroundExecution"; - //$NON-NLS-1$ //$NON-NLS-2$ - - 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 ? - scheduler.createSimpleJobTrigger( new Date( System.currentTimeMillis() + 10000 ), null, 0, 0 ) - : scheduleRequest.getSimpleJobTrigger(); - - if ( scheduleRequest.getSimpleJobTrigger() != null ) { - ISimpleJobTrigger simpleJobTrigger = scheduleRequest.getSimpleJobTrigger(); - - if ( simpleJobTrigger.getStartTime() == null ) { - simpleJobTrigger.setStartTime( new Date() ); - } - - jobTrigger = simpleJobTrigger; - - } else if ( scheduleRequest.getComplexJobTrigger() != null ) { - - ComplexJobTriggerProxy proxyTrigger = scheduleRequest.getComplexJobTrigger(); - String cronString = proxyTrigger.getCronString(); - IComplexJobTrigger complexJobTrigger; - /** - * We will have two options. Either it is a daily scehdule to ignore DST or any other - * complex schedule - */ - if ( cronString != null && cronString.equals( "TO_BE_GENERATED" ) ) { - cronString = generateCronString( (int) proxyTrigger.getRepeatInterval() / 86400 - , proxyTrigger.getStartTime() ); - complexJobTrigger = scheduler.createComplexTrigger( cronString ); - } else { - complexJobTrigger = scheduler.createComplexJobTrigger(); - 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 { - proxyTrigger.getDaysOfMonth(); - 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( proxyTrigger.getStartTime() ); - complexJobTrigger.setHourlyRecurrence( calendar.get( Calendar.HOUR_OF_DAY ) ); - complexJobTrigger.addMinuteRecurrence( calendar.get( Calendar.MINUTE ) ); - } - - complexJobTrigger.setStartTime( proxyTrigger.getStartTime() ); - complexJobTrigger.setEndTime( proxyTrigger.getEndTime() ); - complexJobTrigger.setDuration( scheduleRequest.getDuration() ); - complexJobTrigger.setUiPassParam( scheduleRequest.getComplexJobTrigger().getUiPassParam() ); - jobTrigger = complexJobTrigger; - - } else if ( scheduleRequest.getCronJobTrigger() != null ) { - - if ( scheduler instanceof IScheduler ) { - String cronString = scheduleRequest.getCronJobTrigger().getCronString(); - String delims = "[ ]+"; //$NON-NLS-1$ - String[] tokens = cronString.split( delims ); - if ( tokens.length < 7 ) { - cronString += " *"; - } - IComplexJobTrigger complexJobTrigger = scheduler.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.getSimpleJobTrigger().getStartTime() != null ) { - Date origStartDate = request.getSimpleJobTrigger().getStartTime(); - Date serverTimeZoneStartDate = convertDateToServerTimeZone( origStartDate, request.getTimeZone() ); - request.getSimpleJobTrigger().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() + " 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() ); - return quartzStartDate.getTime(); - } else { - return dateTime; - } - } - - - public static HashMap handlePDIScheduling( RepositoryFile file, - HashMap parameterMap, - Map pdiParameters ) { - - HashMap convertedParameterMap = new HashMap<>(); - - boolean paramsAdded = false; - if ( pdiParameters != null ) { - convertedParameterMap.put( ScheduleExportUtil.RUN_PARAMETERS_KEY, (Serializable) pdiParameters ); - paramsAdded = true; - } else { - pdiParameters = new HashMap(); - } - - if ( file != null && isPdiFile( file ) ) { - - Iterator it = parameterMap.keySet().iterator(); - - while ( it.hasNext() ) { - - String param = 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() ) ); - } - - public static String resolveActionId( final String inputFile ) { - // unchanged logic, ported over from its original location ( SchedulerService ) into this SchedulerUtil class - if ( !StringUtils.isEmpty( inputFile ) && !StringUtils.isEmpty( getExtension( inputFile ) ) ) { - return getExtension( inputFile ) + RESERVED_BACKGROUND_EXECUTION_ACTION_ID; - } - return null; - } - - public static String getExtension( final String filename ) { - // unchanged logic, ported over from its original location ( SchedulerService ) into this SchedulerUtil class - return RepositoryFilenameUtils.getExtension( filename ); - } - - private static String generateCronString( long interval, Date startDate ) { - Calendar calendar = GregorianCalendar.getInstance(); // creates a new calendar instance - calendar.setTime( startDate ); - int hour = calendar.get( Calendar.HOUR_OF_DAY ); - int minute = calendar.get( Calendar.MINUTE ); - - Cron cron = CronBuilder.cron( CronDefinitionBuilder.instanceDefinitionFor( CronType.QUARTZ ) ) - .withYear( always() ) - .withDoM( every( (int) interval ) ) - .withMonth( always() ) - .withDoW( questionMark() ) - .withHour( on( hour ) ) - .withMinute( on( minute ) ) - .withSecond( on( 0 ) ).instance(); - return cron.asString(); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java index aa3bf08e6a9..6885b44f39b 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java @@ -22,13 +22,13 @@ import org.junit.Before; import org.junit.Test; -import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.IBlockoutManager; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; import org.pentaho.platform.api.scheduler2.IJob; import org.pentaho.platform.api.scheduler2.IJobTrigger; +import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.ICronJobTrigger; import org.pentaho.platform.web.http.api.resources.JobScheduleParam; import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; @@ -38,7 +38,9 @@ import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java new file mode 100644 index 00000000000..6715c8bca2e --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java @@ -0,0 +1,10 @@ +package org.pentaho.platform.api.scheduler2; + +import java.io.Serializable; + +public interface IJobScheduleParam { + String getName(); + + String getType(); + Serializable getValue(); +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java new file mode 100644 index 00000000000..ec6c8405d5c --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java @@ -0,0 +1,40 @@ +package org.pentaho.platform.api.scheduler2; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +; + +public interface IJobScheduleRequest { + void setJobName( String jobName ); + + void setDuration( long duration ); + + void setJobState( IJob.JobState state ); + + void setInputFile( String inputFilePath ); + + void setOutputFile( String outputFilePath ); + + Map getPdiParameters(); + + void setPdiParameters( HashMap stringStringHashMap ); + + void setActionClass( String value ); + + void setTimeZone( String value ); + + void setSimpleJobTrigger( ISimpleJobTrigger jobTrigger ); + + void setCronJobTrigger( ICronJobTrigger cron ); + + String getInputFile(); + + String getJobName(); + + String getOutputFile(); + + public List getJobParameters(); +} + diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java index 7bd76037160..709c5a6db81 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java @@ -21,6 +21,7 @@ package org.pentaho.platform.api.scheduler2; import java.io.Serializable; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -35,28 +36,28 @@ */ public interface IScheduler { - public static final String RESERVEDMAPKEY_ACTIONCLASS = ActionUtil.QUARTZ_ACTIONCLASS; - public static final String RESERVEDMAPKEY_ACTIONUSER = ActionUtil.QUARTZ_ACTIONUSER; + String RESERVEDMAPKEY_ACTIONCLASS = ActionUtil.QUARTZ_ACTIONCLASS; + String RESERVEDMAPKEY_ACTIONUSER = ActionUtil.QUARTZ_ACTIONUSER; - public static final String RESERVEDMAPKEY_ACTIONID = ActionUtil.QUARTZ_ACTIONID; + String RESERVEDMAPKEY_ACTIONID = ActionUtil.QUARTZ_ACTIONID; - public static final String RESERVEDMAPKEY_STREAMPROVIDER = ActionUtil.QUARTZ_STREAMPROVIDER; + String RESERVEDMAPKEY_STREAMPROVIDER = ActionUtil.QUARTZ_STREAMPROVIDER; - public static final String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; + String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; - public static final String RESERVEDMAPKEY_UIPASSPARAM = ActionUtil.QUARTZ_UIPASSPARAM; + String RESERVEDMAPKEY_UIPASSPARAM = ActionUtil.QUARTZ_UIPASSPARAM; - public static final String RESERVEDMAPKEY_LINEAGE_ID = ActionUtil.QUARTZ_LINEAGE_ID; + String RESERVEDMAPKEY_LINEAGE_ID = ActionUtil.QUARTZ_LINEAGE_ID; - public static final String RESERVEDMAPKEY_RESTART_FLAG = ActionUtil.QUARTZ_RESTART_FLAG; + String RESERVEDMAPKEY_RESTART_FLAG = ActionUtil.QUARTZ_RESTART_FLAG; - public static final String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = ActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; + String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = ActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; - public static final String RESERVEDMAPKEY_APPEND_DATE_FORMAT = ActionUtil.QUARTZ_APPEND_DATE_FORMAT; + String RESERVEDMAPKEY_APPEND_DATE_FORMAT = ActionUtil.QUARTZ_APPEND_DATE_FORMAT; - public enum SchedulerStatus { + enum SchedulerStatus { RUNNING, PAUSED, STOPPED - }; + } /** * Schedules a job to be run at one or more times in the future. @@ -73,7 +74,7 @@ public enum SchedulerStatus { * @throws SchedulerException * If the job could not be scheduled */ - public IJob createJob( String jobName, Class action, Map jobParams, + IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger ) throws SchedulerException; /** @@ -91,7 +92,7 @@ public IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger ) + IJob createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger ) throws SchedulerException; /** @@ -112,7 +113,7 @@ public IJob createJob( String jobName, String actionId, Map action, Map jobParams, + IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger, IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException; /** @@ -133,7 +134,7 @@ public IJob createJob( String jobName, Class action, Map jobParams, IJobTrigger trigger, + IJob createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger, IBackgroundExecutionStreamProvider outputStreamProvider ) throws SchedulerException; /** @@ -148,7 +149,7 @@ public IJob createJob( String jobName, String actionId, Map jobParams, IJobTrigger trigger ) + void updateJob( String jobId, Map jobParams, IJobTrigger trigger ) throws SchedulerException; /** @@ -157,7 +158,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be removed */ - public void removeJob( String jobId ) throws SchedulerException; + void removeJob( String jobId ) throws SchedulerException; /** * Prevents the specified job from running in the future. The job remains in the list of scheduled jobs in a "paused" @@ -166,7 +167,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be paused */ - public void pauseJob( String jobId ) throws SchedulerException; + void pauseJob( String jobId ) throws SchedulerException; /** * Allows previously paused jobs to resume running in the future. @@ -174,7 +175,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be resumed */ - public void resumeJob( String jobId ) throws SchedulerException; + void resumeJob( String jobId ) throws SchedulerException; /** * Fetches a Job by jobId @@ -182,7 +183,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be returned */ - public IJob getJob( String jobId ) throws SchedulerException; + IJob getJob( String jobId ) throws SchedulerException; /** * Triggers the given quartz job by jobId to be executed immediately @@ -190,7 +191,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param jobId * the job to be executed */ - public void triggerNow( String jobId ) throws SchedulerException; + void triggerNow( String jobId ) throws SchedulerException; /** * Sets when a particular subject is allowed to schedule jobs. @@ -200,7 +201,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param window * the window of time at which the scheduler is available */ - public void setSubjectAvailabilityWindow( IScheduleSubject subject, IComplexJobTrigger window ); + void setSubjectAvailabilityWindow( IScheduleSubject subject, IComplexJobTrigger window ); /** * Replaces the scheduler availability map with the provided availability map. @@ -208,7 +209,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param windows * the new scheduler availability map */ - public void setAvailabilityWindows( Map windows ); + void setAvailabilityWindows( Map windows ); /** * Gets the scheduler availability window to the specified subject @@ -217,32 +218,32 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the subject whose window is being requested * @return the subject's availability window */ - public IComplexJobTrigger getSubjectAvailabilityWindow( IScheduleSubject subject ); + IComplexJobTrigger getSubjectAvailabilityWindow( IScheduleSubject subject ); /** * Gets the scheduler availability window for all subjects for whom a window has been set * * @return the scheduler availability map */ - public Map getAvailabilityWindows(); + Map getAvailabilityWindows(); /** * Pauses the entire scheduler, which prevents all scheduled jobs from running. Any currently running jobs are allowed * to complete. Note that the "paused" state of individual jobs is not changed by this call. */ - public void pause() throws SchedulerException; + void pause() throws SchedulerException; /** * Allows the scheduler to process scheduled jobs. Note that the "paused" state of individual jobs is not changed by * this call. */ - public void start() throws SchedulerException; + void start() throws SchedulerException; /** * Shuts the scheduler down so it will process no more jobs. The implementation will decide if this means kill jobs in * progress or let them finish. */ - public void shutdown() throws SchedulerException; + void shutdown() throws SchedulerException; /** * Sets the minimum time that must elapse between runs of any jobs. For example if set to "5" then a job may not be @@ -253,7 +254,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param intervalInSeconds * the interval in seconds */ - public void setMinScheduleInterval( IScheduleSubject subject, int intervalInSeconds ); + void setMinScheduleInterval( IScheduleSubject subject, int intervalInSeconds ); /** * Get the minimum time that must elapse between job runs. @@ -262,7 +263,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the subject whose min interval is being requested return the minimum interval or null if no interval has * been set */ - public Integer getMinScheduleInterval( IScheduleSubject subject ); + Integer getMinScheduleInterval( IScheduleSubject subject ); /** * Lists currently scheduled jobs. @@ -271,7 +272,7 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the filter to use to determine which jobs to return. If null all scheduled jobs are return. * @return the scheduled jobs */ - public List getJobs( IJobFilter filter ) throws SchedulerException; + List getJobs( IJobFilter filter ) throws SchedulerException; /** * Returns a history of the runs for a particular job. @@ -280,16 +281,16 @@ public void updateJob( String jobId, Map jobParams, IJobTr * the job for which to query it's execution history * @return the execution history for the given job */ - public List getJobHistory( String jobId ); + List getJobHistory( String jobId ); /** * Returns the current scheduler status. * * @return the scheduler status */ - public SchedulerStatus getStatus() throws SchedulerException; + SchedulerStatus getStatus() throws SchedulerException; - public void addListener( ISchedulerListener listener ); + void addListener( ISchedulerListener listener ); /** * Not intended for public use. @@ -299,17 +300,19 @@ public void updateJob( String jobId, Map jobParams, IJobTr * @param params * @param streamProvider */ - public void fireJobCompleted( final IAction actionBean, final String actionUser, + void fireJobCompleted( final IAction actionBean, final String actionUser, final Map params, IBackgroundExecutionStreamProvider streamProvider ); - public ISimpleJobTrigger createSimpleJobTrigger( Date startTime, Date endTime, int repeatCount, long repeatIntervalSeconds ); + IJobScheduleRequest createJobScheduleRequest(); + ISimpleJobTrigger createSimpleJobTrigger( Date startTime, Date endTime, int repeatCount, long repeatIntervalSeconds ); - public ICronJobTrigger createCronJobTrigger(); + ICronJobTrigger createCronJobTrigger(); - public IComplexJobTrigger createComplexTrigger( String cronString ); + IComplexJobTrigger createComplexTrigger( String cronString ); IComplexJobTrigger createComplexJobTrigger(); IComplexJobTrigger createComplexTrigger( Integer year, Integer month, Integer dayOfMonth, Integer dayOfWeek, Integer hourOfDay ); + ArrayList getJobParameters(); /** * A default implementation which doesn't do anything and exists for the backward compatibility sake. * @param jobParams scheduling job parameters diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java b/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java deleted file mode 100644 index 75cb536f77a..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/blockout/BlockoutAction.java +++ /dev/null @@ -1,66 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.blockout; - -import java.util.Date; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IVarArgsAction; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; - -/** - * @author wseyler This is the job that executes when the a block out trigger fires. This job essentially does nothing - * more than logging the firing of the trigger. - */ -public class BlockoutAction implements IVarArgsAction { - - private static final Log logger = LogFactory.getLog( BlockoutAction.class ); - - long duration; - Date scheduledFireTime; - - @Override - public void execute() throws Exception { - Date startDate = new Date(); - long effectiveDuration = duration - ( startDate.getTime() - scheduledFireTime.getTime() ); - if ( effectiveDuration < 0 ) { - logger.warn( "Blocking Scheduled for " + scheduledFireTime + " for " + this.duration - + " milliseconds has already expired" ); - } else { - logger.warn( "Blocking Started at: " + startDate + " and will last: " + effectiveDuration + " milliseconds" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - Thread.sleep( effectiveDuration ); - logger.warn( "Blockout that started at: " + startDate + " has ended at: " + new Date() ); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - @Override - public void setVarArgs( Map args ) { - if ( args.containsKey( IBlockoutManager.DURATION_PARAM ) ) { - this.duration = ( (Number) args.get( IBlockoutManager.DURATION_PARAM ) ).longValue(); - } - if ( args.containsKey( IBlockoutManager.SCHEDULED_FIRE_TIME ) ) { - this.scheduledFireTime = ( (Date) args.get( IBlockoutManager.SCHEDULED_FIRE_TIME ) ); - } - } - -} From 9ffc9cd3f7c74b6dfad29e19187de772fd301ffb Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Mon, 18 Sep 2023 12:13:58 -0400 Subject: [PATCH 22/59] [BACKLOG-38225] SCHEDULER - Make scheduler-plugin/UI basic functionality work again --- .../org/pentaho/mantle/client/MantleApplication.java | 2 +- .../java/org/pentaho/mantle/client/MantleUtils.java | 4 ++++ .../mantle/client/admin/ContentCleanerPanel.java | 12 +++++------- .../client/commands/RunInBackgroundCommand.java | 5 +++-- .../pentaho/mantle/client/ui/PerspectiveManager.java | 3 ++- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleApplication.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleApplication.java index debb92e3975..4308a9bf312 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleApplication.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleApplication.java @@ -406,7 +406,7 @@ public void onResponseReceived( Request arg0, Response response ) { SolutionBrowserPanel.getInstance().setAdministrator( isAdministrator ); try { - String restUrl2 = GWT.getHostPageBaseURL() + "api/scheduler/canSchedule"; //$NON-NLS-1$ + String restUrl2 = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/canSchedule"; //$NON-NLS-1$ RequestBuilder requestBuilder2 = new RequestBuilder( RequestBuilder.GET, restUrl2 ); requestBuilder2.setHeader( "accept", "application/json" ); //$NON-NLS-1$ //$NON-NLS-2$ requestBuilder2.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java index cedfb4d991a..b65f86e98d0 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java @@ -61,6 +61,10 @@ public void fireRefreshFolderEvent( String outputLocation ) { EventBusUtil.EVENT_BUS.fireEvent( event ); } + public static native String getSchedulerPluginContextURL()/*-{ + return $wnd.pho.getSchedulerPluginContextURL(); + }-*/; + private static native void setupNativeHooks( MantleUtils utils ) /*-{ $wnd.mantle.setSchedulesPerspective = function() { diff --git a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java index 3e68466f92a..b9e705ecce9 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/admin/ContentCleanerPanel.java @@ -46,6 +46,7 @@ import com.google.gwt.user.client.ui.VerticalPanel; import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; +import org.pentaho.mantle.client.MantleUtils; import org.pentaho.mantle.client.dialogs.WaitPopup; import org.pentaho.mantle.client.messages.Messages; @@ -72,12 +73,9 @@ public ContentCleanerPanel() { public void activate() { clear(); - String moduleBaseURL = GWT.getModuleBaseURL(); - String moduleName = GWT.getModuleName(); - String contextURL = moduleBaseURL.substring( 0, moduleBaseURL.lastIndexOf( moduleName ) ); RequestBuilder scheduleFileRequestBuilder = - new RequestBuilder( RequestBuilder.GET, contextURL + "api/scheduler/getContentCleanerJob?cb=" + new RequestBuilder( RequestBuilder.GET, MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/getContentCleanerJob?cb=" + System.currentTimeMillis() ); scheduleFileRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); scheduleFileRequestBuilder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ @@ -243,7 +241,7 @@ public void deleteContentNow( long age ) { + "\"repeatInterval\": \"0\", \"startTime\": \"" + date + "\", \"uiPassParam\": \"RUN_ONCE\"} }"; RequestBuilder scheduleFileRequestBuilder = - new RequestBuilder( RequestBuilder.POST, GWT.getHostPageBaseURL() + "api/scheduler/job" ); + new RequestBuilder( RequestBuilder.POST, MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/job" ); scheduleFileRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); scheduleFileRequestBuilder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ try { @@ -254,7 +252,7 @@ public void onError( Request request, Throwable exception ) { public void onResponseReceived( Request request, Response response ) { String jobId = response.getText(); final RequestBuilder requestBuilder = - new RequestBuilder( RequestBuilder.GET, GWT.getHostPageBaseURL() + new RequestBuilder( RequestBuilder.GET, MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/jobinfo?jobId=" + URL.encodeQueryString( jobId ) ); requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); requestBuilder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ @@ -301,7 +299,7 @@ private void deleteContentCleaner() { activate(); return; } - final String url = GWT.getHostPageBaseURL() + "api/scheduler/removeJob"; //$NON-NLS-1$ + final String url = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/removeJob"; //$NON-NLS-1$ RequestBuilder builder = new RequestBuilder( RequestBuilder.DELETE, url ); builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ diff --git a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java index 86d516b6051..51e85b69109 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/commands/RunInBackgroundCommand.java @@ -38,6 +38,7 @@ import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.gwt.widgets.client.utils.NameUtils; import org.pentaho.gwt.widgets.client.utils.string.StringUtils; +import org.pentaho.mantle.client.MantleUtils; import org.pentaho.mantle.client.events.SolutionFileHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel; @@ -263,7 +264,7 @@ private RequestBuilder createParametersChecker( String urlPath ) { } protected void checkSchedulePermissionAndDialog() { - final String url = getFullyQualifiedURL() + "api/scheduler/isScheduleAllowed?id=" + repositoryFile.getRepositoryFile().getId(); //$NON-NLS-1$ + final String url = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/isScheduleAllowed?id=" + repositoryFile.getRepositoryFile().getId(); //$NON-NLS-1$ RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.GET, url ); requestBuilder.setHeader( "accept", "text/plain" ); requestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); @@ -376,7 +377,7 @@ public void onResponseReceived( Request request, Response response ) { // just run it RequestBuilder scheduleFileRequestBuilder = - new RequestBuilder( RequestBuilder.POST, contextURL + "api/scheduler/job" ); //$NON-NLS-1$ + new RequestBuilder( RequestBuilder.POST, MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/job" ); //$NON-NLS-1$ scheduleFileRequestBuilder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ scheduleFileRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 40f851a4e47..7bef0d51318 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -46,6 +46,7 @@ import org.pentaho.gwt.widgets.client.utils.i18n.IResourceBundleLoadCallback; import org.pentaho.gwt.widgets.client.utils.i18n.ResourceBundle; import org.pentaho.mantle.client.MantleApplication; +import org.pentaho.mantle.client.MantleUtils; import org.pentaho.mantle.client.admin.ISysAdminPanel; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.PerspectivesLoadedEvent; @@ -114,7 +115,7 @@ private Collection getMenuItems(){ } private void init() { - final String url = GWT.getHostPageBaseURL() + "api/scheduler/canSchedule/?ts=" + System.currentTimeMillis(); //$NON-NLS-1$ + final String url = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/canSchedule/?ts=" + System.currentTimeMillis(); //$NON-NLS-1$ RequestBuilder builder = new RequestBuilder( RequestBuilder.GET, url ); builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); From 2d715456d57668096376de2c5aa0d23f1aefa32a Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Thu, 21 Sep 2023 15:20:55 -0400 Subject: [PATCH 23/59] [BACKLOG-38225] SCHEDULER - Fix for the ExportManifest throwing a "JAXB can't handle interfaces" exception upon BISERVER start for the first time. --- .../exportManifest/ExportManifest.java | 4 +- .../exportManifest/ExportManifestUtil.java | 74 +++++++++++++++++++ .../bindings/ExportManifestDto.java | 5 +- .../api/scheduler2/IJobScheduleRequest.java | 12 ++- 4 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java index f72f3104ed5..affc325a3a2 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java @@ -95,7 +95,7 @@ public ExportManifest( ExportManifestDto exportManifestDto ) { } mondrianList = exportManifestDto.getExportManifestMondrian(); metadataList = exportManifestDto.getExportManifestMetadata(); - scheduleList = exportManifestDto.getExportManifestSchedule(); + scheduleList = ExportManifestUtil.fromBindingToSchedulerRequest( exportManifestDto.getExportManifestSchedule() ); datasourceList = exportManifestDto.getExportManifestDatasource(); userExports = exportManifestDto.getExportManifestUser(); roleExports = exportManifestDto.getExportManifestRole(); @@ -215,7 +215,7 @@ ExportManifestDto getExportManifestDto() { rawExportManifest.getExportManifestMetadata().addAll( this.metadataList ); rawExportManifest.getExportManifestMondrian().addAll( this.mondrianList ); - rawExportManifest.getExportManifestSchedule().addAll( this.scheduleList ); + rawExportManifest.getExportManifestSchedule().addAll( ExportManifestUtil.fromSchedulerToBindingRequest( this.scheduleList ) ); rawExportManifest.getExportManifestDatasource().addAll( this.datasourceList ); rawExportManifest.getExportManifestUser().addAll( this.getUserExports() ); rawExportManifest.getExportManifestRole().addAll( this.getRoleExports() ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java new file mode 100644 index 00000000000..8cc7a67ab12 --- /dev/null +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java @@ -0,0 +1,74 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.plugin.services.importexport.exportManifest; + +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.engine.core.system.PentahoSystem; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.JobScheduleRequest; + +import java.util.ArrayList; +import java.util.List; + +public class ExportManifestUtil { + + public static ArrayList fromSchedulerToBindingRequest( List scheduleList ) { + ArrayList schedules = new ArrayList<>(); + for ( IJobScheduleRequest schedulerRequest : scheduleList ) { + JobScheduleRequest bindingRequest = new JobScheduleRequest(); + bindingRequest.setJobName( schedulerRequest.getJobName() ); + bindingRequest.setDuration( schedulerRequest.getDuration() ); + //bindingRequest.setJobState( schedulerRequest.getJobState() ); + bindingRequest.setInputFile( schedulerRequest.getInputFile() ); + bindingRequest.setOutputFile( schedulerRequest.getOutputFile() ); + //bindingRequest.setPdiParameters( schedulerRequest.getPdiParameters() ); + bindingRequest.setActionClass( schedulerRequest.getActionClass() ); + bindingRequest.setTimeZone( schedulerRequest.getTimeZone() ); + //bindingRequest.setJobParameters( schedulerRequest.getJobParameters() ); + //bindingRequest.setSimpleJobTrigger( schedulerRequest.getSimpleJobTrigger() ); + //bindingRequest.setCronJobTrigger( schedulerRequest.getCronJobTrigger() ); + schedules.add( bindingRequest ); + } + return schedules; + } + + public static ArrayList fromBindingToSchedulerRequest( List bindingRequests ) { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + assert scheduler != null; + ArrayList schedules = new ArrayList<>(); + for ( JobScheduleRequest bindingRequest : bindingRequests ) { + IJobScheduleRequest scheduleRequest = scheduler.createJobScheduleRequest(); + scheduleRequest.setJobName( bindingRequest.getJobName() ); + scheduleRequest.setDuration( bindingRequest.getDuration() ); + //scheduleRequest.setJobState( bindingRequest.getJobState() ); + scheduleRequest.setInputFile( bindingRequest.getInputFile() ); + scheduleRequest.setOutputFile( bindingRequest.getOutputFile() ); + //scheduleRequest.setPdiParameters( bindingRequest.getPdiParameters() ); + scheduleRequest.setActionClass( bindingRequest.getActionClass() ); + scheduleRequest.setTimeZone( bindingRequest.getTimeZone() ); + //scheduleRequest.setJobParameters( bindingRequest.getJobParameters() ); + //scheduleRequest.setSimpleJobTrigger( bindingRequest.getSimpleJobTrigger() ); + //scheduleRequest.setCronJobTrigger( bindingRequest.getCronJobTrigger() ); + schedules.add( scheduleRequest ); + } + return schedules; + } +} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java index 4d9666946c9..9587b99c9b7 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/ExportManifestDto.java @@ -27,7 +27,6 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; -import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; import org.pentaho.platform.plugin.services.importexport.RoleExport; import org.pentaho.platform.plugin.services.importexport.UserExport; @@ -93,7 +92,7 @@ public class ExportManifestDto { @XmlElement ( name = "ExportManifestMetadata" ) protected List exportManifestMetadata; @XmlElement ( name = "ExportManifestSchedule" ) - protected List exportManifestSchedule; + protected List exportManifestSchedule; @XmlElement ( name = "ExportManifestDatasource" ) protected List exportManifestDatasource; @XmlElement ( name = "ExportManifestEntity" ) @@ -210,7 +209,7 @@ public List getExportManifestMetadata() { *

* Objects of the following type(s) are allowed in the list {@link JobScheduleRequest } */ - public List getExportManifestSchedule() { + public List getExportManifestSchedule() { if ( exportManifestSchedule == null ) { exportManifestSchedule = new ArrayList<>(); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java index ec6c8405d5c..a221a87e32c 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java @@ -4,8 +4,6 @@ import java.util.List; import java.util.Map; -; - public interface IJobScheduleRequest { void setJobName( String jobName ); @@ -35,6 +33,14 @@ public interface IJobScheduleRequest { String getOutputFile(); - public List getJobParameters(); + List getJobParameters(); + + long getDuration(); + + String getActionClass(); + + String getTimeZone(); + + ISimpleJobTrigger getSimpleJobTrigger(); } From 21c823642431942834be05d896962544a4dfeb8e Mon Sep 17 00:00:00 2001 From: wilseyler Date: Sat, 23 Sep 2023 12:24:57 -0400 Subject: [PATCH 24/59] BACKLOG-38036 - Additional code to deal with class loading issues and fixed problem with multiple plugin listeners --- .../platform/api/engine/IPlatformPlugin.java | 1 - .../exportManifest/ExportManifest.java | 12 ++++---- .../pluginmgr/DefaultPluginManager.java | 9 +++--- .../pluginmgr/PentahoSystemPluginManager.java | 9 +++--- .../services/pluginmgr/PlatformPlugin.java | 4 --- .../SystemPathXmlPluginProvider.java | 3 +- .../context/PentahoSystemReadyListener.java | 30 ++++++++++--------- .../api/scheduler2/IJobScheduleRequest.java | 17 +++++++---- 8 files changed, 44 insertions(+), 41 deletions(-) diff --git a/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java b/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java index 64278fa187e..56207ecb758 100644 --- a/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java +++ b/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java @@ -105,7 +105,6 @@ public enum ClassLoaderType { * * @return lifecycle listener class name */ - public String getLifecycleListenerClassname(); /** * Returns the list of fully qualified name of the lifecycle listener class defined by this plugin. The class must be a diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java index affc325a3a2..6afb8a5c43e 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifest.java @@ -91,7 +91,7 @@ public ExportManifest( ExportManifestDto exportManifestDto ) { List exportManifestEntityList = exportManifestDto.getExportManifestEntity(); for ( ExportManifestEntityDto exportManifestEntityDto : exportManifestEntityList ) { exportManifestEntities - .put( exportManifestEntityDto.getPath(), new ExportManifestEntity( exportManifestEntityDto ) ); + .put( exportManifestEntityDto.getPath(), new ExportManifestEntity( exportManifestEntityDto ) ); } mondrianList = exportManifestDto.getExportManifestMondrian(); metadataList = exportManifestDto.getExportManifestMetadata(); @@ -111,14 +111,14 @@ public ExportManifest( ExportManifestDto exportManifestDto ) { public void add( RepositoryFile repositoryFile, RepositoryFileAcl repositoryFileAcl ) throws ExportManifestFormatException { ExportManifestEntity exportManifestEntity = - new ExportManifestEntity( manifestInformation.getRootFolder(), repositoryFile, repositoryFileAcl ); + new ExportManifestEntity( manifestInformation.getRootFolder(), repositoryFile, repositoryFileAcl ); this.add( exportManifestEntity ); } public void add( File file, String userId, String projectId, Boolean isFolder, Boolean isHidden, - Boolean isSchedulable ) throws ExportManifestFormatException { + Boolean isSchedulable ) throws ExportManifestFormatException { ExportManifestEntity exportManifestEntity = - new ExportManifestEntity( file, userId, projectId, isFolder, isHidden, isSchedulable ); + new ExportManifestEntity( file, userId, projectId, isFolder, isHidden, isSchedulable ); this.add( exportManifestEntity ); } @@ -162,7 +162,7 @@ public String toXmlString() throws JAXBException { StringWriter sw = new StringWriter(); Marshaller marshaller = getMarshaller(); marshaller.marshal( new JAXBElement( new QName( "http://www.pentaho.com/schema/", - "ExportManifest" ), ExportManifestDto.class, getExportManifestDto() ), sw ); + "ExportManifest" ), ExportManifestDto.class, getExportManifestDto() ), sw ); return sw.toString(); } @@ -190,7 +190,7 @@ public static ExportManifest fromXml( ByteArrayInputStream input ) throws JAXBEx Source xmlSource = new SAXSource( xmlReader, new InputSource( input ) ); JAXBContext jc = - JAXBContext.newInstance( "org.pentaho.platform.plugin.services.importexport.exportManifest.bindings" ); + JAXBContext.newInstance( "org.pentaho.platform.plugin.services.importexport.exportManifest.bindings" ); Unmarshaller u = jc.createUnmarshaller(); try { diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/DefaultPluginManager.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/DefaultPluginManager.java index 16f38f5806c..fee41dccfcf 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/DefaultPluginManager.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/DefaultPluginManager.java @@ -244,13 +244,14 @@ private static void bootStrapPlugin( IPlatformPlugin plugin, ClassLoader loader throws PlatformPluginRegistrationException { Object listener = null; try { - if ( !StringUtils.isEmpty( plugin.getLifecycleListenerClassname() ) ) { - listener = loader.loadClass( plugin.getLifecycleListenerClassname() ).newInstance(); + if ( plugin.getLifecycleListenerClassnames() != null ) { + for ( String pluginLifeCycleListener : plugin.getLifecycleListenerClassnames() ) + listener = loader.loadClass( pluginLifeCycleListener ).getDeclaredConstructor().newInstance(); } } catch ( Throwable t ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( "PluginManager.ERROR_0017_COULD_NOT_LOAD_PLUGIN_LIFECYCLE_LISTENER", plugin.getId(), plugin //$NON-NLS-1$ - .getLifecycleListenerClassname() ), t ); + .getLifecycleListenerClassnames() ), t ); } if ( listener != null ) { @@ -260,7 +261,7 @@ private static void bootStrapPlugin( IPlatformPlugin plugin, ClassLoader loader .getInstance() .getErrorString( "PluginManager.ERROR_0016_PLUGIN_LIFECYCLE_LISTENER_WRONG_TYPE", plugin.getId(), - plugin.getLifecycleListenerClassname() ) ); //$NON-NLS-1$ + plugin.getLifecycleListenerClassnames() ) ); //$NON-NLS-1$ } plugin.addLifecycleListener( (IPluginLifecycleListener) listener ); } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java index 69285b959ff..b1952ebd32e 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java @@ -118,13 +118,14 @@ private static void createAndRegisterLifecycleListeners( IPlatformPlugin plugin, throws PlatformPluginRegistrationException { Object listener = null; try { - if ( !StringUtils.isEmpty( plugin.getLifecycleListenerClassname() ) ) { - listener = loader.loadClass( plugin.getLifecycleListenerClassname() ).newInstance(); + if ( plugin.getLifecycleListenerClassnames() != null ) { + for ( String pluginLifecycleListener : plugin.getLifecycleListenerClassnames() ) + listener = loader.loadClass( pluginLifecycleListener ).getDeclaredConstructor().newInstance(); } } catch ( Throwable t ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( "PluginManager.ERROR_0017_COULD_NOT_LOAD_PLUGIN_LIFECYCLE_LISTENER", plugin.getId(), plugin - .getLifecycleListenerClassname() + .getLifecycleListenerClassnames() ), t ); } @@ -135,7 +136,7 @@ private static void createAndRegisterLifecycleListeners( IPlatformPlugin plugin, .getInstance() .getErrorString( "PluginManager.ERROR_0016_PLUGIN_LIFECYCLE_LISTENER_WRONG_TYPE", plugin.getId(), - plugin.getLifecycleListenerClassname() ) + plugin.getLifecycleListenerClassnames() ) ); //$NON-NLS-1$ } plugin.addLifecycleListener( (IPluginLifecycleListener) listener ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PlatformPlugin.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PlatformPlugin.java index 6271875301f..58518629aef 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PlatformPlugin.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PlatformPlugin.java @@ -92,10 +92,6 @@ public void init( IPentahoSession session ) { initializer.init( session ); } } - public String getLifecycleListenerClassname() { - return lifecycleListenerClassnames != null - && !lifecycleListenerClassnames.isEmpty() ? lifecycleListenerClassnames.get(0): null; - } public void addLifecycleListenerClassname( String lifecycleListenerClassname ) { this.lifecycleListenerClassnames.add( lifecycleListenerClassname ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java index 7de1bdb44bd..545502583d6 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java @@ -152,8 +152,7 @@ protected PlatformPlugin createPlugin( Document doc, IPentahoSession session, St processExternalResources( plugin, doc ); processPerspectives( plugin, doc ); - String listenerCount = ( StringUtils.isEmpty( plugin.getLifecycleListenerClassname() ) ) ? "0" : "1"; //$NON-NLS-1$//$NON-NLS-2$ - + String listenerCount = plugin.getLifecycleListenerClassnames() != null ? Integer.toString( plugin.getLifecycleListenerClassnames().size() ) : "0"; String msg = Messages.getInstance().getString( "SystemPathXmlPluginProvider.PLUGIN_PROVIDES", //$NON-NLS-1$ diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListener.java b/extensions/src/main/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListener.java index ca547991303..02a5b0b99d3 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListener.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListener.java @@ -20,12 +20,7 @@ package org.pentaho.platform.web.http.context; -import java.util.List; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.lang.StringUtils; +import org.apache.jackrabbit.api.JackrabbitRepository; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPlatformPlugin; import org.pentaho.platform.api.engine.IPlatformReadyListener; @@ -35,8 +30,12 @@ import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.logging.Logger; + import javax.jcr.Repository; -import org.apache.jackrabbit.api.JackrabbitRepository; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.List; + public class PentahoSystemReadyListener implements ServletContextListener { @Override @@ -49,11 +48,13 @@ public void contextInitialized( ServletContextEvent servletContextEvent ) { List providedPlugins = pluginProvider.getPlugins( session ); for ( IPlatformPlugin plugin : providedPlugins ) { try { - if ( !StringUtils.isEmpty( plugin.getLifecycleListenerClassname() ) ) { - ClassLoader loader = pluginManager.getClassLoader( plugin.getId() ); - Object listener = loader.loadClass( plugin.getLifecycleListenerClassname() ).newInstance(); - if ( IPlatformReadyListener.class.isAssignableFrom( listener.getClass() ) ) { - ( (IPlatformReadyListener) listener ).ready(); + if ( plugin.getLifecycleListenerClassnames() != null ) { + for ( String lifecycleListener : plugin.getLifecycleListenerClassnames() ) { + ClassLoader loader = pluginManager.getClassLoader( plugin.getId() ); + Object listener = loader.loadClass( lifecycleListener ).getDeclaredConstructor().newInstance(); + if ( IPlatformReadyListener.class.isAssignableFrom( listener.getClass() ) ) { + ( (IPlatformReadyListener) listener ).ready(); + } } } } catch ( Exception e ) { @@ -63,9 +64,9 @@ public void contextInitialized( ServletContextEvent servletContextEvent ) { } catch ( PlatformPluginRegistrationException e ) { Logger.warn( PentahoSystemReadyListener.class.getName(), e.getMessage(), e ); } - } + @Override public void contextDestroyed( ServletContextEvent servletContextEvent ) { Repository jcrRepository = PentahoSystem.get( Repository.class, "jcrRepository", null ); @@ -75,7 +76,8 @@ public void contextDestroyed( ServletContextEvent servletContextEvent ) { } if ( !( jcrRepository instanceof JackrabbitRepository ) ) { Logger.error( PentahoSystemReadyListener.class.getName(), - String.format( "Expected RepositoryImpl, but got: [%s]. Exiting", jcrRepository.getClass().getName() ) ); + String.format( "Expected RepositoryImpl, but got: [%s]. Exiting", + jcrRepository.getClass().getName() ) ); return; } ( (JackrabbitRepository) jcrRepository ).shutdown(); diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java index a221a87e32c..5589f164a82 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java @@ -5,6 +5,11 @@ import java.util.Map; public interface IJobScheduleRequest { + + void setJobId( String jobId ); + + String getJobId(); + void setJobName( String jobName ); void setDuration( long duration ); @@ -21,10 +26,16 @@ public interface IJobScheduleRequest { void setActionClass( String value ); + String getActionClass(); + void setTimeZone( String value ); + String getTimeZone(); + void setSimpleJobTrigger( ISimpleJobTrigger jobTrigger ); + ISimpleJobTrigger getSimpleJobTrigger(); + void setCronJobTrigger( ICronJobTrigger cron ); String getInputFile(); @@ -36,11 +47,5 @@ public interface IJobScheduleRequest { List getJobParameters(); long getDuration(); - - String getActionClass(); - - String getTimeZone(); - - ISimpleJobTrigger getSimpleJobTrigger(); } From 0cef8687dbb7f4e59e3e9bc328d51c09c74a7f10 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Mon, 25 Sep 2023 16:22:34 -0400 Subject: [PATCH 25/59] [BACKLOG-38225] Fix scheduler request import/export --- .../api/scheduler/JobScheduleParam.java | 4 + .../importer/SolutionImportHandler.java | 233 +++++++++--------- .../exportManifest/ExportManifestUtil.java | 90 ++++++- .../bindings/JobScheduleRequest.java | 30 ++- .../web/http/api/resources/JobRequest.java | 4 +- .../http/api/resources/JobScheduleParam.java | 7 +- .../platform/api/scheduler2/IJobRequest.java | 28 +++ .../api/scheduler2/IJobScheduleParam.java | 9 + .../api/scheduler2/IJobScheduleRequest.java | 11 +- .../platform/api/scheduler2/IScheduler.java | 8 + .../api/scheduler2/ISchedulerResource.java | 38 +++ 11 files changed, 332 insertions(+), 130 deletions(-) create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java diff --git a/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java b/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java index 0e267b12ba3..81229302fd7 100644 --- a/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java +++ b/api/src/main/java/org/pentaho/platform/api/scheduler/JobScheduleParam.java @@ -116,6 +116,10 @@ public List getStringValue() { return this.stringValue; } + public void setStringValue( List stringValue ) { + this.stringValue = stringValue; + } + /** * Gets the value of the type property. * diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index c142b56331c..266c7b6d512 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -25,6 +25,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -36,6 +37,7 @@ import java.util.zip.ZipInputStream; import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.pentaho.database.model.IDatabaseConnection; @@ -51,6 +53,11 @@ import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobScheduleParam; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.ISchedulerResource; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; @@ -75,8 +82,11 @@ import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; +import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.services.FileService; +import javax.ws.rs.core.Response; + public class SolutionImportHandler implements IPlatformImportHandler { private static final String RESERVEDMAPKEY_LINEAGE_ID = "lineage-id"; @@ -279,16 +289,16 @@ public void importFile( IPlatformImportBundle bundle ) throws PlatformImportExce } if ( manifest != null ) { -// importSchedules( manifest.getScheduleList() ); + importSchedules( manifest.getScheduleList() ); } // Process locale files. localeFilesProcessor.processLocaleFiles( importer ); } -// List getAllJobs( SchedulerResource schedulerResource ) { -// return schedulerResource.getAllJobs(); -// } + List getAllJobs( ISchedulerResource schedulerResource ) { + return schedulerResource.getJobsList(); + } private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryFileBundle fileBundle ) { String repositoryFilePath = @@ -296,103 +306,104 @@ private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryF return repository.getFile( repositoryFilePath ); } -// protected void importSchedules( List scheduleList ) throws PlatformImportException { -// if ( CollectionUtils.isNotEmpty( scheduleList ) ) { -// SchedulerResource schedulerResource = new SchedulerResource(); -// schedulerResource.pause(); -// for ( JobScheduleRequest jobScheduleRequest : scheduleList ) { -// -// boolean jobExists = false; -// -// List jobs = getAllJobs( schedulerResource ); -// if ( jobs != null ) { -// -// //paramRequest to map -// Map mapParamsRequest = new HashMap<>(); -// for ( JobScheduleParam paramRequest : jobScheduleRequest.getJobParameters() ) { -// mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() ); -// } -// -// for ( IJob job : jobs ) { -// -// if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null ) -// && ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) -// .equals( job.getJobParams().get( RESERVEDMAPKEY_LINEAGE_ID ) ) ) ) { -// jobExists = true; -// } -// -// if ( overwriteFile && jobExists ) { -// JobRequest jobRequest = new JobRequest(); -// jobRequest.setJobId( job.getJobId() ); -// schedulerResource.removeJob( jobRequest ); -// jobExists = false; -// break; -// } -// } -// } -// -// if ( !jobExists ) { -// try { -// Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); -// if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { -// if ( response.getEntity() != null ) { -// // get the schedule job id from the response and add it to the import session -// ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); -// } -// } -// } catch ( Exception e ) { -// // there is a scenario where if the file scheduled has a space in the file name, that it won't work. the -// // di server -// -// // replaces spaces with underscores and the export mechanism can't determine if it needs this to happen -// // or not -// // so, if we failed to import and there is a space in the path, try again but this time with replacing -// // the space(s) -// if ( jobScheduleRequest.getInputFile().contains( " " ) || jobScheduleRequest.getOutputFile() -// .contains( " " ) ) { -// getLogger().info( Messages.getInstance() -// .getString( "SolutionImportHandler.SchedulesWithSpaces", jobScheduleRequest.getInputFile() ) ); -// File inFile = new File( jobScheduleRequest.getInputFile() ); -// File outFile = new File( jobScheduleRequest.getOutputFile() ); -// String inputFileName = inFile.getParent() + RepositoryFile.SEPARATOR -// + inFile.getName().replace( " ", "_" ); -// String outputFileName = outFile.getParent() + RepositoryFile.SEPARATOR -// + outFile.getName().replace( " ", "_" ); -// jobScheduleRequest.setInputFile( inputFileName ); -// jobScheduleRequest.setOutputFile( outputFileName ); -// try { -// if ( !File.separator.equals( RepositoryFile.SEPARATOR ) ) { -// // on windows systems, the backslashes will result in the file not being found in the repository -// jobScheduleRequest.setInputFile( inputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); -// jobScheduleRequest -// .setOutputFile( outputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); -// } -// Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); -// if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { -// if ( response.getEntity() != null ) { -// // get the schedule job id from the response and add it to the import session -// ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); -// } -// } -// } catch ( Exception ex ) { -// // log it and keep going. we should stop processing all schedules just because one fails. -// getLogger().error( Messages.getInstance() -// .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ), ex ); -// } -// } else { -// // log it and keep going. we should stop processing all schedules just because one fails. -// getLogger().error( Messages.getInstance() -// .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) ); -// } -// } -// } else { -// getLogger().info( Messages.getInstance() -// .getString( "DefaultImportHandler.ERROR_0009_OVERWRITE_CONTENT", jobScheduleRequest.toString() ) ); -// } -// } -// schedulerResource.start(); -// } -// } + protected void importSchedules( List scheduleList ) throws PlatformImportException { + if ( CollectionUtils.isNotEmpty( scheduleList ) ) { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + ISchedulerResource schedulerResource = scheduler.createSchedulerResource(); + schedulerResource.pause(); + for ( IJobScheduleRequest jobScheduleRequest : scheduleList ) { + + boolean jobExists = false; + + List jobs = getAllJobs( schedulerResource ); + if ( jobs != null ) { + + //paramRequest to map + Map mapParamsRequest = new HashMap<>(); + for ( IJobScheduleParam paramRequest : jobScheduleRequest.getJobParameters() ) { + mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() ); + } + + for ( IJob job : jobs ) { + + if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null ) + && ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) + .equals( job.getJobParams().get( RESERVEDMAPKEY_LINEAGE_ID ) ) ) ) { + jobExists = true; + } + + if ( overwriteFile && jobExists ) { + JobRequest jobRequest = new JobRequest(); + jobRequest.setJobId( job.getJobId() ); + schedulerResource.removeJob( jobRequest ); + jobExists = false; + break; + } + } + } + + if ( !jobExists ) { + try { + Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); + if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { + if ( response.getEntity() != null ) { + // get the schedule job id from the response and add it to the import session + ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); + } + } + } catch ( Exception e ) { + // there is a scenario where if the file scheduled has a space in the file name, that it won't work. the + // di server + + // replaces spaces with underscores and the export mechanism can't determine if it needs this to happen + // or not + // so, if we failed to import and there is a space in the path, try again but this time with replacing + // the space(s) + if ( jobScheduleRequest.getInputFile().contains( " " ) || jobScheduleRequest.getOutputFile() + .contains( " " ) ) { + getLogger().info( Messages.getInstance() + .getString( "SolutionImportHandler.SchedulesWithSpaces", jobScheduleRequest.getInputFile() ) ); + File inFile = new File( jobScheduleRequest.getInputFile() ); + File outFile = new File( jobScheduleRequest.getOutputFile() ); + String inputFileName = inFile.getParent() + RepositoryFile.SEPARATOR + + inFile.getName().replace( " ", "_" ); + String outputFileName = outFile.getParent() + RepositoryFile.SEPARATOR + + outFile.getName().replace( " ", "_" ); + jobScheduleRequest.setInputFile( inputFileName ); + jobScheduleRequest.setOutputFile( outputFileName ); + try { + if ( !File.separator.equals( RepositoryFile.SEPARATOR ) ) { + // on windows systems, the backslashes will result in the file not being found in the repository + jobScheduleRequest.setInputFile( inputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); + jobScheduleRequest + .setOutputFile( outputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) ); + } + Response response = createSchedulerJob( schedulerResource, jobScheduleRequest ); + if ( response.getStatus() == Response.Status.OK.getStatusCode() ) { + if ( response.getEntity() != null ) { + // get the schedule job id from the response and add it to the import session + ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() ); + } + } + } catch ( Exception ex ) { + // log it and keep going. we should stop processing all schedules just because one fails. + getLogger().error( Messages.getInstance() + .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ), ex ); + } + } else { + // log it and keep going. we should stop processing all schedules just because one fails. + getLogger().error( Messages.getInstance() + .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) ); + } + } + } else { + getLogger().info( Messages.getInstance() + .getString( "DefaultImportHandler.ERROR_0009_OVERWRITE_CONTENT", jobScheduleRequest.toString() ) ); + } + } + schedulerResource.start(); + } + } protected void importMetaStore( ExportManifestMetaStore manifestMetaStore, boolean overwrite ) { if ( manifestMetaStore != null ) { @@ -760,16 +771,16 @@ public IPlatformImportBundle build( RepositoryFileImportBundle.Builder builder ) // handlers that extend this class may override this method and perform operations // over the job prior to its creation at scheduler.createJob() -// public Response createSchedulerJob( SchedulerResource scheduler, JobScheduleRequest jobScheduleRequest ) -// throws IOException { -// Response rs = scheduler != null ? scheduler.createJob( jobScheduleRequest ) : null; -// if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) { -// JobRequest jobRequest = new JobRequest(); -// jobRequest.setJobId( rs.getEntity().toString() ); -// scheduler.pauseJob( jobRequest ); -// } -// return rs; -// } + public Response createSchedulerJob( ISchedulerResource scheduler, IJobScheduleRequest jobScheduleRequest ) + throws IOException { + Response rs = scheduler != null ? (Response) scheduler.createJob( jobScheduleRequest ) : null; + if ( jobScheduleRequest.getJobState() != IJob.JobState.NORMAL ) { + JobRequest jobRequest = new JobRequest(); + jobRequest.setJobId( rs.getEntity().toString() ); + scheduler.pauseJob( jobRequest ); + } + return rs; + } public boolean isOverwriteFile() { return overwriteFile; diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java index 8cc7a67ab12..1c1945022fc 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java @@ -20,12 +20,19 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest; +import org.pentaho.platform.api.scheduler.JobScheduleParam; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; +import org.pentaho.platform.api.scheduler2.IJobScheduleParam; import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; import org.pentaho.platform.engine.core.system.PentahoSystem; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.CronJobTrigger; import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.JobScheduleRequest; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.SimpleJobTrigger; import java.util.ArrayList; +import java.util.Date; import java.util.List; public class ExportManifestUtil { @@ -36,21 +43,51 @@ public static ArrayList fromSchedulerToBindingRequest( List< JobScheduleRequest bindingRequest = new JobScheduleRequest(); bindingRequest.setJobName( schedulerRequest.getJobName() ); bindingRequest.setDuration( schedulerRequest.getDuration() ); - //bindingRequest.setJobState( schedulerRequest.getJobState() ); + bindingRequest.setJobState( schedulerRequest.getJobState() ); bindingRequest.setInputFile( schedulerRequest.getInputFile() ); bindingRequest.setOutputFile( schedulerRequest.getOutputFile() ); - //bindingRequest.setPdiParameters( schedulerRequest.getPdiParameters() ); + bindingRequest.setPdiParameters( schedulerRequest.getPdiParameters() ); bindingRequest.setActionClass( schedulerRequest.getActionClass() ); bindingRequest.setTimeZone( schedulerRequest.getTimeZone() ); - //bindingRequest.setJobParameters( schedulerRequest.getJobParameters() ); - //bindingRequest.setSimpleJobTrigger( schedulerRequest.getSimpleJobTrigger() ); - //bindingRequest.setCronJobTrigger( schedulerRequest.getCronJobTrigger() ); + bindingRequest.setJobParameters( + fromSchedulerToBindingRequestJobParameters( schedulerRequest.getJobParameters() ) ); + bindingRequest.setSimpleJobTrigger( + fromSchedulerToBindingRequestJobTrigger( schedulerRequest.getSimpleJobTrigger() ) ); + bindingRequest.setCronJobTrigger( + fromSchedulerToBindingRequestCronJobTrigger( schedulerRequest.getCronJobTrigger() ) ); schedules.add( bindingRequest ); } return schedules; } - public static ArrayList fromBindingToSchedulerRequest( List bindingRequests ) { + private static List fromSchedulerToBindingRequestJobParameters( + List incomingParams ) { + List outgoingParams = new ArrayList<>(); + for ( IJobScheduleParam incomingParam : incomingParams ) { + JobScheduleParam outgoingParam = new JobScheduleParam(); + outgoingParam.setName( incomingParam.getName() ); + outgoingParam.setType( incomingParam.getType() ); + outgoingParam.setStringValue( incomingParam.getStringValue() ); + outgoingParams.add( outgoingParam ); + } + return outgoingParams; + } + + private static SimpleJobTrigger fromSchedulerToBindingRequestJobTrigger( ISimpleJobTrigger incomingJobTrigger ) { + SimpleJobTrigger outgoingJobTrigger = new SimpleJobTrigger(); + outgoingJobTrigger.setRepeatCount( incomingJobTrigger.getRepeatCount() ); + outgoingJobTrigger.setRepeatInterval( incomingJobTrigger.getRepeatInterval() ); + return outgoingJobTrigger; + } + + private static CronJobTrigger fromSchedulerToBindingRequestCronJobTrigger( ICronJobTrigger incomingCronJobTrigger ) { + CronJobTrigger outgoingCronJobTrigger = new CronJobTrigger(); + outgoingCronJobTrigger.setCronString( incomingCronJobTrigger.getCronString() ); + return outgoingCronJobTrigger; + } + + public static ArrayList fromBindingToSchedulerRequest( + List bindingRequests ) { IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ assert scheduler != null; ArrayList schedules = new ArrayList<>(); @@ -58,17 +95,48 @@ public static ArrayList fromBindingToSchedulerRequest( List IJobScheduleRequest scheduleRequest = scheduler.createJobScheduleRequest(); scheduleRequest.setJobName( bindingRequest.getJobName() ); scheduleRequest.setDuration( bindingRequest.getDuration() ); - //scheduleRequest.setJobState( bindingRequest.getJobState() ); + scheduleRequest.setJobState( bindingRequest.getJobState() ); scheduleRequest.setInputFile( bindingRequest.getInputFile() ); scheduleRequest.setOutputFile( bindingRequest.getOutputFile() ); - //scheduleRequest.setPdiParameters( bindingRequest.getPdiParameters() ); + scheduleRequest.setPdiParameters( bindingRequest.getPdiParameters() ); scheduleRequest.setActionClass( bindingRequest.getActionClass() ); scheduleRequest.setTimeZone( bindingRequest.getTimeZone() ); - //scheduleRequest.setJobParameters( bindingRequest.getJobParameters() ); - //scheduleRequest.setSimpleJobTrigger( bindingRequest.getSimpleJobTrigger() ); - //scheduleRequest.setCronJobTrigger( bindingRequest.getCronJobTrigger() ); + scheduleRequest.setJobParameters( + fromBindingToSchedulerRequestJobParameters( bindingRequest.getJobParameters() ) ); + scheduleRequest.setSimpleJobTrigger( + fromBindingToSchedulerRequestJobTrigger( bindingRequest.getSimpleJobTrigger() ) ); + scheduleRequest.setCronJobTrigger( + fromBindingToSchedulerRequestCronJobTrigger( bindingRequest.getCronJobTrigger() ) ); schedules.add( scheduleRequest ); } return schedules; } + + private static List fromBindingToSchedulerRequestJobParameters( + List incomingParams ) { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + List outgoingParams = new ArrayList<>(); + for ( JobScheduleParam incomingParam : incomingParams ) { + IJobScheduleParam outgoingParam = scheduler.createJobScheduleParam(); + outgoingParam.setName( incomingParam.getName() ); + outgoingParam.setType( incomingParam.getType() ); + outgoingParam.setStringValue( incomingParam.getStringValue() ); + outgoingParams.add( outgoingParam ); + } + return outgoingParams; + } + + private static ISimpleJobTrigger fromBindingToSchedulerRequestJobTrigger( + SimpleJobTrigger incomingSimpleJobTrigger ) { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + return scheduler.createSimpleJobTrigger( new Date(), null, incomingSimpleJobTrigger.getRepeatCount(), + incomingSimpleJobTrigger.getRepeatInterval() ); + } + + private static ICronJobTrigger fromBindingToSchedulerRequestCronJobTrigger( CronJobTrigger incomingCronJobTrigger ) { + IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ + ICronJobTrigger outgoingCronJobTrigger = scheduler.createCronJobTrigger(); + outgoingCronJobTrigger.setCronString( incomingCronJobTrigger.getCronString() ); + return outgoingCronJobTrigger; + } } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java index f5ba4f180ed..74ac2bfb73c 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java @@ -28,9 +28,11 @@ package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; import org.pentaho.platform.api.scheduler.JobScheduleParam; +import org.pentaho.platform.api.scheduler2.IJob; import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -72,7 +74,7 @@ */ @XmlAccessorType( XmlAccessType.FIELD ) @XmlType( name = "jobScheduleRequest", propOrder = { "actionClass", "complexJobTrigger", "cronJobTrigger", "duration", - "inputFile", "jobName", "jobParameters", "outputFile", "simpleJobTrigger", "timeZone", "jobId" } ) + "inputFile", "jobName", "jobParameters", "outputFile", "simpleJobTrigger", "timeZone", "jobId", "jobState", "pdiParameters" } ) public class JobScheduleRequest { protected String actionClass; @@ -89,6 +91,8 @@ public class JobScheduleRequest { @XmlElement( namespace = "http://www.pentaho.com/schema/" ) protected SimpleJobTrigger simpleJobTrigger; protected String timeZone; + protected IJob.JobState jobState; + protected Map pdiParameters; /** * Gets the value of the actionClass property. @@ -310,4 +314,28 @@ public void setJobId( String jobId ) { this.jobId = jobId; } + public IJob.JobState getJobState() { + return jobState; + } + + public void setJobState( IJob.JobState jobState ) { + this.jobState = jobState; + } + + public Map getPdiParameters() { + return pdiParameters; + } + + public void setPdiParameters( Map pdiParameters ) { + this.pdiParameters = pdiParameters; + } + + public void setJobParameters( List jobParameters ) { + if ( jobParameters != this.jobParameters ) { + this.jobParameters.clear(); + if ( jobParameters != null ) { + this.jobParameters.addAll( jobParameters ); + } + } + } } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java index 5cea4d816c7..f2216bf8fe0 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java @@ -20,11 +20,13 @@ package org.pentaho.platform.web.http.api.resources; +import org.pentaho.platform.api.scheduler2.IJobRequest; + import javax.xml.bind.annotation.XmlRootElement; import java.io.Serializable; @XmlRootElement -public class JobRequest implements Serializable { +public class JobRequest implements Serializable, IJobRequest { private static final long serialVersionUID = 6111578259094385262L; diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java index d98d3318c28..591fd9f3bbe 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java @@ -27,6 +27,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.List; public class JobScheduleParam implements Serializable, IJobScheduleParam { @@ -38,7 +39,7 @@ public class JobScheduleParam implements Serializable, IJobScheduleParam { String type; - ArrayList stringValue = new ArrayList(); + List stringValue = new ArrayList(); public JobScheduleParam() { } @@ -83,11 +84,11 @@ public void setType( String type ) { this.type = type; } - public ArrayList getStringValue() { + public List getStringValue() { return stringValue; } - public void setStringValue( ArrayList value ) { + public void setStringValue( List value ) { this.stringValue = value; } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java new file mode 100644 index 00000000000..bcdee2567a8 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java @@ -0,0 +1,28 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2; + +public interface IJobRequest { + + String getJobId(); + + void setJobId( String jobId ); +} diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java index 6715c8bca2e..c2c22b258c5 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java @@ -1,10 +1,19 @@ package org.pentaho.platform.api.scheduler2; import java.io.Serializable; +import java.util.List; public interface IJobScheduleParam { String getName(); + void setName( String name ); + String getType(); + void setType( String type ); + Serializable getValue(); + + void setStringValue( List value ); + + List getStringValue(); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java index 5589f164a82..221d32b3d09 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java @@ -1,6 +1,5 @@ package org.pentaho.platform.api.scheduler2; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -20,9 +19,9 @@ public interface IJobScheduleRequest { void setOutputFile( String outputFilePath ); - Map getPdiParameters(); + Map getPdiParameters(); - void setPdiParameters( HashMap stringStringHashMap ); + void setPdiParameters( Map stringStringHashMap ); void setActionClass( String value ); @@ -46,6 +45,12 @@ public interface IJobScheduleRequest { List getJobParameters(); + void setJobParameters( List parameters ); + long getDuration(); + + IJob.JobState getJobState(); + + ICronJobTrigger getCronJobTrigger(); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java index 709c5a6db81..7fd699834c6 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java @@ -304,6 +304,9 @@ void fireJobCompleted( final IAction actionBean, final String actionUser, final Map params, IBackgroundExecutionStreamProvider streamProvider ); IJobScheduleRequest createJobScheduleRequest(); + + IJobScheduleParam createJobScheduleParam(); + ISimpleJobTrigger createSimpleJobTrigger( Date startTime, Date endTime, int repeatCount, long repeatIntervalSeconds ); ICronJobTrigger createCronJobTrigger(); @@ -311,8 +314,13 @@ void fireJobCompleted( final IAction actionBean, final String actionUser, IComplexJobTrigger createComplexTrigger( String cronString ); IComplexJobTrigger createComplexJobTrigger(); + IComplexJobTrigger createComplexTrigger( Integer year, Integer month, Integer dayOfMonth, Integer dayOfWeek, Integer hourOfDay ); + ArrayList getJobParameters(); + + ISchedulerResource createSchedulerResource(); + /** * A default implementation which doesn't do anything and exists for the backward compatibility sake. * @param jobParams scheduling job parameters diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java new file mode 100644 index 00000000000..1d5a51e52e3 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java @@ -0,0 +1,38 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.api.scheduler2; + +import java.util.List; + +public interface ISchedulerResource { + + List getJobsList(); + + Object pause(); + + void removeJob( IJobRequest jobRequest ); + + Object createJob( IJobScheduleRequest scheduleRequest ); + + Object start(); + + void pauseJob( IJobRequest jobRequest ); +} From 7675e4a73a97f03abff9fe8744c4964b834ec2f5 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 26 Sep 2023 19:19:24 -0400 Subject: [PATCH 26/59] BACKLOG-38036 - Seperate JobState --- .../java/org/pentaho/platform/api/scheduler2/JobState.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java new file mode 100644 index 00000000000..d8af9fec0b3 --- /dev/null +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java @@ -0,0 +1,5 @@ +package org.pentaho.platform.api.scheduler2; + +public enum JobState { + NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN +} From 1029c34f0b86bb243c131250c970849f9f839d3b Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 26 Sep 2023 21:45:11 -0400 Subject: [PATCH 27/59] BACKLOG-38036 -More code to deal with class loading issues and fixed problem with multiple plugin listeners --- .../platform/api/engine/IPlatformPlugin.java | 7 - .../importer/SolutionImportHandler.java | 15 +- .../bindings/JobScheduleRequest.java | 7 +- .../pluginmgr/PentahoSystemPluginManager.java | 287 +++++++++--------- .../SystemPathXmlPluginProvider.java | 4 +- .../pentaho/platform/api/scheduler2/IJob.java | 24 +- .../api/scheduler2/IJobScheduleRequest.java | 4 +- 7 files changed, 165 insertions(+), 183 deletions(-) diff --git a/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java b/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java index 56207ecb758..912ae73379c 100644 --- a/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java +++ b/api/src/main/java/org/pentaho/platform/api/engine/IPlatformPlugin.java @@ -99,13 +99,6 @@ public enum ClassLoaderType { */ public Map getStaticResourceMap(); - /** - * Returns the fully qualified name of the lifecycle listener class defined by this plugin. The class must be a - * {@link IPluginLifecycleListener}. - * - * @return lifecycle listener class name - */ - /** * Returns the list of fully qualified name of the lifecycle listener class defined by this plugin. The class must be a * {@link IPluginLifecycleListener}. diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 266c7b6d512..6b2887b8f4d 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -58,6 +58,7 @@ import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.ISchedulerResource; +import org.pentaho.platform.api.scheduler2.JobState; import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; @@ -247,13 +248,13 @@ public void importFile( IPlatformImportBundle bundle ) throws PlatformImportExce sourcePath = fileName; } else { sourcePath = - RepositoryFilenameUtils.concat( PentahoPlatformImporter.computeBundlePath( actualFilePath ), fileName ); + RepositoryFilenameUtils.concat( PentahoPlatformImporter.computeBundlePath( actualFilePath ), fileName ); } //This clause was added for processing ivb files so that it would not try process acls on folders that the user //may not have rights to such as /home or /public if ( manifest != null && manifest.getExportManifestEntity( sourcePath ) == null && fileBundle.getFile() - .isFolder() ) { + .isFolder() ) { continue; } @@ -302,7 +303,7 @@ List getAllJobs( ISchedulerResource schedulerResource ) { private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryFileBundle fileBundle ) { String repositoryFilePath = - repositoryPathConcat( importBundle.getPath(), fileBundle.getPath(), fileBundle.getFile().getName() ); + repositoryPathConcat( importBundle.getPath(), fileBundle.getPath(), fileBundle.getFile().getName() ); return repository.getFile( repositoryFilePath ); } @@ -607,7 +608,7 @@ protected void importMondrian( List mondrianList ) { RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder().charSet( UTF_8 ).hidden( RepositoryFile.HIDDEN_BY_DEFAULT ) .schedulable( RepositoryFile.SCHEDULABLE_BY_DEFAULT ).name( catName ).overwriteFile( - isOverwriteFile() ).mime( "application/vnd.pentaho.mondrian+xml" ) + isOverwriteFile() ).mime( "application/vnd.pentaho.mondrian+xml" ) .withParam( "parameters", parametersStr.toString() ) .withParam( DOMAIN_ID, catName ); // TODO: this is definitely named wrong at the very least. // pass as param if not in parameters string @@ -637,10 +638,10 @@ protected void importMondrian( List mondrianList ) { boolean fileIsScheduleInputSource( ExportManifest manifest, String sourcePath ) { boolean isSchedulable = false; if ( sourcePath != null && manifest != null - && manifest.getScheduleList() != null ) { + && manifest.getScheduleList() != null ) { String path = sourcePath.startsWith( "/" ) ? sourcePath : "/" + sourcePath; isSchedulable = manifest.getScheduleList().stream() - .anyMatch( schedule -> path.equals( schedule.getInputFile() ) ); + .anyMatch( schedule -> path.equals( schedule.getInputFile() ) ); } if ( isSchedulable ) { @@ -774,7 +775,7 @@ public IPlatformImportBundle build( RepositoryFileImportBundle.Builder builder ) public Response createSchedulerJob( ISchedulerResource scheduler, IJobScheduleRequest jobScheduleRequest ) throws IOException { Response rs = scheduler != null ? (Response) scheduler.createJob( jobScheduleRequest ) : null; - if ( jobScheduleRequest.getJobState() != IJob.JobState.NORMAL ) { + if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) { JobRequest jobRequest = new JobRequest(); jobRequest.setJobId( rs.getEntity().toString() ); scheduler.pauseJob( jobRequest ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java index 74ac2bfb73c..fe8ecdc0458 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java @@ -29,6 +29,7 @@ import org.pentaho.platform.api.scheduler.JobScheduleParam; import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.JobState; import java.util.ArrayList; import java.util.List; @@ -91,7 +92,7 @@ public class JobScheduleRequest { @XmlElement( namespace = "http://www.pentaho.com/schema/" ) protected SimpleJobTrigger simpleJobTrigger; protected String timeZone; - protected IJob.JobState jobState; + protected JobState jobState; protected Map pdiParameters; /** @@ -314,11 +315,11 @@ public void setJobId( String jobId ) { this.jobId = jobId; } - public IJob.JobState getJobState() { + public JobState getJobState() { return jobState; } - public void setJobState( IJob.JobState jobState ) { + public void setJobState( JobState jobState ) { this.jobState = jobState; } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java index b1952ebd32e..3700046c828 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/PentahoSystemPluginManager.java @@ -108,39 +108,36 @@ public class PentahoSystemPluginManager implements IPluginManager { public static final String SETTINGS_PREFIX = "settings/"; private final Multimap handleRegistry = - Multimaps.synchronizedMultimap( ArrayListMultimap - .create() ); + Multimaps.synchronizedMultimap( ArrayListMultimap + .create() ); private ISystemConfig systemConfig = PentahoSystem.get( ISystemConfig.class ); private Logger logger = LoggerFactory.getLogger( getClass() ); private Set listeners = new HashSet(); private static void createAndRegisterLifecycleListeners( IPlatformPlugin plugin, ClassLoader loader ) - throws PlatformPluginRegistrationException { - Object listener = null; + throws PlatformPluginRegistrationException { try { if ( plugin.getLifecycleListenerClassnames() != null ) { - for ( String pluginLifecycleListener : plugin.getLifecycleListenerClassnames() ) - listener = loader.loadClass( pluginLifecycleListener ).getDeclaredConstructor().newInstance(); + for ( String pluginLifecycleListener : plugin.getLifecycleListenerClassnames() ) { + Object listener = loader.loadClass( pluginLifecycleListener ).getDeclaredConstructor().newInstance(); + if ( !IPluginLifecycleListener.class.isAssignableFrom( listener.getClass() ) ) { + throw new PlatformPluginRegistrationException( + Messages + .getInstance() + .getErrorString( + "PluginManager.ERROR_0016_PLUGIN_LIFECYCLE_LISTENER_WRONG_TYPE", plugin.getId(), + plugin.getLifecycleListenerClassnames() ) + ); //$NON-NLS-1$ + } + plugin.addLifecycleListener( (IPluginLifecycleListener) listener ); + } } } catch ( Throwable t ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0017_COULD_NOT_LOAD_PLUGIN_LIFECYCLE_LISTENER", plugin.getId(), plugin - .getLifecycleListenerClassnames() + "PluginManager.ERROR_0017_COULD_NOT_LOAD_PLUGIN_LIFECYCLE_LISTENER", plugin.getId(), plugin + .getLifecycleListenerClassnames() ), t ); } - - if ( listener != null ) { - if ( !IPluginLifecycleListener.class.isAssignableFrom( listener.getClass() ) ) { - throw new PlatformPluginRegistrationException( - Messages - .getInstance() - .getErrorString( - "PluginManager.ERROR_0016_PLUGIN_LIFECYCLE_LISTENER_WRONG_TYPE", plugin.getId(), - plugin.getLifecycleListenerClassnames() ) - ); //$NON-NLS-1$ - } - plugin.addLifecycleListener( (IPluginLifecycleListener) listener ); - } } @Override @@ -159,17 +156,19 @@ public IContentInfo getContentTypeInfo( String type ) { type = type.substring( type.lastIndexOf( "." ) + 1 ); } return PentahoSystem.get( IContentInfo.class, PentahoSessionHolder.getSession(), Collections - .singletonMap( "extension", type ) ); + .singletonMap( "extension", type ) ); } @Override public IContentGenerator getContentGeneratorForType( String type, IPentahoSession session ) - throws ObjectFactoryException { + throws ObjectFactoryException { // first we check: is there any IContentGeneratorInvoker implementation on the bean registry? If so: use it; final IContentGeneratorInvoker cgInvoker = PentahoSystem.get( IContentGeneratorInvoker.class ); if ( cgInvoker != null && cgInvoker.isSupportedContent( type ) ) { - logger.info( "Located IContentGeneratorInvoker that supports content of type '" + type + "':" + cgInvoker.getClass().getName() ); + logger.info( + "Located IContentGeneratorInvoker that supports content of type '" + type + "':" + cgInvoker.getClass() + .getName() ); return cgInvoker.getContentGenerator(); } @@ -194,11 +193,11 @@ private void unloadPlugins() { // if a spring app context was registered for this plugin, remove and close it final GenericApplicationContext appContext = PentahoSystem - .get( GenericApplicationContext.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + .get( GenericApplicationContext.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); if ( appContext != null ) { final StandaloneSpringPentahoObjectFactory pentahoObjectFactory = - StandaloneSpringPentahoObjectFactory.getInstance( appContext ); + StandaloneSpringPentahoObjectFactory.getInstance( appContext ); if ( pentahoObjectFactory != null ) { PentahoSystem.deregisterObjectFactory( pentahoObjectFactory ); @@ -211,13 +210,13 @@ private void unloadPlugins() { // A plugin unload should not adversely affect anything downstream, it should // log an error and otherwise fail silently String msg = - Messages.getInstance().getErrorString( - "PluginManager.ERROR_0014_PLUGIN_FAILED_TO_PROPERLY_UNLOAD", plugin.getId() ); //$NON-NLS-1$ + Messages.getInstance().getErrorString( + "PluginManager.ERROR_0014_PLUGIN_FAILED_TO_PROPERLY_UNLOAD", plugin.getId() ); //$NON-NLS-1$ logger.error( getClass().toString(), msg, t ); PluginMessageLogger.add( msg ); } final ClassLoader classLoader = - PentahoSystem.get( ClassLoader.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + PentahoSystem.get( ClassLoader.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); if ( classLoader != null ) { try { ( (PluginClassLoader) classLoader ).close(); @@ -252,7 +251,7 @@ public boolean reload( IPentahoSession session ) { } catch ( PlatformPluginRegistrationException e1 ) { String msg = - Messages.getInstance().getErrorString( "PluginManager.ERROR_0012_PLUGIN_DISCOVERY_FAILED" ); + Messages.getInstance().getErrorString( "PluginManager.ERROR_0012_PLUGIN_DISCOVERY_FAILED" ); org.pentaho.platform.util.logging.Logger.error( getClass().toString(), msg, e1 ); PluginMessageLogger.add( msg ); anyErrors = true; @@ -261,54 +260,54 @@ public boolean reload( IPentahoSession session ) { for ( IPlatformPlugin plugin : providedPlugins ) { try { IPlatformPlugin existingPlugin = - PentahoSystem.get( IPlatformPlugin.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + PentahoSystem.get( IPlatformPlugin.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); if ( existingPlugin != null ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0024_PLUGIN_ALREADY_LOADED_BY_SAME_NAME", plugin.getId() ) ); + "PluginManager.ERROR_0024_PLUGIN_ALREADY_LOADED_BY_SAME_NAME", plugin.getId() ) ); } final ClassLoader classloader = createClassloader( plugin ); // Register the classloader, Spring App Context and Object Factory with PentahoSystem IPentahoObjectRegistration handle = PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( IPlatformPlugin.class ) - .object( plugin ) - .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), - IPlatformPlugin.class + new SingletonPentahoObjectReference.Builder( IPlatformPlugin.class ) + .object( plugin ) + .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), + IPlatformPlugin.class ); registerReference( plugin.getId(), handle ); handle = - PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( ClassLoader.class ).object( classloader ) - .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), - ClassLoader.class - ); + PentahoSystem.registerReference( + new SingletonPentahoObjectReference.Builder( ClassLoader.class ).object( classloader ) + .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), + ClassLoader.class + ); registerReference( plugin.getId(), handle ); final GenericApplicationContext beanFactory = createBeanFactory( plugin, classloader ); final StandaloneSpringPentahoObjectFactory pentahoFactory = - new StandaloneSpringPentahoObjectFactory( "Plugin Factory ( " + plugin.getId() + " )" ); + new StandaloneSpringPentahoObjectFactory( "Plugin Factory ( " + plugin.getId() + " )" ); pentahoFactory.init( null, beanFactory ); beanFactory.refresh(); handle = - PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( - GenericApplicationContext.class ) - .object( beanFactory ) - .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), - IPentahoRegistrableObjectFactory.Types.ALL - ); + PentahoSystem.registerReference( + new SingletonPentahoObjectReference.Builder( + GenericApplicationContext.class ) + .object( beanFactory ) + .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), + IPentahoRegistrableObjectFactory.Types.ALL + ); registerReference( plugin.getId(), handle ); handle = - PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( IPentahoObjectFactory.class ) - .object( pentahoFactory ) - .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), - IPentahoObjectFactory.class - ); + PentahoSystem.registerReference( + new SingletonPentahoObjectReference.Builder( IPentahoObjectFactory.class ) + .object( pentahoFactory ) + .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), + IPentahoObjectFactory.class + ); registerReference( plugin.getId(), handle ); @@ -316,8 +315,8 @@ public boolean reload( IPentahoSession session ) { // this has been logged already anyErrors = true; String msg = - Messages.getInstance().getErrorString( - "PluginManager.ERROR_0011_FAILED_TO_REGISTER_PLUGIN", plugin.getId() ); + Messages.getInstance().getErrorString( + "PluginManager.ERROR_0011_FAILED_TO_REGISTER_PLUGIN", plugin.getId() ); org.pentaho.platform.util.logging.Logger.error( getClass().toString(), msg, t ); PluginMessageLogger.add( msg ); } @@ -331,8 +330,8 @@ public boolean reload( IPentahoSession session ) { // this has been logged already anyErrors = true; String msg = - Messages.getInstance().getErrorString( - "PluginManager.ERROR_0011_FAILED_TO_REGISTER_PLUGIN", plugin.getId() ); + Messages.getInstance().getErrorString( + "PluginManager.ERROR_0011_FAILED_TO_REGISTER_PLUGIN", plugin.getId() ); org.pentaho.platform.util.logging.Logger.error( getClass().toString(), msg, t ); PluginMessageLogger.add( msg ); } @@ -345,7 +344,7 @@ public boolean reload( IPentahoSession session ) { svcManager.initServices(); } catch ( ServiceInitializationException e ) { String msg = Messages.getInstance() - .getErrorString( "PluginManager.ERROR_0022_SERVICE_INITIALIZATION_FAILED" ); + .getErrorString( "PluginManager.ERROR_0022_SERVICE_INITIALIZATION_FAILED" ); org.pentaho.platform.util.logging.Logger.error( getClass().toString(), msg, e ); PluginMessageLogger.add( msg ); } @@ -360,19 +359,19 @@ public boolean reload( IPentahoSession session ) { @SuppressWarnings( "unchecked" ) private void registerPlugin( final IPlatformPlugin plugin ) throws PlatformPluginRegistrationException, - PluginLifecycleException { + PluginLifecycleException { // TODO: we should treat the registration of a plugin as an atomic operation // with rollback if something is broken if ( StringUtils.isEmpty( plugin.getId() ) ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0026_PLUGIN_INVALID", plugin.getSourceDescription() ) ); + "PluginManager.ERROR_0026_PLUGIN_INVALID", plugin.getSourceDescription() ) ); } ClassLoader loader = PentahoSystem.get( ClassLoader.class, null, - Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); GenericApplicationContext beanFactory = PentahoSystem - .get( GenericApplicationContext.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + .get( GenericApplicationContext.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); createAndRegisterLifecycleListeners( plugin, loader ); plugin.init(); @@ -392,15 +391,15 @@ private void registerPlugin( final IPlatformPlugin plugin ) throws PlatformPlugi registerServices( plugin, loader, beanFactory ); PluginMessageLogger - .add( Messages.getInstance().getString( "PluginManager.PLUGIN_REGISTERED", plugin.getId() ) ); + .add( Messages.getInstance().getString( "PluginManager.PLUGIN_REGISTERED", plugin.getId() ) ); try { plugin.loaded(); } catch ( Throwable t ) { // The plugin has already been loaded, so there is really no logical response to any type // of failure here except to log an error and otherwise fail silently String msg = - Messages.getInstance().getErrorString( - "PluginManager.ERROR_0015_PLUGIN_LOADED_HANDLING_FAILED", plugin.getId() ); + Messages.getInstance().getErrorString( + "PluginManager.ERROR_0015_PLUGIN_LOADED_HANDLING_FAILED", plugin.getId() ); org.pentaho.platform.util.logging.Logger.error( getClass().toString(), msg, t ); PluginMessageLogger.add( msg ); } @@ -411,10 +410,10 @@ private void registerOverlays( IPlatformPlugin plugin ) { for ( XulOverlay overlay : plugin.getOverlays() ) { // preserve ordering as it may be significant final IPentahoObjectRegistration referenceHandle = PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( XulOverlay.class ) - .object( overlay ).attributes( - Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).priority( priority ).build(), - XulOverlay.class + new SingletonPentahoObjectReference.Builder( XulOverlay.class ) + .object( overlay ).attributes( + Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).priority( priority ).build(), + XulOverlay.class ); priority--; registerReference( plugin.getId(), referenceHandle ); @@ -422,7 +421,7 @@ private void registerOverlays( IPlatformPlugin plugin ) { } private void registerServices( IPlatformPlugin plugin, ClassLoader loader, GenericApplicationContext beanFactory ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { IServiceManager svcManager = PentahoSystem.get( IServiceManager.class, null ); for ( PluginServiceDefinition pws : plugin.getServices() ) { @@ -431,26 +430,26 @@ private void registerServices( IPlatformPlugin plugin, ClassLoader loader, Gener svcManager.registerService( ws ); } catch ( ServiceException e ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0025_SERVICE_REGISTRATION_FAILED", ws.getId(), plugin.getId() ), e ); //$NON-NLS-1$ + "PluginManager.ERROR_0025_SERVICE_REGISTRATION_FAILED", ws.getId(), plugin.getId() ), e ); //$NON-NLS-1$ } } } } /* - * A utility method to convert plugin version of webservice definition to the official engine version consumable by an - * IServiceManager - */ + * A utility method to convert plugin version of webservice definition to the official engine version consumable by an + * IServiceManager + */ private Collection createServiceConfigs( PluginServiceDefinition pws, IPlatformPlugin plugin, ClassLoader loader, GenericApplicationContext beanFactory ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { Collection services = new ArrayList(); // Set the service type (one service config instance created per service type) // if ( pws.getTypes() == null || pws.getTypes().length < 1 ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0023_SERVICE_TYPE_UNSPECIFIED", pws.getId() ) ); + "PluginManager.ERROR_0023_SERVICE_TYPE_UNSPECIFIED", pws.getId() ) ); } for ( String type : pws.getTypes() ) { ServiceConfig ws = new ServiceConfig(); @@ -459,7 +458,7 @@ private Collection createServiceConfigs( PluginServiceDefinition ws.setTitle( pws.getTitle() ); ws.setDescription( pws.getDescription() ); String serviceClassName = - ( StringUtils.isEmpty( pws.getServiceClass() ) ) ? pws.getServiceBeanId() : pws.getServiceClass(); + ( StringUtils.isEmpty( pws.getServiceClass() ) ) ? pws.getServiceBeanId() : pws.getServiceClass(); String serviceId; if ( !StringUtils.isEmpty( pws.getId() ) ) { @@ -475,18 +474,18 @@ private Collection createServiceConfigs( PluginServiceDefinition // Register the service class // final String serviceClassKey = - ws.getServiceType() + "-" + ws.getId() + "/" + serviceClassName; + ws.getServiceType() + "-" + ws.getId() + "/" + serviceClassName; assertUnique( beanFactory, plugin.getId(), serviceClassKey ); // defining plugin beans the old way through the plugin provider ifc supports only prototype scope BeanDefinition beanDef = - BeanDefinitionBuilder.rootBeanDefinition( serviceClassName ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) - .getBeanDefinition(); + BeanDefinitionBuilder.rootBeanDefinition( serviceClassName ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) + .getBeanDefinition(); beanFactory.registerBeanDefinition( serviceClassKey, beanDef ); if ( !this.isBeanRegistered( serviceClassKey ) ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0020_NO_SERVICE_CLASS_REGISTERED", serviceClassKey ) ); + "PluginManager.ERROR_0020_NO_SERVICE_CLASS_REGISTERED", serviceClassKey ) ); } // Load/set the service class and supporting types @@ -503,7 +502,7 @@ private Collection createServiceConfigs( PluginServiceDefinition ws.setExtraClasses( classes ); } catch ( PluginBeanException e ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0021_SERVICE_CLASS_LOAD_FAILED", serviceClassKey ), e ); + "PluginManager.ERROR_0021_SERVICE_CLASS_LOAD_FAILED", serviceClassKey ), e ); } services.add( ws ); } @@ -547,10 +546,10 @@ private void registerPerspectives( IPlatformPlugin plugin, ClassLoader loader ) // PentahoSystem.get( IPluginPerspectiveManager.class ).addPluginPerspective( pluginPerspective ); final IPentahoObjectRegistration referenceHandle = PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( IPluginPerspective.class ) - .object( pluginPerspective ) - .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), - IPluginPerspective.class + new SingletonPentahoObjectReference.Builder( IPluginPerspective.class ) + .object( pluginPerspective ) + .attributes( Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ).build(), + IPluginPerspective.class ); registerReference( plugin.getId(), referenceHandle ); @@ -559,14 +558,14 @@ private void registerPerspectives( IPlatformPlugin plugin, ClassLoader loader ) private void registerContentGenerators( IPlatformPlugin plugin, ClassLoader loader, final GenericApplicationContext beanFactory ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { // register the content generators for ( final IContentGeneratorInfo cgInfo : plugin.getContentGenerators() ) { // define the bean in the factory BeanDefinition beanDef = - BeanDefinitionBuilder.rootBeanDefinition( cgInfo.getClassname() ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) - .getBeanDefinition(); + BeanDefinitionBuilder.rootBeanDefinition( cgInfo.getClassname() ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) + .getBeanDefinition(); // register bean with alias of content generator id (old way) beanFactory.registerBeanDefinition( cgInfo.getId(), beanDef ); @@ -574,19 +573,19 @@ private void registerContentGenerators( IPlatformPlugin plugin, ClassLoader load beanFactory.registerAlias( cgInfo.getId(), cgInfo.getType() ); PluginMessageLogger.add( Messages.getInstance().getString( - "PluginManager.USER_CONTENT_GENERATOR_REGISTERED", cgInfo.getId(), plugin.getId() ) ); + "PluginManager.USER_CONTENT_GENERATOR_REGISTERED", cgInfo.getId(), plugin.getId() ) ); final HashMap attributes = new HashMap(); attributes.put( PLUGIN_ID, plugin.getId() ); attributes.put( CONTENT_TYPE, cgInfo.getType() ); final IPentahoObjectRegistration referenceHandle = PentahoSystem.registerReference( - new PrototypePentahoObjectReference.Builder( IContentGenerator.class ) - .creator( new IObjectCreator() { - @Override - public IContentGenerator create( IPentahoSession session ) { - return (IContentGenerator) beanFactory.getBean( cgInfo.getId() ); - } - } ).attributes( attributes ).build(), IContentGenerator.class + new PrototypePentahoObjectReference.Builder( IContentGenerator.class ) + .creator( new IObjectCreator() { + @Override + public IContentGenerator create( IPentahoSession session ) { + return (IContentGenerator) beanFactory.getBean( cgInfo.getId() ); + } + } ).attributes( attributes ).build(), IContentGenerator.class ); registerReference( plugin.getId(), referenceHandle ); @@ -598,7 +597,7 @@ public IContentGenerator create( IPentahoSession session ) { } String[] names = - BeanFactoryUtils.beanNamesForTypeIncludingAncestors( beanFactory.getBeanFactory(), IContentGenerator.class ); + BeanFactoryUtils.beanNamesForTypeIncludingAncestors( beanFactory.getBeanFactory(), IContentGenerator.class ); ArrayList ids = new ArrayList(); for ( String beanName : names ) { @@ -613,14 +612,14 @@ public IContentGenerator create( IPentahoSession session ) { attributes.put( CONTENT_TYPE, beanName ); final IPentahoObjectRegistration referenceHandle = PentahoSystem.registerReference( - new PrototypePentahoObjectReference.Builder( IContentGenerator.class ) - .creator( new IObjectCreator() { - @Override - public IContentGenerator create( IPentahoSession session ) { - return (IContentGenerator) beanFactory.getBean( beanName ); - } - } ).attributes( attributes ).build(), - IContentGenerator.class + new PrototypePentahoObjectReference.Builder( IContentGenerator.class ) + .creator( new IObjectCreator() { + @Override + public IContentGenerator create( IPentahoSession session ) { + return (IContentGenerator) beanFactory.getBean( beanName ); + } + } ).attributes( attributes ).build(), + IContentGenerator.class ); registerReference( plugin.getId(), referenceHandle ); @@ -630,7 +629,7 @@ public IContentGenerator create( IPentahoSession session ) { protected void registerContentTypes( IPlatformPlugin plugin, ClassLoader loader, GenericApplicationContext beanFactory ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { // index content types and define any file meta providersIContentGeneratorInfo for ( IContentInfo info : plugin.getContentInfos() ) { final HashMap attributes = new HashMap(); @@ -638,9 +637,9 @@ protected void registerContentTypes( IPlatformPlugin plugin, ClassLoader loader, attributes.put( "extension", info.getExtension() ); IPentahoObjectRegistration handle = PentahoSystem.registerReference( - new SingletonPentahoObjectReference.Builder( IContentInfo.class ).object( info ) - .attributes( attributes ).build(), - IContentInfo.class + new SingletonPentahoObjectReference.Builder( IContentInfo.class ).object( info ) + .attributes( attributes ).build(), + IContentInfo.class ); registerReference( plugin.getId(), handle ); @@ -648,11 +647,11 @@ protected void registerContentTypes( IPlatformPlugin plugin, ClassLoader loader, } private GenericApplicationContext createBeanFactory( IPlatformPlugin plugin, ClassLoader classloader ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { if ( !( classloader instanceof PluginClassLoader ) ) { throw new PlatformPluginRegistrationException( - "Can't determine plugin dir to load spring file because classloader is not of type PluginClassLoader. " - + "This is since we are probably in a unit test" + "Can't determine plugin dir to load spring file because classloader is not of type PluginClassLoader. " + + "This is since we are probably in a unit test" ); } @@ -695,14 +694,14 @@ private GenericApplicationContext createBeanFactory( IPlatformPlugin plugin, Cla assertUnique( beanFactory, plugin.getId(), def.getBeanId() ); } catch ( PlatformPluginRegistrationException e ) { logger.error( MessageFormat - .format( "Unable to register plugin bean, a bean by the id {0} is already defined in plugin: {1}", - def.getBeanId(), plugin.getId() ) ); + .format( "Unable to register plugin bean, a bean by the id {0} is already defined in plugin: {1}", + def.getBeanId(), plugin.getId() ) ); continue; } // defining plugin beans the old way through the plugin provider ifc supports only prototype scope BeanDefinition beanDef = - BeanDefinitionBuilder.rootBeanDefinition( def.getClassname() ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) - .getBeanDefinition(); + BeanDefinitionBuilder.rootBeanDefinition( def.getClassname() ).setScope( BeanDefinition.SCOPE_PROTOTYPE ) + .getBeanDefinition(); beanFactory.registerBeanDefinition( def.getBeanId(), beanDef ); } @@ -713,10 +712,10 @@ private GenericApplicationContext createBeanFactory( IPlatformPlugin plugin, Cla * A utility method that throws an exception if a bean with the id is already defined for this plugin */ protected void assertUnique( GenericApplicationContext applicationContext, String pluginId, String beanId ) - throws PlatformPluginRegistrationException { + throws PlatformPluginRegistrationException { if ( applicationContext.containsBean( beanId ) ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0018_BEAN_ALREADY_REGISTERED", beanId, pluginId ) ); + "PluginManager.ERROR_0018_BEAN_ALREADY_REGISTERED", beanId, pluginId ) ); } } @@ -768,18 +767,18 @@ private void registerReference( String id, IPentahoObjectRegistration handle ) { private ClassLoader createClassloader( IPlatformPlugin plugin ) throws PlatformPluginRegistrationException { String pluginDirPath = - PentahoSystem.getApplicationContext().getSolutionPath( "system/" + plugin.getSourceDescription() ); + PentahoSystem.getApplicationContext().getSolutionPath( "system/" + plugin.getSourceDescription() ); // need to scrub out duplicate file delimeters otherwise we will // not be able to locate resources in jars. This classloader ultimately // needs to be made less fragile pluginDirPath = pluginDirPath.replace( "//", "/" ); org.pentaho.platform.util.logging.Logger - .debug( this, - "plugin dir for " + plugin.getId() + " is [" + pluginDirPath + "]" ); + .debug( this, + "plugin dir for " + plugin.getId() + " is [" + pluginDirPath + "]" ); File pluginDir = new File( pluginDirPath ); if ( !pluginDir.exists() || !pluginDir.isDirectory() || !pluginDir.canRead() ) { throw new PlatformPluginRegistrationException( Messages.getInstance().getErrorString( - "PluginManager.ERROR_0027_PLUGIN_DIR_UNAVAILABLE", pluginDir.getAbsolutePath() ) ); + "PluginManager.ERROR_0027_PLUGIN_DIR_UNAVAILABLE", pluginDir.getAbsolutePath() ) ); } PluginClassLoader loader = new PluginClassLoader( pluginDir, this.getClass().getClassLoader() ); if ( plugin.getLoaderType() == IPlatformPlugin.ClassLoaderType.OVERRIDING ) { @@ -810,7 +809,7 @@ public Object getBean( String beanId ) throws PluginBeanException { } throw new PluginBeanException( Messages.getInstance().getString( - "PluginManager.WARN_CLASS_NOT_REGISTERED", beanId ) ); + "PluginManager.WARN_CLASS_NOT_REGISTERED", beanId ) ); } @@ -827,19 +826,21 @@ public IContentGenerator getContentGenerator( String type, String perspectiveNam // first we check: is there any IContentGeneratorInvoker implementation on the bean registry? If so: use it; final IContentGeneratorInvoker cgInvoker = PentahoSystem.get( IContentGeneratorInvoker.class ); if ( cgInvoker != null && cgInvoker.isSupportedContent( beanId ) ) { - logger.info( "Located IContentGeneratorInvoker that supports content of type '" + beanId + "':" + cgInvoker.getClass().getName() ); + logger.info( + "Located IContentGeneratorInvoker that supports content of type '" + beanId + "':" + cgInvoker.getClass() + .getName() ); return cgInvoker.getContentGenerator(); } // otherwise, gracefully fallback to PentahoSystemPluginManager's internal IContentGenerator discovery logic; IContentGenerator contentGenerator = PentahoSystem - .get( IContentGenerator.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( CONTENT_TYPE, beanId ) ); + .get( IContentGenerator.class, PentahoSessionHolder.getSession(), + Collections.singletonMap( CONTENT_TYPE, beanId ) ); if ( contentGenerator == null ) { contentGenerator = PentahoSystem - .get( IContentGenerator.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( CONTENT_TYPE, perspectiveName ) ); + .get( IContentGenerator.class, PentahoSessionHolder.getSession(), + Collections.singletonMap( CONTENT_TYPE, perspectiveName ) ); } return contentGenerator; @@ -852,7 +853,7 @@ public Class loadClass( String beanId ) throws PluginBeanException { } Class type = null; for ( IPentahoObjectReference reference : PentahoSystem.getObjectReferences( - GenericApplicationContext.class, null ) ) { + GenericApplicationContext.class, null ) ) { if ( !reference.getAttributes().containsKey( PLUGIN_ID ) ) { // This GenericApplicationContext was not registered from the plugin manager as it lacks plugin-id continue; @@ -870,7 +871,7 @@ public Class loadClass( String beanId ) throws PluginBeanException { if ( type == null ) { throw new PluginBeanException( Messages.getInstance().getString( - "PluginManager.WARN_CLASS_NOT_REGISTERED", beanId ) ); + "PluginManager.WARN_CLASS_NOT_REGISTERED", beanId ) ); } return type; } @@ -898,14 +899,14 @@ public void unloadAllPlugins() { public String getPluginIdForType( String contentType ) { final IPentahoObjectReference objectReference = PentahoSystem - .getObjectReference( IContentGenerator.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( CONTENT_TYPE, contentType ) ); + .getObjectReference( IContentGenerator.class, PentahoSessionHolder.getSession(), + Collections.singletonMap( CONTENT_TYPE, contentType ) ); if ( objectReference != null && objectReference.getAttributes().containsKey( PLUGIN_ID ) ) { return objectReference.getAttributes().get( PLUGIN_ID ).toString(); } else { // fallback for the case where everything is registered in the new form [contentType].[method] final List> objectReferences = - PentahoSystem.getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession() ); + PentahoSystem.getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession() ); for ( IPentahoObjectReference reference : objectReferences ) { if ( reference.getAttributes().containsKey( CONTENT_TYPE ) ) { @@ -923,8 +924,8 @@ public String getPluginIdForType( String contentType ) { public List getPluginRESTPerspectivesForType( String contentType ) { List retList = new ArrayList(); final List> objectReferences = PentahoSystem - .getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( CONTENT_TYPE, contentType ) ); + .getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession(), + Collections.singletonMap( CONTENT_TYPE, contentType ) ); for ( IPentahoObjectReference objectReference : objectReferences ) { if ( objectReference.getAttributes().containsKey( "id" ) ) { @@ -941,8 +942,8 @@ public List getPluginRESTPerspectivesForType( String contentType ) { public List getPluginRESTPerspectivesForId( String id ) { List retList = new ArrayList(); final List> objectReferences = PentahoSystem - .getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( PLUGIN_ID, id ) ); + .getObjectReferences( IContentGenerator.class, PentahoSessionHolder.getSession(), + Collections.singletonMap( PLUGIN_ID, id ) ); for ( IPentahoObjectReference objectReference : objectReferences ) { if ( objectReference.getAttributes().containsKey( "id" ) ) { final String beanId = (String) objectReference.getAttributes().get( "id" ); @@ -960,7 +961,7 @@ public String getPluginIdForClassLoader( ClassLoader classLoader ) { return null; } final List> objectReferences = - PentahoSystem.getObjectReferences( ClassLoader.class, null ); + PentahoSystem.getObjectReferences( ClassLoader.class, null ); for ( IPentahoObjectReference objectReference : objectReferences ) { if ( objectReference.getObject().equals( classLoader ) ) { return objectReference.getAttributes().get( PLUGIN_ID ).toString(); @@ -1082,7 +1083,7 @@ public boolean isStaticResource( String path ) { @Override public boolean isPublic( String pluginId, String path ) { IPlatformPlugin plugin = PentahoSystem.get( IPlatformPlugin.class, PentahoSessionHolder.getSession(), - Collections.singletonMap( PLUGIN_ID, pluginId ) ); + Collections.singletonMap( PLUGIN_ID, pluginId ) ); if ( plugin == null ) { return false; } @@ -1106,7 +1107,7 @@ public InputStream getStaticResource( String path ) { if ( isRequested( url, path ) ) { IPluginResourceLoader resLoader = PentahoSystem.get( IPluginResourceLoader.class, null ); ClassLoader classLoader = - PentahoSystem.get( ClassLoader.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); + PentahoSystem.get( ClassLoader.class, null, Collections.singletonMap( PLUGIN_ID, plugin.getId() ) ); String resourcePath = path.replace( url, resourceMap.get( url ) ); return resLoader.getResourceAsStream( classLoader, resourcePath ); } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java index 545502583d6..b8b30b3fb74 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/pluginmgr/SystemPathXmlPluginProvider.java @@ -152,14 +152,14 @@ protected PlatformPlugin createPlugin( Document doc, IPentahoSession session, St processExternalResources( plugin, doc ); processPerspectives( plugin, doc ); - String listenerCount = plugin.getLifecycleListenerClassnames() != null ? Integer.toString( plugin.getLifecycleListenerClassnames().size() ) : "0"; + int listenerCount = plugin.getLifecycleListenerClassnames() != null ? plugin.getLifecycleListenerClassnames().size() : 0; String msg = Messages.getInstance().getString( "SystemPathXmlPluginProvider.PLUGIN_PROVIDES", //$NON-NLS-1$ Integer.toString( plugin.getContentInfos().size() ), Integer.toString( plugin.getContentGenerators().size() ), Integer.toString( plugin.getOverlays().size() ), - listenerCount ); + Integer.toString( listenerCount) ); PluginMessageLogger.add( msg ); plugin.setSourceDescription( folder ); diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java index eb975c7d0bd..06087d494c4 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java @@ -6,23 +6,9 @@ public interface IJob { - - enum JobState { - NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED, UNKNOWN - } - - JobState state = JobState.UNKNOWN; - - public IJobTrigger getJobTrigger(); - public Map getJobParams(); - public String getJobId(); - public String getJobName(); - public Date getLastRun(); - public String getUserName(); - public void setJobTrigger( IJobTrigger jobTrigger ); - public void setJobId( String jobId ); - public void setUserName( String userName ); - public void setJobName( String jobName ); - public JobState getState(); - public void setState( JobState state ); + IJobTrigger getJobTrigger(); + Map getJobParams(); + String getJobId(); + String getJobName(); + JobState getState(); } diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java index 221d32b3d09..57f5196fb5d 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java @@ -13,7 +13,7 @@ public interface IJobScheduleRequest { void setDuration( long duration ); - void setJobState( IJob.JobState state ); + void setJobState( JobState state ); void setInputFile( String inputFilePath ); @@ -49,7 +49,7 @@ public interface IJobScheduleRequest { long getDuration(); - IJob.JobState getJobState(); + JobState getJobState(); ICronJobTrigger getCronJobTrigger(); } From c8503e7f4d5a7986d7669508157a75c76e0ae8ae Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Wed, 27 Sep 2023 10:46:38 -0400 Subject: [PATCH 28/59] [BACKLOG-38225] Fix BISERVER was throwing a javascript error when starting without the scheduler-plugin present --- .../src/main/java/org/pentaho/mantle/client/MantleUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java index b65f86e98d0..182a66988dd 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/MantleUtils.java @@ -62,7 +62,9 @@ public void fireRefreshFolderEvent( String outputLocation ) { } public static native String getSchedulerPluginContextURL()/*-{ - return $wnd.pho.getSchedulerPluginContextURL(); + if (typeof $wnd.pho.getSchedulerPluginContextURL !== "undefined" ) { + return $wnd.pho.getSchedulerPluginContextURL(); + } }-*/; private static native void setupNativeHooks( MantleUtils utils ) From 727bbbaefdcbbd31af882f940dc09c2582a4bec0 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Wed, 27 Sep 2023 16:20:58 -0400 Subject: [PATCH 29/59] BACKLOG-38036 - Removed references to the quartz library and supporting function from the platform --- assemblies/pentaho-war/pom.xml | 6 --- .../solution/system/systemListeners.xml | 4 +- extensions/pom.xml | 12 ----- repository/pom.xml | 5 -- scheduler/pom.xml | 12 ----- .../scheduler2/messsages/messages.properties | 46 +++++++++++++++++++ .../messsages/messages_de.properties | 44 ++++++++++++++++++ .../messsages/messages_fr.properties | 44 ++++++++++++++++++ .../messsages/messages_ja.properties | 44 ++++++++++++++++++ .../messsages/messages_zh_CN.properties | 46 +++++++++++++++++++ 10 files changed, 226 insertions(+), 37 deletions(-) create mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties create mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties create mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties create mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties create mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties diff --git a/assemblies/pentaho-war/pom.xml b/assemblies/pentaho-war/pom.xml index 430d6218b4c..826347d2d0c 100644 --- a/assemblies/pentaho-war/pom.xml +++ b/assemblies/pentaho-war/pom.xml @@ -462,12 +462,6 @@ ${wsdl4j.version} compile - - org.quartz-scheduler - quartz-oracle - ${quartz-oracle.version} - compile - pentaho pdi-osgi-bridge-core diff --git a/core/src/test/resources/solution/system/systemListeners.xml b/core/src/test/resources/solution/system/systemListeners.xml index e2cffb2f5e0..1706127954d 100644 --- a/core/src/test/resources/solution/system/systemListeners.xml +++ b/core/src/test/resources/solution/system/systemListeners.xml @@ -17,7 +17,7 @@ VersionCheckSystemListener. - + diff --git a/extensions/pom.xml b/extensions/pom.xml index fb75836fd84..109caec7954 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -316,18 +316,6 @@ ${jboss-modules.version} true - - org.quartz-scheduler - quartz - ${quartz.version} - compile - - - * - * - - - org.mozilla rhino diff --git a/repository/pom.xml b/repository/pom.xml index 5f947bdbb65..9552d7f8498 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -904,11 +904,6 @@ ${simple-jndi.version} test - - org.quartz-scheduler - quartz - ${quartz.version} - com.sun.jersey.jersey-test-framework jersey-test-framework-core diff --git a/scheduler/pom.xml b/scheduler/pom.xml index 77142401c07..766cd90be83 100644 --- a/scheduler/pom.xml +++ b/scheduler/pom.xml @@ -51,18 +51,6 @@ - - org.quartz-scheduler - quartz - ${quartz.version} - compile - - - * - * - - - pentaho pentaho-platform-api diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties new file mode 100644 index 00000000000..52a96b5bfb7 --- /dev/null +++ b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties @@ -0,0 +1,46 @@ +ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. +ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map +ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} +ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" +ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job +ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} +ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have been run \ + remotely: {1} + +QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing +QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing +QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". +QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" +QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type +QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null +QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. +QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. +QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. +QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. +QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" +QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=You don't have scheduling permissions for this file.\nContact your administrator for assistance. +QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Due to user/role changes, job "{0}" is not able to be executed by "{1}" +EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup +EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. +EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object +EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object +EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables +EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql +JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} + +schedulerEmailFromName=Pentaho Scheduler +PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger +PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" +PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger + +Unknown=Unknown + +ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Running action "{0}" in background locally: {1} + +ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} + +ActionInvoker.ERROR_0004_ACTION_FAILED=Action "{0}" failed to execute +ActionInvoker.ERROR_0005_ACTION_NULL=Action is null, cannot invoke +ActionInvoker.ERROR_0006_ACTION_NULL=Action "{0}" is not supported +ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Map is null, cannot return stream provider +ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Cannot get repository file "{0}": {1} diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties new file mode 100644 index 00000000000..86c334439b8 --- /dev/null +++ b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties @@ -0,0 +1,44 @@ +ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Ung\u00fcltiger Cron-Ausdruck. +ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Eigenschaft "{0}" oder "{1}" muss in der Aufgabendatenzuordnung festgesetzt werden, +ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Fehler beim Erstellen einer Instanz der Aktion "{0}": {1} +ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=Klasse {0} muss eine Instanz von "{1}" sein +ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Aktion "{0}" als Quartz-Aufgabe ausf\u00fchren fehlgeschlagen +ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status f\ufffdr Aktion "{0}" ist nicht verf\ufffdgbar; Die Aktion kann \ +# remote ausgef\ufffdhrt worden sein: {1} +# +QuartzJobKey.ERROR_0000=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, jobName nicht vorhanden +QuartzJobKey.ERROR_0001=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, Benutzername nicht vorhanden +QuartzJobKey.ERROR_0002=In jobId "{0}" fehlen Daten +QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz konnte f\u00fcr Aufgabe "{0}" keinen Zeitplan festlegen +QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Ausl\u00f6ser ist ein unzul\u00e4ssiger Typ +QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Aktion darf nicht Null sein +QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz konnte die Aufgaben nicht auflisten. +QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz konnte die Aufgabe nicht anhalten. +QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz konnte die Aufgaben nicht fortsetzen. +QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Quartz-Zeitplanstatus kann nicht abgerufen werden. +QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Aufgabe "{0}" kann nicht abgerufen werden +EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Planer wurde beim Starten nicht ordnungsgem\u00e4\u00df initialisiert +EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Laden von Quartz.properties von Klassenpfad fehlgeschlagen. +EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Instanziieren von Objekt nicht m\u00f6glich +EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Datenquellobjekt nicht abrufbar +EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Beim Erstellen der Quartz-Tabellen ist ein SQL-Fehler aufgetreten +EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Quartz-Initialisierungsskript system/quartz/quartzinit.sql kann nicht gefunden werden +JobParamsAdapter.ERROR_0001=Typ {0} wird von {1} nicht unterst\u00fctzt +# +schedulerEmailFromName=Pentaho-Planer +PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Es wurde versucht, ein IBlockOutTrigger-Objekt hinzuzuf\u00fcgen, das keine Instanz des Ausl\u00f6sers ist +PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Sperre "{0}" konnte nicht gesucht werden +PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Es kann kein g\u00fcltiger Wiederholungsintervall vom bereitgestellten Ausl\u00f6ser analysiert werden +# +Unknown=Unbekannt +ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} +QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Sie haben keine Berechtigungen, um diese Datei zu planen.\nWenden Sie sich wegen Unterst\u00fctzung an den Administrator. +QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Aufgrund Benutzer- oder Rollen\u00e4nderungen kann Job {0} nicht von {1} ausgef\u00fchrt werden. +ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Aktion {0} wird im Hintergrund lokal ausgef\u00fchrt: {1} +ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} +ActionInvoker.ERROR_0004_ACTION_FAILED=Ausf\u00fchren der Aktion {0} fehlgeschlagen +ActionInvoker.ERROR_0005_ACTION_NULL=Aktion ist null, Fortfahren nicht m\u00f6glich ... +ActionInvoker.ERROR_0006_ACTION_NULL=Aktion {0} wird nicht unterst\u00fctzt +ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Zuordnung ist null, Stream-Anbieter kann nicht zur\u00fcckgegeben werden +ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Repository-Datei {0} nicht abrufbar: {1} +# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties new file mode 100644 index 00000000000..41a9d7e312f --- /dev/null +++ b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties @@ -0,0 +1,44 @@ +ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Expression cron non valide. +ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=La propri\u00e9t\u00e9 {0} ou {1} doit \u00eatre d\u00e9finie dans le mappage des donn\u00e9es de t\u00e2che. +ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Impossible de cr\u00e9er une instance de l'action {0}: {1} +ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=la classe {0} doit \u00eatre une instance de {1} +ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u00c9chec d'ex\u00e9cution de l'action {0} en tant que t\u00e2che quartz +ActionAdapterQuartzJob.WARN_0002_NO_STATUS=L'\ufffdtat de l'action "{0}" n'est pas disponible; L'action peut avoir \ufffdt\ufffd \ +# ex\ufffdcut\ufffde \ufffd distance: {1} +# +QuartzJobKey.ERROR_0000=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, jobName est manquant +QuartzJobKey.ERROR_0001=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, username est manquant +QuartzJobKey.ERROR_0002=Donn\u00e9es manquantes dans jobId {0}. +QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=\u00c9chec de la planification de la t\u00e2che {0} par quartz +QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=D\u00e9clencheur est un type non conforme +QuartzScheduler.ERROR_0003_ACTION_IS_NULL=L'action ne peut pas \u00eatre nulle +QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Impossible pour Quartz de lister les t\u00e2ches +QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Impossible pour Quartz de mettre les t\u00e2ches en pause +QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Impossible pour Quartz de reprendre les t\u00e2ches +QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Impossible d'obtenir le statut du planificateur Quartz. +QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Impossible d'obtenir la t\u00e2che {0} +EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Le planificateur n'a pas \u00e9t\u00e9 correctement initialis\u00e9 lors du d\u00e9marrage. +EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u00c9chec du chargement de quartz.properties depuis le Classpath. +EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Impossible d'instancier l'objet +EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Impossible d'obtenir l'objet de la source de donn\u00e9es +EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Erreur SQL lors de la cr\u00e9ation des tables Quartz +EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Impossible de trouver le script d'initialisation Quartz system/quartz/quartzinit.sql +JobParamsAdapter.ERROR_0001=Type {0} non pris en charge par {1} +# +schedulerEmailFromName=Planificateur Pentaho +PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Tentative d'ajout d'un objet IBlockOutTrigger qui n'est pas une instance de d\u00e9clencheur +PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Impossible de localiser le blocage avec le nom : {0} +PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Impossible d'analyser un intervalle de p\u00e9riodicit\u00e9 valide \u00e0 partir du d\u00e9clencheur fourni. +# +Unknown=Inconnu +ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} +QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Vous n'\u00eates pas autoris\u00e9 \u00e0 planifier ce fichier.\nPour obtenir de l'aide, contactez votre administrateur. +QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=En raison de changements d'utilisateur/de r\u00f4le, la t\u00e2che \u00ab\u00a0{0}\u00a0\u00bb ne peut pas \u00eatre ex\u00e9cut\u00e9e par \u00ab\u00a0{1}\u00a0\u00bb +ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb en arri\u00e8re-plan localement\u00a0: {1} +ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} +ActionInvoker.ERROR_0004_ACTION_FAILED=\u00c9chec de l'ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb +ActionInvoker.ERROR_0005_ACTION_NULL=L'action est nulle, impossible de l'appeler +ActionInvoker.ERROR_0006_ACTION_NULL=L'action \u00ab\u00a0{0}\u00a0\u00bb n'est pas prise en charge +ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Le mappage est nul, impossible de revenir au fournisseur de flux +ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Impossible d'obtenir le fichier du r\u00e9f\u00e9rentiel \u00ab\u00a0{0}\u00a0\u00bb\u00a0:{1} +# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties new file mode 100644 index 00000000000..7463353f5cb --- /dev/null +++ b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties @@ -0,0 +1,44 @@ +ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. +ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map +ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} +ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" +ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job +ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have \ +# been run remotely: {1} +# +QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing +QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing +QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". +QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" +QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type +QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null +QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. +QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. +QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. +QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. +QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" +EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup +EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. +EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object +EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object +EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables +EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql +JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} +# +schedulerEmailFromName=Pentaho\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30fc +PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger +PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" +PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger +# +Unknown=Unknown +ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} +QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30ea\u30f3\u30b0\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n\u7ba1\u7406\u8005\u306b\u554f\u3044\u5408\u308f\u305b\u3066\u304f\u3060\u3055\u3044\u3002 +QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u30e6\u30fc\u30b6\u30fc/\u30ed\u30fc\u30eb\u306e\u5909\u66f4\u306b\u3088\u308a\u3001\u30b8\u30e7\u30d6 "{0}" \u306f "{1}" \u3067\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093 +ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u3092\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u30ed\u30fc\u30ab\u30eb\u3067\u5b9f\u884c\u3057\u3066\u3044\u307e\u3059: {1} +ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} +ActionInvoker.ERROR_0004_ACTION_FAILED=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306e\u5b9f\u884c\u306b\u5931\u6557\u3057\u307e\u3057\u305f +ActionInvoker.ERROR_0005_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3\u304cnull\u3067\u3001\u547c\u3073\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 +ActionInvoker.ERROR_0006_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093 +ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u30de\u30c3\u30d7\u304cnull\u3067\u3059\u3002\u30b9\u30c8\u30ea\u30fc\u30e0\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8fd4\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 +ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u30ea\u30dd\u30b8\u30c8\u30ea\u30d5\u30a1\u30a4\u30eb "{0}" \u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093: {1} +# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties new file mode 100644 index 00000000000..8cd2eb3fd00 --- /dev/null +++ b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties @@ -0,0 +1,46 @@ +ComplexJobTrigger.ERROR_0001_InvalidCronExpression=cron \u8868\u8fbe\u5f0f\u65e0\u6548\u3002 +ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=\u5fc5\u987b\u5728\u4f5c\u4e1a\u6570\u636e\u6620\u5c04\u4e2d\u8bbe\u7f6e\u5c5e\u6027 "{0}" \u6216 "{1}" +ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=\u521b\u5efa\u64cd\u4f5c "{0}" \u7684\u5b9e\u4f8b\u5931\u8d25\uff1a{1} +ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=\u7c7b {0} \u5fc5\u987b\u662f "{1}" \u7684\u5b9e\u4f8b +ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u4f5c\u4e3a quartz \u4f5c\u4e1a\u8fd0\u884c\u5931\u8d25 +ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} +ActionAdapterQuartzJob.WARN_0002_NO_STATUS=\u64cd\u4f5c\u72b6\u6001 "{0}" \u4e0d\u53ef\u7528\uff1b\u8be5\u64cd\u4f5c\u53ef\u80fd\u5df2\u8fdc\u7a0b\u8fd0\u884c #\uff1a{1} +# +QuartzJobKey.ERROR_0000=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0cjobName \u4e22\u5931 +QuartzJobKey.ERROR_0001=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0c\u7528\u6237\u540d\u4e22\u5931 +QuartzJobKey.ERROR_0002=jobId "{0}" \u4e2d\u7684\u6570\u636e\u4e22\u5931\u3002 +QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz \u672a\u80fd\u5b89\u6392\u4f5c\u4e1a "{0}" +QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=\u89e6\u53d1\u5668\u4e3a\u975e\u6cd5\u7c7b\u578b +QuartzScheduler.ERROR_0003_ACTION_IS_NULL=\u64cd\u4f5c\u4e0d\u80fd\u4e3a\u7a7a\u503c +QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz \u5217\u51fa\u4f5c\u4e1a\u5931\u8d25\u3002 +QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz \u6682\u505c\u4f5c\u4e1a\u5931\u8d25\u3002 +QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz \u7ee7\u7eed\u4f5c\u4e1a\u5931\u8d25\u3002 +QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=\u65e0\u6cd5\u83b7\u53d6 Quartz \u8c03\u5ea6\u7a0b\u5e8f\u72b6\u6001\u3002 +QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=\u83b7\u53d6\u4f5c\u4e1a "{0}" \u5931\u8d25 +QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u60a8\u6ca1\u6709\u6b64\u6587\u4ef6\u7684\u8c03\u5ea6\u6743\u9650\u3002\n\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u4ee5\u83b7\u53d6\u5e2e\u52a9\u3002 +QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u7531\u4e8e\u7528\u6237/\u89d2\u8272\u7684\u66f4\u6539\uff0c\u4f5c\u4e1a "{0}" \u4e0d\u80fd\u7531 "{1}" \u6267\u884c +EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=\u5728\u542f\u52a8\u65f6\u672a\u6b63\u786e\u521d\u59cb\u5316\u8c03\u5ea6\u7a0b\u5e8f +EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u4ece\u7c7b\u8def\u5f84\u52a0\u8f7d quartz.properties \u5931\u8d25\u3002 +EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=\u65e0\u6cd5\u5b9e\u4f8b\u5316\u5bf9\u8c61 +EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=\u65e0\u6cd5\u83b7\u53d6\u6570\u636e\u6e90\u5bf9\u8c61 +EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=\u521b\u5efa Quartz \u8868\u65f6\u51fa\u73b0 SQL \u9519\u8bef +EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=\u627e\u4e0d\u5230 Quartz \u521d\u59cb\u5316\u811a\u672c system/quartz/quartzinit.sql +JobParamsAdapter.ERROR_0001={1} \u4e0d\u652f\u6301\u7c7b\u578b {0} +# +schedulerEmailFromName=Pentaho \u8ba1\u5212\u7a0b\u5e8f +PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=\u5df2\u5c1d\u8bd5\u6dfb\u52a0\u975e\u89e6\u53d1\u5668\u5b9e\u4f8b\u7684 IBlockOutTrigger \u5bf9\u8c61 +PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=\u65e0\u6cd5\u4f7f\u7528\u540d\u79f0 "{0}" \u627e\u5230\u963b\u6b62 +PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=\u65e0\u6cd5\u4ece\u63d0\u4f9b\u7684\u89e6\u53d1\u5668\u89e3\u6790\u6709\u6548\u7684\u5b9a\u671f\u95f4\u9694 +# +Unknown=\u672a\u77e5 +# +ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u5728\u540e\u53f0\u672c\u5730\u8fd0\u884c\u64cd\u4f5c "{0}"\uff1a{1} +# +ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} +# +ActionInvoker.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u6267\u884c\u5931\u8d25 +ActionInvoker.ERROR_0005_ACTION_NULL=\u64cd\u4f5c\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8c03\u7528 +ActionInvoker.ERROR_0006_ACTION_NULL=\u4e0d\u652f\u6301\u64cd\u4f5c "{0}" +ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u6620\u5c04\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8fd4\u56de\u6d41\u63d0\u4f9b\u7a0b\u5e8f +ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u65e0\u6cd5\u83b7\u53d6\u5b58\u50a8\u5e93\u6587\u4ef6 "{0}"\uff1a{1} +# From 8634357cdb683995c4562749d57d3ab33cb71a3e Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Tue, 3 Oct 2023 11:04:39 -0400 Subject: [PATCH 30/59] [BACKLOG-38227] SCHEDULER - Make ALL scheduler-plugin unit tests work again --- .../PentahoVersionCheckReflectHelperTest.java | 4 +- .../admin/GatherStatsListenerTest.java | 15 +- .../exporter/PentahoPlatformExporterTest.java | 404 ------ .../exporter/ScheduleExportUtilTest.java | 290 ----- .../importer/SolutionImportHandlerTest.java | 712 ----------- .../exportManifest/ExportManifestTest.java | 431 ------- .../bindings/JobScheduleParamTest.java | 48 - .../RepositoryCleanerSystemListenerTest.java | 212 ---- .../SchedulerOutputPathResolverTest.java | 144 --- .../api/resources/SchedulerResourceTest.java | 927 -------------- .../resources/SchedulerResourceUtilTest.java | 372 ------ .../proxies/BlockStatusProxyTest.java | 2 +- .../services/SchedulerServiceTest.java | 1117 ----------------- .../PentahoSystemReadyListenerTest.java | 114 -- .../solution/system/data/hibernate.properties | 34 +- .../solution/system/data/hibernate.script | 410 +++--- .../pentaho/platform/api/scheduler2/IJob.java | 23 +- 17 files changed, 254 insertions(+), 5005 deletions(-) delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParamTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolverTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListenerTest.java diff --git a/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java b/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java index 3cc01ca8a9a..c2cb9a61f79 100644 --- a/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java +++ b/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java @@ -50,8 +50,8 @@ public void performVersionCheckTest() { List results = PentahoVersionCheckReflectHelper.performVersionCheck( false, -1 ); assertNotNull( results ); assertTrue( results.size() > 0 ); - assertTrue( results.get(0).toString().startsWith("\n") ); + assertTrue( results.get(0).toString().startsWith("") ); } @Test diff --git a/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java b/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java index ce4e3dd74ec..6bc2cb21e0e 100644 --- a/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java +++ b/extensions/src/test/java/org/pentaho/platform/admin/GatherStatsListenerTest.java @@ -33,9 +33,10 @@ import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.engine.core.system.PentahoSystem; +import java.util.Date; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -62,13 +63,13 @@ public void setUp() throws Exception { @Test public void testStartUp() throws Exception { PentahoSystem.registerObject( scheduler ); - + IJobTrigger trigger = scheduler.createSimpleJobTrigger( new Date(), null, -1, 101L ); IJob job = mock( IJob.class ); when( scheduler.createJob( eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( IJobTrigger.class ) ) ).thenReturn( job ); + eq( trigger ) ) ).thenReturn( job ); boolean startup = gatherStatsListener.startup( session ); assertTrue( startup ); @@ -79,7 +80,7 @@ public void testStartUp() throws Exception { eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( IJobTrigger.class ) ); + eq( trigger ) ); } @Test @@ -91,12 +92,12 @@ public void testShutdown() { @Test public void testStartup_withExceptionFromScheduleJobCall() throws Exception { PentahoSystem.registerObject( scheduler ); - + IJobTrigger trigger = scheduler.createSimpleJobTrigger( new Date(), null, -1, 101L ); when( scheduler.createJob( eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( IJobTrigger.class ) ) ).thenThrow( new SchedulerException( "error" ) ); + eq( trigger ) ) ).thenThrow( new SchedulerException( "error" ) ); boolean startup = gatherStatsListener.startup( session ); assertTrue( startup ); @@ -107,7 +108,7 @@ public void testStartup_withExceptionFromScheduleJobCall() throws Exception { eq( "Gather Stats" ), eq( GatherStatsAction.class ), eq( gatherStatsListener.jobMap ), - any( IJobTrigger.class ) ); + eq( trigger ) ); } @After diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java deleted file mode 100644 index e345e08ace3..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java +++ /dev/null @@ -1,404 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.exporter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.pentaho.database.model.IDatabaseConnection; -import org.pentaho.metadata.repository.IMetadataDomainRepository; -import org.pentaho.metastore.api.IMetaStore; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IUserRoleListService; -import org.pentaho.platform.api.mt.ITenant; -import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.usersettings.IAnyUserSettingService; -import org.pentaho.platform.api.usersettings.pojo.IUserSetting; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService; -import org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalog; -import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; -import org.pentaho.platform.plugin.services.importexport.RoleExport; -import org.pentaho.platform.plugin.services.importexport.UserExport; -import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseConnection; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetaStore; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian; -import org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper; -import org.pentaho.platform.scheduler2.versionchecker.EmbeddedVersionCheckSystemListener; -import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.security.policy.rolebased.RoleBindingStruct; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; - -import java.io.InputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.any; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.anyBoolean; - -public class PentahoPlatformExporterTest { - - PentahoPlatformExporter exporterSpy; - PentahoPlatformExporter exporter; - IUnifiedRepository repo; - IScheduler scheduler; - IPentahoSession session; - IMondrianCatalogService mondrianCatalogService; - MondrianCatalogRepositoryHelper mondrianCatalogRepositoryHelper; - - ExportManifest exportManifest; - - @Before - public void setUp() throws Exception { - repo = mock( IUnifiedRepository.class ); - scheduler = mock( IScheduler.class ); - session = mock( IPentahoSession.class ); - mondrianCatalogService = mock( IMondrianCatalogService.class ); - mondrianCatalogRepositoryHelper = mock( MondrianCatalogRepositoryHelper.class ); - exportManifest = spy( new ExportManifest() ); - - PentahoSessionHolder.setSession( session ); - exporterSpy = spy( new PentahoPlatformExporter( repo ) ); - exporterSpy.setScheduler( scheduler ); - exporterSpy.setExportManifest( exportManifest ); - - doReturn( "session name" ).when( session ).getName(); - exporter = new PentahoPlatformExporter( repo ); - } - - @After - public void tearDown() { - PentahoSystem.clearObjectFactory(); - } - - @Test - public void testExportSchedules() throws Exception { - List jobs = new ArrayList<>(); - IComplexJobTrigger trigger = mock( IComplexJobTrigger.class ); - IJobTrigger unknownTrigger = mock( IJobTrigger.class ); - - IJob job1 = mock( IJob.class ); - IJob job2 = mock( IJob.class ); - IJob job3 = mock( IJob.class ); - jobs.add( job1 ); - jobs.add( job2 ); - jobs.add( job3 ); - - when( scheduler.getJobs( null ) ).thenReturn( jobs ); - when( job1.getJobName() ).thenReturn( EmbeddedVersionCheckSystemListener.VERSION_CHECK_JOBNAME ); - when( job2.getJobName() ).thenReturn( "job 2" ); - when( job2.getJobTrigger() ).thenReturn( trigger ); - when( job3.getJobName() ).thenReturn( "job 3" ); - when( job3.getJobTrigger() ).thenReturn( unknownTrigger ); - - exporterSpy.exportSchedules(); - - verify( scheduler ).getJobs( null ); - assertEquals( 1, exporterSpy.getExportManifest().getScheduleList().size() ); - } - - @Test - public void testExportSchedules_SchedulereThrowsException() throws Exception { - when( scheduler.getJobs( null ) ).thenThrow( new SchedulerException( "bad" ) ); - - exporterSpy.exportSchedules(); - - verify( scheduler ).getJobs( null ); - assertEquals( 0, exporterSpy.getExportManifest().getScheduleList().size() ); - } - - @Test - public void testExportUsersAndRoles() { - IUserRoleListService mockDao = mock( IUserRoleListService.class ); - IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); - UserDetailsService userDetailsService = mock( UserDetailsService.class ); - PentahoSystem.registerObject( mockDao ); - PentahoSystem.registerObject( userSettingService ); - PentahoSystem.registerObject( userDetailsService ); - - IRoleAuthorizationPolicyRoleBindingDao roleBindingDao = mock( IRoleAuthorizationPolicyRoleBindingDao.class ); - PentahoSystem.registerObject( roleBindingDao ); - - String tenantPath = "path"; - when( session.getAttribute( IPentahoSession.TENANT_ID_KEY ) ).thenReturn( tenantPath ); - - List userList = new ArrayList<>(); - String user = "testUser"; - String role = "testRole"; - - userList.add( user ); - when( mockDao.getAllUsers( any( ITenant.class ) ) ).thenReturn( userList ); - - List roleList = new ArrayList<>(); - roleList.add( role ); - when( mockDao.getAllRoles() ).thenReturn( roleList ); - - Map> map = new HashMap<>(); - List permissions = new ArrayList<>(); - permissions.add( "read" ); - map.put( "testRole", permissions ); - RoleBindingStruct struct = mock( RoleBindingStruct.class ); - struct.bindingMap = map; - when( roleBindingDao.getRoleBindingStruct( nullable( String.class ) ) ).thenReturn( struct ); - - ArgumentCaptor userCaptor = ArgumentCaptor.forClass( UserExport.class ); - ArgumentCaptor roleCaptor = ArgumentCaptor.forClass( RoleExport.class ); - ExportManifest manifest = mock( ExportManifest.class ); - exporter.setExportManifest( manifest ); - - List settings = new ArrayList<>(); - IUserSetting setting = mock( IUserSetting.class ); - settings.add( setting ); - when( userSettingService.getUserSettings( user ) ).thenReturn( settings ); - when( userSettingService.getGlobalUserSettings() ).thenReturn( settings ); - - List authList = new ArrayList<>(); - UserDetails userDetails = new User( "testUser", "testPassword", true, true, true, true, authList ); - when( userDetailsService.loadUserByUsername( nullable( String.class ) ) ).thenReturn( userDetails ); - - exporter.exportUsersAndRoles(); - - verify( manifest ).addUserExport( userCaptor.capture() ); - verify( manifest ).addRoleExport( roleCaptor.capture() ); - verify( userSettingService ).getGlobalUserSettings(); - verify( manifest ).addGlobalUserSetting( any( ExportManifestUserSetting.class ) ); - assertEquals( settings.size(), userCaptor.getValue().getUserSettings().size() ); - - UserExport userExport = userCaptor.getValue(); - assertEquals( "testUser", userExport.getUsername() ); - RoleExport roleExport = roleCaptor.getValue(); - assertEquals( "testRole", roleExport.getRolename() ); - } - - @Test - public void testExportMetadata_noModels() throws Exception { - IMetadataDomainRepository mdr = mock( IMetadataDomainRepository.class ); - exporter.setMetadataDomainRepository( mdr ); - - exporter.exportMetadataModels(); - assertEquals( 0, exporter.getExportManifest().getMetadataList().size() ); - } - - @Test - public void testExportMetadata() throws Exception { - IMetadataDomainRepository mdr = mock( IMetadataDomainRepository.class ); - - Set domainIds = new HashSet<>(); - domainIds.add( "test1" ); - - when( mdr.getDomainIds() ).thenReturn( domainIds ); - exporterSpy.setMetadataDomainRepository( mdr ); - exporterSpy.zos = mock( ZipOutputStream.class ); - - Map inputMap = new HashMap<>(); - InputStream is = mock( InputStream.class ); - when( is.read( any( byte[].class ) ) ).thenReturn( -1 ); - inputMap.put( "test1", is ); - - doReturn( inputMap ).when( exporterSpy ).getDomainFilesData( "test1" ); - - exporterSpy.exportMetadataModels(); - assertEquals( 1, exporterSpy.getExportManifest().getMetadataList().size() ); - - assertEquals( "test1", exporterSpy.getExportManifest().getMetadataList().get( 0 ).getDomainId() ); - assertEquals( PentahoPlatformExporter.METADATA_PATH_IN_ZIP + "test1.xmi", - exporterSpy.getExportManifest().getMetadataList().get( 0 ).getFile() ); - } - - @Test - public void testExportDatasources() throws Exception { - - IDatasourceMgmtService svc = mock( IDatasourceMgmtService.class ); - exporterSpy.setDatasourceMgmtService( svc ); - - List datasources = new ArrayList<>(); - IDatabaseConnection conn = mock( org.pentaho.database.model.DatabaseConnection.class ); - when( conn.getName() ).thenReturn( "aDatasourceName" ); - IDatabaseConnection icon = mock( IDatabaseConnection.class ); - datasources.add( conn ); - datasources.add( icon ); - - when( svc.getDatasources() ).thenReturn( datasources ); - - exporterSpy.exportDatasources(); - - assertEquals( 1, exporterSpy.getExportManifest().getDatasourceList().size() ); - DatabaseConnection exportedDatabaseConnection = exporterSpy.getExportManifest().getDatasourceList().get( 0 ); - assertEquals( "aDatasourceName", exportedDatabaseConnection.getName() ); - } - - @Test - public void testParseXmlaEnabled() throws Exception { - String dsInfo = "DataSource=SampleData;Provider=mondrian;EnableXmla=\"false\""; - assertFalse( exporterSpy.parseXmlaEnabled( dsInfo ) ); - - dsInfo = "DataSource=SampleData;Provider=mondrian;EnableXmla=\"true\""; - assertTrue( exporterSpy.parseXmlaEnabled( dsInfo ) ); - - dsInfo = "DataSource=SampleData;Provider=mondrian"; - assertFalse( exporterSpy.parseXmlaEnabled( dsInfo ) ); - - dsInfo = "DataSource=SampleData;EnableXmla=\"true\";Provider=mondrian"; - assertTrue( exporterSpy.parseXmlaEnabled( dsInfo ) ); - } - - @Test - public void testExportMondrianSchemas_noCatalogs() throws Exception { - PentahoSystem.registerObject( mondrianCatalogService ); - exporterSpy.setMondrianCatalogRepositoryHelper( mondrianCatalogRepositoryHelper ); - - exporterSpy.exportMondrianSchemas(); - - verify( exportManifest, never() ).addMondrian( any( ExportManifestMondrian.class ) ); - verify( mondrianCatalogRepositoryHelper, never() ).getModrianSchemaFiles( nullable( String.class ) ); - } - - @Test - public void testExportMondrianSchemas() throws Exception { - final String catalogName = "test"; - String dataSourceInfo = "EnableXmla=\"true\""; - - executeExportMondrianSchemasForDataSourceInfo( catalogName, dataSourceInfo ); - - verify( exportManifest ).addMondrian( any( ExportManifestMondrian.class ) ); - verify( mondrianCatalogRepositoryHelper ).getModrianSchemaFiles( nullable( String.class ) ); - assertEquals( catalogName, exportManifest.getMondrianList().get( 0 ).getCatalogName() ); - assertTrue( exportManifest.getMondrianList().get( 0 ).isXmlaEnabled() ); - verify( exporterSpy.zos ).putNextEntry( any( ZipEntry.class ) ); - } - - @Test - public void testExportMondrianSchemas_AdditionalParametersSaved() throws Exception { - final String parameterName = "AdditionalParameter"; - final String parameterValue = "TestValue"; - final String expectedParameterValue = "TestValue"; - final String dataSourceInfo = "EnableXmla=\"true\";" + parameterName + "=" + parameterValue; - String catalogName = "test"; - - executeExportMondrianSchemasForDataSourceInfo( catalogName, dataSourceInfo ); - - String returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( parameterName ); - assertNotNull( returnedParameterValue ); - assertEquals( returnedParameterValue, expectedParameterValue ); - } - - @Test - public void testPerformExportMondrianSchemas_XmlUnsafeDataSourceInfoSaved() throws IOException { - - final String dataSourceInfo = "DataSource=\""DS "Test's" & <Fun>"\";" - + "DynamicSchemaProcessor=\""DSP's & "Other" <stuff>"\";"; - - final String dataSourceExpectedValue = "\"DS \"Test's\" & \""; - final String dynamicSchemaProcessorExpectedValue = "\"DSP's & \"Other\" \""; - - executeExportMondrianSchemasForDataSourceInfo( "", dataSourceInfo ); - - String returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( "DataSource" ); - assertNotNull( returnedParameterValue ); - assertEquals( returnedParameterValue, dataSourceExpectedValue ); - - returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( "DynamicSchemaProcessor" ); - assertNotNull( returnedParameterValue ); - assertEquals( returnedParameterValue, dynamicSchemaProcessorExpectedValue ); - - } - - private void executeExportMondrianSchemasForDataSourceInfo( String catalogName, String dataSourceInfo ) throws IOException { - PentahoSystem.registerObject( mondrianCatalogService ); - exporterSpy.setMondrianCatalogRepositoryHelper( mondrianCatalogRepositoryHelper ); - - List catalogs = new ArrayList<>(); - MondrianCatalog catalog = new MondrianCatalog( catalogName, dataSourceInfo, null, null ); - catalogs.add( catalog ); - when( mondrianCatalogService.listCatalogs( any( IPentahoSession.class ), anyBoolean() ) ).thenReturn( catalogs ); - - Map inputMap = new HashMap<>(); - InputStream is = mock( InputStream.class ); - when( is.read( any( byte[].class ) ) ).thenReturn( -1 ); - inputMap.put( catalogName, is ); - when( mondrianCatalogRepositoryHelper.getModrianSchemaFiles( catalogName ) ).thenReturn( inputMap ); - exporterSpy.zos = mock( ZipOutputStream.class ); - - exporterSpy.exportMondrianSchemas(); - } - - @Test - public void testExportMetaStore() throws Exception { - exporterSpy.zos = mock( ZipOutputStream.class ); - IMetaStore metastore = mock( IMetaStore.class ); - exporterSpy.setRepoMetaStore( metastore ); - ExportManifest manifest = mock( ExportManifest.class ); - exporterSpy.setExportManifest( manifest ); - - exporterSpy.exportMetastore(); - verify( exporterSpy.zos ).putNextEntry( any( ZipEntry.class ) ); - verify( manifest ).setMetaStore( any( ExportManifestMetaStore.class ) ); - } - - @Test - public void testIsExportCandidate() throws Exception { - assertTrue( exporter.isExportCandidate( "/etc" ) ); - assertTrue( exporter.isExportCandidate( "/etc/operations_mart" ) ); - assertTrue( exporter.isExportCandidate( "/etc/operations_mart/someSubFolder" ) ); - - assertTrue( exporter.isExportCandidate( "/public" ) ); - assertTrue( exporter.isExportCandidate( "/home" ) ); - - assertFalse( exporter.isExportCandidate( "/etc/someRandomFolder" ) ); - assertFalse( exporter.isExportCandidate( "/etc/someRandomFolder/someSubFOlder" ) ); - assertFalse( exporter.isExportCandidate( "/etc/mondrian" ) ); - assertFalse( exporter.isExportCandidate( "/etc/metadata" ) ); - assertFalse( exporter.isExportCandidate( "/etc/metastore" ) ); - assertFalse( exporter.isExportCandidate( "/etc/olap-servers" ) ); - assertFalse( exporter.isExportCandidate( "/etc/models" ) ); - assertFalse( exporter.isExportCandidate( "/etc/pdi" ) ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java deleted file mode 100644 index 6885b44f39b..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtilTest.java +++ /dev/null @@ -1,290 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.exporter; - -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.ICronJobTrigger; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; -import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ScheduleExportUtilTest { - - @Before - public void setUp() throws Exception { - - } - - @Test( expected = IllegalArgumentException.class ) - public void testCreateJobScheduleRequest_null() throws Exception { - ScheduleExportUtil.createJobScheduleRequest( null ); - } - - @Test( expected = IllegalArgumentException.class ) - public void testCreateJobScheduleRequest_unknownTrigger() throws Exception { - String jobName = "JOB"; - - IJob job = mock( IJob.class ); - IJobTrigger trigger = mock( IJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - } - - @Test - public void testCreateJobScheduleRequest_SimpleJobTrigger() throws Exception { - String jobName = "JOB"; - - IJob job = mock( IJob.class ); - ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - assertNotNull( jobScheduleRequest ); - assertEquals( jobName, jobScheduleRequest.getJobName() ); - assertEquals( trigger, jobScheduleRequest.getSimpleJobTrigger() ); - } - - @Test - public void testCreateJobScheduleRequest_NoStreamProvider() throws Exception { - String jobName = "JOB"; - - IJob job = mock( IJob.class ); - ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - Map params = new HashMap<>(); - params.put( "directory", "/home/admin" ); - params.put( "transformation", "myTransform" ); - - HashMap pdiParams = new HashMap<>(); - pdiParams.put( "pdiParam", "pdiParamValue" ); - params.put( ScheduleExportUtil.RUN_PARAMETERS_KEY, pdiParams ); - - when( job.getJobParams() ).thenReturn( params ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - assertNotNull( jobScheduleRequest ); - assertEquals( jobName, jobScheduleRequest.getJobName() ); - assertEquals( trigger, jobScheduleRequest.getSimpleJobTrigger() ); - assertEquals( "/home/admin/myTransform.ktr", jobScheduleRequest.getInputFile() ); - assertEquals( "/home/admin/myTransform*", jobScheduleRequest.getOutputFile() ); - assertEquals( "pdiParamValue", jobScheduleRequest.getPdiParameters().get( "pdiParam" ) ); - } - - @Test - public void testCreateJobScheduleRequest_StringStreamProvider() throws Exception { - String jobName = "JOB"; - - IJob job = mock( IJob.class ); - ISimpleJobTrigger trigger = mock( ISimpleJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - Map params = new HashMap<>(); - params.put( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER, "import file = /home/admin/myJob.kjb:output file=/home/admin/myJob*" ); - when( job.getJobParams() ).thenReturn( params ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - assertNotNull( jobScheduleRequest ); - assertEquals( jobName, jobScheduleRequest.getJobName() ); - assertEquals( trigger, jobScheduleRequest.getSimpleJobTrigger() ); - assertEquals( "/home/admin/myJob.kjb", jobScheduleRequest.getInputFile() ); - assertEquals( "/home/admin/myJob*", jobScheduleRequest.getOutputFile() ); - } - - @Test - public void testCreateJobScheduleRequest_ComplexJobTrigger() throws Exception { - String jobName = "JOB"; - Date now = new Date(); - - IJob job = mock( IJob.class ); - IComplexJobTrigger trigger = mock( IComplexJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - - when( trigger.getCronString() ).thenReturn( "0 30 13 ? * 2,3,4,5,6 *" ); - when( trigger.getDuration() ).thenReturn( -1L ); - when( trigger.getStartTime() ).thenReturn( now ); - when( trigger.getEndTime() ).thenReturn( now ); - when( trigger.getUiPassParam() ).thenReturn( "uiPassParm" ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - assertNotNull( jobScheduleRequest ); - assertEquals( jobName, jobScheduleRequest.getJobName() ); - - // we should be getting back a cron trigger, not a complex trigger. - assertNull( jobScheduleRequest.getSimpleJobTrigger() ); - assertNull( jobScheduleRequest.getComplexJobTrigger() ); - assertNotNull( jobScheduleRequest.getCronJobTrigger() ); - - assertEquals( trigger.getCronString(), jobScheduleRequest.getCronJobTrigger().getCronString() ); - assertEquals( trigger.getDuration(), jobScheduleRequest.getCronJobTrigger().getDuration() ); - assertEquals( trigger.getEndTime(), jobScheduleRequest.getCronJobTrigger().getEndTime() ); - assertEquals( trigger.getStartTime(), jobScheduleRequest.getCronJobTrigger().getStartTime() ); - assertEquals( trigger.getUiPassParam(), jobScheduleRequest.getCronJobTrigger().getUiPassParam() ); - } - - @Test - public void testCreateJobScheduleRequest_CronJobTrigger() throws Exception { - String jobName = "JOB"; - - IJob job = mock( IJob.class ); - ICronJobTrigger trigger = mock( ICronJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - - assertNotNull( jobScheduleRequest ); - assertEquals( jobName, jobScheduleRequest.getJobName() ); - assertEquals( trigger, jobScheduleRequest.getCronJobTrigger() ); - } - - @Test - public void testCreateJobScheduleRequest_StreamProviderJobParam() throws Exception { - String jobName = "JOB"; - String inputPath = "/input/path/to/file.ext"; - String outputPath = "/output/path/location.*"; - - Map params = new HashMap<>(); - - RepositoryFileStreamProvider streamProvider = mock( RepositoryFileStreamProvider.class ); - params.put( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER, streamProvider ); - - IJob job = mock( IJob.class ); - ICronJobTrigger trigger = mock( ICronJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - when( job.getJobParams() ).thenReturn( params ); - when( streamProvider.getInputFilePath() ).thenReturn( inputPath ); - when( streamProvider.getOutputFilePath() ).thenReturn( outputPath ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - assertEquals( inputPath, jobScheduleRequest.getInputFile() ); - assertEquals( outputPath, jobScheduleRequest.getOutputFile() ); - assertEquals( 0, jobScheduleRequest.getJobParameters().size() ); - } - - @Test - public void testCreateJobScheduleRequest_ActionClassJobParam() throws Exception { - String jobName = "JOB"; - String actionClass = "com.pentaho.Action"; - Map params = new HashMap<>(); - - params.put( IScheduler.RESERVEDMAPKEY_ACTIONCLASS, actionClass ); - - IJob job = mock( IJob.class ); - ICronJobTrigger trigger = mock( ICronJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - when( job.getJobParams() ).thenReturn( params ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - assertEquals( actionClass, jobScheduleRequest.getActionClass() ); - assertEquals( actionClass, jobScheduleRequest.getJobParameters().get( 0 ).getValue() ); - } - - @Test - public void testCreateJobScheduleRequest_TimeZoneJobParam() throws Exception { - String jobName = "JOB"; - String timeZone = "America/New_York"; - Map params = new HashMap<>(); - - params.put( IBlockoutManager.TIME_ZONE_PARAM, timeZone ); - - IJob job = mock( IJob.class ); - ICronJobTrigger trigger = mock( ICronJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - when( job.getJobParams() ).thenReturn( params ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - assertEquals( timeZone, jobScheduleRequest.getTimeZone() ); - assertEquals( timeZone, jobScheduleRequest.getJobParameters().get( 0 ).getValue() ); - } - - @Test - public void testCreateJobScheduleRequest_MultipleTypesJobParam() throws Exception { - String jobName = "JOB"; - Long l = Long.MAX_VALUE; - Date d = new Date(); - Boolean b = true; - - Map params = new HashMap<>(); - - params.put( "NumberValue", l ); - params.put( "DateValue", d ); - params.put( "BooleanValue", b ); - - IJob job = mock( IJob.class ); - ICronJobTrigger trigger = mock( ICronJobTrigger.class ); - - when( job.getJobTrigger() ).thenReturn( trigger ); - when( job.getJobName() ).thenReturn( jobName ); - when( job.getJobParams() ).thenReturn( params ); - - JobScheduleRequest jobScheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - for ( JobScheduleParam jobScheduleParam : jobScheduleRequest.getJobParameters() ) { - assertTrue( jobScheduleParam.getValue().equals( l ) - || jobScheduleParam.getValue().equals( d ) - || jobScheduleParam.getValue().equals( b ) ); - } - } - - @Test - public void testConstructor() throws Exception { - // only needed to get 100% code coverage - assertNotNull( new ScheduleExportUtil() ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java deleted file mode 100644 index 10edf01b627..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java +++ /dev/null @@ -1,712 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.importer; - -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.logging.Log; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.security.userroledao.AlreadyExistsException; -import org.pentaho.platform.api.engine.security.userroledao.IUserRoleDao; -import org.pentaho.platform.api.mimetype.IMimeType; -import org.pentaho.platform.api.mimetype.IPlatformMimeResolver; -import org.pentaho.platform.api.mt.ITenant; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.usersettings.IAnyUserSettingService; -import org.pentaho.platform.api.usersettings.IUserSettingService; -import org.pentaho.platform.api.usersettings.pojo.IUserSetting; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; -import org.pentaho.platform.plugin.services.importexport.ImportSession; -import org.pentaho.platform.plugin.services.importexport.ImportSession.ManifestFile; -import org.pentaho.platform.plugin.services.importexport.ImportSource.IRepositoryFileBundle; -import org.pentaho.platform.plugin.services.importexport.RepositoryFileBundle; -import org.pentaho.platform.plugin.services.importexport.RoleExport; -import org.pentaho.platform.plugin.services.importexport.UserExport; -import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetaStore; -import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.resources.SchedulerResource; - -import javax.ws.rs.core.Response; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.argThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.nullable; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - - -public class SolutionImportHandlerTest { - - private SolutionImportHandler importHandler; - - private IUserRoleDao userRoleDao; - private IUnifiedRepository repository; - private IRoleAuthorizationPolicyRoleBindingDao roleAuthorizationPolicyRoleBindingDao; - private IPlatformMimeResolver mockMimeResolver; - - @Before - public void setUp() throws Exception { - userRoleDao = mockToPentahoSystem( IUserRoleDao.class ); - repository = mockToPentahoSystem( IUnifiedRepository.class ); - roleAuthorizationPolicyRoleBindingDao = mockToPentahoSystem( IRoleAuthorizationPolicyRoleBindingDao.class ); - - List mimeTypes = new ArrayList<>(); - try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ) ) { - mockMimeResolver = mock( IPlatformMimeResolver.class ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( IPlatformMimeResolver.class ) ) - .thenReturn( mockMimeResolver ); - importHandler = spy( new SolutionImportHandler( mimeTypes ) ); - } - - when( importHandler.getImportSession() ).thenReturn( mock( ImportSession.class ) ); - when( importHandler.getLogger() ).thenReturn( mock( Log.class ) ); - } - - private T mockToPentahoSystem( Class cl ) { - T t = mock( cl ); - PentahoSystem.registerObject( t ); - return t; - } - - @Test - public void testImportUsers_oneUserManyRoles() { - List users = new ArrayList<>(); - UserExport user = new UserExport(); - user.setUsername( "scrum master" ); - user.setRole( "coder" ); - user.setRole( "product owner" ); - user.setRole( "cat herder" ); - user.setPassword( "password" ); - users.add( user ); - - Map> rolesToUsers = importHandler.importUsers( users ); - - Assert.assertEquals( 3, rolesToUsers.size() ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "product owner" ).get( 0 ) ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "cat herder" ).get( 0 ) ); - - String[] strings = {}; - - verify( userRoleDao ).createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ); - - // should not set the password or roles explicitly if the createUser worked - verify( userRoleDao, never() ) - .setUserRoles( any( ITenant.class ), nullable( String.class ), any( strings.getClass() ) ); - verify( userRoleDao, never() ) - .setPassword( any( ITenant.class ), nullable( String.class ), nullable( String.class ) ); - } - - @Test - public void testImportUsers_manyUserManyRoles() { - List users = new ArrayList<>(); - UserExport user = new UserExport(); - user.setUsername( "scrum master" ); - user.setRole( "coder" ); - user.setRole( "product owner" ); - user.setRole( "cat herder" ); - user.setPassword( "password" ); - users.add( user ); - - UserExport user2 = new UserExport(); - user2.setUsername( "the dude" ); - user2.setRole( "coder" ); - user2.setRole( "awesome" ); - user2.setPassword( "password" ); - users.add( user2 ); - - Map> rolesToUsers = importHandler.importUsers( users ); - - Assert.assertEquals( 4, rolesToUsers.size() ); - Assert.assertEquals( 2, rolesToUsers.get( "coder" ).size() ); - Assert.assertEquals( 1, rolesToUsers.get( "product owner" ).size() ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "product owner" ).get( 0 ) ); - Assert.assertEquals( 1, rolesToUsers.get( "cat herder" ).size() ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "cat herder" ).get( 0 ) ); - Assert.assertEquals( 1, rolesToUsers.get( "awesome" ).size() ); - Assert.assertEquals( "the dude", rolesToUsers.get( "awesome" ).get( 0 ) ); - - String[] strings = {}; - - verify( userRoleDao ).createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ); - - verify( userRoleDao ).createUser( - any( ITenant.class ), - eq( "the dude" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ); - - // should not set the password or roles explicitly if the createUser worked - verify( userRoleDao, never() ) - .setUserRoles( any( ITenant.class ), nullable( String.class ), any( strings.getClass() ) ); - verify( userRoleDao, never() ) - .setPassword( any( ITenant.class ), nullable( String.class ), nullable( String.class ) ); - } - - @Test - public void testImportUsers_userAlreadyExists() { - List users = new ArrayList<>(); - UserExport user = new UserExport(); - user.setUsername( "scrum master" ); - user.setRole( "coder" ); - user.setPassword( "password" ); - users.add( user ); - String[] strings = {}; - - when( userRoleDao.createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ) ).thenThrow( new AlreadyExistsException( "already there" ) ); - - importHandler.setOverwriteFile( true ); - Map> rolesToUsers = importHandler.importUsers( users ); - - Assert.assertEquals( 1, rolesToUsers.size() ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); - - verify( userRoleDao ).createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ); - - // should set the password or roles explicitly if the createUser failed - verify( userRoleDao ) - .setUserRoles( any( ITenant.class ), nullable( String.class ), any( strings.getClass() ) ); - verify( userRoleDao ).setPassword( any( ITenant.class ), nullable( String.class ), nullable( String.class ) ); - } - - @Test - public void testImportUsers_userAlreadyExists_overwriteFalse() { - List users = new ArrayList<>(); - UserExport user = new UserExport(); - user.setUsername( "scrum master" ); - user.setRole( "coder" ); - user.setPassword( "password" ); - users.add( user ); - String[] strings = {}; - - when( userRoleDao.createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ) ).thenThrow( new AlreadyExistsException( "already there" ) ); - - importHandler.setOverwriteFile( false ); - Map> rolesToUsers = importHandler.importUsers( users ); - - Assert.assertEquals( 1, rolesToUsers.size() ); - Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); - - verify( userRoleDao ).createUser( - any( ITenant.class ), - eq( "scrum master" ), - nullable( String.class ), - nullable( String.class ), - any( strings.getClass() ) ); - - // should set the password or roles explicitly if the createUser failed - verify( userRoleDao, never() ) - .setUserRoles( any( ITenant.class ), nullable( String.class ), any( strings.getClass() ) ); - verify( userRoleDao, never() ) - .setPassword( any( ITenant.class ), nullable( String.class ), nullable( String.class ) ); - } - - @Test - public void testImportRoles() { - String roleName = "ADMIN"; - List permissions = new ArrayList<>(); - - RoleExport role = new RoleExport(); - role.setRolename( roleName ); - role.setPermission( permissions ); - - List roles = new ArrayList<>(); - roles.add( role ); - - Map> roleToUserMap = new HashMap<>(); - final List adminUsers = new ArrayList<>(); - adminUsers.add( "admin" ); - adminUsers.add( "root" ); - roleToUserMap.put( roleName, adminUsers ); - - String[] userStrings = adminUsers.toArray( new String[] {} ); - - importHandler.importRoles( roles, roleToUserMap ); - - verify( userRoleDao ).createRole( any( ITenant.class ), eq( roleName ), nullable( String.class ), - any( userStrings.getClass() ) ); - verify( roleAuthorizationPolicyRoleBindingDao ) - .setRoleBindings( any( ITenant.class ), eq( roleName ), - eq( permissions ) ); - } - - @Test - public void testImportRoles_roleAlreadyExists() { - String roleName = "ADMIN"; - List permissions = new ArrayList<>(); - - RoleExport role = new RoleExport(); - role.setRolename( roleName ); - role.setPermission( permissions ); - - List roles = new ArrayList<>(); - roles.add( role ); - - Map> roleToUserMap = new HashMap<>(); - final List adminUsers = new ArrayList<>(); - adminUsers.add( "admin" ); - adminUsers.add( "root" ); - roleToUserMap.put( roleName, adminUsers ); - - String[] userStrings = adminUsers.toArray( new String[] {} ); - - when( userRoleDao.createRole( any( ITenant.class ), nullable( String.class ), nullable( String.class ), - any( userStrings.getClass() ) ) ) - .thenThrow( new AlreadyExistsException( "already there" ) ); - - importHandler.setOverwriteFile( true ); - importHandler.importRoles( roles, roleToUserMap ); - - verify( userRoleDao ).createRole( any( ITenant.class ), nullable( String.class ), nullable( String.class ), - any( userStrings.getClass() ) ); - - // even if the roles exists, make sure we set the permissions on it Mockito.anyway... they might have changed - verify( roleAuthorizationPolicyRoleBindingDao ) - .setRoleBindings( any( ITenant.class ), eq( roleName ), eq( - permissions ) ); - - } - - @Test - public void testImportRoles_roleAlreadyExists_overwriteFalse() { - String roleName = "ADMIN"; - List permissions = new ArrayList<>(); - - RoleExport role = new RoleExport(); - role.setRolename( roleName ); - role.setPermission( permissions ); - - List roles = new ArrayList<>(); - roles.add( role ); - - Map> roleToUserMap = new HashMap<>(); - final List adminUsers = new ArrayList<>(); - adminUsers.add( "admin" ); - adminUsers.add( "root" ); - roleToUserMap.put( roleName, adminUsers ); - - String[] userStrings = adminUsers.toArray( new String[] {} ); - - when( userRoleDao.createRole( any( ITenant.class ), nullable( String.class ), nullable( String.class ), - any( userStrings.getClass() ) ) ) - .thenThrow( new AlreadyExistsException( "already there" ) ); - - importHandler.setOverwriteFile( false ); - importHandler.importRoles( roles, roleToUserMap ); - - verify( userRoleDao ).createRole( any( ITenant.class ), nullable( String.class ), nullable( String.class ), - any( userStrings.getClass() ) ); - - // even if the roles exists, make sure we set the permissions on it Mockito.anyway... they might have changed - verify( roleAuthorizationPolicyRoleBindingDao, never() ) - .setRoleBindings( any( ITenant.class ), eq( roleName ), eq( - permissions ) ); - - } - - @Test - public void testImportMetaStore() { - String path = "/path/to/file.zip"; - ExportManifestMetaStore manifestMetaStore = new ExportManifestMetaStore( path, - "metastore", - "description of the metastore" ); - importHandler.cachedImports = new HashMap<>(); - - importHandler.importMetaStore( manifestMetaStore, true ); - Assert.assertEquals( 1, importHandler.cachedImports.size() ); - Assert.assertNotNull( importHandler.cachedImports.get( path ) ); - } - - @Test - public void testImportMetaStore_nullMetastoreManifest() { - ExportManifest manifest = spy( new ExportManifest() ); - - importHandler.cachedImports = new HashMap<>(); - importHandler.importMetaStore( manifest.getMetaStore(), true ); - Assert.assertEquals( 0, importHandler.cachedImports.size() ); - } - - @Test - public void testImportUserSettings() throws Exception { - UserExport user = new UserExport(); - user.setUsername( "pentaho" ); - user.addUserSetting( new ExportManifestUserSetting( "theme", "crystal" ) ); - user.addUserSetting( new ExportManifestUserSetting( "language", "en_US" ) ); - IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); - PentahoSystem.registerObject( userSettingService ); - importHandler.setOverwriteFile( true ); - - importHandler.importUserSettings( user ); - verify( userSettingService ).setUserSetting( "pentaho", "theme", "crystal" ); - verify( userSettingService ).setUserSetting( "pentaho", "language", "en_US" ); - } - - @Test - public void testImportUserSettings_NoOverwrite() { - UserExport user = new UserExport(); - user.setUsername( "pentaho" ); - user.addUserSetting( new ExportManifestUserSetting( "theme", "crystal" ) ); - user.addUserSetting( new ExportManifestUserSetting( "language", "en_US" ) ); - IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); - PentahoSystem.registerObject( userSettingService ); - importHandler.setOverwriteFile( false ); - - IUserSetting existingSetting = mock( IUserSetting.class ); - when( userSettingService.getUserSetting( "pentaho", "theme", null ) ).thenReturn( existingSetting ); - when( userSettingService.getUserSetting( "pentaho", "language", null ) ).thenReturn( null ); - - importHandler.importUserSettings( user ); - verify( userSettingService, never() ).setUserSetting( "pentaho", "theme", "crystal" ); - verify( userSettingService ).setUserSetting( "pentaho", "language", "en_US" ); - verify( userSettingService ).getUserSetting( "pentaho", "theme", null ); - verify( userSettingService ).getUserSetting( "pentaho", "language", null ); - } - - @Test - public void testImportGlobalUserSetting() { - importHandler.setOverwriteFile( true ); - List settings = new ArrayList<>(); - settings.add( new ExportManifestUserSetting( "language", "en_US" ) ); - settings.add( new ExportManifestUserSetting( "showHiddenFiles", "false" ) ); - IUserSettingService userSettingService = mock( IUserSettingService.class ); - PentahoSystem.registerObject( userSettingService ); - - importHandler.importGlobalUserSettings( settings ); - - verify( userSettingService ).setGlobalUserSetting( "language", "en_US" ); - verify( userSettingService ).setGlobalUserSetting( "showHiddenFiles", "false" ); - verify( userSettingService, never() ) - .getGlobalUserSetting( nullable( String.class ), nullable( String.class ) ); - } - - @Test - public void testImportGlobalUserSetting_noOverwrite() { - importHandler.setOverwriteFile( false ); - List settings = new ArrayList<>(); - settings.add( new ExportManifestUserSetting( "language", "en_US" ) ); - settings.add( new ExportManifestUserSetting( "showHiddenFiles", "false" ) ); - IUserSettingService userSettingService = mock( IUserSettingService.class ); - PentahoSystem.registerObject( userSettingService ); - IUserSetting setting = mock( IUserSetting.class ); - when( userSettingService.getGlobalUserSetting( "language", null ) ).thenReturn( null ); - when( userSettingService.getGlobalUserSetting( "showHiddenFiles", null ) ).thenReturn( setting ); - - importHandler.importGlobalUserSettings( settings ); - - verify( userSettingService ).setGlobalUserSetting( "language", "en_US" ); - verify( userSettingService, never() ) - .setGlobalUserSetting( eq( "showHiddenFiles" ), nullable( String.class ) ); - verify( userSettingService ).getGlobalUserSetting( "language", null ); - verify( userSettingService ).getGlobalUserSetting( "showHiddenFiles", null ); - - } - - @Test - public void testImportSchedules() throws Exception { - List schedules = new ArrayList<>(); - JobScheduleRequest scheduleRequest = spy( new JobScheduleRequest() ); - schedules.add( scheduleRequest ); - - Response response = mock( Response.class ); - when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); - when( response.getEntity() ).thenReturn( "job id" ); - - doReturn( response ).when( importHandler ) - .createSchedulerJob( any( SchedulerResource.class ), eq( scheduleRequest ) ); - - try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); - MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { - IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); - IScheduler iSchedulerMock = mock( IScheduler.class ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IAuthorizationPolicy.class ) ) ) - .thenReturn( iAuthorizationPolicyMock ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IScheduler.class ), anyString(), eq( null ) ) ) - .thenReturn( iSchedulerMock ); - when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); - pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) - .thenReturn( mock( IPentahoSession.class ) ); - - importHandler.importSchedules( schedules ); - - verify( importHandler ) - .createSchedulerJob( any( SchedulerResource.class ), eq( scheduleRequest ) ); - Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); - } - } - - @Test - public void testImportSchedules_FailsToCreateSchedule() throws Exception { - List schedules = new ArrayList<>(); - JobScheduleRequest scheduleRequest = spy( new JobScheduleRequest() ); - scheduleRequest.setInputFile( "/home/admin/scheduledTransform.ktr" ); - scheduleRequest.setOutputFile( "/home/admin/scheduledTransform*" ); - schedules.add( scheduleRequest ); - - doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( - any( SchedulerResource.class ), eq( scheduleRequest ) ); - - try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); - MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { - IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); - IScheduler iSchedulerMock = mock( IScheduler.class ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IAuthorizationPolicy.class ) ) ) - .thenReturn( iAuthorizationPolicyMock ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IScheduler.class ), anyString(), eq( null ) ) ) - .thenReturn( iSchedulerMock ); - when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); - pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) - .thenReturn( mock( IPentahoSession.class ) ); - - importHandler.importSchedules( schedules ); - Assert.assertEquals( 0, ImportSession.getSession().getImportedScheduleJobIds().size() ); - } - } - - @Test - public void testImportSchedules_FailsToCreateScheduleWithSpace() throws Exception { - List schedules = new ArrayList<>(); - JobScheduleRequest scheduleRequest = spy( new JobScheduleRequest() ); - scheduleRequest.setInputFile( "/home/admin/scheduled Transform.ktr" ); - scheduleRequest.setOutputFile( "/home/admin/scheduled Transform*" ); - schedules.add( scheduleRequest ); - - ScheduleRequestMatcher throwMatcher = - new ScheduleRequestMatcher( "/home/admin/scheduled Transform.ktr", "/home/admin/scheduled Transform*" ); - doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( - any( SchedulerResource.class ), argThat( throwMatcher ) ); - - Response response = mock( Response.class ); - when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); - when( response.getEntity() ).thenReturn( "job id" ); - ScheduleRequestMatcher goodMatcher = - new ScheduleRequestMatcher( "/home/admin/scheduled_Transform.ktr", "/home/admin/scheduled_Transform*" ); - doReturn( response ).when( importHandler ).createSchedulerJob( any( SchedulerResource.class ), - argThat( goodMatcher ) ); - - try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); - MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { - IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); - IScheduler iSchedulerMock = mock( IScheduler.class ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IAuthorizationPolicy.class ) ) ).thenReturn( iAuthorizationPolicyMock ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IScheduler.class ), anyString(), eq( null ) ) ) - .thenReturn( iSchedulerMock ); - when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); - pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ).thenReturn( mock( IPentahoSession.class ) ); - importHandler.importSchedules( schedules ); - verify( importHandler, times( 2 ) ).createSchedulerJob( - any( SchedulerResource.class ), any( JobScheduleRequest.class ) ); - Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); - } - } - - @Test - public void testImportSchedules_FailsToCreateScheduleWithSpaceOnWindows() throws Exception { - String sep = File.separator; - System.setProperty( "file.separator", "\\" ); - List schedules = new ArrayList<>(); - JobScheduleRequest scheduleRequest = spy( new JobScheduleRequest() ); - scheduleRequest.setInputFile( "/home/admin/scheduled Transform.ktr" ); - scheduleRequest.setOutputFile( "/home/admin/scheduled Transform*" ); - schedules.add( scheduleRequest ); - - ScheduleRequestMatcher throwMatcher = - new ScheduleRequestMatcher( "/home/admin/scheduled Transform.ktr", "/home/admin/scheduled Transform*" ); - doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( - nullable( SchedulerResource.class ), argThat( throwMatcher ) ); - - Response response = mock( Response.class ); - when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); - when( response.getEntity() ).thenReturn( "job id" ); - ScheduleRequestMatcher goodMatcher = - new ScheduleRequestMatcher( "/home/admin/scheduled_Transform.ktr", "/home/admin/scheduled_Transform*" ); - doReturn( response ).when( importHandler ).createSchedulerJob( nullable( SchedulerResource.class ), - argThat( goodMatcher ) ); - - try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); - MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { - IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); - IScheduler iSchedulerMock = mock( IScheduler.class ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IAuthorizationPolicy.class ) ) ) - .thenReturn( iAuthorizationPolicyMock ); - pentahoSystemMockedStatic.when( () -> PentahoSystem.get( eq( IScheduler.class ), anyString(), eq( null ) ) ) - .thenReturn( iSchedulerMock ); - when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); - pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) - .thenReturn( mock( IPentahoSession.class ) ); - - importHandler.importSchedules( schedules ); - verify( importHandler, times( 2 ) ) - .createSchedulerJob( nullable( SchedulerResource.class ), nullable( JobScheduleRequest.class ) ); - Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); - System.setProperty( "file.separator", sep ); - } - } - - private static class ScheduleRequestMatcher implements ArgumentMatcher { - private final String input; - private final String output; - - public ScheduleRequestMatcher( String input, String output ) { - this.input = input; - this.output = output; - } - - @Override public boolean matches( JobScheduleRequest jsr ) { - boolean matchedInput = input.equals( FilenameUtils.separatorsToUnix( jsr.getInputFile() ) ); - boolean matchedOutput = output.equals( FilenameUtils.separatorsToUnix( jsr.getOutputFile() ) ); - return matchedInput && matchedOutput; - } - } - - @Test - public void testGetFile() { - RepositoryFileImportBundle importBundle = new RepositoryFileImportBundle(); - importBundle.setPath( "/BASE_PATH/" ); - - RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).build(); - IRepositoryFileBundle fileBundle = new RepositoryFileBundle( repoFile, null, "parentDir", null, "UTF-8", null ); - fileBundle.setPath( "SUB_PATH/" ); - - RepositoryFile expectedFile = new RepositoryFile.Builder( "EXPECTED_FILE" ).build(); - when( repository.getFile( "/BASE_PATH/SUB_PATH/FILE_NAME" ) ).thenReturn( expectedFile ); - } - - @Test - public void testIsFileHidden() { - IMimeType hiddenMime = mock( IMimeType.class ); - IMimeType visibleMime = mock( IMimeType.class ); - when( hiddenMime.isHidden() ).thenReturn( true ); - when( visibleMime.isHidden() ).thenReturn( false ); - ManifestFile manifestFile = mock( ManifestFile.class ); - RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).hidden( true ).build(); - - when( manifestFile.isFileHidden() ).thenReturn( true ); - Assert.assertTrue( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); - - when( manifestFile.isFileHidden() ).thenReturn( false ); - Assert.assertFalse( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); - - when( manifestFile.isFileHidden() ).thenReturn( null ); - Assert.assertTrue( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); - - repoFile = new RepositoryFile.Builder( "FILE_NAME" ).hidden( false ).build(); - Assert.assertFalse( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); - - when( mockMimeResolver.resolveMimeTypeForFileName( "SOURCE_PATH" ) ).thenReturn( hiddenMime ); - Assert.assertTrue( importHandler.isFileHidden( null, manifestFile, "SOURCE_PATH" ) ); - - when( mockMimeResolver.resolveMimeTypeForFileName( "SOURCE_PATH" ) ).thenReturn( visibleMime ); - Assert.assertEquals( RepositoryFile.HIDDEN_BY_DEFAULT, importHandler.isFileHidden( null, manifestFile, "SOURCE_PATH" ) ); - } - - @Test - public void testIsSchedulable() { - ManifestFile manifestFile = mock( ManifestFile.class ); - RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).schedulable( true ).build(); - - when( manifestFile.isFileSchedulable() ).thenReturn( true ); - Assert.assertTrue( importHandler.isSchedulable( repoFile, manifestFile ) ); - - when( manifestFile.isFileSchedulable() ).thenReturn( false ); - Assert.assertFalse( importHandler.isSchedulable( repoFile, manifestFile ) ); - - when( manifestFile.isFileSchedulable() ).thenReturn( null ); - Assert.assertTrue( importHandler.isSchedulable( repoFile, manifestFile ) ); - - Assert.assertEquals( RepositoryFile.SCHEDULABLE_BY_DEFAULT, importHandler.isSchedulable( null, manifestFile ) ); - } - - @Test - public void testFileIsScheduleInputSource() { - ExportManifest manifest = mock( ExportManifest.class ); - List scheduleRequests = new ArrayList<>(); - for ( int i = 0; i < 10; i++ ) { - JobScheduleRequest jobScheduleRequest = new JobScheduleRequest(); - jobScheduleRequest.setInputFile( "/public/test/file" + i ); - scheduleRequests.add( jobScheduleRequest ); - } - Assert.assertFalse( importHandler.fileIsScheduleInputSource( manifest, null ) ); - - when( manifest.getScheduleList() ).thenReturn( scheduleRequests ); - - Assert.assertFalse( importHandler.fileIsScheduleInputSource( manifest, "/public/file" ) ); - Assert.assertTrue( importHandler.fileIsScheduleInputSource( manifest, "/public/test/file3" ) ); - Assert.assertTrue( importHandler.fileIsScheduleInputSource( manifest, "public/test/file3" ) ); - } - @After - public void tearDown() throws Exception { - ImportSession.getSession().getImportedScheduleJobIds().clear(); - PentahoSystem.clearObjectFactory(); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java deleted file mode 100644 index a2c9f8a03c5..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestTest.java +++ /dev/null @@ -1,431 +0,0 @@ -/*! - * - * 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-2020 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.importexport.exportManifest; - -import junit.framework.TestCase; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.repository2.unified.RepositoryFileAce; -import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl; -import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; -import org.pentaho.platform.api.repository2.unified.RepositoryFileSid; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; -import org.pentaho.platform.plugin.services.importexport.UserExport; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseAccessType; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseConnection; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseType; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestDto; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetadata; -import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; - -import javax.xml.bind.JAXBException; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; - -public class ExportManifestTest extends TestCase { - private ExportManifest exportManifest; - - public ExportManifestTest() { - String rootFolder = "/dir1/"; - exportManifest = new ExportManifest(); - ExportManifestDto.ExportManifestInformation exportManifestInformation = exportManifest.getManifestInformation(); - exportManifestInformation.setExportBy( "MickeyMouse" ); - exportManifestInformation.setExportDate( "2013-01-01" ); - exportManifestInformation.setRootFolder( rootFolder ); - - List aces1 = new ArrayList<>(); - aces1.add( createMockAce( "admin-/pentaho/tenant0", "USER", RepositoryFilePermission.READ, - RepositoryFilePermission.WRITE ) ); - aces1.add( createMockAce( "TenantAdmin-/pentaho/tenant0", "ROLE", RepositoryFilePermission.READ ) ); - RepositoryFile repoDir2 = createMockRepositoryFile( "/dir1/dir2", true ); - RepositoryFileAcl repoDir2Acl = createMockRepositoryAcl( "acl2", "admin", false, aces1 ); - RepositoryFile repoFile3 = createMockRepositoryFile( "/dir1/dir2/file1", false ); - RepositoryFile badRepoFile = createMockRepositoryFile( "/baddir/dir2/file1", false ); - - try { - exportManifest.add( repoDir2, repoDir2Acl ); - exportManifest.add( repoFile3, null ); - } catch ( Exception e ) { - fail( e.toString() ); - } - - try { - exportManifest.add( badRepoFile, null ); - fail( "Bad path did not generate a ExportManifestFormatException" ); - } catch ( ExportManifestFormatException e ) { - //ignored - } - - ExportManifestEntity entity2 = exportManifest.getExportManifestEntity( "dir2" ); - assertNotNull( entity2 ); - ExportManifestEntity entity3 = exportManifest.getExportManifestEntity( "dir2/file1" ); - assertNotNull( entity3 ); - - // Mondrian - ExportManifestMondrian mondrian = new ExportManifestMondrian(); - mondrian.setCatalogName( "cat1" ); - mondrian.setParameters( new Parameters() { - { - put( "testKey", "testValue" ); - } - } ); - mondrian.setFile( "testMondrian.xml" ); - exportManifest.addMondrian( mondrian ); - - // Metadata - ExportManifestMetadata metadata = new ExportManifestMetadata(); - metadata.setDomainId( "testDomain" ); - metadata.setFile( "testMetadata.xml" ); - exportManifest.addMetadata( metadata ); - - // JobScheduleRequest - JobScheduleRequest jobScheduleRequest = new JobScheduleRequest(); - HashMap pdiParameters = new HashMap<>(); - pdiParameters.put( "parm1", "val1" ); - jobScheduleRequest.setPdiParameters( pdiParameters ); - jobScheduleRequest.setJobName( "jobName" ); - jobScheduleRequest.setJobState( IJob.JobState.UNKNOWN ); - jobScheduleRequest.setActionClass( "actionClass" ); - jobScheduleRequest.setDuration( 3600 ); - jobScheduleRequest.setTimeZone( "someTimeZone" ); - jobScheduleRequest.setJobId( "jobId" ); - exportManifest.addSchedule( jobScheduleRequest ); - - // Datasource - DatabaseConnection connection = new DatabaseConnection(); - connection.setAccessType( DatabaseAccessType.NATIVE ); - connection.setDatabaseName( "SampleData" ); - connection.setDatabasePort( "9001" ); - DatabaseType type = new DatabaseType(); - type.setName( "Hypersonic" ); - type.setShortName( "HYPERSONIC" ); - type.setDefaultDatabaseName( "defaultDatabaseName" ); - type.setDefaultDatabasePort( 8888 ); - type.setExtraOptionsHelpUrl( "extraOptionsHelpUrl" ); - DatabaseType.DefaultOptions defaultOptions = new DatabaseType.DefaultOptions(); - DatabaseType.DefaultOptions.Entry e = new DatabaseType.DefaultOptions.Entry(); - e.setKey( "someKey" ); - e.setValue( "someValue" ); - defaultOptions.getEntry().add( e ); - type.setDefaultOptions( defaultOptions ); - connection.setDatabaseType( type ); - connection.setHostname( "localhost" ); - connection.setUsername( "pentaho_user" ); - connection.setPassword( null ); - connection.setMaximumPoolSize( 20 ); - - exportManifest.addDatasource( connection ); - - // UserExport - UserExport user = new UserExport(); - user.setUsername( "pentaho" ); - user.setRole( "open source champion" ); - user.setPassword( "123456" ); - user.addUserSetting( new ExportManifestUserSetting( "theme", "crystal" ) ); - user.addUserSetting( new ExportManifestUserSetting( "language", "en_US" ) ); - exportManifest.addUserExport( user ); - exportManifest.addGlobalUserSetting( new ExportManifestUserSetting( "viewHiddenFiles", "false" ) ); - } - - public void testEntityAccess() { - ExportManifestEntity entityR1 = exportManifest.getExportManifestEntity( "dir2" ); - assertNotNull( entityR1 ); - assertEquals( "Path value", "dir2", entityR1.getPath() ); - } - - public void testMarshal() { - try { - exportManifest.toXml( System.out ); - } catch ( Exception e ) { - fail( "Could not marshal to XML " + e ); - } - } - - public void testUnMarshal() { - String xml = XmlToString(); - ExportManifest importManifest = null; - ByteArrayInputStream input = new ByteArrayInputStream( xml.getBytes() ); - try { - importManifest = ExportManifest.fromXml( input ); - } catch ( JAXBException e ) { - fail( "Could not un-marshal to object " + e ); - } - ExportManifestEntity fileEntity = importManifest.getExportManifestEntity( "dir2/file1" ); - assertNotNull( fileEntity ); - assertEquals( "dir2/file1", fileEntity.getPath() ); - assertNotNull( fileEntity.getEntityMetaData() ); - assertFalse( fileEntity.getEntityMetaData().isIsFolder() ); - - fileEntity = importManifest.getExportManifestEntity( "dir2" ); - assertNotNull( fileEntity ); - assertNotNull( fileEntity.getEntityMetaData() ); - assertTrue( fileEntity.getEntityMetaData().isIsFolder() ); - - RepositoryFile r = fileEntity.getRepositoryFile(); - assertEquals( "dir2", r.getPath() ); - assertTrue( r.isFolder() ); - - try { - RepositoryFileAcl rfa = fileEntity.getRepositoryFileAcl(); - assertNotNull( rfa.getAces() ); - } catch ( ExportManifestFormatException e ) { - e.printStackTrace(); - fail( "Could not un-marshal to RepositoryFileAcl" ); - } - - // JobScheduleRequest - assertNotNull( importManifest.getScheduleList() ); - assertEquals( 1, importManifest.getScheduleList().size() ); - JobScheduleRequest jobScheduleRequest = importManifest.getScheduleList().get( 0 ); - assertNotNull( jobScheduleRequest ); - assertNotNull( jobScheduleRequest.getPdiParameters() ); - assertEquals( 1, jobScheduleRequest.getPdiParameters().size() ); - assertEquals( "val1", jobScheduleRequest.getPdiParameters().get( "parm1" ) ); - assertEquals( "jobName", jobScheduleRequest.getJobName() ); - assertEquals( IJob.JobState.UNKNOWN, jobScheduleRequest.getJobState() ); - assertEquals( "actionClass", jobScheduleRequest.getActionClass() ); - assertEquals( 3600, jobScheduleRequest.getDuration() ); - assertEquals( "someTimeZone", jobScheduleRequest.getTimeZone() ); - assertEquals( "jobId", jobScheduleRequest.getJobId() ); - - // Mondrian - assertNotNull( importManifest.getMondrianList() ); - assertEquals( 1, importManifest.getMondrianList().size() ); - ExportManifestMondrian mondrian1 = importManifest.getMondrianList().get( 0 ); - assertNotNull( mondrian1 ); - assertEquals( "cat1", mondrian1.getCatalogName() ); - assertTrue( mondrian1.getParameters().containsKey( "testKey" ) ); - assertEquals( "testValue", mondrian1.getParameters().get( "testKey" ) ); - assertEquals( "testMondrian.xml", mondrian1.getFile() ); - - // Metadata - assertNotNull( importManifest.getMetadataList() ); - assertEquals( 1, importManifest.getMetadataList().size() ); - ExportManifestMetadata metadata1 = importManifest.getMetadataList().get( 0 ); - assertNotNull( metadata1 ); - assertEquals( "testDomain", metadata1.getDomainId() ); - assertEquals( "testMetadata.xml", metadata1.getFile() ); - - // Datasource - assertNotNull( importManifest.getDatasourceList() ); - assertEquals( 1, importManifest.getDatasourceList().size() ); - DatabaseConnection connection = importManifest.getDatasourceList().get( 0 ); - assertNotNull( connection ); - assertEquals( "SampleData", connection.getDatabaseName() ); - assertEquals( "9001", connection.getDatabasePort() ); - assertEquals( "Hypersonic", connection.getDatabaseType().getName() ); - assertEquals( "HYPERSONIC", connection.getDatabaseType().getShortName() ); - assertEquals( "defaultDatabaseName", connection.getDatabaseType().getDefaultDatabaseName() ); - assertEquals( 8888, connection.getDatabaseType().getDefaultDatabasePort() ); - assertEquals( "extraOptionsHelpUrl", connection.getDatabaseType().getExtraOptionsHelpUrl() ); - assertNotNull( connection.getDatabaseType().getDefaultOptions() ); - assertNotNull( connection.getDatabaseType().getDefaultOptions().getEntry() ); - assertEquals( 1, connection.getDatabaseType().getDefaultOptions().getEntry().size() ); - assertNotNull( connection.getDatabaseType().getDefaultOptions().getEntry().get( 0 ) ); - assertEquals( "someKey", connection.getDatabaseType().getDefaultOptions().getEntry().get( 0 ).getKey() ); - assertEquals( "someValue", connection.getDatabaseType().getDefaultOptions().getEntry().get( 0 ).getValue() ); - assertEquals( "localhost", connection.getHostname() ); - assertEquals( "pentaho_user", connection.getUsername() ); - assertEquals( 20, connection.getMaximumPoolSize() ); - - // UserExport - assertNotNull( importManifest.getUserExports() ); - assertEquals( 1, importManifest.getUserExports().size() ); - UserExport userExport = importManifest.getUserExports().get( 0 ); - assertNotNull( userExport ); - assertEquals( "pentaho", userExport.getUsername() ); - assertEquals( "123456", userExport.getPassword() ); - List userRoles = userExport.getRoles(); - assertNotNull( userRoles ); - assertEquals( 1, userRoles.size() ); - assertEquals( "open source champion", userRoles.get( 0 ) ); - assertNotNull( userExport.getUserSettings() ); - assertEquals( 2, userExport.getUserSettings().size() ); - List userSettings = userExport.getUserSettings(); - assertEquals( 2, userSettings.size() ); - userSettings.stream().filter( exportManifestUserSetting -> "theme".equals( exportManifestUserSetting.getName() ) ) - .forEach( exportManifestUserSetting -> assertEquals( "crystal", exportManifestUserSetting.getValue() ) ); - userSettings.stream() - .filter( exportManifestUserSetting -> "language".equals( exportManifestUserSetting.getName() ) ) - .forEach( exportManifestUserSetting -> assertEquals( "en_US", exportManifestUserSetting.getValue() ) ); - } - - public void testXmlToString() { - String s = XmlToString(); - assertNotNull( s ); - } - - private String XmlToString() { - String s = null; - try { - s = exportManifest.toXmlString(); - } catch ( JAXBException e ) { - e.printStackTrace(); - fail( "Could not marshal to XML to string " + e ); - } - return s; - } - - private RepositoryFile createMockRepositoryFile( String path, boolean isFolder ) { - Date createdDate = new Date(); - Date lastModeDate = new Date(); - Date lockDate = new Date(); - Date deletedDate = new Date(); - String baseName = path.substring( path.lastIndexOf( "/" ) + 1 ); - return - new RepositoryFile( "12345", baseName, isFolder, false, false, false, "versionId", path, createdDate, - lastModeDate, - false, "lockOwner", "lockMessage", lockDate, "en_US", "title", "description", - "/original/parent/folder/path", deletedDate, 4096, "creatorId", null ); - } - - public void testToXml_XmlUnsafeManifestParameters() { - final String keyFirst = "DataSource"; - final String keySecond = "DynamicSchemaProcessor"; - final String valueFirst = "\"DS \"Test's\" & \""; - final String valueSecond = "\"DSP's & \"Other\" \""; - - ExportManifestMondrian mondrian = new ExportManifestMondrian(); - Parameters mondrianParameters = new Parameters(); - - mondrianParameters.put( keyFirst, valueFirst ); - mondrianParameters.put( keySecond, valueSecond ); - mondrian.setParameters( mondrianParameters ); - mondrian.setCatalogName( "mondrian" ); - mondrian.setXmlaEnabled( false ); - - exportManifest.addMondrian( mondrian ); - try ( ByteArrayOutputStream out = new ByteArrayOutputStream() ) { - try { - exportManifest.toXml( out ); - } catch ( Exception e ) { - fail( "Could not marshal to XML " + e ); - } - try ( ByteArrayInputStream inputStream = new ByteArrayInputStream( out.toByteArray() ) ) { - ExportManifest ex = null; - try { - ex = ExportManifest.fromXml( inputStream ); - } catch ( Exception e ) { - fail( "Could not un-marshal from XML " + e ); - } - List catalogs = ex.getMondrianList(); - assertNotNull( catalogs ); - assertFalse( catalogs.isEmpty() ); - - ExportManifestMondrian mondrianCatalog = null; - - for ( ExportManifestMondrian catalog : catalogs ) { - if ( "mondrian".equals( catalog.getCatalogName() ) ) { - mondrianCatalog = catalog; - break; - } - } - assertNotNull( mondrianCatalog ); - Parameters parameters = mondrianCatalog.getParameters(); - assertNotNull( parameters ); - assertFalse( parameters.isEmpty() ); - - String parameter = parameters.get( keyFirst ); - assertNotNull( parameter ); - assertEquals( valueFirst, parameter ); - - parameter = parameters.get( keySecond ); - assertNotNull( parameter ); - assertEquals( valueSecond, parameter ); - } - } catch ( Exception e ) { - fail( e.toString() ); - } - } - - public void testToXml_XmlUnsafeEscaped() { - final String keyFirst = "DataSource"; - final String keySecond = "DynamicSchemaProcessor"; - final String valueFirst = "\"DS \"Test's\" & \""; - final String valueSecond = "\"DSP's & \"Other\" \""; - - final String expectedValueFirst = ""DS "Test's" & <Fun>""; - final String expectedValueSecond = ""DSP's & "Other" <stuff>""; - - ExportManifestMondrian mondrian = new ExportManifestMondrian(); - Parameters mondrianParameters = new Parameters(); - - mondrianParameters.put( keyFirst, valueFirst ); - mondrianParameters.put( keySecond, valueSecond ); - mondrian.setParameters( mondrianParameters ); - mondrian.setCatalogName( "mondrian" ); - mondrian.setXmlaEnabled( false ); - - String lineParamFirst = null; - String lineParamSecond = null; - - exportManifest.addMondrian( mondrian ); - - try ( ByteArrayOutputStream out = new ByteArrayOutputStream() ) { - exportManifest.toXml( out ); - try ( ByteArrayInputStream inputStream = new ByteArrayInputStream( out.toByteArray() ); - BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ) - ) { - String line; - while ( ( line = reader.readLine() ) != null ) { - if ( line.contains( keyFirst ) ) { - lineParamFirst = line; - } - if ( line.contains( keySecond ) ) { - lineParamSecond = line; - } - if ( lineParamFirst != null && lineParamSecond != null ) { - break; - } - } - } - } catch ( Exception e ) { - fail( "Could not marshal to XML " + e ); - } - assertNotNull( lineParamFirst ); - assertTrue( lineParamFirst.contains( "value=\"" + expectedValueFirst + "\"" ) ); - assertNotNull( lineParamSecond ); - assertTrue( lineParamSecond.contains( "value=\"" + expectedValueSecond + "\"" ) ); - } - - private RepositoryFileAcl createMockRepositoryAcl( Serializable id, String owner, boolean entriesInheriting, - List aces ) { - RepositoryFileSid ownerSid = new RepositoryFileSid( owner ); - return new RepositoryFileAcl( id, ownerSid, entriesInheriting, aces ); - } - - private RepositoryFileAce createMockAce( String recipientName, String recipientType, RepositoryFilePermission first, - RepositoryFilePermission... rest ) { - RepositoryFileSid.Type type = RepositoryFileSid.Type.valueOf( recipientType ); - RepositoryFileSid recipient = new RepositoryFileSid( recipientName, type ); - return new RepositoryFileAce( recipient, EnumSet.of( first, rest ) ); - } - -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParamTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParamTest.java deleted file mode 100644 index 92f0cba84a5..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleParamTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.importexport.exportManifest.bindings; - -import org.junit.Test; - -import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSettersExcluding; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.*; - -/** - * Created by rfellows on 10/26/15. - */ -public class JobScheduleParamTest { - - @Test - public void testGettersAndSetters() throws Exception { - String[] excludes = new String[] { - "stringValue" - }; - assertThat( JobScheduleParam.class, hasValidGettersAndSettersExcluding( excludes ) ); - } - - @Test - public void testGetStringValue() throws Exception { - JobScheduleParam jsp = new JobScheduleParam(); - assertNotNull( jsp.getStringValue() ); - assertEquals( 0, jsp.getStringValue().size() ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java deleted file mode 100644 index c03aa803dd1..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListenerTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.repository; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatchers; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobFilter; -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.plugin.services.repository.RepositoryCleanerSystemListener.Frequency; -import org.pentaho.test.platform.engine.core.MicroPlatform; - -import java.util.Collections; -import java.util.Map; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyMap; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Andrey Khayrutdinov - */ -public class RepositoryCleanerSystemListenerTest { - - private MicroPlatform mp; - private IScheduler scheduler; - private RepositoryCleanerSystemListener listener; - - @Before - public void setUp() throws Exception { - scheduler = mock( IScheduler.class ); - listener = new RepositoryCleanerSystemListener(); - } - - @After - public void tearDown() throws Exception { - if ( mp != null ) { - mp.stop(); - mp = null; - } - scheduler = null; - listener = null; - } - - - @Test - public void gcEnabledIsTrue_executeIsNull_ByDefault() { - assertTrue( listener.isGcEnabled() ); - assertNull( listener.getExecute() ); - } - - @Test - public void stops_IfSchedulerIsNotDefined() { - assertFalse( listener.startup( null ) ); - } - - - private void prepareMp() throws Exception { - mp = new MicroPlatform(); - mp.defineInstance( IScheduler.class, scheduler ); - mp.start(); - } - - private void verifyJobRemoved( String jobId ) throws SchedulerException { - verify( scheduler ).removeJob( jobId ); - } - - private void verifyJobCreated( Frequency frequency ) throws SchedulerException { - verify( scheduler ).createJob( eq( RepositoryGcJob.JOB_NAME ), eq( RepositoryGcJob.class ), ArgumentMatchers.nullable( Map.class ), - isA( frequency.createTrigger().getClass() ) ); - } - - - private void verifyJobHaveNotCreated() throws SchedulerException { - verify( scheduler, never() ) - .createJob( eq( RepositoryGcJob.JOB_NAME ), eq( RepositoryGcJob.class ), anyMap(), any( IJobTrigger.class ) ); - } - - - @Test - public void returnsTrue_EvenGetsExceptions() throws Exception { - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenThrow( new SchedulerException( "test exception" ) ); - prepareMp(); - assertTrue( "The listener should not return false to let the system continue working", listener.startup( null ) ); - } - - - @Test - public void removesJobs_WhenDisabled() throws Exception { - final String jobId = "jobId"; - IJob job = scheduler.createJob( null, (String)null , null, null ); - job.setJobId( jobId ); - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( job ) ); - - prepareMp(); - - listener.setGcEnabled( false ); - - assertTrue( listener.startup( null ) ); - verifyJobRemoved( jobId ); - } - - @Test - public void schedulesJob_Now() throws Exception { - testSchedulesJob( Frequency.NOW ); - } - - @Test - public void schedulesJob_Weekly() throws Exception { - testSchedulesJob( Frequency.WEEKLY ); - } - - @Test - public void schedulesJob_Monthly() throws Exception { - testSchedulesJob( Frequency.MONTHLY ); - } - - - private void testSchedulesJob( Frequency frequency ) throws Exception { - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); - prepareMp(); - listener.setExecute( frequency.getValue() ); - - assertTrue( listener.startup( null ) ); - verifyJobCreated( frequency ); - } - - @Test - public void schedulesJob_Unknown() throws Exception { - testSchedulesJob_IncorrectExecute( "unknown" ); - } - - @Test - public void schedulesJob_Null() throws Exception { - testSchedulesJob_IncorrectExecute( null ); - } - - private void testSchedulesJob_IncorrectExecute( String execute ) throws Exception { - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.emptyList() ); - prepareMp(); - listener.setExecute( execute ); - - listener.startup( null ); - verifyJobHaveNotCreated(); - } - - - @Test - public void reschedulesJob_IfFoundDifferent() throws Exception { - final String oldJobId = "oldJobId"; -// IJob oldJob = new Job(); - IJob oldJob = scheduler.createJob( null, (String)null , null, null ); - oldJob.setJobTrigger( scheduler.createCronJobTrigger() ); - oldJob.setJobId( oldJobId ); - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( oldJob ) ); - - prepareMp(); - - listener.setExecute( Frequency.NOW.getValue() ); - - assertTrue( listener.startup( null ) ); - verifyJobRemoved( oldJobId ); - verifyJobCreated( Frequency.NOW ); - } - - @Test - public void doesNotRescheduleJob_IfFoundSame() throws Exception { - final String oldJobId = "oldJobId"; - IJob oldJob = scheduler.createJob( null, (String)null , null, null ); - oldJob.setJobTrigger( Frequency.WEEKLY.createTrigger() ); - oldJob.setJobId( oldJobId ); - when( scheduler.getJobs( any( IJobFilter.class ) ) ).thenReturn( Collections.singletonList( oldJob ) ); - - prepareMp(); - - listener.setExecute( Frequency.WEEKLY.getValue() ); - - assertTrue( listener.startup( null ) ); - verify( scheduler, never() ).removeJob( oldJobId ); - verifyJobHaveNotCreated(); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolverTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolverTest.java deleted file mode 100644 index ccfddd746c4..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolverTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.usersettings.IUserSettingService; -import org.pentaho.platform.engine.core.system.PentahoSystem; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Created by rfellows on 9/23/15. - */ -public class SchedulerOutputPathResolverTest { - - SchedulerOutputPathResolver schedulerOutputPathResolver; - - IUnifiedRepository repo; - IUserSettingService userSettingService; - - @Before - public void setUp() throws Exception { - repo = mock( IUnifiedRepository.class ); - userSettingService = mock( IUserSettingService.class ); - PentahoSystem.registerObject( repo ); - PentahoSystem.registerObject( userSettingService ); - } - - @Test - public void testResolveOutputFilePath() throws Exception { - JobScheduleRequest scheduleRequest = new JobScheduleRequest(); - String inputFile = "/home/admin/test.prpt"; - String outputFolder = "/home/admin/output"; - scheduleRequest.setInputFile( inputFile ); - scheduleRequest.setOutputFile( outputFolder ); - - RepositoryFile repoFile = mock( RepositoryFile.class ); - when( repo.getFile( outputFolder ) ).thenReturn( repoFile ); - when( repoFile.isFolder() ).thenReturn( true ); - - schedulerOutputPathResolver = new SchedulerOutputPathResolver( scheduleRequest ); - String outputFilePath = schedulerOutputPathResolver.resolveOutputFilePath(); - - assertEquals( "/home/admin/output/test.*", outputFilePath ); - verify( repo ).getFile( outputFolder ); - - } - - @Test - public void testResolveOutputFilePath_ContainsPatternAlready() throws Exception { - JobScheduleRequest scheduleRequest = new JobScheduleRequest(); - String inputFile = "/home/admin/test.prpt"; - String outputFolder = "/home/admin/output/test.*"; - scheduleRequest.setInputFile( inputFile ); - scheduleRequest.setOutputFile( outputFolder ); - - RepositoryFile repoFile = mock( RepositoryFile.class ); - when( repo.getFile( nullable( String.class ) ) ).thenReturn( repoFile ); - when( repoFile.isFolder() ).thenReturn( true ); - - schedulerOutputPathResolver = new SchedulerOutputPathResolver( scheduleRequest ); - String outputFilePath = schedulerOutputPathResolver.resolveOutputFilePath(); - - assertEquals( "/home/admin/output/test.*", outputFilePath ); - verify( repo ).getFile( "/home/admin/output" ); - } - - @Test - public void testResolveOutputFilePath_Fallback() throws Exception { - JobScheduleRequest scheduleRequest = new JobScheduleRequest(); - String inputFile = "/home/admin/test.prpt"; - String outputFolder = null; - scheduleRequest.setInputFile( inputFile ); - scheduleRequest.setOutputFile( outputFolder ); - - RepositoryFile repoFile = mock( RepositoryFile.class ); - when( repo.getFile( nullable( String.class ) ) ).thenReturn( repoFile ); - when( repoFile.isFolder() ).thenReturn( false ); - - schedulerOutputPathResolver = spy( new SchedulerOutputPathResolver( scheduleRequest ) ); - doReturn( "/home/admin/setting" ).when( schedulerOutputPathResolver ).getUserSettingOutputPath(); - doReturn( "/system/setting" ).when( schedulerOutputPathResolver ).getSystemSettingOutputPath(); - doReturn( "/home/admin" ).when( schedulerOutputPathResolver ).getUserHomeDirectoryPath(); - doReturn( true ).when( schedulerOutputPathResolver ).isValidOutputPath( "/home/admin/setting" ); - String outputFilePath = schedulerOutputPathResolver.resolveOutputFilePath(); - - assertEquals( "/home/admin/setting/test.*", outputFilePath ); - } - - @Test - public void testResolveOutputFilePath_FallbackFarther() throws Exception { - JobScheduleRequest scheduleRequest = new JobScheduleRequest(); - String inputFile = "/home/admin/test.prpt"; - String outputFolder = null; - scheduleRequest.setInputFile( inputFile ); - scheduleRequest.setOutputFile( outputFolder ); - - RepositoryFile repoFile = mock( RepositoryFile.class ); - when( repo.getFile( nullable( String.class ) ) ).thenReturn( repoFile ); - when( repoFile.isFolder() ).thenReturn( false ); - - schedulerOutputPathResolver = spy( new SchedulerOutputPathResolver( scheduleRequest ) ); - doReturn( null ).when( schedulerOutputPathResolver ).getUserSettingOutputPath(); - doReturn( null ).when( schedulerOutputPathResolver ).getSystemSettingOutputPath(); - doReturn( "/home/admin" ).when( schedulerOutputPathResolver ).getUserHomeDirectoryPath(); - doReturn( true ).when( schedulerOutputPathResolver ).isValidOutputPath( "/home/admin" ); - String outputFilePath = schedulerOutputPathResolver.resolveOutputFilePath(); - - assertEquals( "/home/admin/test.*", outputFilePath ); - } - - @After - public void tearDown() throws Exception { - PentahoSystem.clearObjectFactory(); - } -} \ No newline at end of file diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java deleted file mode 100644 index bd86b5e34e7..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceTest.java +++ /dev/null @@ -1,927 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.platform.web.http.api.resources.services.SchedulerService; - - -import javax.ws.rs.core.Response; - -import java.io.IOException; -import java.util.List; - -import static javax.ws.rs.core.Response.Status.FORBIDDEN; -import static javax.ws.rs.core.Response.Status.UNAUTHORIZED; -import static javax.ws.rs.core.Response.Status.OK; -import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static org.mockito.Mockito.*; -import static org.junit.Assert.*; - -public class SchedulerResourceTest { - - SchedulerResource schedulerResource; - private IScheduler scheduler; - - @Before - public void setUp() { - scheduler = mock( IScheduler.class ); - schedulerResource = spy( new SchedulerResource() ); - schedulerResource.schedulerService = mock( SchedulerService.class ); - } - - @After - public void tearDown() { - schedulerResource = null; - } - - @Test - public void testCreateJob() throws Exception { - JobScheduleRequest mockRequest = mock( JobScheduleRequest.class ); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).createJob( mockRequest ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJob ).getJobId(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( jobId ); - - Response testResponse = schedulerResource.createJob( mockRequest ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).createJob( mockRequest ); - verify( mockJob, times( 1 ) ).getJobId(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( jobId ); - } - - @Test - public void testCreateJobError() throws Exception { - JobScheduleRequest mockRequest = mock( JobScheduleRequest.class ); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - - Throwable mockSchedulerExceptionCause = mock( Throwable.class ); - doReturn( mockSchedulerExceptionCause ).when( mockSchedulerException ).getCause(); - - String schedulerExceptionMessage = "schedulerExceptionMessage"; - doReturn( schedulerExceptionMessage ).when( mockSchedulerExceptionCause ).getMessage(); - - Response mockSchedulerExceptionResponse = mock( Response.class ); - doReturn( mockSchedulerExceptionResponse ).when( schedulerResource ) - .buildServerErrorResponse( schedulerExceptionMessage ); - - IOException mockIOException = mock( IOException.class ); - - Throwable mockIOExceptionCause = mock( Throwable.class ); - doReturn( mockIOExceptionCause ).when( mockIOException ).getCause(); - - String ioExceptionMessage = "ioExceptionMessage"; - doReturn( ioExceptionMessage ).when( mockIOExceptionCause ).getMessage(); - - Response mockIOExceptionResponse = mock( Response.class ); - doReturn( mockIOExceptionResponse ).when( schedulerResource ).buildServerErrorResponse( ioExceptionMessage ); - - Response mockUnauthorizedResponse = mock( Response.class ); - doReturn( mockUnauthorizedResponse ).when( schedulerResource ).buildStatusResponse( UNAUTHORIZED ); - - Response mockForbiddenResponse = mock( Response.class ); - doReturn( mockForbiddenResponse ).when( schedulerResource ).buildStatusResponse( FORBIDDEN ); - - // Test 1 - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).createJob( mockRequest ); - - Response testResponse = schedulerResource.createJob( mockRequest ); - assertEquals( mockSchedulerExceptionResponse, testResponse ); - - // Test 2 - doThrow( mockIOException ).when( schedulerResource.schedulerService ).createJob( mockRequest ); - - testResponse = schedulerResource.createJob( mockRequest ); - assertEquals( mockIOExceptionResponse, testResponse ); - - // Test 3 - SecurityException mockSecurityException = mock( SecurityException.class ); - doThrow( mockSecurityException ).when( schedulerResource.schedulerService ).createJob( mockRequest ); - - testResponse = schedulerResource.createJob( mockRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 4 - IllegalAccessException mockIllegalAccessException = mock( IllegalAccessException.class ); - doThrow( mockIllegalAccessException ).when( schedulerResource.schedulerService ).createJob( mockRequest ); - - testResponse = schedulerResource.createJob( mockRequest ); - assertEquals( mockForbiddenResponse, testResponse ); - - verify( mockSchedulerException, times( 1 ) ).getCause(); - verify( mockSchedulerExceptionCause, times( 1 ) ).getMessage(); - verify( schedulerResource, times( 1 ) ).buildServerErrorResponse( schedulerExceptionMessage ); - verify( mockIOException, times( 1 ) ).getCause(); - verify( mockIOExceptionCause, times( 1 ) ).getMessage(); - verify( schedulerResource, times( 1 ) ).buildServerErrorResponse( ioExceptionMessage ); - verify( schedulerResource, times( 1 ) ).buildStatusResponse( UNAUTHORIZED ); - verify( schedulerResource, times( 1 ) ).buildStatusResponse( FORBIDDEN ); - verify( schedulerResource.schedulerService, times( 4 ) ).createJob( mockRequest ); - } - - @Test - public void testTriggerNow() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).triggerNow( jobId ); - - IJob.JobState mockJobState = IJob.JobState.BLOCKED; - doReturn( mockJobState ).when( mockJob ).getState(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( mockJobState.name() ); - - Response testResponse = schedulerResource.triggerNow( mockJobRequest ); - assertEquals( mockResponse, testResponse ); - - verify( mockJobRequest, times( 1 ) ).getJobId(); - verify( schedulerResource.schedulerService, times( 1 ) ).triggerNow( jobId ); - verify( mockJob, times( 1 ) ).getState(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( mockJobState.name() ); - } - - @Test - public void testTriggerNowError() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).triggerNow( jobId ); - - try { - schedulerResource.triggerNow( mockJobRequest ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( mockJobRequest, times( 1 ) ).getJobId(); - verify( schedulerResource.schedulerService, times( 1 ) ).triggerNow( jobId ); - } - - @Test - public void testGetContentCleanerJob() throws Exception { - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).getContentCleanerJob(); - - IJob testJob = schedulerResource.getContentCleanerJob(); - assertEquals( mockJob, testJob ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getContentCleanerJob(); - } - - @Test - public void testGetContentCleanerJobError() throws Exception { - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).getContentCleanerJob(); - - try { - schedulerResource.getContentCleanerJob(); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).getContentCleanerJob(); - } - - @Test - public void testGetJobs() throws Exception { - List mockJobs = mock( List.class ); - doReturn( mockJobs ).when( schedulerResource.schedulerService ).getJobs(); - - Boolean asCronString = Boolean.FALSE; - - List testJobs = schedulerResource.getJobs( asCronString ); - assertEquals( mockJobs, testJobs ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobs(); - } - - @Test - public void testGetJobsError() throws Exception { - Boolean asCronString = Boolean.FALSE; - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).getJobs(); - - try { - schedulerResource.getJobs( asCronString ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobs(); - } - - @Test - public void testIsScheduleAllowed() { - String id = "id"; - - boolean isScheduleAllowed = true; - doReturn( isScheduleAllowed ).when( schedulerResource.schedulerService ).isScheduleAllowed( id ); - - String testResult = schedulerResource.isScheduleAllowed( id ); - assertEquals( "" + isScheduleAllowed, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).isScheduleAllowed( id ); - } - - @Test - public void testDoGetCanSchedule() { - String canSchedule = "true"; - doReturn( canSchedule ).when( schedulerResource.schedulerService ).doGetCanSchedule(); - - String testResult = schedulerResource.doGetCanSchedule(); - assertEquals( canSchedule, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).doGetCanSchedule(); - } - - @Test - public void testGetState() throws Exception { - String state = "state"; - doReturn( state ).when( schedulerResource.schedulerService ).getState(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( state ); - - Response testResult = schedulerResource.getState(); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getState(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( state ); - } - - @Test - public void testGetStateError() throws Exception { - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).getState(); - - try { - schedulerResource.getState(); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).getState(); - } - - @Test - public void testStart() throws Exception { - String status = "state"; - doReturn( status ).when( schedulerResource.schedulerService ).start(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( status ); - - Response testResult = schedulerResource.start(); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).start(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( status ); - } - - @Test - public void testStartError() throws Exception { - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).start(); - - try { - schedulerResource.start(); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).start(); - } - - @Test - public void testPause() throws Exception { - String status = "state"; - doReturn( status ).when( schedulerResource.schedulerService ).pause(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( status ); - - Response testResult = schedulerResource.pause(); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).pause(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( status ); - } - - @Test - public void testPauseError() throws Exception { - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).pause(); - - try { - schedulerResource.pause(); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).pause(); - } - - @Test - public void testShutdown() throws Exception { - String status = "state"; - doReturn( status ).when( schedulerResource.schedulerService ).shutdown(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( status ); - - Response testResult = schedulerResource.shutdown(); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).shutdown(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( status ); - } - - @Test - public void testShutdownError() throws Exception { - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).shutdown(); - - try { - schedulerResource.shutdown(); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).shutdown(); - } - - @Test - public void testGetJobState() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - IJob.JobState mockJobState = IJob.JobState.BLOCKED; - doReturn( mockJobState ).when( schedulerResource.schedulerService ).getJobState( mockJobRequest ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( mockJobState.name() ); - - Response testResponse = schedulerResource.getJobState( mockJobRequest ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobState( mockJobRequest ); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( mockJobState.name() ); - } - - @Test - public void testGetJobStateError() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - Response mockUnauthorizedResponse = mock( Response.class ); - doReturn( mockUnauthorizedResponse ).when( schedulerResource ).buildPlainTextStatusResponse( UNAUTHORIZED ); - - // Test 1 - UnsupportedOperationException mockUnsupportedOperationException = mock( UnsupportedOperationException.class ); - doThrow( mockUnsupportedOperationException ).when( schedulerResource.schedulerService ) - .getJobState( mockJobRequest ); - - Response testResponse = schedulerResource.getJobState( mockJobRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 2 - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).getJobState( mockJobRequest ); - - try { - schedulerResource.getJobState( mockJobRequest ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource, times( 1 ) ).buildPlainTextStatusResponse( UNAUTHORIZED ); - verify( schedulerResource.schedulerService, times( 2 ) ).getJobState( mockJobRequest ); - } - - @Test - public void testPauseJob() throws Exception { - String jobId = "jobId"; - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IJob.JobState state = IJob.JobState.BLOCKED; - doReturn( state ).when( schedulerResource.schedulerService ).pauseJob( jobId ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( state.name() ); - - Response testResult = schedulerResource.pauseJob( mockJobRequest ); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).pauseJob( jobId ); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( state.name() ); - } - - @Test - public void testPauseJobError() throws Exception { - String jobId = "jobId"; - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).pauseJob( jobId ); - - try { - schedulerResource.pauseJob( mockJobRequest ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).pauseJob( jobId ); - } - - @Test - public void testResumeJob() throws Exception { - String jobId = "jobId"; - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IJob.JobState state = IJob.JobState.BLOCKED; - doReturn( state ).when( schedulerResource.schedulerService ).resumeJob( jobId ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( state.name() ); - - Response testResult = schedulerResource.resumeJob( mockJobRequest ); - assertEquals( mockResponse, testResult ); - - verify( schedulerResource.schedulerService, times( 1 ) ).resumeJob( jobId ); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( state.name() ); - } - - @Test - public void testResumeJobError() throws Exception { - String jobId = "jobId"; - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).resumeJob( jobId ); - - try { - schedulerResource.resumeJob( mockJobRequest ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).resumeJob( jobId ); - } - - @Test - public void testRemoveJob() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).getJob( jobId ); - - IJob.JobState mockJobState = IJob.JobState.BLOCKED; - doReturn( mockJobState ).when( mockJob ).getState(); - - Response mockRemovedResponse = mock( Response.class ); - doReturn( mockRemovedResponse ).when( schedulerResource ).buildPlainTextOkResponse( "REMOVED" ); - - Response mockJobStateResponse = mock( Response.class ); - doReturn( mockJobStateResponse ).when( schedulerResource ).buildPlainTextOkResponse( mockJobState.name() ); - - // Test 1 - doReturn( true ).when( schedulerResource.schedulerService ).removeJob( jobId ); - - Response testResponse = schedulerResource.removeJob( mockJobRequest ); - assertEquals( mockRemovedResponse, testResponse ); - - // Test 2 - doReturn( false ).when( schedulerResource.schedulerService ).removeJob( jobId ); - testResponse = schedulerResource.removeJob( mockJobRequest ); - assertEquals( mockJobStateResponse, testResponse ); - - verify( mockJobRequest, times( 3 ) ).getJobId(); - verify( schedulerResource.schedulerService, times( 1 ) ).getJob( jobId ); - verify( mockJob, times( 1 ) ).getState(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( "REMOVED" ); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( mockJobState.name() ); - } - - @Test - public void testRemoveJobError() throws Exception { - String jobId = "jobId"; - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).removeJob( jobId ); - - try { - schedulerResource.removeJob( mockJobRequest ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).removeJob( jobId ); - } - - @Test - public void testGetJob() throws Exception { - String jobId = "jobId"; - String asCronString = "asCronString"; - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).getJobInfo( jobId ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildOkResponse( mockJob ); - - Response testResponse = schedulerResource.getJob( jobId, asCronString ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobInfo( jobId ); - } - - @Test - public void testGetJobNull() throws Exception { - String jobId = "jobId"; - String asCronString = "asCronString"; - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildStatusResponse( Response.Status.NO_CONTENT ); - - Response testResponse = schedulerResource.getJob( jobId, asCronString ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobInfo( jobId ); - } - - @Test - public void testGetJobError() throws Exception { - String jobId = "jobId"; - String asCronString = "asCronString"; - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).getJobInfo( jobId ); - - try { - schedulerResource.getJob( jobId, asCronString ); - fail(); - } catch ( RuntimeException e ) { - // correct - } - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobInfo( jobId ); - } - - @Test - public void testGetJobInfo() { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - doReturn( mockJobScheduleRequest ).when( schedulerResource.schedulerService ).getJobInfo(); - - JobScheduleRequest testJobScheduleRequest = schedulerResource.getJobInfo(); - assertEquals( mockJobScheduleRequest, testJobScheduleRequest ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getJobInfo(); - } - - @Test - public void testGetBlockoutJobs() { - List mockJobs = mock( List.class ); - doReturn( mockJobs ).when( schedulerResource.schedulerService ).getBlockOutJobs(); - - List blockoutJobs = schedulerResource.getBlockoutJobs(); - assertNotNull( blockoutJobs ); - - verify( schedulerResource, times( 1 ) ).getBlockoutJobs(); - } - - @Test - public void testHasBlockouts() { - Boolean hasBlockouts = Boolean.FALSE; - doReturn( hasBlockouts ).when( schedulerResource.schedulerService ).hasBlockouts(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildOkResponse( hasBlockouts.toString() ); - - Response testResponse = schedulerResource.hasBlockouts(); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).hasBlockouts(); - verify( schedulerResource, times( 1 ) ).buildOkResponse( hasBlockouts.toString() ); - } - - @Test - public void testAddBlockout() throws Exception { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).addBlockout( mockJobScheduleRequest ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJob ).getJobId(); - - Response mockJobResponse = mock( Response.class ); - doReturn( mockJobResponse ).when( schedulerResource ).buildPlainTextOkResponse( jobId ); - - Response testResponse = schedulerResource.addBlockout( mockJobScheduleRequest ); - assertEquals( mockJobResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).addBlockout( mockJobScheduleRequest ); - verify( mockJob, times( 1 ) ).getJobId(); - verify( schedulerResource, times( 1 ) ).buildPlainTextOkResponse( jobId ); - } - - @Test - public void testAddBlockoutError() throws Exception { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - Response mockUnauthorizedResponse = mock( Response.class ); - doReturn( mockUnauthorizedResponse ).when( schedulerResource ).buildStatusResponse( UNAUTHORIZED ); - - // Test 1 - IOException mockIOException = mock( IOException.class ); - doThrow( mockIOException ).when( schedulerResource.schedulerService ).addBlockout( mockJobScheduleRequest ); - - Response testResponse = schedulerResource.addBlockout( mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 2 - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).addBlockout( mockJobScheduleRequest ); - - testResponse = schedulerResource.addBlockout( mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 3 - IllegalAccessException mockIllegalAccessException = mock( IllegalAccessException.class ); - doThrow( mockIllegalAccessException ).when( schedulerResource.schedulerService ) - .addBlockout( mockJobScheduleRequest ); - - testResponse = schedulerResource.addBlockout( mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 3 ) ).addBlockout( mockJobScheduleRequest ); - verify( schedulerResource, times( 3 ) ).buildStatusResponse( UNAUTHORIZED ); - } - - @Test - public void testUpdateBlockout() throws Exception { - String jobId = "jobId"; - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - doReturn( true ).when( schedulerResource.schedulerService ).isScheduleAllowed(); - - JobRequest mockJobRequest = mock( JobRequest.class ); - doReturn( mockJobRequest ).when( schedulerResource ).getJobRequest(); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerResource.schedulerService ).updateBlockout( jobId, mockJobScheduleRequest ); - - doReturn( jobId ).when( mockJob ).getJobId(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildPlainTextOkResponse( jobId ); - - Response testResponse = schedulerResource.updateBlockout( jobId, mockJobScheduleRequest ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).updateBlockout( jobId, mockJobScheduleRequest ); - verify( mockJob, times( 1 ) ).getJobId(); - } - - @Test - public void testUpdateBlockoutError() throws Exception { - String jobId = "jobId"; - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - Response mockUnauthorizedResponse = mock( Response.class ); - doReturn( mockUnauthorizedResponse ).when( schedulerResource ).buildStatusResponse( UNAUTHORIZED ); - - // Test 1 - IOException mockIOException = mock( IOException.class ); - doThrow( mockIOException ).when( schedulerResource.schedulerService ).updateBlockout( jobId, - mockJobScheduleRequest ); - - Response testResponse = schedulerResource.updateBlockout( jobId, mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 2 - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - doThrow( mockSchedulerException ).when( schedulerResource.schedulerService ).updateBlockout( jobId, - mockJobScheduleRequest ); - - testResponse = schedulerResource.updateBlockout( jobId, mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - // Test 3 - IllegalAccessException mockIllegalAccessException = mock( IllegalAccessException.class ); - doThrow( mockIllegalAccessException ).when( schedulerResource.schedulerService ) - .updateBlockout( jobId, mockJobScheduleRequest ); - - testResponse = schedulerResource.updateBlockout( jobId, mockJobScheduleRequest ); - assertEquals( mockUnauthorizedResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 3 ) ).updateBlockout( jobId, mockJobScheduleRequest ); - verify( schedulerResource, times( 3 ) ).buildStatusResponse( UNAUTHORIZED ); - } - - @Test - public void testBlockoutWillFire() throws Exception { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - IJobTrigger mockJobTrigger = mock( IJobTrigger.class ); - doReturn( mockJobTrigger ).when( schedulerResource ).convertScheduleRequestToJobTrigger( mockJobScheduleRequest ); - - Boolean willFire = Boolean.FALSE; - doReturn( willFire ).when( schedulerResource.schedulerService ).willFire( mockJobTrigger ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildOkResponse( willFire.toString() ); - - Response testResponse = schedulerResource.blockoutWillFire( mockJobScheduleRequest ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource, times( 1 ) ).convertScheduleRequestToJobTrigger( mockJobScheduleRequest ); - verify( schedulerResource.schedulerService, times( 1 ) ).willFire( mockJobTrigger ); - verify( schedulerResource, times( 1 ) ).buildOkResponse( willFire.toString() ); - } - - @Test - public void testBlockoutWillFireError() throws Exception { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - UnifiedRepositoryException mockUnifiedRepositoryException = mock( UnifiedRepositoryException.class ); - - SchedulerException mockSchedulerException = mock( SchedulerException.class ); - - Response mockUnifiedRepositoryExceptionResponse = mock( Response.class ); - doReturn( mockUnifiedRepositoryExceptionResponse ).when( schedulerResource ) - .buildServerErrorResponse( mockUnifiedRepositoryException ); - - Response mockSchedulerExceptionResponse = mock( Response.class ); - doReturn( mockSchedulerExceptionResponse ).when( schedulerResource ) - .buildServerErrorResponse( mockSchedulerException ); - - // Test 1 - doThrow( mockUnifiedRepositoryException ).when( schedulerResource ) - .convertScheduleRequestToJobTrigger( mockJobScheduleRequest ); - - Response testResponse = schedulerResource.blockoutWillFire( mockJobScheduleRequest ); - assertEquals( mockUnifiedRepositoryExceptionResponse, testResponse ); - - // Test 2 - doThrow( mockSchedulerException ).when( schedulerResource ) - .convertScheduleRequestToJobTrigger( mockJobScheduleRequest ); - - testResponse = schedulerResource.blockoutWillFire( mockJobScheduleRequest ); - assertEquals( mockSchedulerExceptionResponse, testResponse ); - - verify( schedulerResource, times( 1 ) ).buildServerErrorResponse( mockUnifiedRepositoryException ); - verify( schedulerResource, times( 1 ) ).buildServerErrorResponse( mockSchedulerException ); - verify( schedulerResource, times( 2 ) ).convertScheduleRequestToJobTrigger( mockJobScheduleRequest ); - } - - @Test - public void testShouldFireNow() { - Boolean shouldFireNow = Boolean.FALSE; - doReturn( shouldFireNow ).when( schedulerResource.schedulerService ).shouldFireNow(); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildOkResponse( shouldFireNow.toString() ); - - Response testResponse = schedulerResource.shouldFireNow(); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).shouldFireNow(); - verify( schedulerResource, times( 1 ) ).buildOkResponse( shouldFireNow.toString() ); - } - - @Test - public void testGetBlockStatus() throws Exception { - JobScheduleRequest mockJobScheduleRequest = mock( JobScheduleRequest.class ); - - BlockStatusProxy mockBlockStatusProxy = mock( BlockStatusProxy.class ); - doReturn( mockBlockStatusProxy ).when( schedulerResource.schedulerService ) - .getBlockStatus( mockJobScheduleRequest ); - - Response mockResponse = mock( Response.class ); - doReturn( mockResponse ).when( schedulerResource ).buildOkResponse( mockBlockStatusProxy ); - - Response testResponse = schedulerResource.getBlockStatus( mockJobScheduleRequest ); - assertEquals( mockResponse, testResponse ); - - verify( schedulerResource.schedulerService, times( 1 ) ).getBlockStatus( mockJobScheduleRequest ); - verify( schedulerResource, times( 1 ) ).buildOkResponse( mockBlockStatusProxy ); - } - - - @Test - public void updateJob_ReturnsJobId() throws Exception { - JobScheduleRequest request = new JobScheduleRequest(); - IJob job = scheduler.createJob( null, (String)null , null, null ); - job.setJobId( "job-id" ); - when( schedulerResource.schedulerService.updateJob( request ) ).thenReturn( job ); - - assertUpdateJob( request, OK, job.getJobId() ); - } - - @Test - public void updateJob_Returns500_WhenSchedulerFails() throws Exception { - JobScheduleRequest request = new JobScheduleRequest(); - when( schedulerResource.schedulerService.updateJob( request ) ) - .thenThrow( new SchedulerException( new RuntimeException( "error" ) ) ); - - assertUpdateJob( request, INTERNAL_SERVER_ERROR, "error" ); - } - - @Test - public void updateJob_Returns500_WhenIoFails() throws Exception { - JobScheduleRequest request = new JobScheduleRequest(); - when( schedulerResource.schedulerService.updateJob( request ) ) - .thenThrow( new IOException( new RuntimeException( "error" ) ) ); - - assertUpdateJob( request, INTERNAL_SERVER_ERROR, "error" ); - } - - @Test - public void updateJob_Returns401_WhenNotAuthorized() throws Exception { - JobScheduleRequest request = new JobScheduleRequest(); - when( schedulerResource.schedulerService.updateJob( request ) ) - .thenThrow( new SecurityException( "error" ) ); - - assertUpdateJob( request, UNAUTHORIZED, null ); - } - - @Test - public void updateJob_Returns403_WhenNotPermitted() throws Exception { - JobScheduleRequest request = new JobScheduleRequest(); - when( schedulerResource.schedulerService.updateJob( request ) ) - .thenThrow( new IllegalAccessException( "error" ) ); - - assertUpdateJob( request, FORBIDDEN, null ); - } - - private void assertUpdateJob( JobScheduleRequest request, Response.Status expectedStatus, String expectedResponse ) { - Response response = schedulerResource.updateJob( request ); - assertEquals( expectedStatus.getStatusCode(), response.getStatus() ); - assertEquals( expectedResponse, response.getEntity() ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java deleted file mode 100644 index b7de41b3970..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/SchedulerResourceUtilTest.java +++ /dev/null @@ -1,372 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.ICronJobTrigger; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; -import org.pentaho.platform.api.scheduler2.wrappers.ITimeWrapper; -import org.pentaho.platform.scheduler2.recur.ITimeRecurrence; -import org.pentaho.platform.plugin.services.exporter.ScheduleExportUtil; -import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; -import org.pentaho.platform.scheduler2.recur.RecurrenceList; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.TimeZone; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Created by rfellows on 11/9/15. - */ -@RunWith( MockitoJUnitRunner.class ) -public class SchedulerResourceUtilTest { - - @Mock JobScheduleRequest scheduleRequest; - @Mock IScheduler scheduler; - @Mock ISimpleJobTrigger simple; - @Mock RepositoryFile repo; - ICronJobTrigger cron; - ComplexJobTriggerProxy complex; - Date now; - - private TimeZone system; - - @Before - public void setUp() throws Exception { - // this makes the test non-deterministic! - now = new Date(); - - complex = new ComplexJobTriggerProxy(); - complex.setStartTime( now ); - - system = TimeZone.getDefault(); - TimeZone.setDefault( TimeZone.getTimeZone( "EST" ) ); - } - - @After - public void tearDown() { - TimeZone.setDefault( system ); - system = null; - } - - @Test - public void testConvertScheduleRequestToJobTrigger_SimpleJobTrigger() throws Exception { - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof ISimpleJobTrigger ); - assertTrue( trigger.getStartTime().getTime() > System.currentTimeMillis() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_SimpleJobTrigger_basedOnExisting() throws Exception { - when( scheduleRequest.getSimpleJobTrigger() ).thenReturn( simple ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertEquals( simple, trigger ); - verify( simple ).setStartTime( any( Date.class ) ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_daysOfMonth() throws Exception { - complex.setDaysOfMonth( new int[] { 1, 25 } ); - - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - List recurrences = trig.getDayOfMonthRecurrences(); - assertEquals( 2, recurrences.size() ); - ITimeWrapper rec = recurrences.get( 0 ); - assertEquals( 1, rec.getRecurrences().size() ); - rec = recurrences.get( 1 ); - assertEquals( 25, rec.getRecurrences().size() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_monthsOfYear() throws Exception { - complex.setMonthsOfYear( new int[] { 1, 8 } ); - - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - List recurrences = trig.getMonthlyRecurrences(); - assertEquals( 2, recurrences.size() ); - ITimeWrapper rec = recurrences.get( 0 ); - assertEquals( 2, rec.getRecurrences().size() ); - rec = recurrences.get( 1 ); - assertEquals( 9, rec.getRecurrences().size() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_years() throws Exception { - complex.setYears( new int[] { 2016, 2020 } ); - - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - List recurrences = trig.getYearlyRecurrences(); - assertEquals( 2, recurrences.size() ); - ITimeWrapper rec = recurrences.get( 0 ); - assertEquals( 2016, rec.getRecurrences().size() ); - rec = recurrences.get( 1 ); - assertEquals( 2020, rec.getRecurrences().size() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_daysOfWeek() throws Exception { - complex.setDaysOfWeek( new int[] { 1, 5 } ); - - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - List recurrences = trig.getDayOfWeekRecurrences(); - assertEquals( 2, recurrences.size() ); - ITimeWrapper rec = recurrences.get( 0 ); - assertEquals( 2, rec.getRecurrences().size() ); - rec = recurrences.get( 1 ); - assertEquals( 6, rec.getRecurrences().size() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_ComplexJobTrigger_weeksOfMonth() throws Exception { - complex.setDaysOfWeek( new int[] { 1, 5 } ); - complex.setWeeksOfMonth( new int[] { 3, 4 } ); - - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( complex ); - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertNotNull( trigger ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - List recurrences = trig.getDayOfWeekRecurrences(); - assertEquals( 4, recurrences.size() ); - -// ITimeWrapper rec = (QualifiedDayOfWeek) recurrences.get( 0 ); -// assertEquals( "MON", rec.getDayOfWeek().toString() ); -// assertEquals( "FOURTH", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 1 ); -// assertEquals( "MON", rec.getDayOfWeek().toString() ); -// assertEquals( "LAST", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 2 ); -// assertEquals( "FRI", rec.getDayOfWeek().toString() ); -// assertEquals( "FOURTH", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 3 ); -// assertEquals( "FRI", rec.getDayOfWeek().toString() ); -// assertEquals( "LAST", rec.getQualifier().toString() ); - } - - @Test - public void testConvertScheduleRequestToJobTrigger_CronString() throws Exception { - cron = scheduler.createCronJobTrigger(); - cron.setCronString( "0 45 16 ? * 2#4,2L,6#4,6L *" ); - cron.setDuration( 200000 ); - cron.setStartTime( now ); - cron.setUiPassParam( "param" ); - cron.setEndTime( now ); - - when( scheduleRequest.getCronJobTrigger() ).thenReturn( cron ); - - IJobTrigger trigger = SchedulerResourceUtil.convertScheduleRequestToJobTrigger( scheduleRequest, scheduler ); - assertTrue( trigger instanceof IComplexJobTrigger ); - - IComplexJobTrigger trig = (IComplexJobTrigger) trigger; - assertEquals( now, trig.getStartTime() ); - assertEquals( now, trig.getEndTime() ); - assertEquals( 200000, trig.getDuration() ); - assertEquals( "param", trig.getUiPassParam() ); - - List recurrences = trig.getDayOfWeekRecurrences(); - assertEquals( 4, recurrences.size() ); - -// QualifiedDayOfWeek rec = (QualifiedDayOfWeek) recurrences.get( 0 ); -// assertEquals( "MON", rec.getDayOfWeek().toString() ); -// assertEquals( "FOURTH", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 1 ); -// assertEquals( "MON", rec.getDayOfWeek().toString() ); -// assertEquals( "LAST", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 2 ); -// assertEquals( "FRI", rec.getDayOfWeek().toString() ); -// assertEquals( "FOURTH", rec.getQualifier().toString() ); -// -// rec = (QualifiedDayOfWeek) recurrences.get( 3 ); -// assertEquals( "FRI", rec.getDayOfWeek().toString() ); -// assertEquals( "LAST", rec.getQualifier().toString() ); - - } - - @Test - public void testUpdateStartDateForTimeZone_simple() throws Exception { - ISimpleJobTrigger sjt = scheduler.createSimpleJobTrigger( null, null, 0, 0 ); - sjt.setStartTime( now ); - when( scheduleRequest.getSimpleJobTrigger() ).thenReturn( sjt ); - when( scheduleRequest.getTimeZone() ).thenReturn( "GMT" ); - - long gmtTime = now.getTime() + TimeZone.getTimeZone( "EST" ).getRawOffset(); - - SchedulerResourceUtil.updateStartDateForTimeZone( scheduleRequest ); - assertEquals( gmtTime, scheduleRequest.getSimpleJobTrigger().getStartTime().getTime() ); - } - - @Test - public void testUpdateStartDateForTimeZone_complex() throws Exception { - ComplexJobTriggerProxy t = new ComplexJobTriggerProxy(); - t.setStartTime( now ); - when( scheduleRequest.getComplexJobTrigger() ).thenReturn( t ); - when( scheduleRequest.getTimeZone() ).thenReturn( "GMT" ); - - long gmtTime = now.getTime() + TimeZone.getTimeZone( "EST" ).getRawOffset(); - - SchedulerResourceUtil.updateStartDateForTimeZone( scheduleRequest ); - assertEquals( gmtTime, scheduleRequest.getComplexJobTrigger().getStartTime().getTime() ); - } - - @Test - public void testUpdateStartDateForTimeZone_cron() throws Exception { - ICronJobTrigger t = scheduler.createCronJobTrigger(); - t.setStartTime( now ); - when( scheduleRequest.getCronJobTrigger() ).thenReturn( t ); - when( scheduleRequest.getTimeZone() ).thenReturn( "GMT" ); - - long gmtTime = now.getTime() + TimeZone.getTimeZone( "EST" ).getRawOffset(); - - SchedulerResourceUtil.updateStartDateForTimeZone( scheduleRequest ); - assertEquals( gmtTime, scheduleRequest.getCronJobTrigger().getStartTime().getTime() ); - } - - @Test - public void testIsPdiFile_ktr() throws Exception { - when( repo.getName() ).thenReturn( "transform.ktr" ); - assertTrue( SchedulerResourceUtil.isPdiFile( repo ) ); - } - - @Test - public void testIsPdiFile_kjb() throws Exception { - when( repo.getName() ).thenReturn( "job.kjb" ); - assertTrue( SchedulerResourceUtil.isPdiFile( repo ) ); - } - - @Test - public void testIsPdiFile_txt() throws Exception { - when( repo.getName() ).thenReturn( "readme.txt" ); - assertFalse( SchedulerResourceUtil.isPdiFile( repo ) ); - } - - @Test - public void testIsPdiFile_null() throws Exception { - assertFalse( SchedulerResourceUtil.isPdiFile( null ) ); - } - - @Test - public void testHandlePdiScheduling_ktr() throws Exception { - HashMap params = new HashMap<>(); - params.put( "test", "value" ); - when( repo.getName() ).thenReturn( "transform.ktr" ); - when( repo.getPath() ).thenReturn( "/home/me/transform.ktr" ); - HashMap pdiParams = new HashMap<>(); - pdiParams.put( "pdiParam", "pdiParamValue" ); - - HashMap result = SchedulerResourceUtil.handlePDIScheduling( repo, params, pdiParams ); - assertEquals( params.size() + 3, result.size() ); - assertEquals( "transform", result.get( "transformation" ) ); - assertEquals( "home/me", result.get( "directory" ) ); - assertEquals( "pdiParamValue", ( (HashMap) result.get( ScheduleExportUtil.RUN_PARAMETERS_KEY ) ).get( "pdiParam" ) ); - } - - @Test - public void testHandlePdiScheduling_requestParamsAreTransferred() throws Exception { - HashMap params = new HashMap<>(); - params.put( "test1", "value1" ); - params.put( "test2", "value2" ); - params.put( "test3", "value3" ); - when( repo.getName() ).thenReturn( "job.kjb" ); - when( repo.getPath() ).thenReturn( "/home/me/job.kjb" ); - HashMap result = SchedulerResourceUtil.handlePDIScheduling( repo, params, null ); - assertEquals( params.size() + 3, result.size() ); - Map resultPdiMap = (HashMap) result.get( ScheduleExportUtil.RUN_PARAMETERS_KEY ); - assertEquals( "value1", resultPdiMap.get( "test1" ) ); - assertEquals( "value2", resultPdiMap.get( "test2" ) ); - assertEquals( "value3", resultPdiMap.get( "test3" ) ); - } - - @Test - public void testHandlePdiScheduling_job() throws Exception { - HashMap params = new HashMap<>(); - params.put( "test", "value" ); - when( repo.getName() ).thenReturn( "job.kjb" ); - when( repo.getPath() ).thenReturn( "/home/me/job.kjb" ); - HashMap pdiParams = new HashMap<>(); - pdiParams.put( "pdiParam", "pdiParamValue" ); - - HashMap result = SchedulerResourceUtil.handlePDIScheduling( repo, params, pdiParams ); - assertEquals( params.size() + 3, result.size() ); - assertEquals( "job", result.get( "job" ) ); - assertEquals( "home/me", result.get( "directory" ) ); - assertEquals( "pdiParamValue", ( (HashMap) result.get( ScheduleExportUtil.RUN_PARAMETERS_KEY ) ).get( "pdiParam" ) ); - } - - @Test - public void testHandlePdiScheduling_notPdiFile() throws Exception { - HashMap params = new HashMap<>(); - params.put( "test", "value" ); - when( repo.getName() ).thenReturn( "readme.txt" ); - HashMap pdiParams = new HashMap<>(); - pdiParams.put( "pdiParam", "pdiParamValue" ); - - HashMap result = SchedulerResourceUtil.handlePDIScheduling( repo, params, pdiParams ); - assertEquals( params.size() + pdiParams.size(), result.size() ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java index dbf4332c2d4..59d841a38eb 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java +++ b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java @@ -20,7 +20,7 @@ package org.pentaho.platform.web.http.api.resources.proxies; -import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; +import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; import org.pentaho.test.BeanTester; public class BlockStatusProxyTest extends BeanTester { diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java deleted file mode 100644 index c1fbe78f8bd..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/services/SchedulerServiceTest.java +++ /dev/null @@ -1,1117 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources.services; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJobFilter; -import org.pentaho.platform.api.scheduler2.IJobTrigger; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; -import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; -import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction; -import org.pentaho.platform.web.http.api.resources.JobRequest; -import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.JobScheduleRequest; -import org.pentaho.platform.web.http.api.resources.SchedulerOutputPathResolver; -import org.pentaho.platform.web.http.api.resources.SessionResource; -import org.pentaho.platform.web.resources.proxies.BlockStatusProxy; -import org.pentaho.platform.web.resources.services.SchedulerService; - -@RunWith( MockitoJUnitRunner.class ) -public class SchedulerServiceTest { - - private static SchedulerService schedulerService; - - @Before - public void setUp() throws SchedulerException, IOException, IllegalAccessException { - schedulerService = spy( new SchedulerService() ); - doCallRealMethod().when( schedulerService ).createJob( any() ); - schedulerService.policy = mock( IAuthorizationPolicy.class ); - schedulerService.scheduler = mock( IScheduler.class ); - schedulerService.repository = mock( IUnifiedRepository.class ); - schedulerService.blockoutManager = mock( IBlockoutManager.class ); - } - - @After - public void cleanup() { - schedulerService = null; - } - - @Test - public void testCreateJob() throws Exception { - - List jobParameters = new ArrayList<>(); - JobScheduleParam jobScheduleParam1 = mock( JobScheduleParam.class ); - doReturn( "name1" ).when( jobScheduleParam1 ).getName(); - doReturn( "value1" ).when( jobScheduleParam1 ).getValue(); - jobParameters.add( jobScheduleParam1 ); - - IJob job = mock( IJob.class ); - - JobScheduleRequest scheduleRequest = mock( JobScheduleRequest.class ); - doReturn( "className" ).when( scheduleRequest ).getActionClass(); - doReturn( "jobName" ).when( scheduleRequest ).getJobName(); - doReturn( jobParameters ).when( scheduleRequest ).getJobParameters(); - doNothing().when( scheduleRequest ).setJobName( nullable( String.class ) ); - doReturn( "timezone" ).when( scheduleRequest ).getTimeZone(); - doNothing().when( schedulerService ).updateStartDateForTimeZone( scheduleRequest ); - - doReturn( true ).when( schedulerService ).isPdiFile( any( RepositoryFile.class ) ); - doReturn( false ).when( schedulerService ).isPdiFile( null ); - - SchedulerOutputPathResolver schedulerOutputPathResolver = mock( SchedulerOutputPathResolver.class ); - doReturn( "outputFile" ).when( schedulerOutputPathResolver ).resolveOutputFilePath(); - doReturn( schedulerOutputPathResolver ).when( schedulerService ).getSchedulerOutputPathResolver( any( JobScheduleRequest.class ) ); - - ISimpleJobTrigger simpleJobTrigger = mock( ISimpleJobTrigger.class ); - - RepositoryFile repositoryFile = mock( RepositoryFile.class ); - doReturn( "file.ext" ).when( repositoryFile ).getName(); - - Map metadata = mock( Map.class ); - doReturn( metadata ).when( schedulerService.repository ).getFileMetadata( nullable( String.class ) ); - doReturn( true ).when( metadata ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - doReturn( "true" ).when( metadata ).get( RepositoryFile.SCHEDULABLE_KEY ); - - doReturn( simpleJobTrigger ).when( scheduleRequest ).getSimpleJobTrigger(); - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doReturn( "file.ext" ).when( scheduleRequest ).getInputFile(); - doReturn( repositoryFile ).when( schedulerService.repository ).getFile( nullable( String.class ) ); - - doReturn( true ).when( schedulerService ).getAutoCreateUniqueFilename( any( JobScheduleRequest.class ) ); - - doReturn( job ).when( schedulerService.scheduler ) - .createJob( nullable( String.class ), nullable( String.class ), any( Map.class ), any( IJobTrigger.class ), - any( IBackgroundExecutionStreamProvider.class ) ); - - doReturn( Class.class ).when( schedulerService ).getAction( nullable( String.class ) ); - - doReturn( job ).when( schedulerService.scheduler ) - .createJob( nullable( String.class ), any( Class.class ), any( Map.class ), any( IJobTrigger.class ) ); - - //Test 1 - schedulerService.createJob( scheduleRequest ); - - //Test 2 - doReturn( "" ).when( scheduleRequest ).getJobName(); - - schedulerService.createJob( scheduleRequest ); - - //Test 3 - doReturn( "" ).when( scheduleRequest ).getInputFile(); - doReturn( "" ).when( scheduleRequest ).getActionClass(); - - schedulerService.createJob( scheduleRequest ); - - verify( scheduleRequest, times( 15 ) ).getSimpleJobTrigger(); - verify( scheduleRequest, times( 9 ) ).getInputFile(); - verify( schedulerService.policy, times( 3 ) ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.repository, times( 2 ) ).getFile( nullable( String.class ) ); - verify( scheduleRequest, times( 6 ) ).getJobName(); - verify( scheduleRequest, times( 3 ) ).setJobName( nullable( String.class ) ); - verify( scheduleRequest, times( 5 ) ).getActionClass(); - verify( schedulerService.repository, times( 2 ) ).getFileMetadata( nullable( String.class ) ); - verify( schedulerService, times( 3 ) ).isPdiFile( nullable( RepositoryFile.class ) ); - verify( schedulerService, times( 2 ) ).handlePDIScheduling( any( RepositoryFile.class ), any( HashMap.class ), any( HashMap.class ) ); - verify( schedulerService, times( 2 ) ).getSchedulerOutputPathResolver( any( JobScheduleRequest.class ) ); - verify( scheduleRequest, times( 5 ) ).getActionClass(); - verify( schedulerService ).getAction( nullable( String.class ) ); - verify( schedulerService, times( 3 ) ).updateStartDateForTimeZone( scheduleRequest ); - verify( schedulerService.scheduler ) - .createJob( nullable( String.class ), any( Class.class ), any( Map.class ), any( IJobTrigger.class ) ); - } - - @Test - public void testCreateJobException() throws Exception { - - List jobParameters = new ArrayList<>(); - JobScheduleParam jobScheduleParam1 = mock( JobScheduleParam.class ); - doReturn( "name1" ).when( jobScheduleParam1 ).getName(); - doReturn( "value1" ).when( jobScheduleParam1 ).getValue(); - jobParameters.add( jobScheduleParam1 ); - - IJob job = mock( IJob.class ); - - JobScheduleRequest scheduleRequest = mock( JobScheduleRequest.class ); - doReturn( "className" ).when( scheduleRequest ).getActionClass(); - doReturn( "jobName" ).when( scheduleRequest ).getJobName(); - doReturn( jobParameters ).when( scheduleRequest ).getJobParameters(); - doNothing().when( scheduleRequest ).setJobName( nullable( String.class ) ); - - doReturn( true ).when( schedulerService ).isPdiFile( nullable( RepositoryFile.class ) ); - - SchedulerOutputPathResolver schedulerOutputPathResolver = mock( SchedulerOutputPathResolver.class ); - - ISimpleJobTrigger simpleJobTrigger = mock( ISimpleJobTrigger.class ); - - RepositoryFile repositoryFile = mock( RepositoryFile.class ); - - Map metadata = mock( Map.class ); - doReturn( metadata ).when( schedulerService.repository ).getFileMetadata( nullable( String.class ) ); - doReturn( true ).when( metadata ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - - doReturn( simpleJobTrigger ).when( scheduleRequest ).getSimpleJobTrigger(); - doReturn( false ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doReturn( "file.ext" ).when( scheduleRequest ).getInputFile(); - doReturn( repositoryFile ).when( schedulerService.repository ).getFile( nullable( String.class ) ); - - //Test 1 - try { - schedulerService.createJob( scheduleRequest ); - fail(); - } catch ( SecurityException e ) { - //Should catch it - } - - //Test 2 - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - doReturn( "false" ).when( metadata ).get( RepositoryFile.SCHEDULABLE_KEY ); - - try { - schedulerService.createJob( scheduleRequest ); - fail(); - } catch ( IllegalAccessException e ) { - //Should catch it - } - - //Test 3 - doReturn( "" ).when( scheduleRequest ).getInputFile(); - doThrow( new ClassNotFoundException() ).when( schedulerService ).getAction( nullable( String.class ) ); - - try { - schedulerService.createJob( scheduleRequest ); - fail(); - } catch ( RuntimeException e ) { - //Should catch it - } - - verify( scheduleRequest, times( 7 ) ).getSimpleJobTrigger(); - verify( scheduleRequest, times( 3 ) ).getInputFile(); - verify( schedulerService.policy, times( 3 ) ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.repository, times( 1 ) ).getFile( nullable( String.class ) ); - verify( scheduleRequest, times( 1 ) ).getJobName(); - verify( scheduleRequest, times( 2 ) ).setJobName( nullable( String.class ) ); - verify( scheduleRequest, times( 7 ) ).getActionClass(); - verify( schedulerService.repository, times( 1 ) ).getFileMetadata( nullable( String.class ) ); - verify( schedulerService, times( 1 ) ).isPdiFile( nullable( RepositoryFile.class ) ); - verify( schedulerService, times( 1 ) ).handlePDIScheduling( nullable( RepositoryFile.class ), any( HashMap.class ), any( HashMap.class ) ); - verify( scheduleRequest, times( 7 ) ).getActionClass(); - verify( schedulerService ).getAction( nullable( String.class ) ); - } - - @Test - public void testTriggerNow() throws Exception { - - JobRequest jobRequest = mock( JobRequest.class ); - IJob job = mock( IJob.class ); - - doReturn( job ).when( schedulerService.scheduler ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService.policy ).isAllowed( nullable( String.class ) ); - doNothing().when( schedulerService.scheduler ).triggerNow( nullable( String.class ) ); - - //Test 1 - IJob resultJob1 = schedulerService.triggerNow( jobRequest.getJobId() ); - - assertEquals( job, resultJob1 ); - - //Test 2 - doReturn( "test" ).when( job ).getUserName(); - doReturn( false ).when( schedulerService.policy ).isAllowed( nullable( String.class ) ); - - IPentahoSession pentahoSession = mock( IPentahoSession.class ); - doReturn( "test" ).when( pentahoSession ).getName(); - doReturn( pentahoSession ).when( schedulerService ).getSession(); - - IJob resultJob2 = schedulerService.triggerNow( jobRequest.getJobId() ); - - assertEquals( job, resultJob2 ); - - verify( schedulerService.scheduler, times( 4 ) ).getJob( nullable( String.class ) ); - verify( schedulerService.scheduler, times( 2 ) ).triggerNow( nullable( String.class ) ); - verify( schedulerService.policy, times( 2 ) ).isAllowed( nullable( String.class ) ); - } - - @Test - public void testGetContentCleanerJob() throws Exception { - - IJobFilter jobFilter = mock( IJobFilter.class ); - - List jobs = new ArrayList<>(); - - IPentahoSession session = mock( IPentahoSession.class ); - doReturn( session ).when( schedulerService ).getSession(); - doReturn( "sessionName" ).when( session ).getName(); - - doReturn( true ).when( schedulerService.policy ).isAllowed( AdministerSecurityAction.NAME ); - doReturn( jobFilter ).when( schedulerService ).getJobFilter( anyBoolean(), nullable( String.class ) ); - doReturn( jobs ).when( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); - - //Test 1 - IJob job = schedulerService.getContentCleanerJob(); - - assertNull( job ); - - //Test 2 - IJob job1 = mock( IJob.class ); - jobs.add( job1 ); - - job = schedulerService.getContentCleanerJob(); - - assertNotNull( job ); - - verify( schedulerService, times( 2 ) ).getSession(); - verify( session, times( 2 ) ).getName(); - verify( schedulerService.policy, times( 2 ) ).isAllowed( AdministerSecurityAction.NAME ); - verify( schedulerService.scheduler, times( 2 ) ).getJobs( any( IJobFilter.class ) ); - } - - @Test - public void testGetContentCleanerJobException() throws Exception { - - IJobFilter jobFilter = mock( IJobFilter.class ); - - List jobs = new ArrayList<>(); - - IPentahoSession session = mock( IPentahoSession.class ); - doReturn( session ).when( schedulerService ).getSession(); - doReturn( "sessionName" ).when( session ).getName(); - - doReturn( true ).when( schedulerService.policy ).isAllowed( AdministerSecurityAction.NAME ); - doReturn( jobFilter ).when( schedulerService ).getJobFilter( anyBoolean(), nullable( String.class ) ); - doThrow( new SchedulerException( "" ) ).when( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); - - try { - schedulerService.getContentCleanerJob(); - fail(); - } catch ( SchedulerException e ) { - //Should catch the exception - } - - verify( schedulerService ).getSession(); - verify( session ).getName(); - verify( schedulerService.policy ).isAllowed( AdministerSecurityAction.NAME ); - verify( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); - } - - @Test - public void testDoGetCanSchedule() { - - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - //Test 1 - String isAllowed = schedulerService.doGetCanSchedule(); - - assertEquals( "true", isAllowed ); - - //Test 2 - doReturn( false ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - isAllowed = schedulerService.doGetCanSchedule(); - - assertEquals( "false", isAllowed ); - - verify( schedulerService.policy, times( 2 ) ).isAllowed( SchedulerAction.NAME ); - } - - @Test - public void testGetState() throws SchedulerException { - - doReturn( IScheduler.SchedulerStatus.RUNNING ).when( schedulerService.scheduler ).getStatus(); - - String state = schedulerService.getState(); - - assertEquals( "RUNNING", state ); - - verify( schedulerService.scheduler ).getStatus(); - } - - @Test - public void testGetStateException() throws SchedulerException { - - doThrow( new SchedulerException( "" ) ).when( schedulerService.scheduler ).getStatus(); - - try { - schedulerService.getState(); - fail(); - } catch ( SchedulerException e ) { - //Should go here - } - - verify( schedulerService.scheduler ).getStatus(); - } - - @Test - public void testStart() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doNothing().when( schedulerService.scheduler ).start(); - - doReturn( IScheduler.SchedulerStatus.RUNNING ).when( schedulerService.scheduler ).getStatus(); - - //Test 1 - String state = schedulerService.start(); - - assertEquals( "RUNNING", state ); - - //Test 2 - doReturn( IScheduler.SchedulerStatus.STOPPED ).when( schedulerService.scheduler ).getStatus(); - doReturn( false ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - state = schedulerService.start(); - - assertEquals( "STOPPED", state ); - - verify( schedulerService.policy, times( 2 ) ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler, times( 1 ) ).start(); - verify( schedulerService.scheduler, times( 2 ) ).getStatus(); - } - - - @Test - public void testStartException() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doThrow( new SchedulerException( "" ) ).when( schedulerService.scheduler ).start(); - - try { - schedulerService.start(); - fail(); - } catch ( SchedulerException e ) { - //Should go here - } - - verify( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler ).start(); - } - - @Test - public void testPause() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doNothing().when( schedulerService.scheduler ).pause(); - - doReturn( IScheduler.SchedulerStatus.PAUSED ).when( schedulerService.scheduler ).getStatus(); - - //Test 1 - String state = schedulerService.pause(); - - assertEquals( "PAUSED", state ); - - //Test 2 - doReturn( IScheduler.SchedulerStatus.RUNNING ).when( schedulerService.scheduler ).getStatus(); - doReturn( false ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - state = schedulerService.pause(); - - assertEquals( "RUNNING", state ); - - verify( schedulerService.policy, times( 2 ) ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler, times( 1 ) ).pause(); - verify( schedulerService.scheduler, times( 2 ) ).getStatus(); - } - - @Test - public void testPauseJob() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doNothing().when( schedulerService.scheduler ).pauseJob( nullable( String.class ) ); - schedulerService.pauseJob( "job-id" ); - } - - @Test - public void testPauseJobException() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).pauseJob( nullable( String.class ) ); - try { - schedulerService.pauseJob( "job-id" ); - } catch ( SchedulerException e ) { - assertEquals( "pause-exception", e.getMessage() ); - } - } - - @Test - public void testResumeJob() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doNothing().when( schedulerService.scheduler ).resumeJob( nullable( String.class ) ); - schedulerService.resumeJob( "job-id" ); - } - - @Test - public void testResumeJobException() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).resumeJob( nullable( String.class ) ); - try { - schedulerService.resumeJob( "job-id" ); - } catch ( SchedulerException e ) { - assertEquals( "pause-exception", e.getMessage() ); - } - } - - @Test - public void testRemoveJob() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doNothing().when( schedulerService.scheduler ).removeJob( nullable( String.class ) ); - schedulerService.removeJob( "job-id" ); - } - - @Test - public void testRemoveJobException() throws SchedulerException { - IJob job = mock( IJob.class ); - doReturn( job ).when( schedulerService ).getJob( nullable( String.class ) ); - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doThrow( new SchedulerException( "pause-exception" ) ).when( schedulerService.scheduler ).removeJob( nullable( String.class ) ); - try { - schedulerService.removeJob( "job-id" ); - } catch ( SchedulerException e ) { - assertEquals( "pause-exception", e.getMessage() ); - } - } - - @Test - public void testPauseException() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doThrow( new SchedulerException( "" ) ).when( schedulerService.scheduler ).pause(); - - try { - schedulerService.pause(); - fail(); - } catch ( SchedulerException e ) { - //Should go here - } - - verify( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler ).pause(); - } - - @Test - public void testShutdown() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doNothing().when( schedulerService.scheduler ).shutdown(); - - doReturn( IScheduler.SchedulerStatus.STOPPED ).when( schedulerService.scheduler ).getStatus(); - - //Test 1 - String state = schedulerService.shutdown(); - - assertEquals( "STOPPED", state ); - - //Test 2 - doReturn( IScheduler.SchedulerStatus.RUNNING ).when( schedulerService.scheduler ).getStatus(); - doReturn( false ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - state = schedulerService.shutdown(); - - assertEquals( "RUNNING", state ); - - verify( schedulerService.policy, times( 2 ) ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler, times( 1 ) ).shutdown(); - verify( schedulerService.scheduler, times( 2 ) ).getStatus(); - } - - - @Test - public void testShutdownException() throws SchedulerException { - doReturn( true ).when( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - - doThrow( new SchedulerException( "" ) ).when( schedulerService.scheduler ).shutdown(); - - try { - schedulerService.shutdown(); - fail(); - } catch ( SchedulerException e ) { - //Should go here - } - - verify( schedulerService.policy ).isAllowed( SchedulerAction.NAME ); - verify( schedulerService.scheduler ).shutdown(); - } - - @Test - public void testGetJobs() throws Exception { - IPentahoSession mockPentahoSession = mock( IPentahoSession.class ); - - doReturn( mockPentahoSession ).when( schedulerService ).getSession(); - doReturn( "admin" ).when( mockPentahoSession ).getName(); - doReturn( true ).when( schedulerService ).canAdminister( mockPentahoSession ); - List mockJobs = new ArrayList<>(); - mockJobs.add( mock( IJob.class ) ); - doReturn( mockJobs ).when( schedulerService.scheduler ).getJobs( any( IJobFilter.class ) ); - - List jobs = schedulerService.getJobs(); - - assertEquals( mockJobs, jobs ); - - verify( schedulerService, times( 1 ) ).getSession(); - verify( mockPentahoSession, times( 1 ) ).getName(); - verify( schedulerService, times( 1 ) ).canAdminister( mockPentahoSession ); - verify( schedulerService.scheduler, times( 1 ) ).getJobs( any( IJobFilter.class ) ); - } - - @Test - public void testDoGetGeneratedContentForSchedule() throws Exception { - String lineageId = "test.prpt"; - - FileService mockFileService = mock( FileService.class ); - doReturn( mockFileService ).when( schedulerService ).getFileService(); - - SessionResource mockSessionResource = mock( SessionResource.class ); - doReturn( mockSessionResource ).when( schedulerService ).getSessionResource(); - - String currentUserDir = "currentUserDir"; - doReturn( currentUserDir ).when( mockSessionResource ).doGetCurrentUserDir(); - - List mockList = mock( List.class ); - doReturn( mockList ).when( mockFileService ) - .searchGeneratedContent( currentUserDir, lineageId, IScheduler.RESERVEDMAPKEY_LINEAGE_ID ); - - List list = schedulerService.doGetGeneratedContentForSchedule( lineageId ); - assertEquals( mockList, list ); - } - - @Test - public void testGetJobState() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IPentahoSession mockSession = mock( IPentahoSession.class ); - doReturn( mockSession ).when( schedulerService ).getSession(); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerService ).getJob( jobId ); - doReturn( IJob.JobState.BLOCKED ).when( mockJob ).getState(); - - String username = "username"; - doReturn( username ).when( mockJob ).getUserName(); - doReturn( username ).when( mockSession ).getName(); - - // Test 1 - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - - IJob.JobState testState = schedulerService.getJobState( mockJobRequest ); - assertEquals( IJob.JobState.BLOCKED, testState ); - - // Test 2 - doReturn( false ).when( schedulerService ).isScheduleAllowed(); - - testState = schedulerService.getJobState( mockJobRequest ); - assertEquals( IJob.JobState.BLOCKED, testState ); - - verify( mockJobRequest, times( 2 ) ).getJobId(); - verify( schedulerService, times( 1 ) ).getSession(); - verify( schedulerService, times( 2 ) ).getJob( jobId ); - verify( mockJob, times( 2 ) ).getState(); - verify( mockJob, times( 1 ) ).getUserName(); - verify( mockSession, times( 1 ) ).getName(); - } - - @Test - public void testGetJobStateError() throws Exception { - JobRequest mockJobRequest = mock( JobRequest.class ); - - String jobId = "jobId"; - doReturn( jobId ).when( mockJobRequest ).getJobId(); - - IPentahoSession mockSession = mock( IPentahoSession.class ); - doReturn( mockSession ).when( schedulerService ).getSession(); - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerService ).getJob( jobId ); - - String username = "username"; - doReturn( username ).when( mockJob ).getUserName(); - - String sessionName = "notUsername"; - doReturn( sessionName ).when( mockSession ).getName(); - - doReturn( false ).when( schedulerService ).isScheduleAllowed(); - - try { - schedulerService.getJobState( mockJobRequest ); - fail(); - } catch ( UnsupportedOperationException e ) { - // Expected - } - } - - @Test - public void testGetJobInfo() throws Exception { - String jobId = "jobId"; - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerService ).getJob( jobId ); - - IPentahoSession mockPentahoSession = mock( IPentahoSession.class ); - doReturn( mockPentahoSession ).when( schedulerService ).getSession(); - - String sessionName = "sessionName"; - doReturn( sessionName ).when( mockPentahoSession ).getName(); - doReturn( sessionName ).when( mockJob ).getUserName(); - - Map mockJobParams = mock( Map.class ); - doReturn( mockJobParams ).when( mockJob ).getJobParams(); - - Set jobParamsKeyset = new HashSet<>(); - doReturn( jobParamsKeyset ).when( mockJobParams ).keySet(); - - String jobParamKey = "key"; - jobParamsKeyset.add( jobParamKey ); - - String value = "value"; - String[] testArray = new String[]{value}; - doReturn( testArray ).when( mockJobParams ).get( jobParamKey ); - - // Test 1 - IJob testJob = schedulerService.getJobInfo( jobId ); - assertEquals( mockJob, testJob ); - - // Test 2 - testJob = schedulerService.getJobInfo( jobId ); - assertEquals( mockJob, testJob ); - - verify( mockJobParams, times( 2 ) ).put( eq( jobParamKey ), any( Serializable.class ) ); - verify( schedulerService, times( 2 ) ).getJob( jobId ); - verify( schedulerService, times( 2 ) ).getSession(); - verify( mockPentahoSession, times( 2 ) ).getName(); - verify( mockJob, times( 2 ) ).getUserName(); - verify( mockJob, times( 6 ) ).getJobParams(); - verify( mockJobParams, times( 2 ) ).keySet(); - verify( mockJobParams, times( 2 ) ).get( jobParamKey ); - verify( schedulerService, times( 2 ) ).canAdminister( null ); - } - - @Test - public void testGetJobInfoError() throws Exception { - String jobId = "jobId"; - - IJob mockJob = mock( IJob.class ); - doReturn( mockJob ).when( schedulerService ).getJob( jobId ); - - IPentahoSession mockPentahoSession = mock( IPentahoSession.class ); - doReturn( mockPentahoSession ).when( schedulerService ).getSession(); - - String sessionName = "sessionName"; - doReturn( sessionName ).when( mockPentahoSession ).getName(); - - String username = "username"; - doReturn( username ).when( mockJob ).getUserName(); - - try { - schedulerService.getJobInfo( jobId ); - fail(); - } catch ( RuntimeException e ) { - // Expected - } - } - - @Test - public void testIsScheduleAllowed() { - - // Test 1 - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - - Map metadata = mock( Map.class ); - - doReturn( metadata ).when( schedulerService.repository ).getFileMetadata( nullable( String.class ) ); - - doReturn( true ).when( metadata ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - doReturn( "true" ).when( metadata ).get( RepositoryFile.SCHEDULABLE_KEY ); - - boolean canSchedule = schedulerService.isScheduleAllowed( nullable( String.class ) ); - - assertTrue( canSchedule ); - - // Test 2 - doReturn( false ).when( schedulerService ).isScheduleAllowed(); - - canSchedule = schedulerService.isScheduleAllowed( nullable( String.class ) ); - - assertFalse( canSchedule ); - - // Test 3 - doReturn( true ).when( schedulerService ).isScheduleAllowed(); - doReturn( false ).when( metadata ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - - canSchedule = schedulerService.isScheduleAllowed( nullable( String.class ) ); - - assertTrue( canSchedule ); - - // Test 4 - doReturn( true ).when( metadata ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - doReturn( "false" ).when( metadata ).get( RepositoryFile.SCHEDULABLE_KEY ); - - canSchedule = schedulerService.isScheduleAllowed( nullable( String.class ) ); - - assertFalse( canSchedule ); - - verify( schedulerService, times( 4 ) ).isScheduleAllowed(); - verify( schedulerService.repository, times( 3 ) ).getFileMetadata( nullable( String.class ) ); - verify( metadata, times( 3 ) ).containsKey( RepositoryFile.SCHEDULABLE_KEY ); - verify( metadata, times( 2 ) ).get( RepositoryFile.SCHEDULABLE_KEY ); - } - - @Test - public void testGetBlockoutJobs() { - - List jobs = new ArrayList<>(); - - doReturn( jobs ).when( schedulerService.blockoutManager ).getBlockOutJobs(); - - List returnJobs = schedulerService.getBlockOutJobs(); - - assertEquals( returnJobs, jobs ); - - verify( schedulerService.blockoutManager ).getBlockOutJobs(); - } - - @Test - public void testHasBlockouts() { - - List jobs = new ArrayList<>(); - - doReturn( jobs ).when( schedulerService.blockoutManager ).getBlockOutJobs(); - - // Test 1 - boolean hasBlockouts = schedulerService.hasBlockouts(); - - assertFalse( hasBlockouts ); - - // Test 2 - jobs.add( mock( IJob.class ) ); - hasBlockouts = schedulerService.hasBlockouts(); - - assertTrue( hasBlockouts ); - - verify( schedulerService.blockoutManager, times( 2 ) ).getBlockOutJobs(); - } - - @Test - public void testAddBlockout() throws Exception { - - JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - IJob jobMock = mock( IJob.class ); - - JobScheduleParam jobScheduleParamMock1 = mock( JobScheduleParam.class ); - JobScheduleParam jobScheduleParamMock2 = mock( JobScheduleParam.class ); - - List jobScheduleParams = new ArrayList<>(); - - doReturn( true ).when( schedulerService ).canAdminister(); - doNothing().when( jobScheduleRequest ).setActionClass( nullable( String.class ) ); - doReturn( jobScheduleParams ).when( jobScheduleRequest ).getJobParameters(); - doReturn( jobScheduleParamMock1 ).when( schedulerService ).getJobScheduleParam( nullable( String.class ), nullable( String.class ) ); - doReturn( jobScheduleParamMock2 ).when( schedulerService ).getJobScheduleParam( nullable( String.class ), anyLong() ); - doReturn( jobMock ).when( schedulerService ).createJob( any( JobScheduleRequest.class ) ); - - IJob job = schedulerService.addBlockout( jobScheduleRequest ); - - assertNotNull( job ); - assertEquals( 2, jobScheduleParams.size() ); - - verify( schedulerService ).canAdminister(); - verify( jobScheduleRequest ).setActionClass( nullable( String.class ) ); - verify( jobScheduleRequest, times( 2 ) ).getJobParameters(); - verify( schedulerService ).createJob( any( JobScheduleRequest.class ) ); - } - - @Test - public void testAddBlockoutException() throws Exception { - - // Test 1 - JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - doReturn( false ).when( schedulerService ).canAdminister(); - - try { - schedulerService.addBlockout( jobScheduleRequest ); - fail(); - } catch ( IllegalAccessException e ) { - //Should catch exception - } - - // Test 2 - IJob jobMock = mock( IJob.class ); - - JobScheduleParam jobScheduleParamMock1 = mock( JobScheduleParam.class ); - JobScheduleParam jobScheduleParamMock2 = mock( JobScheduleParam.class ); - - List jobScheduleParams = new ArrayList<>(); - - doReturn( true ).when( schedulerService ).canAdminister(); - doNothing().when( jobScheduleRequest ).setActionClass( nullable( String.class ) ); - doReturn( jobScheduleParams ).when( jobScheduleRequest ).getJobParameters(); - doReturn( jobScheduleParamMock1 ).when( schedulerService ).getJobScheduleParam( nullable( String.class ), nullable( String.class ) ); - doReturn( jobScheduleParamMock2 ).when( schedulerService ).getJobScheduleParam( nullable( String.class ), anyLong() ); - - doThrow( new IOException() ).when( schedulerService ).createJob( jobScheduleRequest ); - - try { - schedulerService.addBlockout( jobScheduleRequest ); - fail(); - } catch ( IOException e ) { - //Should catch exception - } - - // Test 3 - doThrow( new SchedulerException( "" ) ).when( schedulerService ).createJob( jobScheduleRequest ); - - try { - schedulerService.addBlockout( jobScheduleRequest ); - fail(); - } catch ( SchedulerException e ) { - //Should catch exception - } - - verify( schedulerService, times( 3 ) ).canAdminister(); - verify( jobScheduleRequest, times( 2 ) ).setActionClass( nullable( String.class ) ); - verify( jobScheduleRequest, times( 4 ) ).getJobParameters(); - verify( schedulerService, times( 2 ) ).createJob( any( JobScheduleRequest.class ) ); - } - - @Test - public void testUpdateBlockout() throws Exception { - - String jobId = "jobId"; - JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - IJob jobMock = mock( IJob.class ); - - doReturn( true ).when( schedulerService ).canAdminister(); - doReturn( true ).when( schedulerService ).removeJob( nullable( String.class ) ); - doReturn( jobMock ).when( schedulerService ).addBlockout( jobScheduleRequest ); - - IJob job = schedulerService.updateBlockout( jobId, jobScheduleRequest ); - - assertNotNull( job ); - - verify( schedulerService ).canAdminister(); - verify( schedulerService ).removeJob( nullable( String.class ) ); - verify( schedulerService ).addBlockout( jobScheduleRequest ); - } - - @Test - public void testUpdateBlockoutException() throws Exception { - - String jobId = "jobId"; - JobScheduleRequest jobScheduleRequest = mock( JobScheduleRequest.class ); - IJob job = mock( IJob.class ); - - // Test 1 - doReturn( false ).when( schedulerService ).canAdminister(); - - try { - schedulerService.updateBlockout( jobId, jobScheduleRequest ); - fail(); - } catch ( IllegalAccessException e ) { - // Should catch the exception - } - - // Test 2 - doReturn( true ).when( schedulerService ).canAdminister(); - doThrow( new SchedulerException( "" ) ).when( schedulerService ).removeJob( nullable( String.class ) ); - - try { - schedulerService.updateBlockout( jobId, jobScheduleRequest ); - fail(); - } catch ( SchedulerException e ) { - // Should catch the exception - } - - // Test 3 - doReturn( false ).when( schedulerService ).removeJob( nullable( String.class ) ); - - try { - schedulerService.updateBlockout( jobId, jobScheduleRequest ); - fail(); - } catch ( IllegalAccessException e ) { - // Should catch the exception - } - - // Test 4 - doReturn( true ).when( schedulerService ).removeJob( nullable( String.class ) ); - doThrow( new IOException() ).when( schedulerService ).addBlockout( jobScheduleRequest ); - - try { - schedulerService.updateBlockout( jobId, jobScheduleRequest ); - fail(); - } catch ( IOException e ) { - // Should catch the exception - } - - // Test 5 - doThrow( new SchedulerException( "" ) ).when( schedulerService ).addBlockout( jobScheduleRequest ); - - try { - schedulerService.updateBlockout( jobId, jobScheduleRequest ); - fail(); - } catch ( SchedulerException e ) { - // Should catch the exception - } - - verify( schedulerService, times( 5 ) ).canAdminister(); - verify( schedulerService, times( 4 ) ).removeJob( nullable( String.class ) ); - verify( schedulerService, times( 2 ) ).addBlockout( jobScheduleRequest ); - } - - @Test - public void testWillFire() { - - IJobTrigger jobTrigger = mock( IJobTrigger.class ); - - // Test 1 - doReturn( true ).when( schedulerService.blockoutManager ).willFire( jobTrigger ); - - boolean willFire = schedulerService.willFire( jobTrigger ); - - assertTrue( willFire ); - - // Test 2 - doReturn( false ).when( schedulerService.blockoutManager ).willFire( jobTrigger ); - - willFire = schedulerService.willFire( jobTrigger ); - - assertFalse( willFire ); - - verify( schedulerService.blockoutManager, times( 2 ) ).willFire( jobTrigger ); - } - - @Test - public void testShouldFireNow() { - - // Test 1 - doReturn( true ).when( schedulerService.blockoutManager ).shouldFireNow(); - - boolean shouldFireNow = schedulerService.shouldFireNow(); - - assertTrue( shouldFireNow ); - - // Test 2 - doReturn( false ).when( schedulerService.blockoutManager ).shouldFireNow(); - - shouldFireNow = schedulerService.shouldFireNow(); - - assertFalse( shouldFireNow ); - - verify( schedulerService.blockoutManager, times( 2 ) ).shouldFireNow(); - - } - - @Test - public void testGetBlockStatus() throws Exception { - - JobScheduleRequest jobScheduleRequestMock = mock( JobScheduleRequest.class ); - BlockStatusProxy blockStatusProxyMock = mock( BlockStatusProxy.class ); - IJobTrigger jobTrigger = mock( IJobTrigger.class ); - - doReturn( jobTrigger ).when( schedulerService ).convertScheduleRequestToJobTrigger( jobScheduleRequestMock ); - doReturn( true ).when( schedulerService.blockoutManager ).isPartiallyBlocked( jobTrigger ); - doReturn( true ).when( schedulerService.blockoutManager ).willFire( jobTrigger ); - doReturn( blockStatusProxyMock ).when( schedulerService ).getBlockStatusProxy( anyBoolean(), anyBoolean() ); - - // Test 1 - BlockStatusProxy blockStatusProxy = schedulerService.getBlockStatus( jobScheduleRequestMock ); - - assertNotNull( blockStatusProxy ); - - // Test 2 - doReturn( false ).when( schedulerService.blockoutManager ).isPartiallyBlocked( jobTrigger ); - - blockStatusProxy = schedulerService.getBlockStatus( jobScheduleRequestMock ); - - assertNotNull( blockStatusProxy ); - - verify( schedulerService, times( 2 ) ).convertScheduleRequestToJobTrigger( jobScheduleRequestMock ); - verify( schedulerService.blockoutManager, times( 2 ) ).isPartiallyBlocked( jobTrigger ); - verify( schedulerService, times( 2 ) ).getBlockStatusProxy( anyBoolean(), anyBoolean() ); - verify( schedulerService.blockoutManager, times( 1 ) ).willFire( jobTrigger ); - } - - @Test - public void testGetBlockStatusException() throws Exception { - - JobScheduleRequest jobScheduleRequestMock = mock( JobScheduleRequest.class ); - - doThrow( new SchedulerException( "" ) ).when( schedulerService ).convertScheduleRequestToJobTrigger( jobScheduleRequestMock ); - - try { - schedulerService.getBlockStatus( jobScheduleRequestMock ); - fail(); - } catch ( SchedulerException e ) { - // Should catch the exception - } - - verify( schedulerService ).convertScheduleRequestToJobTrigger( jobScheduleRequestMock ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListenerTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListenerTest.java deleted file mode 100644 index 3fb1a08f3de..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/context/PentahoSystemReadyListenerTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/*! - * - * 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-2021 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.context; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPlatformPlugin; -import org.pentaho.platform.api.engine.IPlatformReadyListener; -import org.pentaho.platform.api.engine.IPluginManager; -import org.pentaho.platform.api.engine.IPluginProvider; -import org.pentaho.platform.api.engine.PluginLifecycleException; -import org.pentaho.platform.engine.core.system.PentahoSystem; - -import javax.servlet.ServletContextEvent; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.when; - -/** - * Created by rfellows on 10/28/15. - */ -@RunWith( MockitoJUnitRunner.class ) -public class PentahoSystemReadyListenerTest { - - PentahoSystemReadyListener systemReadyListener; - - @Mock ServletContextEvent contextEvent; - @Mock IPluginManager pluginManager; - @Mock IPluginProvider pluginProvider; - @Mock IPlatformPlugin pluginA; - @Mock IPlatformPlugin pluginB; - @Mock ClassLoader classLoader; - - List pluginList; - - @Before - public void setUp() throws Exception { - systemReadyListener = new PentahoSystemReadyListener(); - PentahoSystem.registerObject( pluginManager ); - PentahoSystem.registerObject( pluginProvider ); - pluginList = new ArrayList<>(); - pluginList.add( pluginA ); - pluginList.add( pluginB ); - - } - - @After - public void tearDown() throws Exception { - PentahoSystem.clearObjectFactory(); - } - - @Test - public void testContextInitialized() throws Exception { - when( pluginProvider.getPlugins( nullable( IPentahoSession.class ) ) ).thenReturn( pluginList ); - - when( pluginA.getLifecycleListenerClassname() ).thenReturn( TestReadyListener.class.getName() ); - when( pluginA.getId() ).thenReturn( "PluginA" ); - when( pluginB.getLifecycleListenerClassname() ).thenReturn( "" ); - - when( pluginManager.getClassLoader( "PluginA" ) ).thenReturn( classLoader ); - Class clazz = TestReadyListener.class; - when( classLoader.loadClass( TestReadyListener.class.getName() ) ).thenReturn( clazz ); - - systemReadyListener.contextInitialized( contextEvent ); - assertTrue( TestReadyListener.readyCalled ); - } - - @Test - public void testContextDestroyed() throws Exception { - // no-op, calling for code coverage - systemReadyListener.contextDestroyed( contextEvent ); - } - - static class TestReadyListener implements IPlatformReadyListener { - static boolean readyCalled = false; - - public TestReadyListener() { - readyCalled = false; - } - - @Override public void ready() throws PluginLifecycleException { - // to verify this is called in the new instance created within the listener, we are going to - // set a static property that we can check. we don't have the luxury of getting at the actual instance. - readyCalled = true; - } - } - -} diff --git a/repository/src/test/resources/solution/system/data/hibernate.properties b/repository/src/test/resources/solution/system/data/hibernate.properties index ac1d33563f3..110bff575a0 100644 --- a/repository/src/test/resources/solution/system/data/hibernate.properties +++ b/repository/src/test/resources/solution/system/data/hibernate.properties @@ -1,17 +1,17 @@ -#HSQL Database Engine 1.8.0.5 -#Wed Aug 16 11:09:15 EDT 2017 -hsqldb.script_format=0 -runtime.gc_interval=0 -sql.enforce_strict_size=false -hsqldb.cache_size_scale=8 -readonly=false -hsqldb.nio_data_file=true -hsqldb.cache_scale=14 -version=1.8.0 -hsqldb.default_table_type=memory -hsqldb.cache_file_scale=1 -hsqldb.log_size=200 -modified=yes -hsqldb.cache_version=1.7.0 -hsqldb.original_version=1.8.0 -hsqldb.compatible_version=1.8.0 +#HSQL Database Engine 1.8.0.5 +#Wed Oct 04 12:47:30 EDT 2023 +hsqldb.cache_version=1.7.0 +sql.enforce_strict_size=false +hsqldb.compatible_version=1.8.0 +hsqldb.cache_scale=14 +hsqldb.nio_data_file=true +version=1.8.0 +runtime.gc_interval=0 +readonly=false +hsqldb.cache_file_scale=1 +hsqldb.cache_size_scale=8 +hsqldb.log_size=200 +hsqldb.script_format=0 +hsqldb.default_table_type=memory +hsqldb.original_version=1.8.0 +modified=yes diff --git a/repository/src/test/resources/solution/system/data/hibernate.script b/repository/src/test/resources/solution/system/data/hibernate.script index 494ecad50a6..86a10da751d 100644 --- a/repository/src/test/resources/solution/system/data/hibernate.script +++ b/repository/src/test/resources/solution/system/data/hibernate.script @@ -1,205 +1,205 @@ -CREATE SCHEMA PUBLIC AUTHORIZATION DBA -CREATE MEMORY TABLE USERS(USERNAME VARCHAR(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR(50) NOT NULL,ENABLED BOOLEAN NOT NULL,DESCRIPTION VARCHAR(100)) -CREATE MEMORY TABLE AUTHORITIES(AUTHORITY VARCHAR(50) NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR(100)) -CREATE MEMORY TABLE GRANTED_AUTHORITIES(USERNAME VARCHAR(50) NOT NULL,AUTHORITY VARCHAR(50) NOT NULL,CONSTRAINT FK_GRANTED_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME),CONSTRAINT FK_GRANTED_AUTHORITIES_AUTHORITIES FOREIGN KEY(AUTHORITY) REFERENCES AUTHORITIES(AUTHORITY)) -CREATE MEMORY TABLE DATASOURCE(NAME VARCHAR(50) NOT NULL PRIMARY KEY,MAXACTCONN INTEGER,DRIVERCLASS VARCHAR(50) NOT NULL,IDLECONN INTEGER,USERNAME VARCHAR(50) NOT NULL,PASSWORD VARCHAR(150) NOT NULL,URL VARCHAR(100) NOT NULL,QUERY VARCHAR(100),WAIT INTEGER) -CREATE MEMORY TABLE BDPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(50),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE BGCONTENTID(BGCONTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,BGUSER VARCHAR(100) NOT NULL) -CREATE MEMORY TABLE CONTENTITEM(CONTITEMID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,NAME VARCHAR(200) NOT NULL,PARENT_ID VARCHAR(100),PATH VARCHAR(1024) NOT NULL,TITLE VARCHAR(200) NOT NULL,MIMETYPE VARCHAR(100),URL VARCHAR(254),LATESTVERNUM INTEGER,EXTENSION VARCHAR(10) NOT NULL,WRITEMODE INTEGER NOT NULL,CONSTRAINT SYS_CT_61 UNIQUE(PATH)) -CREATE MEMORY TABLE CONTENTLOCATION(CONTENTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,NAME VARCHAR(200) NOT NULL,SOLNID VARCHAR(100) NOT NULL,DESCRIPTION VARCHAR(200) NOT NULL,DIRPATH VARCHAR(1024) NOT NULL,CONSTRAINT SYS_CT_65 UNIQUE(DIRPATH)) -CREATE MEMORY TABLE CONTITEMFILE(CONTIFILEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,OSFILENAME VARCHAR(200) NOT NULL,OSPATH VARCHAR(1024) NOT NULL,ACTNAME VARCHAR(100) NOT NULL,PARENT_ID VARCHAR(100),FILESIZE BIGINT,FILEDATETIME TIMESTAMP NOT NULL,ISINITIALIZED INTEGER,CONSTRAINT FK7FC3F44164D906F3 FOREIGN KEY(PARENT_ID) REFERENCES CONTENTITEM(CONTITEMID)) -CREATE MEMORY TABLE CPLXPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE DTPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE TIMESTAMP,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE LNGPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE BIGINT,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE LSPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARCHAR,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE PARAMTYPESMAP(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(25),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) -CREATE MEMORY TABLE PRO_ACLS_LIST(ACL_ID VARCHAR(100) NOT NULL,ACL_MASK INTEGER NOT NULL,RECIP_TYPE INTEGER NOT NULL,RECIPIENT VARCHAR(255) NOT NULL,ACL_POSITION INTEGER NOT NULL,PRIMARY KEY(ACL_ID,ACL_POSITION)) -CREATE MEMORY TABLE PRO_FILES(FILE_ID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,PARENT VARCHAR(100),FILENAME VARCHAR(255) NOT NULL,FULLPATH VARCHAR(1024) NOT NULL,DATA VARBINARY(1000000000),DIRECTORY BOOLEAN NOT NULL,LASTMODIFIED BIGINT NOT NULL,CHILD_ID VARCHAR(100),CONSTRAINT SYS_CT_83 UNIQUE(FULLPATH),CONSTRAINT FK94A87E2569FABF5E FOREIGN KEY(CHILD_ID) REFERENCES PRO_FILES(FILE_ID),CONSTRAINT FK94A87E25CBBBB0EA FOREIGN KEY(PARENT) REFERENCES PRO_FILES(FILE_ID)) -CREATE MEMORY TABLE PRO_SCHEDULE(SCHEDULEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SCHEDTITLE VARCHAR(200) NOT NULL,SCHEDREF VARCHAR(1024) NOT NULL,SCHEDDESC VARCHAR(50) NOT NULL,CRONSTRING VARCHAR(256),REPEATCOUNT INTEGER,REPEATINTERVAL INTEGER,STARTDATE TIMESTAMP,ENDDATE TIMESTAMP,GROUPNAME VARCHAR(50),LAST_TRIGGER TIMESTAMP) -CREATE MEMORY TABLE PRO_SUBCONTENT(SUBCONTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SUBCONTTYPE VARCHAR(255) NOT NULL,SUBCONTACTREF VARCHAR(1024) NOT NULL,CONSTRAINT SYS_CT_89 UNIQUE(SUBCONTACTREF)) -CREATE MEMORY TABLE PRO_SUBCONTPARMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(100) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FKF3CE4C47846761A FOREIGN KEY(ITEMID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) -CREATE MEMORY TABLE PRO_SUBCONT_SCHEDLIST(SCHEDULEID VARCHAR(100) NOT NULL,ELT VARCHAR(100) NOT NULL,SCHEDID INTEGER NOT NULL,PRIMARY KEY(SCHEDULEID,SCHEDID),CONSTRAINT FKF0D3FBD69E226721 FOREIGN KEY(ELT) REFERENCES PRO_SCHEDULE(SCHEDULEID),CONSTRAINT FKF0D3FBD62593BC9E FOREIGN KEY(SCHEDULEID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) -CREATE MEMORY TABLE PRO_SUBSCRIBE(SUBSCRID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SUBSCRTYPE INTEGER NOT NULL,SUBSCRUSER VARCHAR(100) NOT NULL,SUBSCRTITLE VARCHAR(200) NOT NULL,SUBSCR_CONTID VARCHAR(100),SUBSCRDEST VARCHAR(200),CONSTRAINT FK5E7511F89D8AC376 FOREIGN KEY(SUBSCR_CONTID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) -CREATE MEMORY TABLE PRO_SUBSCRPARMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(100) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FK95DADE9355DC7DE8 FOREIGN KEY(ITEMID) REFERENCES PRO_SUBSCRIBE(SUBSCRID)) -CREATE MEMORY TABLE PRO_SUBS_SCHEDLIST(SCHEDULEID VARCHAR(100) NOT NULL,ELT VARCHAR(100) NOT NULL,SCHEDID INTEGER NOT NULL,PRIMARY KEY(SCHEDULEID,SCHEDID),CONSTRAINT FK2A8C749B9E226721 FOREIGN KEY(ELT) REFERENCES PRO_SCHEDULE(SCHEDULEID),CONSTRAINT FK2A8C749B7329C46C FOREIGN KEY(SCHEDULEID) REFERENCES PRO_SUBSCRIBE(SUBSCRID)) -CREATE MEMORY TABLE RTELEMENT(INSTANCEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,PARID VARCHAR(254),PARTYPE VARCHAR(50),SOLNID VARCHAR(254),READONLY BOOLEAN,CREATED TIMESTAMP NOT NULL) -CREATE MEMORY TABLE SSPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(254),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FK60E4AFE6FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID)) -CREATE MEMORY TABLE USER_SETTINGS(USER_SETTINGS_ID BIGINT NOT NULL PRIMARY KEY,USERNAME VARCHAR(50) NOT NULL,SETTING_NAME VARCHAR(100) NOT NULL,SETTING_VALUE VARCHAR(2048) NOT NULL) -ALTER TABLE BDPARAMS ADD CONSTRAINT FK61733C48FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE CONTENTITEM ADD CONSTRAINT FK692B5EEC44F32395 FOREIGN KEY(PARENT_ID) REFERENCES CONTENTLOCATION(CONTENTID) -ALTER TABLE CPLXPARAMS ADD CONSTRAINT FKD6D6E97FFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE DTPARAMS ADD CONSTRAINT FK7F994A16FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE LNGPARAMS ADD CONSTRAINT FKE304FCCBFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE LSPARAMS ADD CONSTRAINT FK89BC75CDFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE PARAMTYPESMAP ADD CONSTRAINT FKD3EDA1B0FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) -ALTER TABLE PRO_ACLS_LIST ADD CONSTRAINT FKB65646C2B23C5D30 FOREIGN KEY(ACL_ID) REFERENCES PRO_FILES(FILE_ID) -CREATE USER SA PASSWORD "" -CREATE USER HIBUSER PASSWORD "PASSWORD" -CREATE USER PENTAHO_USER PASSWORD "PASSWORD" -GRANT DBA TO SA -GRANT DBA TO HIBUSER -GRANT DBA TO PENTAHO_USER -SET WRITE_DELAY 20 -SET SCHEMA PUBLIC -INSERT INTO USERS VALUES('admin','password',TRUE,NULL) -INSERT INTO USERS VALUES('cooldude','password',TRUE,'password1212') -INSERT INTO USERS VALUES('pat','password',TRUE,NULL) -INSERT INTO USERS VALUES('suzy','password',TRUE,NULL) -INSERT INTO USERS VALUES('tiffany','password',TRUE,NULL) -INSERT INTO AUTHORITIES VALUES('Administrator','Administrator') -INSERT INTO AUTHORITIES VALUES('Anonymous','User has not logged in') -INSERT INTO AUTHORITIES VALUES('Authenticated','User has logged in') -INSERT INTO AUTHORITIES VALUES('Business Analyst','Business Analyst Role') -INSERT INTO AUTHORITIES VALUES('Power User','Power User Role') -INSERT INTO AUTHORITIES VALUES('Report Author','Report Author Role') -INSERT INTO AUTHORITIES VALUES('ultimate','ultimate') -INSERT INTO GRANTED_AUTHORITIES VALUES('admin','Administrator') -INSERT INTO GRANTED_AUTHORITIES VALUES('admin','Authenticated') -INSERT INTO GRANTED_AUTHORITIES VALUES('suzy','Power User') -INSERT INTO GRANTED_AUTHORITIES VALUES('suzy','Authenticated') -INSERT INTO GRANTED_AUTHORITIES VALUES('pat','Business Analyst') -INSERT INTO GRANTED_AUTHORITIES VALUES('pat','Authenticated') -INSERT INTO GRANTED_AUTHORITIES VALUES('tiffany','Report Author') -INSERT INTO GRANTED_AUTHORITIES VALUES('tiffany','Authenticated') -INSERT INTO GRANTED_AUTHORITIES VALUES('cooldude','Authenticated') -INSERT INTO GRANTED_AUTHORITIES VALUES('cooldude','Power User') -INSERT INTO DATASOURCE VALUES('Hibernate',20,'org.hsqldb.jdbcDriver',5,'hibuser','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/hibernate','select * from users',1000) -INSERT INTO DATASOURCE VALUES('Quartz',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/quartz','select * from orders',1000) -INSERT INTO DATASOURCE VALUES('SampleData',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/sampledata','select * from orders',1000) -INSERT INTO DATASOURCE VALUES('SampleDataAdmin',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/sampledata','select * from orders',1000) -INSERT INTO CONTENTITEM VALUES('170521e0-7b5d-11dd-b851-9b2343f3bcd9',0,'MyXML.xml','170521df-7b5d-11dd-b851-9b2343f3bcd9','!CONTREPTEST.FOLDER_PATH!/MyXML.xml','!CONTREPTEST.ITEM_TITLE!','text/xml',NULL,0,'.xml',0) -INSERT INTO CONTENTLOCATION VALUES('170521df-7b5d-11dd-b851-9b2343f3bcd9',0,'!CONTREPTEST.FOLDER_NAME!','ca825b3b-eb03-11d9-ad29-005056c00008','!CONTREPTEST.FOLDER_DESCRIPTION!','!CONTREPTEST.FOLDER_PATH!') -INSERT INTO CONTITEMFILE VALUES('170792e1-7b5d-11dd-b851-9b2343f3bcd9',1,'170792e1-7b5d-11dd-b851-9b2343f3bcd9.xml','!CONTREPTEST.FOLDER_PATH!','!CONTREPTEST.ACTION_NAME!','170521e0-7b5d-11dd-b851-9b2343f3bcd9',27,'2008-09-05 11:12:43.953000000',-1) -INSERT INTO CONTITEMFILE VALUES('170792e2-7b5d-11dd-b851-9b2343f3bcd9',1,'170792e2-7b5d-11dd-b851-9b2343f3bcd9.xml','!CONTREPTEST.FOLDER_PATH!','!CONTREPTEST.ACTION_NAME_2!','170521e0-7b5d-11dd-b851-9b2343f3bcd9',28,'2008-09-05 11:12:43.953000000',-1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',0) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',1) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',2) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',3) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',4) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',5) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',6) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',7) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',8) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',9) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',10) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',11) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',12) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',13) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',14) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',15) -INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',16) -INSERT INTO PRO_FILES VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',1,NULL,'solution','/solution',NULL,TRUE,1214444693000,NULL) -INSERT INTO PRO_FILES VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',1,'6b1644df-6757-11dd-a492-c111aa2b74dc','samples','/solution/samples',NULL,TRUE,1214444693000,'6b1644df-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',129,'6b1c3850-6757-11dd-a492-c111aa2b74dc','reporting','/solution/samples/reporting',NULL,TRUE,1214444694000,'6b1c3850-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',1,'6b1644df-6757-11dd-a492-c111aa2b74dc','test','/solution/test',NULL,TRUE,1218380602000,'6b1644df-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','dashboard','/solution/test/dashboard',NULL,TRUE,1218380623000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','datasources','/solution/test/datasources',NULL,TRUE,1214444693000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','platform','/solution/test/platform',NULL,TRUE,1214444691000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','tmp','/solution/test/tmp',NULL,TRUE,1218426075000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b264a77-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFree-quadrant-budget-hsql.png','/solution/samples/reporting/JFree-quadrant-budget-hsql.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000002b744558744372656174696f6e2054696d650046726920352041756720323030352031363a31333a3330202d303530309f930d620000000774494d4507d50805140d3001d1d982000000097048597300000b1200000b1201d2dd7efc0000000467414d410000b18f0bfc6105000017bb4944415478dad45a6b6c1cd775bef7ce9df7ecce3e49ee92122d51a21e966cd97212a548041bb153db305aa04150343f6220285a2028faf895feeb9f22010a1871fbaf3f1aa00960b4400ba705e2022d62bb501cbbb26cd99225511225527c2df7bdb33befb98fde21296a49d14a21c9527530d05eddb973ee39f73cbe736608f77e7f36d4cd7ea8030aee1ff1fbc385df3d1f4b43d3a38ae3d38c8192049871732ca92f7424ecad745eff33fedabfb53533c739ad0dd0fe6cb4126a94b2bd79beec49a6cc07219b280013b2568cc290794cc9624a25c973493e836492b4a8822540225632582bc206a696cc6aae54d0a19f001df3550f510e25c86d8d4b0a2201c91a60108218e0712339bda854f20443c820b2649a04ccc8a41bf53cb4bbc8eb03d88bb00209c2d052a1109f229c1e29867d1f4cdab193281f2fa0a3937c424daeb640c4f17c075546e531a62441f43b4f58b3b5e8dbfcd471e5daf73f2de3012c9fbeee7551218bd451336a27788e9a459b1006eb31b53220a192cfe4469c00423946ba464c88bc58ce69cce7ca6280b21ad7351a450067708770c3a4ab03ddc6dccc02c229e710a84ca23221b46a339ff2ac0aba548db054b0632f911a4c55142a996a117a3ec0ab81955783aa1dcd71dd90500f20ac24328463592463102428c0bac2e318c8827521c74d0ba961acdae500441da8c40ace9b3456d544c2bb47c2390f5e5a0a6b1e6972e2b095489d867ff4378bcf7fd5e2a9ff0078d39300841b6eb9ee53f0e6ed5b2ec6d75d0ec24df7636083c1363fdce4c3b74fa63f1caeffac0f6edde61b926c8ab43d5886b8f11d386f0e20c286550ecfbce51f3cf6e119191fde855e7a5afdecfccce252edc5179f3d7f7ea6b1ba7cf0c8d14ac97ee79d5366c6feca89e34b4bf5c51bd710c284c47edf3df9cd6f847de7d2ccd55ed7f9da7327c32039f7f18758514f9efceacd9db6edca874f8adf9ae1436704b76a056fdde5eb16d8387b3e6c896d1b6d3d97f529840032d47f3fbffcd4be7ed47d09fedd3f2fbffa92d5eb7673f99c5832705d5dd3242c71c65cd7cd64b3eb0f3abd9e9dcb6d328da28831aaebba1827491c06a16e1858423b1cfffa031cec6c9c5b9adf66227e4bbbe16787266e3bd61d1e04489265bdd8ab5f29168c9ffc878685572224e78be5300c354dcbdaf98d8512b7f32aa32c218908b27ca124b6f222c1885abac42489728a9004580c033f6b17284d384051c274551a168591987322617d48cc0d13254922cb58ec207c278e1255c5623a08b988558ce186edd7a309409638003080d4c497836eac66b09c91e284ca98638c599a2a36fc8172264178334284e1a2c85dd64dd38f4014b4a5dffed69f3f7dc068361b83bee3fbbe2454100918498c1204d1d2e262df7184c1539b73a0d697ae2f78a5b1cc52d0fc970bbf7a7a6c8f76f9efc9a01b5b7b8575eb01ae0115f51a61e07b9e9f3a8b0268f73f817fbad1cb8509109ed06a75a230322dfdc3d5d3a7ae5fb668266ba96ecf07fd6b2ecba8aad470253f48d6b084d69b032192105e7853c65cb0f261ec79a77ed8aafd6a1e6b491316aece9eb35462eaf2bb0bf3179ad274493dbf507ff7c2ec91dda3e066b40c87d8a757132462837112f87e12c741e0511227021678029158455d6f4088b813aead232b8d81cf85dfd24b8d45451de58cbeaffdfe7be1094768433db670a6c23d4ae31bf3731dc7111b2259e3fe6506b8951fedb4569bada6e0b6b8b8c438eb9065439dc492b02abd91d8e7f197fd2814e3a45fbf72f1d320f409891a8d26a544585e115ed33d4f97dea641f34b7fb26beae419aabcdba8bb02b1fcd08f235fedf9572fde10a050e3c14c33f06322300e400ac505588a77e925c614fef88d85efbd62534a3b9d4eb15444e23cd712c8fa918451e47b6e3e5f583b17d06a05227b944a5abb1392848d9435e1c38c715d45c1a02bab96acca4351960e48d0065092b5ec6642b9999d78afe7d9b62162a1db972c03e85aba6d1046fdbe3732921b4ada2927e6cf31e24b99fd0062ea36052c71649224d075555664117a240e154d1709ce8b8925a2630356b664877ffc8507fff69f16befba2b1991ba2840aac4b08c959da4e39e6eee81e39f02de9fcff463d8fbb7e6c5a2b17dab3d3d95d15b324267ffa0b0f0bfb0c9c6ebdd19244fe8640b3f2ff3a8f8f68a42cd524108f562bd7ae5c1b1dc9d5da7d5bb70c1dd51a8e0c13c32ec461a21bb21b045933e3b9fdac6dbb9eab2a9af00488b8efc7baa1077e68662c05f15edfd54ddd69f7453121128fc8ffe3e323a11751c6250409e4240ca9800f5d03946aa6c508f18210708215cc992c4ba0effa8a8c0cd3607184358b249eeb91ea78a5d76c98f9e2c1e9bddb149e5de9ac76398f661adcebde6864568d679f13a849b1084e2b9b951545d534e100414cbf517605284d54aa3d6780009b3a749026e1e1d1f13008344d31f3651115c2d53521bb04ca40a2493c561d8b091da954fc209031460886510c2114c90e22499525dd0e444c144ae5346b27c9e8f858c6b2e228743ddf324d9163dbed66369bc29e785c205cb3d118c96524415861446003a252a798b735dd74fb5d1121009876816b9aae4c8c635969777bdb143675300a718cecd9d6c2d7abc7a70f4faef90782afbf31ffea4b66fa9fad1e2f7c9b88f31f76aa9bd5c030caede467370b0338f4ef36a804c05010429b73c3dc37cb14be95e57af5c17706ed2dcebfde74f08f3ffae4d8b1a3a2046cb9f4a32b0b2f3fb3e7a76ff9a20910b8c52e5c6b4f291ecc82b3f5ee71b3084747009427c6aaf7167b3bd3423d9aab2593f9a5998b1745fe3f7cf080100f01926656049238a956471cc711965f9d5fea2c2e1d3e79a2db73def9f0faf3cf4c0c5ce1e4b2c0682c412c8b1c8f0584c4312b97ed3479a6e52d127ed79eef681279faa9c70567a1dfe9b72e1e3bf77667df1f8bf3c26b351bedf5039f36290717679d27a6644fc5d9dcc817a16dea3b04b5dd70778e81abd7e57cb7ef8cd41addca585ed3339d46d30bc958a5a4288a90fe7a1d9a8625068376afc85de190ed563757b4078e03254c93e4b1a94951750c069ee875786a5d94a20ca7a20e90c632eca63b1c7f613aaeca8933e0dc80affdeceaab2fea7c1d9d3910b58b22a7a55298087f463b09cc3f7792ffc695a9088c8114c9642aacb4d3ca9b80917626f0565f711bc66c666ee11802d86f753f7cb38017502c114284cdd7effcecad100ffabd56b3071e38250f641708c94640a7f9980711c4aa661d3874f0c12bfc80298cc99bef2c32ccf0c396e43713a7318f521f0c90e5afbd872a1aba48b4826459de5c46d33806a21bd9918970e9c7768fcd2dad3c020a278b6f0fde7c490c7e5c79fd879744bd0d9a3ff8d3daf56b7122f2f0b1cd65dec071635e1d2d6dce745a0d3d9317a527588b6bc2e484804740e11d098bcc4ad9cce5cba2260802d7cc64561616f3e5b2e882ea4bf3d9427165b9b66b62ac2469eb0a0b5a2f2a1e0185a19ac3951362b0ab387662224e85468850eeb88382aa88648c6555147f9a967604b69d759a69c928605c948f9aaadee2031e1185dd6ce5d2f1ef88c1cbe792173e392706d61ffcdef8d8a8aee9a5821dc6a270a2aaaecb92626432a66194474745bb5f28140d435387425a91b8a8a31f018545bb1e918118105f219d3504e53c5f288a4b0ced9bcbf2f6c670d7e4e4ed4c2444f757a23319f808280c45c50fa574205a11f92e0516fe6ce992e8cc1e01850bd69e670ffe201d8972e13b7f788fdc528599d777fefb23e3f17de2285910438c7892205d6731e16e9f7384f3d9b4cca44434225052d5c92fa4a97830b466619666ece0d265296b917e884431ad4b51df477641d260d2a8278d5568da200c94dd5551063c6c99ef596194c9155e7e4e0ce2daaa592aa3b479d8422c0c00561096ee6283ff6f94f643611c9d5a5a0d09890bf9561c7b499250ea46e1f966c78fe3863be80169d5f712f6b085bd1fb4f6ee3b0acfac364fcdcf898e50e230ab2b5fdb336501d2f3fdbf3e7f216fe8794511caffe8f967e57bdeefa153aa703e63ffc53347450375bdd79fca6f021b9806e0eb93bb1fb6845f80c2e0ec9be0bf5e134835f5b0a5b9ff74f805f0ca5fdda6b04063d147100f480a50b220e80084c1600538ab0f5bde9d68ff73c0ef00b304221f2c9f0164ebab047b02e4c7d3494902411f84ceb6a7d7141648236e1b55103be95251855396a2eef1ef021e02ab04e2007417c0e55f3e087d9efc16c05afa8292bae0eccf7758e03bc02ca617dde9ad49faaa4a34816aca41cb0059db767f4de1411dccfd7a8787cfbe011463ede510078c3c086d055d7c0b48b2282301fb1cc05ffef84e8ff797d26b93c6a67752f8f8b7c1de130f489f074c46610785179bed99056fac5490b0e4b46a3d3799da3b2963f4eebbef3ffd5b27b83fa050e224a18c2b185300f3f9ecd4de4735c1a58547c62eecae5442df9770fa217862bc2242584c1e7bf270e47b61e8afae2c75071e4c3fb5c594d18c653d6cb1ef9e520be78a23e2da98d8b76ff35ebfd769347ba5f2c8f4a1270a43f8fc4550120c3efaf4826ada8ac89eb20c157930e81f3d727478cdcccca5300ced6cc6b032b5a57906b543871fd7d5ad0ddf95cb40d5401801dd00bd569ab7a6b738e39ddac3f493bf2ab1f47d38045f3041ac9a86c90041921a46beefc1f1eae876791828958a2b2bb53c8358cb224eb7cb25908551d0e903d1cff55d30f9580a375be97315168597aaa959810251e2bbbd566395505a2e9506ae57ad5640da62d12421ead04ba37b21128776a1d0efb62d33a3e04c863246481445c36b7443777afd917259d50de803dff5489244fcd65f107a4ea72d6b76c94e8280c9286937a1a4ed296cc95b9fabb0b0eafcdc4279a4dc68346c4b0f22d123aee42c6369a576e6830f34d35a5d59cee7b212c247bef495fd7beeb502859ccc5eb9922f9566af5c2ee7332b0d2797b3abd52d8df76aadb66f6acfb9cf3e13277ef9ea8de9e969d3d086bd6f9004b3d7e64c3b2b451143104be8d0a143db37fad13f5cfacbefedf0e54158388e774042cea8eb8719cbbc2f861d26c6d8da17542e1c67f80dfb6d0bd6fffc67a7468673c6b958430949bf222228c6eb2b491251467ef2f3c69d2cfc3f1fbc2f7e56eaada307f6de585c1d29647d2ac56eefe0134fbef7ce2f4b13bb65491af47abae89f318612761deff9179fbfbb708ffcfee90f3fedb6ebd5c9fd95a239b7daae968bfba6f60daff9f57bef0d7add5c79b4902f5cba720526e1375ff95d156ff9e277fe933304a9bee38e8c97176717c627771d38b07f78c19d62786affb49dc91cf07d04816a6630421cc07a0dc8c2559e3896b5b3224378f97cafefe432a6a88d0af99288babb539871343151ddb77f4a4063b3567bfcc08156b3b92d8677edde9d3d72a4dfef2baa76e2cbc74565c0a930dc163ea572a5db7747f74c3084a70fefcf64f3db36ba93853bed66ab596fb47b93d5513f660ae4969d1bab54eab5ba8291aaea2286ef4abb1d2861b1d31fd46b4dd3ce144ba5200c82c0db9611fb7dc769b604728c8c6ab5953a0dfc5ca164685b7cbb3f7034dda010f5dbed8404ce20b0b35baacb3bc192a699f95cceb46c110c523c8802bfd976caa59ce3749d5e17e9e67d5458c092aa2886ae94cad556a36666edf1895ddbd6c858b17276bbdd09825855642e5992b4fd0b76c63456db03539791ac18322e57c676b0700bb496c0d2761138580535e02061ea916a796d4aa0941a81c4da9fb540d603bdb3d1d9fba57077b9e5a14491a599c5996c31d7a95d14e852b28ac36b6ef8f31ad2634c74dae00a0b5d7f108532dba273cdad419d4561a25b2689e37e3f78c67e6abbc22c45ebdbfe1e1e8290fe6f37d7d6dbc67185cfde2fbcdf2fa224cb566cc3b121a028e2a6766f7062c74552f429af45f350f4a1edbf28fa3bd2c7f6b92e8aa0ed435b24ae83c6b1d0588a2e965849a44891bbe42ef77ee919ca48c92523bbb12803395a50e0ecec70ce9e9939e73be7cce8adc3dea06fe52fe460c66423c6358c245a1da1d1db5735cd81049515c66660b3b5cf0c64c73073a56cafdb0bfcb078a51609f876fb6d9cd98e4f1744afb1df1217a20622a99e877c16b2939d58b9bc0267162a3fbff2cc2a2b779ea3cef5913a97102a44c7fcd04d0b343d3d9de36b48c301b1f667f8f0b72fbb27b3a1f3afc3f77e3ec1b0aec2f647e00c882b4b4c81a99219ece830e8bcecfe4ea3ea3530148865c13641794200c328c50a206708ce083d702db41f224f0f196605c82d839400570397816c15020a0e3e859577c156c8f3ae0dfd06ecfef32cf8b9f8263c4dd17360edaf532a24ca50ba4c18c32ea9bbd1bba849f20b1032c49b8532cb54a631acd6e1f1bd294d1bf78807ef3841ca31ce825ba4c62a71a4312ce9ee545affe0a4c7bb5be4fa8252518c3964f8d53bf0b3df9d113f674cd9288c230c372dfaa15abab858f1d120a6d944328eb8f765f77456441866793e9b4eadadadf91425c9c9745cfa9a339c2fcde1854a3b72ef3ff5dd9eaac793722e5f4ac4e599f6c335f5cf9fecd9a69e4823fee7db5d2d9d4e54ca634bcef6f6b6ef7b34cd246252ababf83e5c7df50adaf9630dedee90288a20822c93d0042ee10bb5d1fb27d91b83816e79ae65188669cefac5530ce739566d61c91ef4f7f60f8aa562b7ab44ea68fd7eb954ee763b47471dec9aef3b41247d155594aa80e540f3101a0df002c84c332da712e2e1eadc3cfee34511ad705dd3389e27ee08c7e3780e912a623777e8121996bf2885818fa8d0f39c442a198fc768086b7373113c8cc8b4ab288b0b8ba224a130689af55d271a11a954718a92380bded074843e11cfc84978f8c3bfffcdb25d4bebf901aaa73c9886aa1be56a395f2a37f6ead96cb6dd6adba6e5a1115f2cdcbafdc68b306ce9bdfb0f1e6412f1f9e5cb5beb8f0f15ebe2a5a54bcb631e8fcd8d8d5c32f6c9a3d65239576fb668dfb971ebad7462247a8412dede84a60ab2088893972fc0610bc6bde827f9b4745d27f9f243c29983e640e007c772f6fde0b89ce42a073ec31038fb62220e2ddbc6118aa818a790280ad878c471e5380e96b843e2058124333113591838e86892574fac468eb87fb8e17ec1e7f2697df6f093e2e2d2d2c23ccc9e5c53fbf8e3074033021f2be7134d450d9de03bdfbd315a6775751597148a622bd5f9d6c65aa3ddbff5e61b72c4112f08d80e4a9ae6d0f4348be5dac5e5b10d2f27cde142a52a8be254dfe5a99317507373b57ca1685906c770c90c22702af2d3195cb853299e6570a22d2c5d4866fb38511d27ea6acfa433b822488914cef0fc847e3dc9c5433314cb704ae78817a4bd7afddcf9738228735f3517ee591cdb9aa60d0686144be6d31c2e4e99643a32a4fdc06f1eec795e98cde60c73e0d80ecdb0dc44ce1156e359c125cac5f0436a69714ca19e34a41dd77db2b3b9b7b5932f177b8ab25baffff09db7671476a1398163d96ca16868fd4ea75d995f44ed13f92dc7767385625c127bbd81284a2cc304c33850a4297c113d9c110c9b906385dc737b2dc942c570d7ae5ec3cb18e8a8286559726736bc03cf4da5331cf200d45c6dde751d9ee3226a299d494b82a8e946229d3406039ee771198dd4c1d75428550481f35cfcc351a3c7c757e99324bcb5b9fdd9a34fe38964a3d17cedb5ebaf8c7bb44f976cdfd9d9d9e929dd956f7e6b7d7d4d4ea57ddbaed5c68ca4dd9d1d720e80efe58ad57a7dd71f68d77f707b648f24a1f6e1c176bd5daee4345543a301955c041f12b5f4abf7167a104dfe20890e4ee8d8166a1c869979f47098571152433bd1755cb46d26abfc2fd4f225154833c3411ef85e380cb548b494e1c8a81e534b3ae80770107d94827ffde32345b54ccd79fb27b767cdefd6837f6fee75aac5f4e7abeb85b9620ba5b45cbb79672c11e3defb7f88a5e3478dd6f2cae5dee1615f71effef46e64c9a26c27fbfbbf50b6692f2fd2035b482ec0cd1f8d554009fff2bdf9291206b2551cd7097cf7624c8419936b3bfe7013174d531e39a8036d0a3a22465337c2101876b8e57e381838919f1c7bb441368200da46922887629a234ef53109c72086d7945e60cbb3c54823341a54f9b2d7fb9c9916d3fbfcf48c806327de11a8fb67c5d9d9929c39767af821fda7fb6aa71fb06824078f3f803ffee665776d3674f52efcf8d740a2937e3229d0b4c1e2d4b9e75c79e5ddf7c9521cfa109ee619442f48e3e79744b7241f172a8ed974a92a30a9181784014d4d20fc8da7896c352904db65eb03da694ab4ba61e82acb5337befd0dea1436fd9f0e0501413ec79f91af5f14da3df9d19617709d7650efa8dab9c55257316d4bf7dcf0e6f75f17470c4f44753c6f52effce27e2976542c261972c244005fed44a7c91309464bfecff30a46044a3d3d18e8b857a35f470a7b2ac24946109e91cd8d80f6e19afb5fc83f5dc56ad3ae760000000049454e44ae426082',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b26bfa8-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFree_Quad.xaction','/solution/samples/reporting/JFree_Quad.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e20200a202020203c726573756c742d747970653e7265706f72743c2f726573756c742d747970653e20200a202020203c69636f6e3e4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574732f3e0a0a20203c7265736f75726365733e200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a4672656551756164466f72526567696f6e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e53514c20517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c7420747970653d22726573756c742d736574222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c6c6976653e747275653c2f6c6976653e20200a20202020202020203c71756572793e3c215b43444154415b73656c6563742020205155414452414e545f41435455414c532e524547494f4e2c2020205155414452414e545f41435455414c532e4445504152544d454e542c2020205155414452414e545f41435455414c532e504f534954494f4e5449544c452c2020205155414452414e545f41435455414c532e41435455414c2c2020205155414452414e545f41435455414c532e4255444745542c2020205155414452414e545f41435455414c532e56415249414e4345202066726f6d205155414452414e545f41435455414c53206f72646572206279205155414452414e545f41435455414c532e524547494f4e2c205155414452414e545f41435455414c532e4445504152544d454e545d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e437265617465205265706f7274205573696e6720517565727920526573756c74733c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d2271756572792d726573756c74222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6f75747075742d747970653e68746d6c3c2f6f75747075742d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b27aa09-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFreeQuadForRegion.xml','/solution/samples/reporting/JFreeQuadForRegion.xml','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a3c21444f4354595045207265706f7274205055424c494320222d2f2f4a467265655265706f72742f2f445444207265706f727420646566696e6974696f6e2f2f454e2f2f73696d706c652f76657273696f6e20302e382e35220d0a20202020202020202020202020202020202020202020202022687474703a2f2f6a667265657265706f72742e736f75726365666f7267652e6e65742f7265706f72742d3038352e647464223e0d0a3c212d2d0d0a2020546865207265706f7274206e65656473204a467265655265706f727420302e382e36206f7220746865206d6573736167652d6669656c640d0a2020636f6e74656e74732077696c6c206c6f6f6b2066756e6e792e0d0a2d2d3e0d0a3c7265706f727420626f74746f6d6d617267696e3d22333622206c6566746d617267696e3d22333622206e616d653d225175616472616e7420466f7220526567696f6e22206f7269656e746174696f6e3d22706f727472616974222070616765666f726d61743d224c4554544552222072696768746d617267696e3d2233362220746f706d617267696e3d223336223e0d0a20203c212d2d205468697320697320776861742069732063616c6c656420277469746c652720696e204a61737065725265706f727473202d2d3e0d0a20203c7061676568656164657220666f6e746e616d653d22417269616c2220666f6e7473697a653d223130223e0d0a202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d223135222077696474683d22313030252220783d22302220793d2232223e50656e7461686f2053616d706c65205265706f72743c2f6c6162656c3e0d0a202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d223135222077696474683d22313030252220783d22302220793d223137223e4a467265655265706f72743c2f6c6162656c3e0d0a20203c2f706167656865616465723e0d0a20203c70616765666f6f7465723e0d0a202020203c212d2d3c6d6573736167652d6669656c6420616c69676e6d656e743d2263656e7465722220666f6e746e616d653d22417269616c2220666f6e7473697a653d223130220d0a20206865696768743d223135222077696474683d22313030252220783d2230223e2428506167656f665061676573293c2f6d6573736167652d6669656c643e0d0a2d2d3e0d0a20203c2f70616765666f6f7465723e0d0a20203c7265706f72746865616465723e0d0a202020203c72656374616e676c6520636f6c6f723d22233030393939392220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223230222077696474683d22313030252220783d22302220793d2230222f3e0d0a202020203c6c6162656c20616c69676e6d656e743d226c6566742220636f6c6f723d2277686974652220666f6e746e616d653d22417269616c20556e69636f6465204d532220666f6e7473697a653d2231342220666f6e747374796c653d22626f6c6422206865696768743d2232302220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d22313030252220783d22302220793d2230223e526567696f6e616c205265706f72743c2f6c6162656c3e0d0a202020203c212d2d3c696d6167657265662064796e616d69633d2266616c736522206865696768743d22343022206b656570417370656374526174696f3d2266616c7365220d0a20207363616c653d2274727565220d0a20207372633d22687474703a2f2f6c6f63616c686f73743a383038302f70656e7461686f2f696d616765732f7175616472616e745f6c6f676f2e676966220d0a202077696474683d223330252220783d223730252220793d223235222f3e0d0a2d2d3e0d0a20203c2f7265706f72746865616465723e0d0a20203c67726f7570733e0d0a202020203c67726f7570206e616d653d22526567696f6e47726f7570223e0d0a2020202020203c6669656c64733e0d0a20202020202020203c6669656c643e524547494f4e3c2f6669656c643e0d0a2020202020203c2f6669656c64733e0d0a2020202020203c67726f757068656164657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231322220666f6e747374796c653d22626f6c64223e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d222330303939393922206865696768743d2231382220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d22313030252220783d22302220793d2235223e526567696f6e3a202428524547494f4e293c2f6d6573736167652d6669656c643e0d0a2020202020203c2f67726f75706865616465723e0d0a2020202020203c67726f7570666f6f74657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231322220666f6e747374796c653d22626f6c64222070616765627265616b2d61667465722d7072696e743d2274727565223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d22233030393939392220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223135222077696474683d22313030252220783d22302220793d2230222f3e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d22776869746522206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223535252220783d22302220793d2230223e2428524547494f4e2920546f74616c3c2f6d6573736167652d6669656c643e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e41637475616c2220666f726d61743d2224232c23233022206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223535252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e4275646765742220666f726d61743d2224232c23233022206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223730252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e56617269616e63652220666f726d61743d2224232c23233022206865696768743d22313522206e616d653d2256617269616e636520526567696f6e204669656c642220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223835252220793d2230222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22353625222078323d22373025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22373125222078323d22383525222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22383625222078323d2231303025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22353625222078323d22373025222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22373125222078323d22383525222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22383625222078323d2231303025222079313d223137222079323d223137222f3e0d0a20202020202020203c72656374616e676c6520636f6c6f723d227768697465222066696c6c3d227472756522206865696768743d223134222077696474683d22313030252220783d22302220793d223138222f3e0d0a2020202020203c2f67726f7570666f6f7465723e0d0a202020203c2f67726f75703e0d0a202020203c67726f7570206e616d653d224465706172746d656e7447726f7570223e0d0a2020202020203c6669656c64733e0d0a20202020202020203c6669656c643e524547494f4e3c2f6669656c643e0d0a20202020202020203c6669656c643e4445504152544d454e543c2f6669656c643e0d0a2020202020203c2f6669656c64733e0d0a2020202020203c67726f757068656164657220636f6c6f723d2277686974652220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231302220666f6e747374796c653d22626f6c6422207265706561743d2274727565223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d22234646363630302220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223135222077696474683d22313030252220783d22302220793d2230222f3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d226c65667422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d22302220793d2230223e4465706172746d656e743c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d226c65667422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223430252220783d223135252220793d2230223e506f736974696f6e3c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223535252220793d2230223e41637475616c3c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223730252220793d2230223e4275646765743c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223835252220793d2230223e56617269616e63653c2f6c6162656c3e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d22626c61636b2220666f6e7473697a653d22313222206865696768743d223135222077696474683d22313030252220783d22302220793d223136223e24284445504152544d454e54293c2f6d6573736167652d6669656c643e0d0a2020202020203c2f67726f75706865616465723e0d0a2020202020203c212d2d0d0a2020202020204279207370656369666979696e6720612062616e642068656967687420746861742069732067726561746572207468616e2074686520757365642073697a652c2077650d0a202020202020656e666f72636520736f6d6520656d707479207370616365206265747765656e207468652067726f7570732e0d0a2020202020202d2d3e0d0a2020202020203c67726f7570666f6f74657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231312220666f6e747374796c653d22626f6c64223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d2223363646463636222066696c6c3d227472756522206865696768743d223134222077696474683d223835252220783d223135252220793d2230222f3e0d0a20202020202020203c6c6162656c206865696768743d223134222077696474683d223430252220783d223135252220793d2230223e546f74616c3c2f6c6162656c3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e7441637475616c2220666f726d61743d2224232c23233022206865696768743d223134222077696474683d223135252220783d223535252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e744275646765742220666f726d61743d2224232c23233022206865696768743d223134222077696474683d223135252220783d223730252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e7456617269616e63652220666f726d61743d2224232c23233022206865696768743d22313422206e616d653d2256617269616e6365204465706172746d656e74204669656c64222077696474683d223135252220783d223835252220793d2230222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22353625222078323d22373025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22373125222078323d22383525222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22383625222078323d2231303025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22353625222078323d22373025222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22373125222078323d22383525222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22383625222078323d2231303025222079313d223137222079323d223137222f3e0d0a20202020202020203c72656374616e676c6520636f6c6f723d227768697465222066696c6c3d227472756522206865696768743d223134222077696474683d22313030252220783d22302220793d223138222f3e0d0a2020202020203c2f67726f7570666f6f7465723e0d0a202020203c2f67726f75703e0d0a20203c2f67726f7570733e0d0a20203c212d2d205468697320697320776861742069732063616c6c6564202764657461696c2720696e204a61737065725265706f727473202d2d3e0d0a20203c6974656d7320666f6e746e616d653d22417269616c2220666f6e7473697a653d2231302220766572746963616c2d616c69676e6d656e743d226d6964646c65223e0d0a202020203c737472696e672d6669656c64206669656c646e616d653d22504f534954494f4e5449544c4522206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223430252220783d223135252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d2241435455414c2220666f726d61743d2224232c23233022206865696768743d223135222077696474683d223135252220783d223535252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224255444745542220666f726d61743d2224232c23233022206865696768743d223135222077696474683d223135252220783d223730252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d2256415249414e43452220666f726d61743d2224232c23233022206865696768743d22313522206e616d653d2256617269616e6365204669656c64222077696474683d223135252220783d223835252220793d2230222f3e0d0a202020203c6c696e6520636f6c6f723d226772617922206865696768743d223022207765696768743d222e3235222077696474683d22383525222078313d22313525222078323d2231303025222079313d223136222079323d223136222f3e0d0a202020203c6c696e6520636f6c6f723d22776869746522206865696768743d223022207765696768743d222e3235222077696474683d22383525222078313d22313525222078323d2231303025222079313d223137222079323d223137222f3e0d0a20203c2f6974656d733e0d0a20203c66756e6374696f6e733e0d0a202020203c212d2d2054686973206d616b657320737572652c20746861742077652063616e206163636573732074686520706172616d6574657220617320696620697420776173206120636f6c756d6e2066726f6d20746865207461626c65202d2d3e0d0a202020203c70726f70657274792d726566206e616d653d22524547494f4e222f3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d22697356617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b56415249414e43452671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e6765436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e6365204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e697356617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d2269734465706172746d656e7456617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b4465706172746d656e7456617269616e63652671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e67654465706172746d656e74436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e6365204465706172746d656e74204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e69734465706172746d656e7456617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d226973526567696f6e56617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b526567696f6e56617269616e63652671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e6765526567696f6e436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e636520526567696f6e204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e6973526567696f6e56617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e41637475616c223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e41435455414c3c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e427564676574223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e4255444745543c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e56617269616e6365223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e56415249414e43453c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e7441637475616c223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e41435455414c3c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e74427564676574223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e4255444745543c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e7456617269616e6365223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e56415249414e43453c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c66756e6374696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e506167654f66506167657346756e6374696f6e22206e616d653d22506167656f665061676573222f3e0d0a20203c2f66756e6374696f6e733e0d0a20203c636f6e66696775726174696f6e3e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7461626c652e68746d6c2e426f6479467261676d656e74223e747275653c2f70726f70657274793e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7061676561626c652e7064662e456e636f64696e67223e4964656e746974792d483c2f70726f70657274793e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7061676561626c652e7064662e456d626564466f6e7473223e747275653c2f70726f70657274793e0d0a20203c2f636f6e66696775726174696f6e3e0d0a3c2f7265706f72743e0d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b27f82a-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.png','/solution/samples/reporting/MDX_report.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000002c744558744372656174696f6e2054696d6500546875203133204f637420323030352031363a32343a3531202d303530300a0ba0930000000774494d4507d50a0d141a3a5bf3cf85000000097048597300000b1200000b1201d2dd7efc0000000467414d410000b18f0bfc61050000142d4944415478daec3a5b8c24d575f7d6bbbaabbafa31dd33d33d3d333bfb06766097c5c08271b043ec38584189e5c82806822547492c2bf948a2fce43b8a14e5238ee50f48ac28c2769404c9c89613c018300eec629659587697d9d9793ffa315ddd5dcf5b75ab6e4ef5f4ccce3ebd0b7608668f667aaa4f9d7bebbc1fb70633c6d04709b80f9a811b02df10f886c03704be21f00d816f08fcd1811b02ffaac3474e60bcfb4fce35111fa20ca31f342f97c2fb186cf60c8b29917748984d8b8e1f0dd3e502699c6d6b4265e5e52f8cfce054fe2b76b8abe672658335cc4896798e61ca28c552ad8b3e311e2cb9a21c060e27bfb588c74aacacd196cdc6729ce345ab1e9f1599c7b02144ed507c755ef8a0f594c04855b01d564885778ec9f34df288f7ecfe74fdcbdf1b157e42ef0f5ac254fcb17d9acb04b4ea731dcc4b34a231df0ca4523a6861e9f516298ace72902698f74571917021f6511c1d6f4919319cf152594603122932af0b21a767628c7f11e6edfdbc57687a64bc18ccad7347a79d6e141f775567b1d314caf8af9fa83d70d04fa5d39224bab61d234e05c679cef77d5951706f5c761c3b9d4e238cacaea5eb5a1846a2c88761280a02c2cc34cd5c361b8654148528a270579625200687c47d9ed97919fad7db3f7b170c5d88e9a12e405e85781b01bb18ef9c9ac192802bc39e1ffcf76b482864b8c09c75d7d9dd47ee3cb3beb2b2dcd87ff39ef2e0d0d157df0a3dba77f296817cf6c5e78f65f61da856067f78f47fd2ba1133500b4ba9a97cae30b173d4a9ad2d9c9e4e6bdaa14307a64f9f999e5eaa8e556f9ddc77012bdb0461e7311772cc2e27400f0f57f8bc945bc49bfaec5fe0cd1df0a6dcc945fd47a7043dcddf54f49528a771f8ef9e5a79f4d3f245dabdf0795b6bd12564bd275ccce845c9e6f2626c19105fbc20b9c46cbb922ede764b7ea0e9cb7a9efe9255db16fed3338ec0f37c4843dbb272f99c288a11a5ed4e077c3593d1619f336bfebf9e8e6e2b0b0fede21717960242c6c6476377b635fdcdb6f2d8f8ee9b62ac8201d4240812ce89ef4b8ac2e21890b033eb2b84f5be2625308a62b888a2081e7cde463d328c31e0398ec3fd14c036e8134cef7b14c71d17d7cd78b4b03eef9cd6246d243502b7dc009d6b23993abbc726d05581d0d3023c6c7565a5dbedc2535435e17e6d752d08c8e4e401cff34e3b8a867cd5f362aa8541007741a4752be3a51f0b2810836042c7218c3867ce9c92a58c80fd8861cb71d3699583bb316f394e4c5c190221a499826175db693543e398479120f231c35dcb2f0d641a2d1351ace774abd52a56aaa1dd351d5f129063114d173a365524542c0e2b853d332bad6a8e4d79a77947b875c176036ecfde3d5d335388ac7088148bc5ab080c8ac57fffed95473f233a8ea36bda86c61dd785f4238922502cb682ba8f6e2ef2b2c8d9960d892a97cb521ad5d73be0540305238cc08c31d06f5992bb2045f77d298e639c18aa6f7084f18521b3f16476097f0ce3ad8b84c225cc0f583ee5837f0002f7e23688901906885243c9825b6d7b767fc32d8779f23fd684200ce65682ca804088d7215d43ce083cf6080d68429653b99c0a5bc5f0830545121428e280370c033e83a45789e11714b1b1358d90e532550c143e8c39de26413e25e19e7c28ee47ddd2d2a9f2f05e7054afdd51b2194aa9633b8691d9a6288809002608fc86b8b8978fe0c3353bba9e62eb1e94cd28a372500e7a9087be018a696071227f6906d9522da85c687450b3cbf4b77ed0adb0676b635f104d7fd7be7ca932387035dfb812b4acf8e5137307f728767bcdf407474b03b5c5b757ea1d0e3c80e327c62a0daff96fcffcd97dbbff76df64b9f9fa4fcb1fbfdf25eef185770e576f5a5eabc741a46741f654366b2c2f37462a05a8252ca6984bc4505415713a63d14f4ed62684a7e3cc83359b40bd802a582c950c43b72c677828bf95d6fa36dee64c1c87f0df7c6bfaf73f95206c2ff602563438b8ed532ccba96b93f1023f0497abb599a1389a4802c4d9ae5f508588258907dc123883cf136797f68e0e82b93c2fc81a1a303567af8ca606c189e2880a90308524405cd7531479abba260e8c71a7ebab8a806d179c2255d0498c64a8b1a08ec47a3cfcc597f0b6ad52b17ff97e88bff974fbd3b7299059de833d3f2c6018fcc848e2fcfff89de544978f3f3effc20bd607cdd52f11bef8c5dc534ff52bd6476d3c64d731d9fcdec3f94e23842c3d752af8ddcf689d000b343e3e1d3c7024fdd24b1612b9e1123f3f17982efad43deacfdef4798c94341f87f189b7fdaf7ead08b9f399ef7522ca462ae2c25278e7c75273b3a1a6e3b595d02808a7dff6f6ee55621ecf9cf62c8f7de9910247e337def46055a3495599fbdcef18a7a6bca59550d1f8c559521e16230eeddb25ffe7d39deb92f83a041eab8a7e96d7f3dc2d07d9fe7171a5415f7bc52e0c420dc68f7d291f70dc408eb34dfa0fdf6adfff492d9713864b82a708375784affef1fca1bbd23acf5409ab792127e190443ee24a3972e86ed56c446d0f55f2389d954a55797795af59f8c00175fe1de79e23e9fd07d3390d4f1df56eb923b56b978cacc891f84a49e8d68353ef1245bd6e0fbd0e81bff18d464858a1288424eed8b1224293144b329e3de15a0ed806c13554e5b615ffe55fad763bb1a6731143228f3b3efad33f5a04022831505d0401c73192444c48fcdda739c0938081e531e7421e4e9a50011ffba94543264a98ff8e493c2649387e920129b4a787ef48bff882a5697c10c6b0d5f50b7ccd4b6c2bc9e42bcbfd1e23f093841f401daa6f9e95d8fdbfed7672abdb3d9ff9bb9d68db4ebda96de3d28b2e7cc805034048fb3371109ec73fff5c925fdbfd0daf7b62865e1a4d4c48cda67abd2b3f4450ad4adb0446e88927c63f6896feef007a2d74a2d9f0a25fe5c6633b242e3df99edae60f29f4b2f4d73f87a65ffaa039f965c2ed9f478f3cb94de0c0417ef7bd6d55f7505e41501d60f883e1cba348bd72a59be9a009a33fc37057ad0e34469d1015e4645b125d6d4fd49ba3d709d204a4087d362e86c0dbba7cbf67c8afaea2690be50454234812203ad003e52b12fffb0ccac8a8e5a106451f2f2298751ede7d79ca9a8d9e9a451287ec086538146224c7e848191dbc42f03df52e5a0f902a2248c77e8c8625f4f9bd48bf9c70ef4be030460fee48340a0611367b1e2b44bad8c76cd73710ffc5c1c4b680dc22b643941650c42e262e69e8cf2793b30540f2fd0304e484c9d7f81262a8d65f9b4c30ac87dc20065fa3bd449c106f9b19de97c0cf2e228b26fe0c767874d3563f5a4cbe3a51c2c72706d1cdf93efef925040d96192387a0afec3fef20b510b548c2c75d83e860a18f7f713961f48c83f808fdc13eb4716c73b289a62c4442246174a088eedeb4f6d13544303a6b263dd4c3fb50ba27f019131d6ba1384a46e1dd55f4c94d9e9379f80ff57f46b577df8fe4974210216803f96b6be3c0f860966b6c13a18082c5c46b6ba2c1ecd0a4c93b0ea37b1e47c93cbc9458b87bc7e3aeebd298692995f81e8db12a8b3e21a5c12181bfccc6ad56d3f7439ec35dc7ce65f381eb40533b323cbcb8b41090286be896dd11a5541486462ecfa1c0ecfa8a28f8812f4b0a63d427747c6c747975c9b34971b0d86d9bbc208694e68dbc20b2d586a9ab4a187811afc83c731d7f6c7c7cadb61a87a1202961184a8260fb5e31575054716e61d930322c0abd204aa9b2673b2363e3f5468d4b4e77a1d1e662c66cd731746d6093f944e04edb04f7732c6bbd1e49928c38b1493d81c5996c5e4b2997d11b8b09258a207b9e9b5255081de2266930088817046a2011422531743d4f3722f04cc7773113ad8e4d54caa2204a0ecfa1090f100ed75bed28249a24bbc42d72031c8e5d0fc621ec5976c8873e02eae4ec0f760e7c974b7a6b1c86be4b7c9e2b618e23c4f17c99faae1fc794788404718f98518278050b92477c9f38a552698bf79e4b3f64fc62fdf9ff2df48f788ebd7eb4d3e9e85adef75c49e6525aa6b6524fa724cf2531cfc3682609da912387b7af7cedd8abe55c69b1d1e485b8b3de125399fbefbbb76bd69f7bf9e88e4ad9f13b1092a0eceac8c4f858e5b5d75f2b1bc5a9d32777ecda5b5f5bf043f49bbff1ebc4b37ffcd2d16a7570adb6a2a732e07885c1cae44d7b8178a4503ef9eec962b1ecb866abed3cf85b9fc52cfce1f79fab4e543a5d5be6f98eede40a03876e9d3c7efc682e533e377f3a93c9a3c85f58ae7df6b71f9239f4c2b3ff353252ad3b5e0ac7b5f56eb1943f7cf0509f75b030bb02f8becfae0c71ef7dcac6e7cfc5bf37e26bd964f3eb35117ffddbbda4357bee6c18620815818f4be5aabe19b7b22c5fc937cece4ceb69bd596b4a9adc315b4a2a73cb4dfb3da77b666621974999ed56a954363bedcae048369f99999d514571bdd5115425c509a663df36798006fe89b74f16068a10a6bc08268cc574ba323c786ef65c4a915ba649636e40d757d79b070f1ee45874fcc49bb94c1e72112f26699d57a4ea48657efe9c20a59cae697ba45a1a9c5b5abcf5f63ba05d79ebe494aee52037e94696d15852c46ab5da63bc77a6552e575aad0ee4001643b2e1d1354046d705411e1c1a641cd252298e4b064e5e94f285ac2acaaaa64b100bca60aaa73b208676a05080642cc9b224a592136fccf185e2802aa5944c5211d46c8af59eac6774d07d3e5be0044e9195a1dea106c3385f185044259d4a412e540ca54fac6768c40c036a0507778786cb4272ac8eb2d9bc2cca292569fae099dcb66ea3f74e08e1e1f2d0c677d334e55ceee70a0cc6174525e07c102220b8a776e8721216b346260e2989222182acca4013323c12d4097542e46918f68ed741e03eb1e374d5941ad04012127c8f180738e425814551e265a02d861559363259e23b404cc240e613158ba224491ca5506b39c631555170efcc1d88b5b41150c263ce2544c1171e00cccf2fd86db3d6ececdebba75d5f6e38de4006fa50a11b925fbbf7c865055e5a5982b26476bb92ac76ccc6406928973588ef9e9b9bcdea19310c88a0763bcd1d3b7743795c5e5d9605d1b3a8aa49b6e38434bcfdf6dba3303837333d3ab27b696526ade98eeb8c94c7f5747a7965599524d7f4a46cdab72c2f20f9421eb1085c7d78a0da6aaf4a8a6a39cec85055d7f55a6d0561195312503e29f8edae9e2f804bcf2fcee5d50107fb38a49d847824a3673638ffa895a55ed27ae3d56304631c53d70f72ba1a7362216f98eb9d08e23d64a2a2d0c0b39c309fd76fbb6d7263e5cf8e1f4b49ea52ad36541a76ba2d4533200f599df5a353272ba5e2eaea6aa93408c6ac56c7cbc3a5374fbca1a7f4d9f9b952a95234d2b3738d23f71d0e7ce7a5575e191bdf59afaf6a69addd6a8f8c4fec1c1f9d7a6b4a4fa5d796e770aa3431589c393777d77d77434e7bfec51f170b4330864a9cbcda58ab54ab7b76ed7ce79d295ed42cb3e60478dff8c4c2ccd903f71e81b2f4f22b2f148d7c87e081b432bbb4343a36ba77cfeef316fef283694a29c76168533dc74e6b5ad2da425870c92bf9e45f04c23009c2a4268b1bcba062c5d098e364620132e886207e00e3fa844fde06c3fc83050122888724e5139f4531e4ab300844598e2885c88392e1382e9fbcef47c99b5151049d8ba2b8412c2b72108410f4b01510439eb16d1bbac0e4bf0468f23211734812a54d6205c2b8371131886a8c99e338b03649c3517276c5f31c109fb770bd5e87bd188b603185eedc762481efbdef075a8e06e1d0f0d0458dfd7aab090af03c4f4beb9e6341461ea994a10fafd7d78bd95ca3d5c868598f3819230f029b664b14845aa3094af1bd1aa8696c6c34a2e15a6d4dd30c4a7c4d539b663badaa8542de6cb7a15b5e6fd499a8427086341edf318e59bc56afa9721ad4220852d7b2c02906060aed761b046b9b2d123145e41cdb1fdf39011aaf356ab2a88892084c5a09717af33f03702230a4f2f6ffb66b2ebb4d035118aec77662c7d7380da6766851a14894168190900021c46dc18ac78047e23158b261830001a5b4698b0a6a811668499512c7777b3cb6394e802e90000924449a7f69d9d29c3933ff7cc773ba3620284331bc2c74ad564252f83e8e2932925645e9c7cd80a31021d6b61d45d14a652e0ce3916272a820f2d35401934e30018e158bf20ce036223113042e54088460a6b8dd8435845cc7e5391ea7d8759292a040a2e039f81d89009d038c09ca48e1d0bdb73ddbe1ebe5cf5600b30669e4f8e2e58c602f008b8e034c92187243faa5af0f6eaa711dab536239583b7c65efea775f9a5673611eaa3dcbdaa1a994660449a8c0e9da6a6deba69986b187bda9a913870cfdfb67eb6bab9befb7445edeb15af5d1833870704e5fbf72f9fefd7b18d380c75b1fb6ab6ad576dc63d3c739146d6c7950e444becb727c12fb2388bf74f1fc93b92771c7691c99de7cb7aaa82a2c4e637cd2a80b8b2fdff3e51ca5a195b0220b5b175fbd76656efe69e6c5655968b5db750d2aca8e3ed6383ad978f0f0b95a1538067ddcb53449f46df7c2b5ebcd85672ca1122a731d4f90c4aee51c18ab9d3975e6ebe87fc2d23fd7ffc9d21f8a0c6fbcdbf03d2fc9f393b3b3e8f77e3bacadbf66e992efc7b222e431c6883e3a791858fad59b4d7db466db5d70c53849745daf69da9bb7eb15aeb2d36a19e644b7bb0bcf67676680a59b2b2f757dacdb692b552df04349968db1830018b04bc1b4b49a1106b61f8633b327c16d5f341747b53ab82aec49cf053b944dc30096a659deb3762b828650d26e774e9c3a0de0b1b4b2a8ca1a38115b62a00e57aa72c36cf4475e042c2b52d1ed83be3714fd5abd1e27062036cbd3b25a057f1fe9b1b422831444e53403274b99ea3511014b6719357e7882a5cb4414e51e87c2d1a2aa40964ab9042702314cb33fd7c0d2194e1be31334c5208af015a9cfd28aa22a6a35cb92288c0cb3417f63e93822c6a1718aa2c1a8e0f0efb3b424caa2ac82a56529111b6689d92b10a83b77bbb76eee23d3427fd2a2fb3f8af9d4da7efcb8c9d0a85eaf15eb241fcc5bb57e3faad50981073c55959697960da3beb6baea47619ee5e7ce9dfed723fccb021301860408a66edc7e74761af25a34bff66c6330330c0986236a6e25e9b7bcef23edb73ead61c003af61c083ae61c083ae61c083ae61c083ae61c083ae2f788d524b31db0cfe0000000049454e44ae426082',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b27f82b-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.properties','/solution/samples/reporting/MDX_report.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d412063726f737320746162207265706f727420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520706167650d0a7469746c653d4f4c41502043726f7373746162205265706f72740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',10,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.xaction','/solution/samples/reporting/MDX_report.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f7265706f72742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e4d44585f7265706f72742e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e68746d6c3c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f727420747970653d22636f6e74656e74223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f7265706f72743e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c212d2d20736f6c7574696f6e2d66696c653e0a090909093c6c6f636174696f6e3e53616d706c65446174612e786d6c3c2f6c6f636174696f6e3e0a090909093c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e0a0909093c2f736f6c7574696f6e2d66696c65202d2d3e20200a2020202020203c75726c3e200a20202020202020203c6c6f636174696f6e3e73616d706c65732f7265706f7274696e672f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f75726c3e200a202020203c2f636174616c6f673e20200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a467265654d6f6e647269616e5175616472616e742e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e4f4c415020517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e50656e7461686f205265706f72743c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e20200a20202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e7422206d617070696e673d227265706f7274222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b28464d-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_de.properties','/solution/samples/reporting/MDX_report_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d44657220546162656c6c656e766572676c65696368207a6569677420646965206d6f6d656e74616e656e20756e642062756467657469657274656e20446174656e20665c753030666372206a6564652041627465696c756e6720676567656e5c7530306663626572206a6564657220526567696f6e2e2044657220426572696368742066725c753030653467742065696e656e204d6f64617269616e204f4c41502053657276657220616220756e642076657277656e646574204a467265655265706f72742c20756d206469657365205365697465207a752065727a657567656e2e0d0a7469746c653d4f4c41502043726f737374616220426572696368740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b286d5e-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_es.properties','/solution/samples/reporting/MDX_report_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d556e20696e666f726d65206465207461626c6173206372757a6164617320717565206d756573747261206c6f73206461746f732061637475616c65732079206465206661637475726163695c75303066336e206465206361646120646570617274616d656e746f2079206361646120726567695c75303066336e2e20456c20696e666f726d6520636f6e73756c746120756e207365727669646f72204f4c4150204d6f6e647269616e207920757361204a467265655265706f727420706172612067656e65726172206c6120705c753030653167696e610d0a7469746c653d496e666f726d65204f4c4150206465205461626c6173204372757a616461730d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b28946f-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_fr.properties','/solution/samples/reporting/MDX_report_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5461626c6561752063726f69735c753030453920717569206d6f6e747265206c65206275646765742070725c7530304539766973696f6e6e656c20657420725c7530304539616c69735c753030453920706f75722063686171756520645c753030453970617274656d656e742065742063686171756520725c753030453967696f6e2e204c6520726170706f727420696e746572726f676520756e2073657276657572204f4c4150204d6f6e647269616e206574207574696c697365204a467265655265706f727420706f757220675c75303045396e5c7530304539726572206c6120706167650d0a7469746c653d4f4c4150202d20446f63756d656e742061766563207461626c6561752063726f69735c75303045390d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2930b0-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_nl.properties','/solution/samples/reporting/MDX_report_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45656e2063726f737374616220726170706f7274206461742061637475656c6520656e206765627564676574746565726465206461746120766f6f7220656c6b6520616664656c696e6720696e20656c6b6520726567696f20746f6f6e742e2048657420726170706f7274206861616c742064617461206f70207569742065656e204d6f6e647269616e204f4c41502073657276657220656e206765627275696b74204a467265655265706f7274206f6d20646520706167696e612074652067656e65726572656e0d0a7469746c653d4f4c41502043726f737374616220526170706f72740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2930b1-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS.properties','/solution/samples/reporting/MDX_report_XLS.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4120737072656164736865657420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520584c532066696c652e0d0a7469746c653d4f4c41502043726f73737461622053707265616473686565740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2957c2-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS.xaction','/solution/samples/reporting/MDX_report_XLS.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f7265706f72745f584c532e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e4d44585f7265706f72742e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e786c733c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f727420747970653d22636f6e74656e74223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f7265706f72743e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c212d2d20736f6c7574696f6e2d66696c653e0a090909093c6c6f636174696f6e3e53616d706c65446174612e786d6c3c2f6c6f636174696f6e3e0a090909093c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e0a0909093c2f736f6c7574696f6e2d66696c65202d2d3e20200a2020202020203c75726c3e200a20202020202020203c6c6f636174696f6e3e73616d706c65732f7265706f7274696e672f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f75726c3e200a202020203c2f636174616c6f673e20200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a467265654d6f6e647269616e5175616472616e742e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e4f4c415020517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e20200a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e50656e7461686f205265706f72743c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e20200a20202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e7422206d617070696e673d227265706f7274222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b297ed3-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_de.properties','/solution/samples/reporting/MDX_report_XLS_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4469657365204b616c6b756c6174696f6e73746162656c6c65207a6569677420646965206d6f6d656e74616e656e20756e642062756467657469657274656e20446174656e20665c753030666372206a6564652041627465696c756e6720676567656e5c7530306663626572206a6564657220526567696f6e2e2044657220426572696368742066725c753030653467742065696e656e204d6f6e647269616e204f4c41502053657276657220616220756e642076657277656e646574204a467265655265706f72742c20756d2064696520584c5320446f6b756d656e7465207a752065727a657567656e2e0d0a7469746c653d4f4c41502043726f7373746162204b616c6b756c6174696f6e0d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b297ed4-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_es.properties','/solution/samples/reporting/MDX_report_XLS_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d556e6120686f6a6120646520635c75303065316c63756c6f20717565206d756573747261206c6f73206461746f732061637475616c65732079206465206661637475726163695c75303066336e2070617261206361646120646570617274616d656e746f2079206361646120726567695c75303066336e2e20456c20696e666f726d6520636f6e73756c746120756e207365727669646f72204d6f6e647269616e204f4c4150207920757361204a467265655265706f727420706172612067656e6572617220656c206172636869766f20584c532e0d0a7469746c653d486f6a6120646520635c75303065316c63756c6f204f4c4150206465207461626c6173206372757a616461730d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b29a5e5-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_fr.properties','/solution/samples/reporting/MDX_report_XLS_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d466575696c6c6520717569206d6f6e747265206c65206275646765742070725c7530304539766973696f6e6e656c20657420725c7530304539616c69735c753030453920706f75722063686171756520645c753030453970617274656d656e742065742063686171756520725c753030453967696f6e2e204c6520726170706f727420696e746572726f676520756e2073657276657572204f4c4150204d6f6e647269616e206574207574696c697365204a467265655265706f727420706f757220675c75303045396e5c7530304539726572206c65206669636869657220584c532e0d0a7469746c653d4f4c4150202d20466575696c6c6520457863656c2061766563207461626c6561752063726f69735c75303045390d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b29ccf6-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_nl.properties','/solution/samples/reporting/MDX_report_XLS_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45656e207370726561647368656574206469652064652061637475656c6520656e206765627564676574746565726465206461746120766f6f7220656c6b6520616664656c696e6720696e20656c6b6520726567696f20746f6f6e742e204465207370726561647368656574206861616c742064617461206f70207569742065656e204d6f6e647269616e204f4c41502073657276657220656e206765627275696b74204a467265655265706f7274206f6d2068657420584c532062657374616e642074652067656e65726572656e2e0d0a7469746c653d4f4c41502043726f73737461622053707265616473686565740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b29ccf7-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_zh_CN.properties','/solution/samples/reporting/MDX_report_XLS_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75346530305c75346532615c75356262645c75383836385c75363633655c75373933615c75346538365c75366263665c75346532615c75386465385c75386438615c75353931615c75346532615c75353333615c75353764665c75373638345c75393065385c75393565385c75373638345c75356239655c75393634355c75353438635c75393838345c75376239375c75363537305c75363336655c75333030325c75386664395c75346532615c75363261355c75383836385c75363765355c7538626532204d6f6e647269616e204f4c4150207365727665725c75356537365c75346531345c75346637665c75373532384a467265655265706f72745c75363736355c75346561375c7537353166584c535c75363538375c75346566362e0d0a7469746c653d4f4c41505c75346561345c75353363395c75356262645c75383836380d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2a1b18-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_zh_CN.properties','/solution/samples/reporting/MDX_report_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75346530305c75346532615c75346561345c75353363395c75383836385c75373638345c75363261355c75383836385c75666630635c75363633655c75373933615c75346538365c75356266395c75346538655c75386465385c75386438615c75366263665c75346532615c75353333615c75353764665c75373638345c75393065385c75393565385c75373638345c75356239655c75393634355c75353438635c75393838345c75376239375c75363537305c75363336655c7533303032205c75386664395c75346532615c75363261355c75383836385c75363765355c7538626532204d6f6e647269616e204f4c4150207365727665725c75356537365c75346531345c75346637665c75373532384a467265655265706f72745c75363736355c75346561375c75373531665c75393837355c75393736320d0a7469746c653d4f4c41505c75346561345c75353363395c75383836385c75373638345c75363261355c75383836380d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2a1b19-6757-11dd-a492-c111aa2b74dc',0,'6b1c3852-6757-11dd-a492-c111aa2b74dc','.DS_Store','/solution/test/.DS_Store','000000014275643100001000000008000000100000000087000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000000002000000000000000200000001000010000073006f0075007200630065000000000000000000000000000000000000000000000000000000000000000000000000000000020000000b00640061007400610073006f0075007200630065007366776930626c6f6200000010000000000000000069636e76000100000000000b00640061007400610073006f00750072006300650073667773776c6f6e6700000087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000080b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000002000000001000000400000000100000080000000010000010000000001000002000000000100000400000000000000000100001000000000010000200000000001000040000000000100008000000000010001000000000001000200000000000100040000000000010008000000000001001000000000000100200000000000010040000000000001008000000000000101000000000000010200000000000001040000000000000108000000000000011000000000000001200000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000100b0000004500000087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104445344420000000100000000000000000000000000000000000000000000000200000020000000600000000000000000000000010000010000000001000002000000000100000400000000020000080000001800000000000000000100002000000000010000400000000001000080000000000100010000000000010002000000000001000400000000000100080000000000010010000000000001002000000000000100400000000000010080000000000001010000000000000102000000000000010400000000000001080000000000000110000000000000012000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',FALSE,1218380570000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2a422a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f63-6757-11dd-a492-c111aa2b74dc','.DS_Store','/solution/test/dashboard/.DS_Store','00000001427564310000100000000800000010000000002500000000000000000000000000000000000000000000080000000800000000000000000000000000000000000000000200000000000000000000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000080b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000002000000001000000400000000100000080000000010000010000000001000002000000000100000400000000000000000100001000000000010000200000000001000040000000000100008000000000010001000000000001000200000000000100040000000000010008000000000001001000000000000100200000000000010040000000000001008000000000000101000000000000010200000000000001040000000000000108000000000000011000000000000001200000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000100b0000004500000025000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104445344420000000100000000000000000000000000000000000000000000000100000060000000000000000100000080000000010000010000000001000002000000000100000400000000020000080000001800000000000000000100002000000000010000400000000001000080000000000100010000000000010002000000000001000400000000000100080000000000010010000000000001002000000000000100400000000000010080000000000001010000000000000102000000000000010400000000000001080000000000000110000000000000012000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',FALSE,1218380623000,'6b1c5f63-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b2a422b-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f63-6757-11dd-a492-c111aa2b74dc','departments.rule.xaction','/solution/test/dashboard/departments.rule.xaction','0d0a3c616374696f6e2d73657175656e63653e0d0a0d0a093c6e616d653e6465706172746d656e74732e72756c652e78616374696f6e3c2f6e616d653e0d0a093c76657273696f6e3e313c2f76657273696f6e3e0d0a093c7469746c653e526567696f6e73206c6973743c2f7469746c653e0d0a093c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a093c646f63756d656e746174696f6e3e0d0a09093c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a09093c6465736372697074696f6e3e3c2f6465736372697074696f6e3e0d0a09093c68656c703e3c2f68656c703e0d0a09093c726573756c742d747970653e72756c653c2f726573756c742d747970653e0d0a093c2f646f63756d656e746174696f6e3e0d0a0d0a093c696e707574733e0d0a202020203c2f696e707574733e0d0a20200d0a093c6f7574707574733e0d0a09093c72756c652d726573756c7420747970653d226c697374222f3e0d0a093c2f6f7574707574733e0d0a20203c7265736f75726365732f3e0d0a20200d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020200d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a0909093c72756c652d726573756c7420747970653d226c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0d0a202020202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e6374204445504152544d454e542066726f6d205155414452414e545f41435455414c53206f72646572206279204445504152544d454e545d5d3e3c2f71756572793e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a0d0a',FALSE,1199678409000,'6b1c5f63-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b36ec5c-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','books.xml','/solution/test/datasources/books.xml','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a0d0a3c626f6f6b73746f72653e0d0a0d0a3c626f6f6b2063617465676f72793d22434f4f4b494e47223e0d0a20203c7469746c65206c616e673d22656e223e4576657279646179204974616c69616e3c2f7469746c653e0d0a20203c617574686f723e4769616461204465204c617572656e746969733c2f617574686f723e0d0a20203c796561723e323030353c2f796561723e0d0a20203c70726963653e33302e30303c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d224348494c4452454e223e0d0a20203c7469746c65206c616e673d22656e223e486172727920506f747465723c2f7469746c653e0d0a20203c617574686f723e4a204b2e20526f776c696e673c2f617574686f723e0d0a20203c796561723e323030353c2f796561723e0d0a20203c70726963653e32392e39393c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d22574542223e0d0a20203c7469746c65206c616e673d22656e223e585175657279204b69636b2053746172743c2f7469746c653e0d0a20203c617574686f723e4a616d6573204d63476f7665726e3c2f617574686f723e0d0a20203c617574686f723e50657220426f74686e65723c2f617574686f723e0d0a20203c617574686f723e4b757274204361676c653c2f617574686f723e0d0a20203c617574686f723e4a616d6573204c696e6e3c2f617574686f723e0d0a20203c617574686f723e5661696479616e617468616e204e61676172616a616e3c2f617574686f723e0d0a20203c796561723e323030333c2f796561723e0d0a20203c70726963653e34392e39393c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d22574542223e0d0a20203c7469746c65206c616e673d22656e223e4c6561726e696e6720584d4c3c2f7469746c653e0d0a20203c617574686f723e4572696b20542e205261793c2f617574686f723e0d0a20203c796561723e323030333c2f796561723e0d0a20203c70726963653e33392e39353c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c2f626f6f6b73746f72653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b37136d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','MDX_Datasource.xaction','/solution/test/datasources/MDX_Datasource.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f44617461736f757263652e78616374696f6e3c2f6e616d653e0a20203c7469746c653e416e204d44582044617461736f757263653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e45786572636973657320746865204d445820436f6e6e656374696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c6f7574707574733e200a202020203c72756c652d726573756c7420747970653d22726573756c742d736574222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f636174616c6f673e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e517565727920466f72204f4c415020446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d2272756c652d726573756c74222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b37618e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','query_rule.xaction','/solution/test/datasources/query_rule.xaction','0d0a3c616374696f6e2d73657175656e63653e0d0a0d0a093c6e616d653e71756572795f72756c65312e78616374696f6e3c2f6e616d653e0d0a093c76657273696f6e3e313c2f76657273696f6e3e0d0a093c7469746c653e43757272656e7420506f736974696f6e205469746c65733c2f7469746c653e0d0a093c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a093c646f63756d656e746174696f6e3e0d0a09093c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a09093c6465736372697074696f6e3e4a6176617363726970742071756572792072756c6520746573743c2f6465736372697074696f6e3e0d0a09093c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a09093c726573756c742d747970653e72756c653c2f726573756c742d747970653e0d0a093c2f646f63756d656e746174696f6e3e0d0a0d0a093c696e707574733e0d0a09093c6465707420747970653d22737472696e67223e0d0a090920203c64656661756c742d76616c75653e50726f6475637420446576656c6f706d656e743c2f64656661756c742d76616c75653e0d0a09093c2f646570743e0d0a20203c2f696e707574733e0d0a20200d0a093c6f7574707574733e0d0a09093c72756c652d726573756c7420747970653d226c697374222f3e0d0a093c2f6f7574707574733e0d0a20203c7265736f75726365732f3e0d0a20200d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6465707420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020200d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a0909093c72756c652d726573756c7420747970653d226c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0d0a202020202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420506f736974696f6e5469746c652066726f6d207175616472616e745f61637475616c73207768657265206465706172746d656e743d277b646570747d27206f7264657220627920506f736974696f6e5469746c655d5d3e3c2f71756572793e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b37618f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','SampleData.mondrian.xml','/solution/test/datasources/SampleData.mondrian.xml','3c3f786d6c2076657273696f6e3d22312e30223f3e0d0a3c536368656d61206e616d653d2253616d706c6544617461223e0d0a3c212d2d205368617265642064696d656e73696f6e73202d2d3e0d0a0d0a20203c44696d656e73696f6e206e616d653d22526567696f6e223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c20526567696f6e73223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d22526567696f6e2220636f6c756d6e3d22524547494f4e2220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a20203c44696d656e73696f6e206e616d653d224465706172746d656e74223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c204465706172746d656e7473223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d224465706172746d656e742220636f6c756d6e3d224445504152544d454e542220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a0d0a20203c44696d656e73696f6e206e616d653d22506f736974696f6e73223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c20506f736974696f6e73223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d22506f736974696f6e732220636f6c756d6e3d22504f534954494f4e5449544c452220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a0d0a20203c43756265206e616d653d225175616472616e7420416e616c79736973223e0d0a202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d22526567696f6e2220736f757263653d22526567696f6e222f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d224465706172746d656e742220736f757263653d224465706172746d656e7422202f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d22506f736974696f6e732220736f757263653d22506f736974696f6e7322202f3e0d0a202020203c4d656173757265206e616d653d2241637475616c2220636f6c756d6e3d2241435455414c222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a202020203c4d656173757265206e616d653d224275646765742220636f6c756d6e3d22425544474554222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a202020203c4d656173757265206e616d653d2256617269616e63652220636f6c756d6e3d2256415249414e4345222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a3c212d2d202020203c43616c63756c617465644d656d626572206e616d653d2256617269616e63652050657263656e74222064696d656e73696f6e3d224d656173757265732220666f726d756c613d22285b4d656173757265735d2e5b56617269616e63655d2f5b4d656173757265735d2e5b4275646765745d292a31303022202f3e202d2d3e0d0a20203c2f437562653e0d0a0d0a3c2f536368656d613e0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3788a0-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','SampleDataSchema.zip','/solution/test/datasources/SampleDataSchema.zip','504b0304140008000800787535350000000000000000000000001700100053616d706c65446174612e6d6f6e647269616e2e786d6c55580c0009d1914564dd1245f601f601a5944d4fdb401086ef48fc87ede6422b1287bb0d5a628b464a4c6a3b5c50544decc1b1b46bd3fd40f0efbb8ee38f528a0af16d67fdbc33efcc68ddab67c1c9134a5554a5472f26537a75797ae2c6e90e059012047a3406f1c8d1070db4befb321e9378071233921502cb1a55643cb677a72784b87e1b3ce011e6f650a3c47eeef70225c874f74276a018e71ed5d22025c0f912c51665b8a7ec0d6948d5a2164e60cbf1a0fb63cdfc8885c94f364bd66c1153a7ff6f814fc8ffcc4fd28a1b614d46c1cdfc36a4c494c52f834d4e75a8a295709daecc7dc4753a57976f9af4f111a4b631fd19a33d7dacd9411d9d613f58b128590661728ce9376daf2a55e8e18c3ee2fa2ff8939e7b9dcef2ea369e2776cac93c590447bb9e996d5793814c42a9092b81bfa8a237fe5f95f70d5c2bc8f1d586aacac8b43fbf0f0d27dd82c3d8fbf4a0672d3c0875ec124119d9422cd50678dfe5c69d9d6d9e4bcc4157d2a3ca084a1e2a2940c75a1665eed1d1f968349a4ca7f41fb2d726cb71b0afd76bff26488e96bd03594099622f7cc7a2390b67c1c7a4f70f5e2d3f039e1a0e1ab366935ee5212bb47dac5bdf3d8b1e3d94a49a0c96f6e8d97d1bdc4cee5b78e30ca34d47365fbf5dd81aec349ad7b5decd7a15f76be93acd1b6d0fbf01504b070812e5414fd9010000c5050000504b010215031400080008007875353512e5414fd9010000c505000017000c000000000000000040a4810000000053616d706c65446174612e6d6f6e647269616e2e786d6c5558080009d1914564dd1245504b05060000000001000100510000002e0200000000',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b37afb1-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource.properties','/solution/test/datasources/XQ_Datasource.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b37fdd2-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource.xaction','/solution/test/datasources/XQ_Datasource.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e58515f44617461736f757263652e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e584d4c5f44617461736f757263652e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c6f7574707574733e200a202020203c72756c652d726573756c7420747970653d22726573756c742d736574222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c646f63756d656e743e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e626f6f6b732e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f646f63756d656e743e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e5851756572794c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c646f63756d656e7420747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c7420747970653d22726573756c742d73657422206d617070696e673d2272756c652d726573756c74222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c71756572793e3c215b43444154415b2f626f6f6b73746f72652f626f6f6b5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3824e3-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_cn.properties','/solution/test/datasources/XQ_Datasource_cn.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b636e5f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b636e5f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b384bf4-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_de.properties','/solution/test/datasources/XQ_Datasource_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4469657365204e6f726d2076657277656e6465742065696e6520584d4c20416266726167652c20756d2065696e6520425c7530306663636865726c69737465207a75725c7530306663636b207a75206c69656665726e2e3c703e2044696520446174656e7175656c6c65206973742065696e20584d4c20446f6b756d656e742e0d0a7469746c653d58517565727920416266726167652065696e657220584d4c20446174656e7175656c6c650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b387305-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_es.properties','/solution/test/datasources/XQ_Datasource_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45737461207265676c612075736120756e6120636f6e73756c746120584d4c2070617261206465766f6c76657220756e61204c69737461206465204c6962726f732e3c703e4c61206675656e7465206465206461746f7320657320756e20446f63756d656e746f20584d4c2e0d0a7469746c653d436f6e73756c74612058517565727920646520756e61204675656e7465206465204461746f7320584d4c0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b389a16-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_fr.properties','/solution/test/datasources/XQ_Datasource_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a233c703e4c613d736f7572636520646520646f6e6ee965732065737420756e20646f63756d656e7420584d4c2e0d0a6465736372697074696f6e3d436574746520725c7530304538676c65207574696c69736520756e6520726571755c7530304541746520584d4c20706f757220657874726169726520756e65206c69737465206465206c69767265732e0d0a7469746c653d526571755c75303045417465205851756572792073757220756e6520736f7572636520646520646f6e6e5c7530304539657320584d4c0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b38c127-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_it.properties','/solution/test/datasources/XQ_Datasource_it.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b69745f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b69745f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b38e838-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_nl.properties','/solution/test/datasources/XQ_Datasource_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d44657a6520726567656c206765627275696b742065656e20584d4c207175657279206f6d2065656e206c696a73742076616e20626f656b656e207465207665726b72696a67656e2e3c703e4465206461746162726f6e2069732065656e20584d4c20446f63756d656e742e0d0a7469746c653d5851756572792051756572792076616e2065656e20584d4c204461746162726f6e2e0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b390f49-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_pt.properties','/solution/test/datasources/XQ_Datasource_pt.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b70745f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b70745f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b39365a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_zh_CN.properties','/solution/test/datasources/XQ_Datasource_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75386664395c75346532615c75383963345c75353231395c75346637665c7537353238584d4c5c75363765355c75386265325c75346565355c75383362375c75356639375c75346530305c75346532615c75346536365c75373638345c75353231375c75383836382e3c703e5c75363537305c75363336655c75366539305c75363632665c75346530305c7534653261584d4c5c75363538375c75363836332e0d0a7469746c653d5c75393438385c7535626639584d4c5c75363537305c75363336655c75366539305c75363765355c75386265325c75373638345851756572790d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3d2dfb-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','burst.png','/solution/test/platform/burst.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000000774494d4507d50813111f06c526f660000000097048597300002e2300002e230178a53f760000000467414d410000b18f0bfc610500003a364944415478da45bc67b025c9752696aefcadaa6b9f776d5efb1eef0d8019cc60382040d0800b924bad76978a60acb45248542842a15048bff44bfaa91f0a990d29b4ab5dad96028346f024b1188f9e9ee99eee69f35e3fefae37e5abd2e8d47d8d6577c7eb7befbb959599e79cef7c5f569ec4beeb2384149218fe43042b54fe854f30fc45b8fcab0826b4fc4422840966420a8c19c6848b02be891155445e38777663734f2a3a6d8630cd91a25022459856ab9e66188341ca0553082e341133a12d895c828444922825b58ab29b48310c17ea0ed16c5ca49cc75429c473f8068e8644d76511e0a8036da2a2a7e3ae6192289a2025cace2b051d9df61d13681cba3ded3e0c07c3b830869b6042a8aee9f0cd72c4124daf92a87c5bfe2fa743843fd55a354e5231fd0e74502152febefc1656a7d383b4f1381302eec510f531d61171a0f572500a6799d088e67a4e9890f2f6e54504be001d9344838f90664bb3a9c3ed740fd90d62fa4833a5c8cbde31e5d5cc24ca541e4197104f91148ae8988fa548f22c518a97bd2e6d86a6d63a1d242e0d05a660ace6d94996534acb0921949a9a814b2b9d8e56a9d31708b9ae2b1457a2b46a9ae667ce2e8e86a19c0e4f952da3c7d384a1c38c104b200d465b364574cac8f58bb56fbefd9465998349c28b02bef9fc5317b7760f894a0dcb5dbfb03a4919d3f5b279aacfae9e0f0b26a9a34c1f130dfea972a624d885239a64e015d2d264ade64551568e051c8e0fb00a301253039efe2907796a5fc6181804de4825b38ce3e9544c8daca8ae1bd351c06f9561c2bcf2d3f1e7790edf864660bec08f87a3706a7cf8a0b49253a9f01c2c0a7da2046b6573d42ddb6316366adf7ca6f6076f5f71067bdffbfa3a729c2f378e73a1b6f70e60704cb7ffbd77affd8ffffd3ffee7dfff284cc1351137ab71619533a857085cae99e09998990822826a187c5bf26a552b927c1c72e82f866ef00c89115109b87be966e5fc63ca4a1b623c8d3df05e743a7c54abd95922a64e5b8e869a863dfd5d79114cc874a610fabb5880ef90cbebab09b84551a8e97b986101a681c8c61a029f2494309310036b3a25a65199bbe0917ffe8bde478f924fbf38fcea257bccb5de30e31c460746b5df5e92c3c3bd63d952057fe78db3157fe168c290e660bbaac0bc9862dd414552da4babc05d90e4e938e2054c2fc784d57cddd1b322ec225510fc3860cb015322c1aa98e05f3969d95384d24c4cbdbb0ce3126f0cdd9a8e9194a684192ae1e957b13ebd08a26d300eb33c3f9d17f832050f76ec229710ab98d810698de6fcdb5fb9f2d273e717166635bdf1f191164a274c513b4277363a6f3c33ffc576980b06cd3926192572a3ab2d2d78f7b782fff43b173f3fb176fa101626f4059ac2ba09b8587a9359016fc760e7326e3900218289607a168c04e7224f4abc2026520942626a2c35c55452f56d78579a64da5b8c7e65a6e94c50135a81868d0a443f9ec275094a946853302bfdbe9c08390d6f85a70687f92c7241cbfb3188d8ebab8defbd733d9ee8e3b173b6b5f8ad372e6d0cb5e3802962c93c85a01b0679ab6175061caeb66da31feb7b23bcbe5add1e5858b89d941c8e754500eac13804694639b18451d306cb2851803b014ae2e9ed0090511a882c28ed02a821c1750bf8778a5753df54595648f9188cca4443c9e9cba99d31b5740f7e2c9ebd228b495ef0d3d08751698c0921dc8a9d832ffddd2491d34be1f7e56b0ca8e4365dff67f7b55f761b0f43ff51e0ee0cdcef3cd33888b57e446519de721cabaa4bfb636182c19413e52c0788b33d622d6c8f2d4af5f6a480d88221294d2754d319d675ba3c6b4f12f0678847510e550a62547011aa6448f8188c845805234e24bce6a7a644e871482af47738361d7619db650842c0b8b5b3ca59371a679fbcb272727432756c88162500bd307eeae9eb9d4e4f96ee51a6684dd74bf403b7b3c0fdc04575cbb24fd2da98cc2b67ce729b9ad7ec22f3f6b1f6950bb5fdb1482585e61843599a39061688667c9af5341b1933cdc66cb5662dcd590f0f2254a29d038385ee41eb4cd3b332339599f3146c2cc7128aa9b08d8a8851981ce3c2f9a5272fdac727874a40a3c52948310a774486a697883bb5c9e9387f357e4ced9957df78fb5bdffef5e7dfbf35199cecc9222e61709a62c18f0e8fbb102fd3a64adc9325aac1f5301d18d2a16198863b1b0a5f398bd4697a8d19bf55bb7eb95a6dda1b23ed42cbda1fa460b19ac79e3cef7ce3a5b91cd17637827933fc79af36d330e87ff655f3996bd5ef7f9c48666306f807b94a332b966d6b4f5daf164069c4d43630a60282aac0e343220b80a7779f9f5f5d58b9a26d7b2d636befa4f46f484590ca6419ba424a3205340a432e27ec71ce82f1d3e567ffc17ffb275f79e252ad3537f7f31bc732192a194f3379e91830bd044d6377eae7d3ffa011604b90d2b5579ebd723cc2426f4a7bceaa34abadea375eae7eef6bee73e74dddd31eb5955e48602cdf7cd25caecafef1f177bf7a6eab1374039623777dc9ada8ecf697d1f919edc70f914ef1a505779461a7e62dafbabff546f5dbcfd98bf346772cdfbd6cbf75ddbbb915ca2c42690fa6fb6b97ab4759e3e39d7877f3976f5e313e79d8064b10467e45234e51b7ecb5611b828b5f7d541a9a0d7bbd7b3be94b55fbf6c3110a4e101f61c5257a9caaa7b989d03235f053faa2191a07c42e9d83dedf39cc45d3f21c66189ee75ebb54fd9d57dc8a5562dfbb4f9887475974a4bdb2ee47e9e0f64e128dc971efd6b75e5bbf7774e058c02af8de440581fcce58cc7aece925e7ef7fb5f11ffedf2398a9b79eb57ee309c06ad13883cf79b5fe6e240e4ffefed7e63ebd35ba3554f3be0629ed5147168307dd74a832ea38c67892f1bc28ed38b56799a244c98f209b963ca2849ec7a84675627c703bfae861f6e18f7f500c1fccd48dac48cb009e46be2c51434e1b99728e72a053c763400f7ca752fff7bff5c4ef7cf5d20bd7ce5eba507ff5a9daf9054809ca317446d06295791abbbe6838b6b932ef6eee76c13d35660d226c3b6e9a8a1cb334c13e7632b7eec3ac1ac67ec8ce2ddb6f3fe334edf28e06452457731eb9df11fff477969ebb50f9f0eed872bc8db1a751cebbb789e83c71b6b171380a6318ed29312ab9bf2c333329bd9100fe6982cb53282ed392ad9bd9e4a87fd253e3cf55310ca331f8003e4d4230c0925f3c7607726a6d5a3a33a1d2b5d8d79f6adc3f4cfffa4efca32fe9c38e9952e3fc92deb419f00f9de9ffe2c3e88bdbfddbf77a1fdc9fdc7fb4f5c25a78ff20190e82d9861927c9781448dd3a6f98ae4389e717590ebdd9de4f405874997e6e5e33189ea4e483cfc7755464c390b7773bdd8926b35f6c43142759fb3e4d369598582a3b1ac500fb429512a374cd29fa9069369a927f75ca284e419b42f060192211abac8f64a6e91ae4ec52583cce45a7013c4d4a44198cbcf6fcb9efbe73ede94bb36f3cbdd013e4fe5e7e125690ee51eae479992a5b3e8ba5da3c2cd020cea2e8709457a23c4e850c032279914fcecc193b07a3f124c776bd41f0489a8e4365a18e4712c562808ccd40edf55522e82f3e0fa24e72b929bfff61d020f97b0f42c48c93203fd74c4eb6be201c4237ef0649942231e5fc68ead0d3de124c7e1593484db19a96fe0a36f75c0fe213800d6876e91525330504289de334e74e7f826f80d1c8efbf756979c9ffc9070fd324cc156ad9e6c5b38be03cbbed42127b90d130a19feef3c940dcbc1d3e61c4a837feeb7bed76d83b4fc37e1cbeac678ffa61b5616f1e1492eacc3466b07ae76b4b9380c705d9e8146798f679a1c741de1ff0a36e21264555a5956472304c6d47fbb71b11108dada35e78bc918d77100a84e454338a29be9caadb5349086f7ccf02d90079d4d0182fd3dba94f63aa11565a5c1665762ed1594e59e6af18c6d4991925ae865e7b7a7176b1facbfb3d18bc6dd2ed93ecd3fbe1c3834983b2e7d7ec7b5d4e85a20a1d1c6593b17406712d4f3d9bc70747dbc17181422feddf1aa6ef36b5bd2407ab24415e63e42b6bd5efbc557bb85bf413f1a89d2d9ae646988292ae83f02d9055a4f34ebe7b32b1746d7798df3d0a8328eb9c1c27dd07326f833f42e4f132094fc3133f1688a71e99e55336aacaf82d87aa4e59b702f160e1c7a024cb94f3d891a7ee001e8fb1cbd0da62fddd37aebefaccd9747768f2e4c26cd5ae78fd488e26d9284093284d26e9d2b26369da4e3b445cf433001c35eec5cb76b18ef7f67a3138dfb251ec04595d43b392eea771c2896bb9df5891b32edd1b17b7f7d230373525734d5e7762966629656b5efeac19e640ae30bd7d309964c5625d1ded3dc2c9269211000c9866aa7724d34a8673fdead9c1700c715ba6152030baf1facbd7c6e334cb3255a61a407e095cda7a9c654b77002e614cdda39c34680e2cf9ebaf9cbbbc54afd0e22f3e78f0cb8db6088aed2439b8d7cf27e930c93cdfcee344cff1463f9babe33c55364d2f2fd67c957f7c38f47b7d473b39570cf7c7b160b84ab2938c5fd3f39d0c8759b1dab0afd44442641e479f3f4a0c858f331ea6c96adced229de3ecc54a0a8a7023d67a31fffc30046ad1dbdf43c1ad4b672b8361df343529c5295f28b9a0c2c3f104f467a9a2c51483843a38ee01dbbff4d44bd1789c830253925a9a25f1bf0326b0a851d254c5c11b6c53fb8daf5d3c6a8f87eda14bf0c961d0cd0b65b1bd93f4242e802847820741a40a054925a74510a4ffe875fb698fafea9a47552ce3ace88f8f8eabd5ec892c1fa791e9f97bc3f125964b94b5d3ecea8c7675d69d849340d0ed7d0e4cf2200e6a683223266d9c372df9b44fdf1f028be60743981611a5996a7f6214dd79015948d56bf6601c01eb2e53ecd42f21f702b51425e8e2721453e96058ee1ffcc1dfdb7cb81d8e07e0c5a54b1360b0527a44e984f93367fff01ffed117b76f2195bff3e2da17bb838d83d1f219efc1e66041a979db08137c1c16b2a42fb8e1b983303710b7488e74f1db5f5dfec97b5b8fbae32f22f7f06084e2497fd2d9ee77e7f86889a818e3062bd65af8fad5596b943dc8d286a1afd5d9f1493f4858bf9f0380f793de0a4949de8e197fa1d67aa4dbbd51dca2221f456d8ef2ee9773f260c910b787dd30cf47204a80f78bc7ca083407bc2e0af178a10a97980cc2a3c8e34f3ef86032eacaa91c0497364f433857d06b1086d4f2677737bfb098184ce2937eb2d8b221fc77ba6157d145539b247cc136bb69a13450b6053885c0a4a0e8b5a7166e6d0e8edb415dd3d6f4ca5648781e6979af1f81b5c2966be822afe4c367bef3bc08a2f949b89125ad0a72300ea2819cc8860c36469d4c3796f920c379d5541717eb07bdb185c8c930fba23794497f297d6088ee83c9c08438b4cd3c2f3039c5abe96a8e285f4fc54f398a72c8e8b1eb969e7f9ab0a0bb4619c325a2035683438b3ceeee6ff03cf6311a1710096271ce79b4332a57f014398eb3242f1b9977ed31e063b96ea42aae5b33d91b4b2e7ad49b33489719b7a3da79435b612910d5393d858ef07c72d1a6eb6f9cbbf4e4c5ded10108c2a33c7667ec96e104e33e9f2494e2bb91c23ab946c39ec62febc63e130e300fccfbbda150592dded2f2dded7882a93ab736330e268ead91e93295ae317062d334a6d69e0e6c4a34807b60752a1a0190cad765d05aba75ba240b98edebac26e58c63d465deaae8409c75db08c23c88a569c08c66692e1389c69c2fe834cc31486fbbe2f22c78ee62edd1c31e40e32b4f5f980920be9b9fa59a86d33364e46bc86ce5941b2be7bd675eb87af3879fbcf7c5d165c4db989b4d633ed73abd6106b4240d36895a657cbe6a700ed0c248944e6211a4833512d7e46638da063e2e51beb6e4552b7465a1f2f2b5c5dffbf64b4837fbc3499a169e6bc569f67865636ae9d38102ef035b013f2c17ba20ef58bae394845107bf4d250911eda53ca0ec385120dfaefa6616cb11e7e0177373f57367e7e75b958a6dec8ed342a8f9334fbdfeeedff382feebe71d77c65b69b983c18911043384ccd8c6761686e3dd65349af5fcdab2f9d28bcf4e1eee8c364e3e9c6455108d961c28e9240a05453f8d4745764c6813dc9e09230d954fab59b6c54757c464233c8a44f008d0117110d59320690fe2e138b9b0beb2bbbdf9fbef3cb37130e8f482284a1ed38fc7d2979cae37ca53c496e5e841e150dba83010d9cc1465e8b3a9ede5544a12a9e1765eaec2bff5dcfa77bff5d473d7cf57156f60d6544c339c8c58cfbff107af7fed155b8f7e7effe4a307ddeec9681e5044a9194ce60dbd42e53e206c326822f5c6f77e6de5cddfdbf9f0b03d1ef8a6de35c88c9507b9ac0acae3f038e51352b46af38b88c2c885c9e6507e57eaebaebc7dd85659f4601c514d23a65d604b88c2f7cd738bd58a2134c3d2457a6665e6ce562f4e8aa97c20d345f7c77e7dfa9ca01c30b1ca4708a0a3c03485625c4e656fa92ee89c69d46154343f5fd52fcffbdffbeecb8e83febf9f3ffcf187f76edc6fdfdeef6f0d8379dd90399f748f1b6ab477e3e3e1ee6151c45d44b6118d535e2f178ed5f3165f54f1312196c6af2cdadbbd62e3bd8f47a393b5aab341f4953c8c74ede9abd71f3ddaa1a63b64b2824cb84a2681ee68c7c389cab3de60a8f2e251b91e8c75bf2e79d4f2c9eb4f2f5f5e727522a770223482d697e63ef9f244522d4d4a76ac6b7a893853c022d3652c045cd1a84da14bb2e5a5e5bd8313aa55441a820ad29418722908ab18f56fbe7519fcff677f79230f0549d13850d3442faa9292f9d9e2d1e69be7e207bff88bd59a1f6afc82654c98b63d89ee73d5a6eaad2246fd78ddd793acf818690ff7bb0777fe8226c74b4ec5f48d8b0ccfe1d9833cddb8b309505531b18f2c391a3955677f9c5de3e49190b3ac48d3fc51210535a8e980f4ffc6f36ba05e7ef4fea66e80bd9961d2c5f9eac1d1e1f2e2ca643c4ed2691e52c8b68d7c1251046e484108094125f14c438f8484e8a5b38bd7c711b6bc2660922415a1554d4a2fcd37ffcb3f7ef1ee5efc83f70e0f42fe28c88f33e952bca2e375475ff7ed59912d343491ca6830c0ddde0c469e86d634f4825bb9506b75b079586f2291f3c1d1a26fbdf9d2e55bdd8875c66b6f3f314be9e1bd3dc5ec4a1a75355a0d4537185fb9700e08b14ee5200c354af679e1285c64e9fd4c6abab1e6576a55746ec9bf79e7a8330cc298972be1e08f8c7a96012f5c0bdd7cd8497305241f222ace72528a61541210f896de10b802a303ffcd3966bb90d1cda5887ac80602e2ce68e2e5b5fc1ffcf6da9f7d1afee5fbe3a2b0b0e40c250e232e13dd829302b7548e45f2d2d23c37ac56d3de6b4fd438b7106e0bb91f774d36f99ae1a08c3e2062cbf518cf9f3edf98b9f5882c380eb33f7af4c53a47c1589ef03448e492249c175a3e51c349110d8f2745d3b7ecbc001dd22954cd34e72da379c11f4f82837bed973ddba638aab15f063138ee4cd51a4de2f9d92a82ccbfd438e946fd710c498b4ec148969287e9ba99149082e272414ee5e0e1d45af83ad61bd85dc14645586b67d666de78aaf2379f0cfeec4694704de6a003882c1f3149c33321c6392ab8e7bcfaceb5d66c353b9e7c7e92f6c67189058cd631f14db755af324b1ff4baab708941cf3fb30c9ee96779f3fafa8d7ff3d76a75b91a18335ffb6e4cd97cdaad033700ba2af308c9bd307181872881629e2a3521c6b9965f3de7c95160ef4dc0a67b587e3ec93a842caf369fbbbab0b6506d54cdb92ae83da3dd095fb93e7fedeab982394106194843ca518a70c148b9528fcb05106220e6b3e599cb27c2119aae0a7fbd66bdba2e7e7a27bb7b548db30c499812aee1e4cc5afdfc2c6610da93c044e6b7df7c2279b0fbf07e278a8abc48ad9ccf561ce538599a365c960613a21bad66a3e2e0c58ab6d0741fdd3ebcfaceab3b3ff808692e39ec6cfbabcb8b8b9ca5a2f7c5f5b7af8c7efcfe2cb3ef6e6e474aab69dce012d4ed80996716fce5b3b5d1edad30969f273935e9a5e59967e65b1ac91f6e1fed1ef686413c18f1e7ae2f0547e1edfde260d811d1a3efbc7aeec9b5337ffae3fba5c4a775105530ed656813f85991d8a0f9d9ff80589ee5b926d5dfbae8feed43d18bf5765cae7deb3a7bfa5ce3379ff11ab1d8dfcdc6476d2024dff98d173eba71eb6fbeec1d45792ef992ed0d29db2eb23aa2f076e19db7875b0f2eadd62f3f7bc6c3a256d541e89d79f5da173ffb65f7c1d13ce245928c8dc4bc7d2f3efcf4b9b72f25f7b6371fee69026f071107da4b29956c9f194f9d9b9969b9079fdc7f44f02147e7cfcf3e7561d10ac3de4ebbb7d5f3285170f78c8e847ee9fcecf6f6f1783c827c3b8ad9977b93572ed49e7a6afdf38d49bd86b3389e3e77b2dc8a95c0980c9fce3cff4fdcba7beeac7f69bed2157a90b35ea15f586dc5a9fd27bf361f46e2879f8f6f0e689b837a937ff8edcb1b9f1dab584c3262032b352a91669eabf8ab5ea3a5571a9e3fded8995ff4bd8b2b3b3ffd0c058967eaa4de3453a16edccf2ddb628031488f8b936cf8ea7a7de1d9f3777ff089659aed51f0458e3c06ec4d8daab36faef92d91fff2eea3896bbcf8f4ca0b97177a0f8f0f1e9d6c0e92fd301b20141bfa5e40515e9c5db69c4a6df700d043a6a994905c490504e6b75f9aed253a46c560046c04d29296d3d6f4398e459ffabdffe21b2f57df7dde630df38b9e0a339a4a369ea8b75668673b1e779314fb29b53dbff1d252ed38b347986a85336b3a315c8c75378d0310eb421c987a8f1a4eb375f9eb2f8d3edad1a86937348de2b9d79eeafef896413d150c06c978beeaf573acd16cfefa5a6156065f6ecd569d8f7a13028a91d248afbc5897205a7ebad71e69a46a699df60454eac5eb1707bb274d939e9ff166965aa0d6207cdc99a66d420a95db870353d7e2cc84bcebd7aa3980b2c9cfb6d88f3e6e4ba421622aa4c10b2c626478ecd75faabc7916521a3f37636193fcf9cf417aab772fb207fbe29301f0e72a538946750f727014d33474f1288a64ab6683c49d7895dc9b9905468d64924474d05e5d2d3ef9cb1fca04afcd37357fc6bdba103e1ad22c0dc1ffa4b6e6d5123f3da3345575f59636d83cc4cd163f2500a2d0f5ca577471eb680c821368244a1508c51661175bfe33af5cfa7ffffa567718e271be5a646f3e77e6ccb975b779ee7ffe67ff3b08078274c57cd3b66c7fd1afea9e15c73cee1c06ba61154591f39235321c0ba663679e3dbda01b0c6818dc53beb8641c2f9b076971ab9fdf38e6058f513e91c570cd504f93c2e25dcd180e4f46a8283646c2c4e49a6bc8700c3201e4f1a26611cb21fbc65a6a701381f5398a0cd7e81d26bcb5641cee32878779ea0e34fbb97913744dd5d90640cab2deeefe594dd15af3928e7e3109029179197dc77540e982a6b466bcaa69265b07cfcc783d4675a0be61dafbf2649149df162f5d59bb7373ab4e2abdd08a31a47692aa6cb6925cbdb8fc706b405594f10c8b504ac3718c38113c0be96ffdd17fde748828d314dee8f09fde0cec24b9f1b093076d14ef35b2bdabb86b89411775daf9310c1e87a3055ae8b868685c6519e3a0fe91656860a88378d40d46a218b61cac8ba2b1d612bd6474675f25a16660a52366620bc84e18386b756ebbc5de51ab6e49952cf95ed540eff72632cb5618ab2a16731160b4a96473a592f074388974490fc77190e527481558da068d79fedaf3d77efae9f6204475ac164cd311939c6048a788c74d5f5b596e3cd8ed033984e82dca07115a2919eb2ffd9385ba8619da1ff01fdc0cbb87493006b80f308fd6c55125ef3d8826110aaf5e681ab2b328219f13365f6148b4c338e4dc617ac8d898e799a19b15bb6b5452cb1e01f3ab99d69cbb77f36e01542c8a49513e43b41c9d7a9a050a70d1cb8e3b86254d072ff8d576186c9f0ceabadd0bf96e9c6f8302916a916a4b75880a0fa026cc08f29a87bdf880134504906d0eea93b1865168cdc51bf7fac34274b3b440a4652509f4aa62ecf7f9ac2bd75761cc432520156ba01f946652f7e21fdd38c88078fdec4e7cf75e8427f1ee4964f0f8ac8a4e92763b1a22991a54c4e3ce0ba6240bcdb35e25d9eae541565546ace9e36a0d7e5d6db68aca0c00dbb57aa5a568cbf1bc5655a5080d84a59b76b5a6982e41c76826b0750d0861ab5af1e4c2b7bfd97cee7995f64867ac2b4b773d8b699e5d5d76eb79017994630b258877f20c58b54f657f63ef9286cf3955cbb57caa6c8c9351fadab367376f6db94ad53597d322a2f6e20c95122571360e93a52aad35fcdda301c22ed02f209aac731c263d2d89c58bcbfa4e988cc78583f22a1f6f1443298bf2510bc8ad22ffcaaab3b8eefed9478f7e398e9628e266855935a2193584eb5a8586c10c1b24a1dc57acdea84b40259fc20785eb10c3a68e611a78703ca6d904552a82cbf828a8cc235af1b1395384e33161513ee8737e28cd431425e360a55a1f287b0367b5b4a011bf7869ee58908f32c164f1b5eb8bf6f07098a9c2a51b9df8e96462aed66fddca149857972d5e5c9f7136bbf1602ca547bfd8eafdfa6b674ffa8b07ed6c92082c87b472e60f12b8dbb878707f24e3dc62c31aee6c77b770da51f190f021a0f4b7cf372ebdbafebffce8f36a220ac358b4ab15cd0e25723506913ce1c500dc189b155d519b66419fe9598af393ed313351d0ed64fb7be54a6c6fe22e56a8ad656181f208c215f06a70ebe7fdcf3be391e84e123a89d64cb45cf3665c0b849fc68995e7382e3284676ad6b2eb1eeef507b908a2e1582a00da0ac639d3f4a85f995bb979ef50622bce27c25295aa9e0db28a6377c3dc60e53afd2bd7163fb8d5a53a9352076e1fab4289825654da0d429a9d58bc7d263fb08bb1a1a53ac9963de3abafccffe8471f5f2b04a17ac115596eee77ba1ed3304f3ba96ca1d44adb23916d98d675bf8afc0a99b1774e423a19fa2462b916528bc54847dc589bd9bbb1559ba9c821cf99c76e1eee0e7be944aa903976b5a7c9cd93a1eaa6beef3a9ed94bf98e6028156717c05bcc31222e362eea7ca1626f45bc4f64dda636d1b7bbd14a5594ebf118d880722ba83d109d445b728c2c4d68cd391e6babf5c9b50bad4fef76b992f4ec93bf03e803b22a0f0eed74e74ab6b7907724822988b94c6cc6bff3e6c2bffab77787a382275947aa8ac6d0b803d3a425a9968cea22057dde056de7b608270d9ee67254859cd29e688216106dba81f338cc07eec5d660cc49222b355fb94d1a0de2a3fe6e926f76c72b6e254a69c8953e37df0b937014678c5d99f50d646f49aeb57ca9d30ad337774700b45d0cda9d3408ce11aa6a3a76bd7e273c89f4c6ac9f26c94c531f4ea04f457b9c832aa9d5ccc3f664aeae5d3ddbf8e8ce09a8686691441563557067f26545060f044a80a0e52191a2c2d8f7de59ff6737eeeef58b852c6d33b9ec1a0e8d2c8bac7b4e3a2ab44046d474ab2d2b9b38c921e4489012d46da6d8f12ae58e3c331820aada613273718e34962a7737d99939642f727d2e79f8b0dd8e1307d7165bc79d74d5adec8e049bf0957a2b9c2dcc71f6e06028a8f975df2fa41a24c9f1681454ec4cb2999c48a318189921f0f58a73fb70d82f2015246a1cd65ce875298c8a82732e28d5c6110fc36ca733599f776dbd88418404d68b0ab044a649d4898b384f03553e584bb1487ff312db1c0f1eee0e573117482c1ac6322b166ceddad5352c716cea56135487d55441184d6ad86a394ecd37918fdc8a490efaa33c0c9294323a70679eb8765e6eb71996def5278e77c6cbbff53b479f7f89e3768ef020a41f4f0072d9a2aff591ce86905f9d9ba996295a6968b726e94addf039d9d81d81b4589eabdc3be9c94cf8d52ad7bd2f8e83798ac24876c344d3a965b17aad1647f1242a772954abc6380457d71b35aaf164f328033d4d8dd6cb8ae7b2c851da5339c00120738e5551a793069d24ede00c803c61305d4e45cdfa64e199f378e1e27118dbaee6f3c91289971a5eade2fbbec27904737ce5379feffdcd5d4485a1e14ea1198d853995d98b46bc755239732e8db2e2e020fcf0b3a383db45901ca56a97eb138440a07a3906fdf001775c9cf785f120904babf58b4d7710e5a304ed26cce7eaf575f7d1182598581596657127d09d9693f792b4e0446779212641360a5121344290699a9380dbb651a28de2db477212a654afbd88788a6542921e46021383cad824d1db4fcc0fdac17ea68e256917685c1480d0afbd76d1f1ace1c11ea49262d017bd9125ec6c90322dc1051f0ca3a597af460f8ee35e34c8735eab56d75a4b38b79f588a1f9c14d88891934e8e3a9da19507fd34d725914036ac0ac9500e39da2eb3f413e7cff86f7ddbdbbcbf2f5191d1a50b754faafdddf176acfad24c62f5dd37961f1ce67aa51e47c9689cced5adcf0fe20a6231485ec3b00c126582735aae461356e4c2f74d298563d3a35e0aac8b9af51719853ba7286e2b254d4da07cd042e16e7ff8282c810b38804e8a97cebafff89b9725d53ffd6cbfdc8d303a9915c582a61b796eda342864d409ce5d5df1179a47f7f7efa4e9c8f01693c21322f5f4d69cdbdde9606ce73a2b5854a9d3ae04a6dab71c137b4ecdae7692f456c22a7efdedb75f79f677bf4591f9feadfb2b94f6cca6efd97fb34b161667612ec69322a1facb671b8e668d121672d3602a2be86004bee146710121930b76f16c1524540ab2212b14d66d8b546d9e66e8b85beed0a59a7b5d65a14ada448d91c2a2483c97e514f5212a286f0267ae1adffaca19803b4ee87bfbb8d6b43eb9bd8ba2bc9e01cfcc0dcc4c5783f60c4d5bfedad307376fef0dc28a619e21d86858c66acd338071f31cf29d6df8155e24a14bf4116658e5a9c2dba9ec2662898b632e41bf5dbe76554f4637fef59feec72162fee27c4d08636fa0ddecd077d6ab56dd420524bbf8c957cedfbdd399849a57d5bbc334ce88028204e903a98493762fbf76b6566bd69c7a0bbca0daa8ced4d8fe89c0a659c411d59d4b04719c75c0c852e5145cb388c07f09065648cecedadffad6b39f7f7950f36cea379360f2f0eed6a2ae9e017838df8801732afaf161b80f7af0d9331b879da3de10724653b7fd9633ffca3972dc37966a3c2ca8a7fb3e1b0ad1e984b39eb5a3a495f2a3b11a2a96eb98b8da12640bc3bfb9371edfdb064e7910e0ada258f3bd90e97c9277b1bf33f157abeeec1927e88c5fbb3efbf3edc8e1a25923f7f641f5d0f2f142f90801f3728b373b1e64971634df353be382216919f4a023b2b87c7e420dfb0c2e4606ca6d1517124836e88d1c48a5639227ce365f7969fd5ffce01692fcf7bef3f2a3bbdbf7bfdc4f83e27cacaacb8dc8d021051f7422c3335796ed33cf9e3b7eb4e34270205b5946ed424dee0fa334309657505ad42e35cda6bdbd13372be697dbc1df6ef7e689365ba51507d7abe698b3ba690f59d564761fe0165b3bb25e69ccf68ef3e595c6cff7450b6907520b91018af8992bfe5ccbf072f1f961bc6892cd9e986e7ca5d33dc4a02949f9140089839e78fdc966ad6a6659d21df32c27b42c5910d470ce520eb439ccd5e99336c118761df3d5ebadf36766fecfbfbc8378f1c7ef5cf9db3b9d1f7db0a14bf60c805ac3baf2e6d5687ff4a09fdb88572cba38efbcffc92e9ee4cca8d88ec39aa6787832088bda5bef1879e45fbbec5e5ce5043ffc72b7058ebd7e764e45dd89424eebd6908fc6d9b0b58286d1443346d46964854e6a96e91f23bb27ccabcb331b3d4e29519a516df8612c78c15e3e63e98b33e9d64910a6228d039e23aa51cd02e6028e0946049aae081da7e8b75e996d87a2dd06d3943b73213b53cb6880e73b28d331e45f00f3d2999fbfe02d2e36fef58fef732eaf9e9f015df7d3f7bef4117e9d9103ac5e78e789fec3de070f7a411a6229001b4027b6c71c3127d02d6c33f508862379533fb3e84b0b379eff8ab6fcf668e716cac5703bfb706337177aca498cfd835cc3313f58ba54d78d87b1d7b7e7ac448b85e957eb6de47995fa4ccde6d4f86c84d628da8d7821b50bcb5e6f205fb856fdc956a6f5263ee7fbdc9a6e49624c27baa197299822c37660e426ca7ffd95a5bffab0ab9b46543e3fc77465be95447dd03fa9ca914a35aa2e2ebbafbe78fefffacb3b1957f30dfb1bafadff9b1fdeaa28f43553df92d25a9ff775e7279f6c4722a642b688f4ab2cccd17cb531bbe8ba15dddb1b8d94e20ece52cbf51d14a7b699114d88938796be9074469d22b1429e7b3ec15ae0cd3a26b5ad19ddac259546643540f886c4d7ab6ea84ce657a13f9e45ef04966d9a234e11c6cb0dbde6697631a8b61a7f7a279d27a92e8a3171393104e08f28eb0730d32b36836b7c97b42868f51a7835b02c4580f8496bba6f404e1f978baa43fff8779ffb5fbf7f334a0a8da9dffbe6f5ffe7c7b7eb76e502520f38ef58da9ffcfe2b9ffef4262659cb22cb1660231d496a2ae310316ce8d983218ad00321126e784046342d3ae88a34480eb7c1697bf7b63b39e912dfe2229b59c26e1dfc4d2dae1d0f62e62dd6eb733948a05c998e236afe8aa17d19a19459cde5e68934b86612566ef4c702bd76d93f3e4e1fec8d5617b58f8fa039dfc76a820dc8eae5e66abd2ca8715c1bcca913de1e45d7ced4bf3ce251b9ed9250d39c45a898960d0870e857cf557ef1f9c1f12085f7bff6e299fd5ebabfd36f2669bb9085c5fea3df7d6ee351f7e347032032c34cdce81583a2dc99df6ccdacb4a8bb3bd2b9f1a3cc38c82ab3666d69c1df7bb0bb72e1ecadc3442056ad55a3a37823c5ed80250b175c51b85e7d62f9561ae3e5f3a338d7cd3a9e9d03d9d6c4782f262ed5b0695b731565990b2d77f3382f69826d4829571c8c4deb877772805fd727e930df136c89e5132e0475c0b589ae83913d471ba67a21f0faac763c41837eacc30596335fee4a9b96791814655c6ef520af91a66f7ce5c50b3ffdf0d8e7458af24423bff1e6b533beb972f1f5cbab6b7ffee9bd9d50ad52b950a59ae95c5fb5f8d6389be8ff32a8c408bf36dbccdd059ec8868d42c4a906798f5690a3359b27c2194c9251a232677664d4ed9ad7208cf8b3ed24f597cea75161cf5499d2ba36a85add3a539d5bf5cc8afd9ffcd66a3fc147dd22cba4abb3609cbd7cc9fb9b87493fd1af40a28ad2344a3b859a5749a4b06486691a4596fa6eb9d7324ed48c8bfcaab7dfcb153017b7ba2c815a96bb43a4ad934122a682437dfbf9b907fddaeffea3fff8e79fdd71417fcf59575bf6d6601cb7a36b4f3f7f3cceeae1c113cb9531f59fb950bdf1d9c92aaffc286291e2ef5e6e6e8652525fc7dab5e7e7debb737c697dd66ed4470f0f787dee5e8fd1dafcc86c686e2d8424b37a51fa6e350ce8ec9cee78aec10aa7d2ac99c8b5aca5caa56beea57963180807891f7ed0ebf726419cb63c2392da8cc695696f0fd028c8ceaf5477873c4de384e88b240bc15b35c7d678011087139d16269f9c5dd43ffaecd0d008b5aa57a65bef042592e97a9a0a706f0b642625770f24d0e3a3dd7b7134fafd77aebe7ffff8deeee0c37b07cb0b4b941195b57795b7ba56eb3cec6913712ce881645f99679f0546ca9c73eeecb58bcb3b051944e1f995994aa5015cfe8bcdd1f0b06f316b74f60a40a46d589071802e51cd6655cf35dd202546dd92984618bff982f7d533f6524d6b5649ff68f2834ffa4c531c51a09305cf8a427be592f5de46c6858ce3fca98bb5479dbcd479329f71cc71b9d6086404a4509c25d142957b5a71f3e138cf386d3ef3473c8d65912a5e42f474cbad5caeeb1b6d1544e1d1c12696d9f72ef9370f063a958ff6c654e69b1bf7b3a4131be65cdd49a222db1932a39a60fd52d3fa65d41871f464a3593e643e53fdfeadec8975779e04bde32868343a8136664d9c674769beb0beae7bcd0203d780f4531d61cb66bae35afe62651ca1f979e3a515c3d5cbe43907dadfd27ef22033759ae56a141416ca86e3f16b67c8870f2720632771b1de92519206a36156e43e2e30434266907a94ca8b022fcfb0d138dcede4af7cfd65f23ffc37dfb9fcfa77ede61a617e9697c217707d920ad01cf06d24b23526b222190ec234cd3524750d635773672a3ce597cecf7cf165682337b4cc998673583dbf8f669e5d5b4a88bb549fbb9bd7123c37539d47eef2c4a81eb671e0da8386a7d69e5e76e70ec7a9d568390b337ecb377c6766a6babc5a39bb68d62c4d8225b3f24941b9ed84b0849795431068e358fa15068200b1929c6d1ca4eb0b7ac5224ce5b7768a6f3c3d8b4c5fe9d661a166b3714932b2b4c814a30838733f861840a2b7472eafd8bffdee65d5785a3a6bca68968584988d22312d27512d220c0b7f7494689636048948f482195f7d6ab5bb37faad779fff9fbebf5311fabe5199f7661e69f337dada1317ce0464b9ce2a17de79698f83012dcf6e8e79b5d274beb8d5a1399f7402554cb47ad5f2bc244e1c1f82d5acb62a17e6ede756dc67cfb9b656566a0276bebf957c762c37bafc97f7420f7322b84af37e2f7ebca79498ed505e98a361102540a3703c1e0e5e7a66195596adfae288da0e978c00a38430cef22489f3088becc6179beca89dfdf0a78f78f7218af6251f2159eedb118a11c66c9943daeb2a0214fce21afbec24ce31f9edaf5e7c78fbe037de7af2a7370e269171d5d349dd8eaaaddb5bfaea8cd9b0d45e1faf37ecfdfdd1ce7131e3ebac523d1953bdd272175b6d64683239e8723d38f1d77570dcd9ba3e63512a54a3ae1fc7529a2ce8454d5f170ac22769f70b9f7033c85e9eb56b3622898a5251a54904940b2049e0334d07246091c7418436bbc50bebe8868cc230cda8b334eff447239c15b643c7218a4b8745455ed00ff6d6b76ebf4f932d998f18053d21ca6203d3fdc37ff84ff3b4d8edb50b51981a035f3a18a46f3cb3d60f2524d8ec38fcfe474775461cddf7ce2fa5c9dc11a76f3c3977734bd944831cd458a9fcf4be78f5b26d49a5bbd647db72c1a51f1c144d5d0f9c1a71aa580089e0d59a7b65415bf4f5959a21cbfda8409a31643144c848e0ee4954e1021772d5131fdd0ffb9d88278141c43018eb949fa924e9b0f7d9217c9979158b194ed3c693ac24e740390220569a9e2759c5ce81e668940cc71155820c1ffe080d6e30d9531cf007265909456bf5995ffbfa33979e7e96606214c2af68410ce4c76ed41c4df24a3ff9ab1b3b351d7922eb6ac2a36a6b10ac35967b4323548d81b194551bef3fe2709ff90a0e22e5d7b45e0f694d608b46ccec510ab8c813d3b6cb2568ec943ab42c4d9ab3d9aa47afcc92afacd96127ee3d1a84ed7802241422314a57672d10b04d0da5499c8268988cd33cd83be95934aa3a65f5f524481f9ef073400c1855c01b44148f02a2620dde8441968c6d2d4172c448b2a3e148275aa4b2d32a7009b17df2e8bffaafffbbf6d18e1210fea84590d2ab6f3fd5bafbe0e8ca52e3f84ebb935744b98198bc78a1716b937699f76b0bee7b077840a954daf973d6bffc38b24ce57ad66e3faf1393d8401889d064a0310e37ab1bb333f67a9d2d58f2e6bd93951abb76f5acad1140a08351fed956328cc032241fc49ded2e3165c7664bb57a2cb4a79ada7040f07842551ac4e62866a02ee79b95ad836e554fda9d98151a2946a01f0cbde022d271184e32c8419330cab3b268921131ca84c8d2187090ea5ab91f11045021361edcc08a10220dcb28a2dcc4c3a37dba96a1dd1b7b3b05cb013c55f5e519f7fe211b87a2d914fd0cf70a0d997ab56675531c33c3354cc0c67126767ab8de60c01fc2a80014188579ae65db297f7d851ad2381a25450ced172d8f3417568fbbc97e27ecf772c89f613401e2a8e2d1bd9d7c65a94ff2f18a6dbdb7cd41c66b9a35188e47e36e27412bcda5aa9ddb7298213e9c28cc39e2e31080974786299224d7410ae7a87c7284152b2b379198ee4544be63c4a01c9596a7d9f40880b2a40d526191f12590eabbbd0f127c899250b08093791380d3f8b26f57add65335f728942b6b6e2fa67ff8edd69f7f16d7ea146efcd909320c6bff04cd79663757484f38a40956961173cdf9c9966a6d6e0770df451b481f96da4f7ef6f9dda89943be8e0baa1b0459713a1ef2c0cdb2758fc7c393a8e38a44d58d1c0682b32c48384ac23b9ff5b824ee72b96f258451837c20c04da20b17a08ff1f6f68182a850625a398f1930e5c795e418f781eb4db71b4f0bf104681388fe34c9ea269161d22fca7af08da252d6e8a7de936ee5e711b36aaeeed4e71af51b5d94f6b2272e35bef274c569e8ffc75f8d3425fa0ad9041de4a8a5b34e2204d2b0ad95eb48a18004e36915ddb60efb81531c7eb6135f5dad4c7ad1fece8396eece79d6ed1d3a63799b03cbf66642d50bb60e7c1ad4689af602c831b39ec61d0f7816487f2058b2c886dda4338054a4f3b40f6409b8633a6c9f4cfabcc81caf1a7350e8654d259beeb115423d2e2c96a7f56a20c278b93d938284426a1eb03bcdef70f46cddbc39e610a60bbaf4171be101b595f65285ec47f420504ccbad3cfbdf7e323e1c8842c85acd6c475259a48290d164c727b151f3c234cf0919c4f1fe30a9dbaad2129b9be31919f615b5f2e385f3cdfd9fddae2f548ff78371d46cce37b1046d608445e572a28ffbfc80752a224446bed2308f8f1eaa09c0083b7b65b67732704dad2b469217e52908942911ef9f0c60d840829fb87ae6a39b77833039dd3e7b5aae5afeb46d2b4d5234ad6293c06728a186ed659125e4a792828183499a726672f99427fff4fe31aa9c8b94ee307c37280f1a7035e233fce79f044baea674f6da53de8f3793b939ad6593f52af93cc0c32d450dad184631c7694ed6ea5aa7330492880be57b6c9c383ff9db76a7976f98f99299647bef17dec56632deef2f13b604249b1a711804162571d4d9df0897ce2e1cf64e88500fee8560b73866029811485d95138c0a199d161c82d0ffc57bbfcc4f0bb7caaaf2e92116a7dbe509a1a7271b70355d0d509247a1af9303444ea44e4f2bb1a9ef4aba13d104b9c4ae036b00c9be5b94d522f3beb9315218087a4503b0fce166e2d7d9cb67f5ab356c50e2bbf45fe968eba850a30411adc08061fca413e40075853047f95f7d7910940bced6c1717cc61f4246a5e37d1107eaf02ec16ea2a17acc3a3835041f436ac2d9c1d636d0a4b2de58b701b293ac1c928ea76b57393f2d963c3da48397b9564c2b3115639a3e2d03296b23d2386cd4bcfe288456aabe9384c04fa48fd103c932c93c864350384e734dd14f73a25821a2beaa9e3f2cac04e68a8b2a925b21b2349650401c2a0c727d495bf791af97fb78cfd7d11bd7ed6e10760d266210e9b2868a092f2b688cfe6442ab194f655e24613692b8c8b36c34eab7f3d5b53393ce21a8826d061cb1dc5747cba7bbc0af793b2c41154c3319a565a1d269017f59098a0d430ba31289a725fd10bbe4f4188bd2799f79e27cbd5629c75eaef4a8c13028e318481e2d8bb918301ec42602526ee91b4301823a1a0b95301b5113c98253f64859a7f5ab452a26b984f8a140c7295e696a2b1e31a93a3df803c264b1a21a40c42c8894726734ef24a3546742d6636d67203aa19d655444bd603491dce2d2d9deed1f6f3eea8fd32c0f375024515400f6e44179c048792c01fc2c50b969e557a7ad94c71f08a6017172cbb153623b0646449e9e39723ae04f6edeed0f46e8715d7479d207a6d8acf8ed5e5814ca66f898abd38ae3045913642f31ba09682d012d601628117928a75bd1416321cd675a31dd8a3a4ee4de487d72a28ea2b2b80f62249718e8d7bdbd74a6dcd4a414a07f67d81b8f749132d9bd73723001f59a64404c64dacd2613486041aef34e2fcbf24cc9c8000d5e24aa001415aaac931702fa41c4b44e6b7a70ccb472091a01589c7618ccdfaab98f8f01785cdc5496f100db45f5869726b93a2df780b68a7c3a27aa4ed04496db709532a68522e62249f769c399bb90979bdc88667a5ecd8d73a25323d71886fe121c109a62ca0dda4fc4ce3187645948f4b75bf293fbf151271b8cf2f27c852c7578b603161171d1ef6e45bdbce0a96249d887d9aff0e430eee7421842f60b51f18d93de8873319a06248c3f2fcf033aad5899e650f5b852f2f42c99c9242204bff0eaf33b5bbbe5490ee5a6f8c7272040acd621a2cbe35c280516cecb4a535c64c5b466a03c592357b6a27ae902a40203d4a999b02ab25b30576555a6ee28706fab4540ae576ad436a9015f618ea7d39a4e94b432c812a8e9b3c37e918cf3f12011d34db82a9ee01426b3b40a1e6f4e4f2aca10f350b00559949569e5188908534b01e78554a392d281cba266323d03a8d0ca078410541cfdbb00458f2b974ecb5a80fc4fc214ec3cd37406a3043c24cf04354ddb32282f0fc4284f3a115c9c16804c8b7c1847007b5a793f2021e50c32ce5ca4594aab12c567ea005d6e0e735eeedbb43133ca0a91b24eaa048af290208d4c463c1c65ed6e3c3a0e61a43ccb449aa9a2903c57797950922a620867c809334d5de4c9f28c9c8c46d08ca5e78ce594809961380565d32317f0f4bc89e9e884e4538f24bf2af027d3f2c95f9d6e302d309d1e384480d24e43609a96e0f7f039502868a962b3b0045cb33c6aa93c10649ac6c8b48c8b9a0a3160104ad3b1a643f281dff5c6caa99567c230d394840015847c000d49ae6af36c3048a1a922c86452ae3ec83457a70e974660799c0fa785cc1a5690ca3851e1b013c2b44e4681a641548292c955199390e005e44b40c11c2e663a12539208324eb7f3b2aefcb1633f2e4ac38f6b78907a5c2ead1b5a9ef3c7e71e60fcff03e53ba0e76351d11f0000000049454e44ae426082',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3da32c-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','BurstingHTMLTest.xaction','/solution/test/platform/BurstingHTMLTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a3c616374696f6e2d73657175656e63653e200d0a20203c6e616d653e4275727374696e6748544d4c546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e4275727374696e67205465737420313c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e200d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e20200d0a202020203c6465736372697074696f6e3e4275727374696e672072756c6520746573742073656e64696e672048544d4c204174746163686d656e743c2f6465736372697074696f6e3e20200d0a202020203c68656c703e546869732062616420626f7920746573747320746865206162696c69747920746f206c6f6f7020616e642062757273742048544d4c3c2f68656c703e20200d0a202020203c69636f6e3e62757273742e706e673c2f69636f6e3e20200d0a202020203c726573756c742d747970653e7265706f72743c2f726573756c742d747970653e200d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e200d0a202020203c6f75747075742d7479706520747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e68746d6c3c2f64656661756c742d76616c75653e20200d0a2020202020203c736f75726365733e200d0a20202020202020203c726571756573743e747970653c2f726571756573743e200d0a2020202020203c2f736f75726365733e200d0a202020203c2f6f75747075742d747970653e20200d0a202020203c746f20747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200d0a202020203c2f746f3e20200d0a202020203c66726f6d20747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200d0a202020203c2f66726f6d3e20200d0a202020203c7375626a65637420747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e427572737420546573743c2f64656661756c742d76616c75653e20200d0a2020202020203c736f75726365733e200d0a20202020202020203c726571756573743e656d61696c2d7375626a6563743c2f726571756573743e200d0a2020202020203c2f736f75726365733e200d0a202020203c2f7375626a6563743e20200d0a202020203c61747461636820747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e7265706f72742d6f75747075743c2f64656661756c742d76616c75653e200d0a202020203c2f6174746163683e20200d0a202020203c6174746163682d6e616d6520747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e7265706f72742e68746d6c3c2f64656661756c742d76616c75653e200d0a202020203c2f6174746163682d6e616d653e20200d0a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20203c2f696e707574733e0d0a0d0a20203c6f7574707574733e200d0a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20203c2f6f7574707574733e0d0a0d0a20203c7265736f75726365733e200d0a202020203c7265706f72742d646566696e6974696f6e3e200d0a2020202020203c736f6c7574696f6e2d66696c653e200d0a20202020202020203c6c6f636174696f6e3e2f7265706f7274696e672f7175616472616e742d6275646765742d666f722d726567696f6e2d616e642d646570742d6873716c2e72707464657369676e3c2f6c6f636174696f6e3e20200d0a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200d0a2020202020203c2f736f6c7574696f6e2d66696c653e200d0a202020203c2f7265706f72742d646566696e6974696f6e3e200d0a20203c2f7265736f75726365733e0d0a20200d0a20203c616374696f6e733e200d0a202020203c616374696f6e2d646566696e6974696f6e3e200d0a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a2020202020203c616374696f6e2d6f7574707574733e200d0a20202020202020203c72756c652d726573756c7420747970653d226c697374222f3e20200d0a20202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a20202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200d0a20202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420526567696f6e2c204465706172746d656e742066726f6d205155414452414e545f41435455414c5320776865726520526567696f6e3d275765737465726e275d5d3e3c2f71756572793e200d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a202020203c616374696f6e73206c6f6f702d6f6e3d2272756c652d726573756c74223e200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e636f6d706f6e656e742e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e200d0a202020202020202020203c6d6573736167652d68746d6c20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020202020202020203c746573743e666f726d61743c2f746573743e20200d0a202020202020202020203c70313e203c215b43444154415b0d0a0909202020203c68746d6c3e3c626f64793e3c7370616e207374796c653d22666f6e742d66616d696c793a7461686f6d612c617269656c3b636f6c6f723a233030303038303b666f6e742d7765696768743a626f6c64223e0d0a0909202020202048692c3c703e4865726520697320746865207265706f727420796f752072657175657374656420666f72207b307d20696e20746865207b317d20726567696f6e2e3c2f703e0d0a090920202020203c2f7370616e3e3c2f626f64793e3c2f68746d6c3e0d0a090920205d5d3e203c2f70313e20200d0a202020202020202020203c70323e4445504152544d454e543c2f70323e20200d0a202020202020202020203c70333e524547494f4e3c2f70333e20200d0a202020202020202020203c6e65776e616d653e6d6573736167652d68746d6c3c2f6e65776e616d653e200d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e47656e6572617465204d6573736167653c2f616374696f6e2d6e616d653e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c6d6573736167652d68746d6c20747970653d22737472696e67223e200d0a20202020202020203c64656661756c742d76616c75652f3e200d0a2020202020203c2f6d6573736167652d68746d6c3e20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574732f3e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020202020202020203c746573743e7072696e74323c2f746573743e20200d0a202020202020202020203c70313e524547494f4e3c2f70313e20200d0a202020202020202020203c70323e4445504152544d454e543c2f70323e200d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5072696e742069743c2f616374696f6e2d6e616d653e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e424952545265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e7265706f72743c2f616374696f6e2d747970653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e20200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d7265736f75726365733e0d0a202020202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e0d0a20202020202020203c2f616374696f6e2d7265736f75726365733e0d0a20202020202020203c616374696f6e2d6f7574707574733e200d0a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e456d61696c436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e656d61696c3c2f616374696f6e2d747970653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e20200d0a202020202020202020203c746f20747970653d22737472696e67222f3e20200d0a202020202020202020203c7375626a65637420747970653d22737472696e67222f3e20200d0a202020202020202020203c66726f6d20747970653d22737472696e67222f3e20200d0a202020202020202020203c6d6573736167652d68746d6c20747970653d22737472696e67222f3e20200d0a202020202020202020203c61747461636820747970653d22737472696e67222f3e20200d0a202020202020202020203c6174746163682d6e616d6520747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a200d0a202020203c2f616374696f6e733e0d0a200d0a20203c2f616374696f6e733e200d0a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3dca3d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','BurstingTest.xaction','/solution/test/platform/BurstingTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4275727374696e67546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e4275727374696e67205465737420313c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e4275727374696e672072756c6520746573743c2f6465736372697074696f6e3e20200a202020203c68656c703e546869732062616420626f7920746573747320746865206162696c69747920746f206c6f6f7020616e642062757273743c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7064663c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e20200a202020203c746f20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200a202020203c2f746f3e20200a202020203c66726f6d20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200a202020203c2f66726f6d3e20200a202020203c7375626a65637420747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e427572737420546573743c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e656d61696c2d7375626a6563743c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f7375626a6563743e20200a202020203c6d6573736167652d706c61696e20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e5468697320656d61696c20776173206175746f6d61746963616c6c792067656e65726174656420627920612077686f6c652068656170206f66206e6f6f646c652d636f646528746d292e204e6f7420737572652077687920697420776f726b73202d20627574206865792077686f206b6e6f77732077687920616e797468696e6720776f726b73202d2072696768743f3c2f64656661756c742d76616c75653e200a202020203c2f6d6573736167652d706c61696e3e20200a202020203c61747461636820747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7265706f72742d6f75747075743c2f64656661756c742d76616c75653e200a202020203c2f6174746163683e20200a202020203c6174746163682d6e616d6520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7265706f72742e7064663c2f64656661756c742d76616c75653e200a202020203c2f6174746163682d6e616d653e20200a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e2f7265706f7274696e672f7175616472616e742d6275646765742d666f722d726567696f6e2d616e642d646570742d6873716c2e72707464657369676e3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c72756c652d726573756c7420747970653d226c697374222f3e20200a20202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200a20202020202020203c524547494f4e20747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420526567696f6e2c204465706172746d656e742066726f6d205155414452414e545f41435455414c5320776865726520526567696f6e3d275765737465726e275d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e73206c6f6f702d6f6e3d2272756c652d726573756c74223e200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574732f3e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a202020202020202020203c746573743e7072696e74323c2f746573743e20200a202020202020202020203c70313e524547494f4e3c2f70313e20200a202020202020202020203c70323e4445504152544d454e543c2f70323e200a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202020203c616374696f6e2d6e616d653e5072696e742069743c2f616374696f6e2d6e616d653e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e424952545265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e7265706f72743c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e20200a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e20200a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e456d61696c436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e656d61696c3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e20200a202020202020202020203c746f20747970653d22737472696e67222f3e20200a202020202020202020203c7375626a65637420747970653d22737472696e67222f3e20200a202020202020202020203c66726f6d20747970653d22737472696e67222f3e20200a202020202020202020203c6d6573736167652d706c61696e20747970653d22737472696e67222f3e20200a202020202020202020203c61747461636820747970653d22737472696e67222f3e20200a202020202020202020203c6174746163682d6e616d6520747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a202020203c2f616374696f6e733e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3df14e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ComponentTest.xaction','/solution/test/platform/ComponentTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e436f6d706f6e656e74546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e46697273742074657374206f6620746865205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e0d0a202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6170706c65733c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c726571756573743e74686546727569743c2f726571756573743e200d0a0909093c2f736f75726365733e0d0a202020203c2f66727569743e0d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a202020203c686f772d6d616e7920747970653d226c6f6e67223e0d0a2020202020203c64656661756c742d76616c75653e31303c2f64656661756c742d76616c75653e0d0a202020203c2f686f772d6d616e793e0d0a20203c2f696e707574733e0d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d22737472696e67222f3e0d0a20203c2f6f7574707574733e0d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e46697273742074657374206f66207468652054657374436f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c667275697420747970653d22737472696e67222f3e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67222f3e0d0a202020202020202020203c686f772d6d616e7920747970653d226c6f6e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6f72616e67657320747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020202020093c746573743e736f6d657468696e673c2f746573743e0d0a202020202020202020203c73657474696e67313e54686973206973207468652066697273742073657474696e673c2f73657474696e67313e0d0a202020202020202020203c73657474696e67323e5468697320697320746865207365636f6e642073657474696e673c2f73657474696e67323e0d0a202020202020202020203c73657474696e67333e54686973206973207468652074686972642073657474696e673c2f73657474696e67333e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3e185f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest.xaction','/solution/test/platform/ContentOutputTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e203c2f64656661756c742d76616c75653e200a202020203c2f434f4e54454e544f55545055543e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c636f6e74656e7420747970653d22737472696e67223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f636f6e74656e743e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c434f4e54454e544f555450555420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c636f6e74656e7420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e20200a2020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3e3f70-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_Bytearray.xaction','/solution/test/platform/ContentOutputTest_Bytearray.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e434f4e54454e544f55545055543c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f434f4e54454e544f55545055543e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c636f6e74656e7420747970653d22737472696e67223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f636f6e74656e743e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c434f4e54454e544f555450555420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c636f6e74656e7420747970653d226f626a656374222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e20200a2020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3e3f71-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_error1.xaction','/solution/test/platform/ContentOutputTest_error1.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220313c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574732f3e0d0a0d0a20203c6f7574707574733e0d0a202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20203c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574732f3e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3e6682-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_error2.xaction','/solution/test/platform/ContentOutputTest_error2.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220323c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a20203c6f757470757473202f3e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e202f3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3e8d93-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentRepoOutputTest_file.xaction','/solution/test/platform/ContentRepoOutputTest_file.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a3c6f7574707574733e0d0a093c636f6e74656e7420747970653d22636f6e74656e74223e0d0a2020202009093c64657374696e6174696f6e733e0d0a202020200909093c66696c653e636f6e74656e747265706f3a746573742f436f6e74656e744f7574707574546573742e7478743c2f66696c653e0d0a2020202009093c2f64657374696e6174696f6e733e0d0a093c2f636f6e74656e743e200d0a3c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c636f6e74656e7420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3eb4a4-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','HelloWorld.xaction','/solution/test/platform/HelloWorld.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e48656c6c6f576f726c642e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e48656c6c6f20576f726c6420416374696f6e2053657175656e63653c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e546865206d6f737420626173696320416374696f6e2053657175656e636520446f63756d656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e48656c6c6f20576f726c642064656d6f6e7374726174657320746865206d6f737420626173696320416374696f6e2053657175656e636520646f63756d656e742e202049742075736573207468652048656c6c6f20576f726c6420436f6d706f6e656e742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574732f3e0d0a0d0a20203c6f7574707574732f3e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e48656c6c6f20576f726c6420416374696f6e3c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574732f3e0d0a20202020202020203c616374696f6e2d6f7574707574732f3e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e48656c6c6f576f726c64436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c71756f74653e283242207c7c2021324229205468617420697320746865207175657374696f6e3c2f71756f74653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3eb4a5-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','index.xml','/solution/test/platform/index.xml','3c696e6465783e0d0a093c6e616d653e424920506c6174666f726d2054657374733c2f6e616d653e0d0a093c6465736372697074696f6e3e416374696f6e7320616e64207265736f7572636573207573656420746f207465737420626173696320706c6174666f726d2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e0d0a093c69636f6e3e706c6174666f726d2e706e673c2f69636f6e3e0d0a093c76697369626c653e747275653c2f76697369626c653e0d0a3c2f696e6465783e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3edbb6-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','jdbc.properties','/solution/test/platform/jdbc.properties','2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a756e69745465737444532f747970653d6a617661782e73716c2e44617461536f757263650d0a756e69745465737444532f6472697665723d6e756c6c0d0a756e69745465737444532f75726c3d6e756c6c0d0a756e69745465737444532f757365723d6e756c6c0d0a756e69745465737444532f70617373776f72643d6e756c6c0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3edbb7-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','LoopingTest.xaction','/solution/test/platform/LoopingTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4c6f6f70696e67546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63652077697468206d756c7469706c65206c6f6f70733c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c612d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226170706c65223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226f72616e6765223e53776565743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2267726170656672756974223e536f75723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f6d656772616e617465223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22636172726f74223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22637563756d626572223e4c6f6e673c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f7461746f223e44696d706c793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2262726f63636f6c69223e466c6f776572793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227a75636368696e69223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22626967206d6163223e536c6f7070793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2277686f70706572223e4c616d653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227461636f223e4772656173793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c72756e74696d653e72756e74696d652d613c2f72756e74696d653e200d0a0909093c2f736f75726365733e0d0a202020203c2f612d6d61703e0d0a202020200d0a202020203c622d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e7370686572653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e64696d706c793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e677261706566727569743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e59656c6c6f773c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e7370686572653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e64696d706c793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e636172726f743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e636f6e653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e62756d70793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e637563756d6265723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e677265656e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e656c6c6970736f69643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e736d6f6f74683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e7a75636368696e693c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e677265656e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e656c6c6970736f69643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e73656d692d736d6f6f74683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e7461636f3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e62726f776e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e736164646c653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e726f7567683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c72756e74696d653e72756e74696d652d613c2f72756e74696d653e200d0a0909093c2f736f75726365733e0d0a202020203c2f622d6d61703e0d0a202020200d0a202020203c632d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e6e616d653c2f64656661756c742d76616c75653e202020200d0a202020203c2f632d737472696e673e0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c616374696f6e73206c6f6f702d6f6e3d22612d6d6170223e0d0a202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e416374696f6e20313c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c612d6d617020747970653d2270726f70657274792d6d6170222f3e0d0a20202020202020203c622d6d617020747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20202020202020203c632d737472696e6720747970653d22737472696e67222f3e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020203c616374696f6e312d6f757420747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c746573743e6d657267653c2f746573743e0d0a20202020202020203c70313e612d6d61703c2f70313e0d0a20202020202020203c70323e622d6d61703c2f70323e0d0a20202020202020203c70333e632d737472696e673c2f70333e0d0a20202020202020203c6e65776e616d653e616374696f6e312d6f75743c2f6e65776e616d653e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020203c616374696f6e73206c6f6f702d6f6e3d22616374696f6e312d6f7574223e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e416374696f6e20323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c616374696f6e312d6f757420747970653d2270726f70657274792d6d6170222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c616374696f6e322d6f757420747970653d22737472696e672d6c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e6765746b6579733c2f746573743e0d0a202020202020202020203c70313e616374696f6e312d6f75743c2f70313e0d0a202020202020202020203c6e65776e616d653e616374696f6e322d6f75743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e416374696f6e20333c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c616374696f6e322d6f757420747970653d22737472696e672d6c697374222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c7a2d6f757420747970653d22737472696e672d6c6973742220617070656e643d2274727565222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e72656e616d653c2f746573743e0d0a202020202020202020203c70313e616374696f6e322d6f75743c2f70313e0d0a202020202020202020203c6e65776e616d653e7a2d6f75743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a2020202020200d0a2020202020203c616374696f6e73206c6f6f702d6f6e3d227a2d6f7574223e0d0a2020202020202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020202020202020203c616374696f6e2d6e616d653e416374696f6e20343c2f616374696f6e2d6e616d653e0d0a2020202020202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d696e707574733e0d0a20202020202020202020202020203c7a2d6f757420747970653d22737472696e67222f3e0d0a2020202020202020202020203c2f616374696f6e2d696e707574733e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020202020202020203c6d736720747970653d22737472696e67222f3e0d0a2020202020202020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020200d0a2020202020202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020202020202020203c746573743e666f726d61743c2f746573743e0d0a20202020202020202020202020203c70313e54686973206973206120666f726d6174746564206d657373616765202d7b307d3c2f70313e0d0a20202020202020202020202020203c70323e7a2d6f75743c2f70323e0d0a20202020202020202020202020203c70333e7a2d6f75743c2f70333e0d0a20202020202020202020202020203c6e65776e616d653e6d73673c2f6e65776e616d653e0d0a2020202020202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a202020202020202020200d0a2020202020202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020202020202020203c616374696f6e2d6e616d653e416374696f6e20353c2f616374696f6e2d6e616d653e0d0a2020202020202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d696e707574733e0d0a20202020202020202020202020203c6d736720747970653d22737472696e672d6c697374222f3e0d0a2020202020202020202020203c2f616374696f6e2d696e707574733e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d6f7574707574733e0d0a2020202020202020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020200d0a2020202020202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020202020202020203c746573743e7072696e743c2f746573743e0d0a20202020202020202020202020203c70313e6d73673c2f70313e0d0a2020202020202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c2f616374696f6e2d646566696e6974696f6e3e2020202020200d0a202020202020202020200d0a2020202020203c2f616374696f6e733e0d0a2020203c2f616374696f6e733e200d0a0d0a2020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e416374696f6e20363c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c7a2d6f757420747970653d22737472696e672d6c697374222f3e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c746573743e7072696e743c2f746573743e0d0a20202020202020203c70313e7a2d6f75743c2f70313e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f29d8-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','message1.txt','/solution/test/platform/message1.txt','7468697320697320746865206d6573736167652074656d706c6174652c20796f7520666573746572696e6720626c6f62206f66207b307d',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f29d9-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','MultiComponentTest.xaction','/solution/test/platform/MultiComponentTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6170706c65733c2f64656661756c742d76616c75653e0d0a202020203c2f66727569743e0d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a20203c2f696e707574733e0d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d22737472696e67222f3e0d0a20203c2f6f7574707574733e0d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420313c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e46697273742074657374206f662074686520616374696f6e20636861696e3c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c667275697420747970653d22737472696e67223e0d0a2020202020202020202020203c64656661756c742d76616c75653e746f6d61746f3c2f64656661756c742d76616c75653e0d0a202020202020202020203c2f66727569743e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020202020202020203c64656661756c742d76616c75653e6368657272793c2f64656661756c742d76616c75653e0d0a202020202020202020203c2f6d6f72652d66727569743e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e65772d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e636f6e6361743c2f746573743e0d0a202020202020202020203c70313e66727569743c2f70313e0d0a202020202020202020203c70323e6d6f72652d66727569743c2f70323e0d0a202020202020202020203c6e65776e616d653e6e65772d66727569743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e5365636f6e642074657374206f662074686520616374696f6e20636861696e3c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6e65772d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e657765722d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e746f75707065723c2f746573743e0d0a202020202020202020203c70313e6e65772d66727569743c2f70313e0d0a202020202020202020203c6e65776e616d653e6e657765722d66727569743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f50ea-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','MultiComponentTestLoop.xaction','/solution/test/platform/MultiComponentTestLoop.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e636520616e642061206c6f6f703c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c66727569742d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226b657931223e56616c7565312d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657932223e56616c7565322d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657933223e56616c7565332d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657934223e56616c7565342d413c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226b657931223e56616c7565312d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657932223e56616c7565322d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657933223e56616c7565332d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657934223e56616c7565342d423c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f66727569742d6d61703e0d0a202020200d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a0d0a202020203c6d65737361676520747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a0d0a20203c616374696f6e73206c6f6f702d6f6e3d2266727569742d6d6170223e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420313c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c66727569742d6d617020747970653d2270726f70657274792d6d6170222f3e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e65772d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e636f6e6361743c2f746573743e0d0a202020202020202020203c70313e66727569742d6d61703c2f70313e0d0a202020202020202020203c70323e6d6f72652d66727569743c2f70323e0d0a202020202020202020203c6e65776e616d653e6e65772d66727569742d6d61703c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6e65772d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e657765722d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e746f75707065723c2f746573743e0d0a202020202020202020203c70313e6e65772d66727569742d6d61703c2f70313e0d0a202020202020202020203c6e65776e616d653e6e657765722d66727569742d6d61703c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f50eb-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','platform.png','/solution/test/platform/platform.png','89504e470d0a1a0a0000000d4948445200000050000000500803000000b9cf029f0000002c744558744372656174696f6e2054696d6500467269203239204a756c20323030352031383a32363a3239202d303530305b26eedf0000000774494d4507d5080215202a408c2899000000097048597300000af000000af00142ac34980000000467414d410000b18f0bfc610500000300504c5445fffffffffbf0ccff99ccff66ccff33ccffcce7e7d6ffffcc999999555555292929040404777777c0c0c0222222dddddd333333393939d7d7d71c1c1c0c0c0c5f5f5f3399cc3399ff6699991111118080804d4d4d3366666666996699ff99ccffccecff66ccff6699cccccccca6caf0b2b2b2f1f1f1161616666666e3e3e3eaeaea424242a0a0a496969686868699ccccccccfff8f8f8cbcbcb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f09ae8320000051f4944415478dabd986973da4810868791b41c43382cb0ca267114230411b661f7ffffb8edee91e66c2136456d7f8853127ad46f5fd320c41f9a94d99f3eca5a0a968c1fc79329d9e380c9a3810ff79062983e3086e4e263d3ecd8683c7e7cbea188fe8b0b99944992c82c76649c1abbaf2cb3d4b5c80befee70509334c62dcf0a6cfdc4f086d22e035e3a828b53d5da370c45084c46fd6193dc8727883a9e67f06f18c1fecc348d9b3b6b701538d3aa2c2bf85bb341617be778643f09effe506a53022f576ad709093ff757c4435127c649ba453ceb1f134619e05e95ca4f98c5a864301f2be09596b73f9ea2440741fc8290c333477828f7854b148cbc835a773c4a4d7213b851ea82aad0c9336631b1c0b9065ef4ab30d80494372503e85a92b54e9a108dc54c0341f251eb5504f45b292a6d1d7732e8884f1b2221162aa7eb109695d65b223028c530c7abd60dedcace024700d4b7ae80faaac1bf6d35081ca3e8bc155de66e88326c3a7dfdbaa5dedb961f91e4a0f592d4137da1fa302fde99f86269e73ace419603bd942347f45a1dda07e07a0d4e35261c958ec9ccafc3a06664d70fb3ee29b5d953905a5e2d4ad7768e02b64bda7740160f262d0a8899d67b0e78509753b70ca3e93aeede02a25755f70cd51ce71f54d5ac71721c0dae915d06f4047d15a2fc546ab1f478557e82977d82c71840d19f10932d7cd3efc906670e1051f5d2d15b75035b2d0e3e8f8da07d538d2ecc01823e3a7af38e97d7e1384ab808baef3a19d58e5ef29b7924d6cc4ca19648aa8dde30e4bd9ad9db042062657931c9f6fb2d60db6de823544f7e29ab95d6dbcbf32a314b5922c5ec6ff2f132e49f9f9684e59d28a12d7190e7a5850f311e04dac739ceab9b7a7de098bb07fead1a6cc4d7d6c72586468a7e47fd4163222161771b116f8139be5ad5cb9b31e28176c92340adc700fa78d27d0de3e883d5e4d58d1df49de9c74d3d1bd535ad5f7bf784b5360e0464c26456d1e072e781c9b55acff4548b89590084ffec77669cfc437aa99e573bed239d4e7951b43e0e01e1ef99d6bff97caa164fd6bf866eb4c497a230c4a457b2a413b0066776dd44f6787ac6629ede0bb2ef5af52da0a47577ee8d79ad577f0402b76efdb33e061d6bb39ca1e0dfd01465d92ed155b72434f43a81ab08c5cf212e43a273a060636ff0449eaacf064c9fa586d79e34cf8563dfa9f0050f1458cfb01c01e2a02fbc40342b7242eac6ce031e477481230456a519c94f6a5d123e6beb01b2500416a9768f14449c4b0b6c34f0553711f9ff1c02431f8363ea80290981270d9414c28223ae2c315836f758833d1e26b44ffc88893a6d19e36018c3651743d3951b96e8f898c5c01d8e2ad136c60596df452707abe030a05a848675783dab6f5887b97a29af399e794ec03737544b06a83be56c3a45792b7432a45a46406c57a79737d4adced1a0556f58e24970b684a5f9dc8d85ad3e37ddc346fbf8ceaa16bce172359b1fbef0d4545fe106d34b7c3ee2321b19d6e564d10dec4d137fd5ec53fd56e8539b238af60cf8c4b1ca7d6976a6acb1aad0fb6c68d26f1ee65b7d0fb12e567c1447f6bb50c6e15ad5136772a3fdea058a1e4a78700444f1b3d06387b13b80b16a8149e12b91db7463e2c8f3b11655b1ed8e329ddceeeb1cd91dc4b423be5525ac17bf8adc8f6062a508e6d7a27ed53f8ab7b2fc5914ef7ea71897ba79764766ba5f99b6d025d3179fe73cee54cf3daa97660d7a129c83ce40bbc747a74f276208780f32e9fbb130f35eca5def31d9038c93721ff1c66f8fac83b7850ffc368aed91f4de0b2b5d8ec4ff6aff025ffdb9d338b8f8370000000049454e44ae426082',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f77fc-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SetGlobalOutputTest.xaction','/solution/test/platform/SetGlobalOutputTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e53657420476c6f62616c205661726961626c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d6172633c2f617574686f723e20200a202020203c6465736372697074696f6e3e53657473206120676c6f62616c207661726961626c652066726f6d20616e20616374696f6e2073657175656e63653c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970652f3e0a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c474c4f42414c5f5445535420747970653d22737472696e67223e200a2020202020203c64657374696e6174696f6e733e200a20202020202020203c676c6f62616c3e474c4f42414c5f544553543c2f676c6f62616c3e200a2020202020203c2f64657374696e6174696f6e733e200a202020203c2f474c4f42414c5f544553543e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a2020202020203c616374696f6e2d646566696e6974696f6e3e0a202020202020093c616374696f6e2d696e70757473202f3e0a20202020202020203c616374696f6e2d6f7574707574733e0a20202020202020202020093c474c4f42414c5f5445535420747970653d22737472696e67222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020200a20202020202020203c636f6d706f6e656e742d6e616d653e4a61766173637269707452756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202009093c7363726970743e3c215b43444154415b200a202020202020090920202020474c4f42414c5f54455354203d20225468697320697320612074657374223b0a09092020202020205d5d3e0a09092020202020203c2f7363726970743e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a202020202020093c616374696f6e2d696e707574733e0a20202020202020202020093c474c4f42414c5f5445535420747970653d22737472696e67222f3e0a202020202020093c2f616374696f6e2d696e707574733e0a202020202020093c616374696f6e2d6f7574707574733e0a2020202020200920203c6a756e6b20747970653d22737472696e6722202f3e0a202020202020093c2f616374696f6e2d6f7574707574733e0a20202020202020200a20202020202020203c636f6d706f6e656e742d6e616d653e4a61766173637269707452756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202009093c7363726970743e3c215b43444154415b200a2020202020200909202020206f75742e7072696e746c6e2822476c6f62616c205661726961626c6520474c4f42414c5f544553543d22202b20474c4f42414c5f54455354293b0a2020202020200909202020206a756e6b203d20474c4f42414c5f544553543b0a09092020202020205d5d3e0a09092020202020203c2f7363726970743e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f9f0d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','subaction_shareresultset.xaction','/solution/test/platform/subaction_shareresultset.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e537562616374696f6e2063616c6c20746f207368617265206120726573756c74207365743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f722f3e20200a202020203c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c636f6e6e2f3e0a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e200a20200a202020203c616374696f6e733e200a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e476574204d445820436f6e6e656374696f6e3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574732f3e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c636174616c6f6720747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e7420747970653d2273716c2d636f6e6e656374696f6e22206d617070696e673d22636f6e6e222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e222f3e20202020202020200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6c6976653e747275653c2f6c6976653e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a202020203c2f616374696f6e733e0a0a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3f9f0e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','subaction_useconn.xaction','/solution/test/platform/subaction_useconn.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e537562616374696f6e2063616c6c20746f207465737420612073686172656420636f6e6e656374696f6e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f722f3e20200a202020203c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e0a20202020203c636f6e6e3e0a20202020202020203c736f75726365733e0a20202020202020202020203c726571756573743e636f6e6e3c2f726571756573743e0a20202020202020203c2f736f75726365733e0a20202020203c2f636f6e6e3e0a20203c2f696e707574733e0a0a20203c6f7574707574732f3e200a0a20203c7265736f75726365732f3e200a20200a202020203c616374696f6e733e200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c212d2d2070617373656420696e2066726f6d20706172656e74202d2d3e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e222f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a202020203c2f616374696f6e733e0a0a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3fc61f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest1.xaction','/solution/test/platform/SubActionConnectionTest1.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e642072657573657320697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e697072657061726564636f6d706f6e656e74733c2f706174683e0a20202020202020203c616374696f6e3e697072657061726564636f6d706f6e656e745f73716c5f617661696c61626c652e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e742f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b3fc620-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest2.xaction','/solution/test/platform/SubActionConnectionTest2.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574732f3e200a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e697072657061726564636f6d706f6e656e74733c2f706174683e0a20202020202020203c616374696f6e3e697072657061726564636f6d706f6e656e745f73716c5f617661696c61626c652e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e742f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b401441-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest3.xaction','/solution/test/platform/SubActionConnectionTest3.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574733e0a2020202020202020203c636f6e6e2f3e0a2020202020202020203c71756572792d726573756c74732f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e706c6174666f726d3c2f706174683e0a20202020202020203c616374696f6e3e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b403b52-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest4.xaction','/solution/test/platform/SubActionConnectionTest4.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a0a20203c616374696f6e733e200a0a202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e4765742053514c20436f6e6e656374696f6e3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574732f3e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c636174616c6f6720747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e2220747970653d2273716c2d636f6e6e656374696f6e222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a0a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e0a202020202020202020203c636f6e6e2f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574732f3e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e706c6174666f726d3c2f706174683e0a20202020202020203c616374696f6e3e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e2220747970653d2273716c2d636f6e6e656374696f6e222f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a090920203c6c6976653e747275653c2f6c6976653e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b403b53-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionTest.xaction','/solution/test/platform/SubActionTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f6620537562416374696f6e20636f6d706f6e656e742e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c736f6c7574696f6e20747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e736f6c7574696f6e3c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f736f6c7574696f6e3e20200a202020203c7061746820747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e706174683c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f706174683e20200a202020203c737562616374696f6e20747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e737562616374696f6e3c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f737562616374696f6e3e20200a202020203c696e707574537472696e6720747970653d22737472696e67223e0a2020202020203c736f75726365733e0a20202020202020203c726571756573743e696e707574537472696e673c2f726571756573743e0a2020202020203c2f736f75726365733e0a202020203c2f696e707574537472696e673e0a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c736f6c7574696f6e20747970653d22737472696e67222f3e20200a20202020202020203c7061746820747970653d22737472696e67222f3e20200a20202020202020203c616374696f6e20747970653d22737472696e6722206d617070696e673d22737562616374696f6e222f3e20200a20202020202020203c696e707574537472696e6720747970653d22737472696e67222f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b406264-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionTestTarget.xaction','/solution/test/platform/SubActionTestTarget.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e2054657374205461726765742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e58414354494f4e206265696e672063616c6c656420627920537562416374696f6e546573742e78616374696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c696e707574537472696e6720747970653d22737472696e67223e0a2020202020203c736f75726365733e0a20202020202020203c726571756573743e696e707574537472696e673c2f726571756573743e0a2020202020203c2f736f75726365733e0a202020203c2f696e707574537472696e673e0a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e0a2020202020203c636f6d706f6e656e742d6e616d653e5574696c697479436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e436f707920506172616d657465723c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e0a20202020202020203c636f70792d66726f6d20747970653d22737472696e6722206d617070696e673d22696e707574537472696e67222f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c636f70792d746f20747970653d22737472696e6722206d617070696e673d226f7574707574537472696e67222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202020203c636f70793e0a202020202020202020203c66726f6d3e636f70792d66726f6d3c2f66726f6d3e0a202020202020202020203c72657475726e3e636f70792d746f3c2f72657475726e3e0a20202020202020203c2f636f70793e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b406265-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','UtilityTest.xaction','/solution/test/platform/UtilityTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e5574696c697479546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e5574696c69747920546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865207574696c69747920636f6d706f6e656e742066756e6374696f6e616c6974793c2f6465736372697074696f6e3e0d0a202020203c68656c703e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c612d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226170706c65223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226f72616e6765223e53776565743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2267726170656672756974223e536f75723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f6d656772616e617465223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22636172726f74223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22637563756d626572223e4c6f6e673c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f7461746f223e44696d706c793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2262726f63636f6c69223e466c6f776572793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227a75636368696e69223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22626967206d6163223e536c6f7070793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2277686f70706572223e4c616d653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227461636f223e4772656173793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f612d6d61703e0d0a202020200d0a202020203c612d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4120537472696e673c2f64656661756c742d76616c75653e202020200d0a202020203c2f612d737472696e673e0d0a0d0a202020203c622d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4220537472696e673c2f64656661756c742d76616c75653e202020200d0a202020203c2f622d737472696e673e0d0a0d0a202020203c632d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e5468697320697320746865204d657373616765202d20506172616d207b307d20506172616d207b317d3c2f64656661756c742d76616c75653e202020200d0a202020203c2f632d737472696e673e0d0a0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c69737422202f3e0d0a0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c69737422202f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c616374696f6e733e0d0a202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e666f726d61743c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e5574696c697479436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c612d737472696e6720747970653d22737472696e67222f3e0d0a20202020202020203c622d737472696e6720747970653d22737472696e67222f3e0d0a20202020202020203c632d737472696e6720747970653d22737472696e67222f3e0d0a0d0a20202020202020203c642d737472696e6720747970653d22737472696e67223e0d0a202020202020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4420537472696e673c2f64656661756c742d76616c75653e202020200d0a20202020202020203c2f642d737472696e673e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020203c616374696f6e312d6f757420747970653d22737472696e67222f3e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c666f726d61743e0d0a202020202020202020203c666f726d61742d737472696e673e225468697320697320746865204d657373616765202d20506172616d207b307d20506172616d207b317d223c2f666f726d61742d737472696e673e0d0a202020202020202020203c6172673e612d737472696e673c2f6172673e0d0a202020202020202020203c6172673e622d737472696e673c2f6172673e0d0a202020202020202020203c72657475726e3e746d702d6f75743c2f72657475726e3e0d0a20202020202020203c2f666f726d61743e0d0a20202020202020203c636f70793e0d0a202020202020202020203c66726f6d3e746d702d6f75743c2f66726f6d3e0d0a202020202020202020203c72657475726e3e616374696f6e312d6f75743c2f72657475726e3e0d0a20202020202020203c2f636f70793e0d0a20202020202020203c7072696e743e0d0a202020202020202020203c64656c696d697465723e22202d20223c2f64656c696d697465723e0d0a202020202020202020203c6172673e746d702d6f75743c2f6172673e0d0a202020202020202020203c6172673e2220436f6e7374616e7420223c2f6172673e0d0a202020202020202020203c6172673e642d737472696e673c2f6172673e0d0a20202020202020203c2f7072696e743e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b408976-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','VFSOutputTest_file.xaction','/solution/test/platform/VFSOutputTest_file.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a20203c6f7574707574733e0d0a202020203c636f6e74656e7420747970653d22636f6e74656e74223e0d0a2020202009093c64657374696e6174696f6e733e0d0a202020200909093c66696c653e7666732d66696c653a2f2f633a2f5646534f7574707574546573742e7465737446696c654f75747075742e7478743c2f66696c653e0d0a202020200909093c212d2d3c66696c653e7666732d6674703a2f2f6a6469786f6e3a6d7970617373776f72644070726f736f757263652e70656e7461686f2e6f72672f72656c656173652f5646534f7574707574546573742e7465737446696c654f75747075742e7478743c2f66696c653e2d2d3e0d0a2020202009093c2f64657374696e6174696f6e733e0d0a202020203c2f636f6e74656e743e200d0a093c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c636f6e74656e7420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b408977-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','EditSubscription.txt','/solution/test/tmp/EditSubscription.txt','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b408978-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','GetArchived.html','/solution/test/tmp/GetArchived.html','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b40b089-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','RuntimeRepositoryTest.testRuntimeRepository.txt','/solution/test/tmp/RuntimeRepositoryTest.testRuntimeRepository.txt','214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a',FALSE,1218426075000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b40b08a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','SaveSubscription.html','/solution/test/tmp/SaveSubscription.html','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_FILES VALUES('6b44f64b-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','SolutionRepositoryTest.testSolutionRepository.txt','/solution/test/tmp/SolutionRepositoryTest.testSolutionRepository.txt','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c7265706f7369746f72793e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2273616d706c6573223e3c7469746c653e73616d706c65733c2f7469746c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d227265706f7274696e67223e3c706174683e7265706f7274696e673c2f706174683e3c7469746c653e7265706f7274696e673c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d227265706f7274223e3c66696c656e616d653e4a467265655f517561642e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e257469746c653c2f7469746c653e3c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f7265706f72742e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e4f4c41502043726f7373746162205265706f72743c2f7469746c653e3c6465736372697074696f6e3e412063726f737320746162207265706f727420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520706167653c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4d44585f7265706f72742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f7265706f72745f584c532e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e4f4c41502043726f73737461622053707265616473686565743c2f7469746c653e3c6465736372697074696f6e3e4120737072656164736865657420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520584c532066696c652e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4d44585f7265706f72742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2274657374223e3c7469746c653e746573743c2f7469746c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2264617368626f617264223e3c706174683e64617368626f6172643c2f706174683e3c7469746c653e64617368626f6172643c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e6465706172746d656e74732e72756c652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617368626f6172643c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e526567696f6e73206c6973743c2f7469746c653e3c6465736372697074696f6e3e3c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d747275653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2264617461736f7572636573223e3c706174683e64617461736f75726365733c2f706174683e3c7469746c653e64617461736f75726365733c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f44617461736f757263652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e416e204d44582044617461736f757263653c2f7469746c653e3c6465736372697074696f6e3e45786572636973657320746865204d445820436f6e6e656374696f6e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e71756572795f72756c652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e43757272656e7420506f736974696f6e205469746c65733c2f7469746c653e3c6465736372697074696f6e3e4a6176617363726970742071756572792072756c6520746573743c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e58515f44617461736f757263652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e585175657279205175657279206f6620616e20584d4c2044617461736f757263653c2f7469746c653e3c6465736372697074696f6e3e546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e266c743b702667743b546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e584d4c5f44617461736f757263652e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c44455222206e616d653d22706c6174666f726d2220706174683d22706c6174666f726d222076697369626c653d22747275652220646973706c6179747970653d2269636f6e73223e3c706174683e706c6174666f726d3c2f706174683e3c7469746c653e424920506c6174666f726d2054657374733c2f7469746c653e3c6465736372697074696f6e3e416374696f6e7320616e64207265736f7572636573207573656420746f207465737420626173696320706c6174666f726d2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f706c6174666f726d2e706e673c2f69636f6e3e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d227265706f7274223e3c66696c656e616d653e4275727374696e6748544d4c546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e4275727374696e67205465737420313c2f7469746c653e3c6465736372697074696f6e3e4275727374696e672072756c6520746573742073656e64696e672048544d4c204174746163686d656e743c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f62757273742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4275727374696e67546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e4275727374696e67205465737420313c2f7469746c653e3c6465736372697074696f6e3e4275727374696e672072756c6520746573743c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6d706f6e656e74546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e46697273742074657374206f6620746865205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220313c2f7469746c653e3c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220323c2f7469746c653e3c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e48656c6c6f576f726c642e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e48656c6c6f20576f726c6420416374696f6e2053657175656e63653c2f7469746c653e3c6465736372697074696f6e3e546865206d6f737420626173696320416374696f6e2053657175656e636520446f63756d656e743c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4c6f6f70696e67546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63652077697468206d756c7469706c65206c6f6f70733c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e636520616e642061206c6f6f703c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d22223e3c66696c656e616d653e536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e53657420476c6f62616c205661726961626c653c2f7469746c653e3c6465736372697074696f6e3e53657473206120676c6f62616c207661726961626c652066726f6d20616e20616374696f6e2073657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4d6172633c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2063616c6c20746f207368617265206120726573756c74207365743c2f7469746c653e3c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2063616c6c20746f207465737420612073686172656420636f6e6e656374696f6e3c2f7469746c653e3c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e642072657573657320697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f6620537562416374696f6e20636f6d706f6e656e742e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e546573745461726765742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2054657374205461726765742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e58414354494f4e206265696e672063616c6c656420627920537562416374696f6e546573742e78616374696f6e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e5574696c697479546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e5574696c69747920546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865207574696c69747920636f6d706f6e656e742066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e5646534f7574707574546573745f66696c652e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d22746d70223e3c706174683e746d703c2f706174683e3c7469746c653e746d703c2f7469746c653e3c2f66696c653e3c2f66696c653e3c2f7265706f7369746f72793e0a3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c7265706f736974696f7279206c6f636174696f6e3d222f55736572732f6a616d65736469786f6e2f446f63756d656e74732f776f726b73706163652d76322f62692d706c6174666f726d2d7265706f7369746f72792f746573742d7372632f736f6c7574696f6e223e3c656e74727920747970653d226469726563746f727922206e616d653d22736f6c7574696f6e223e3c656e74727920747970653d226469726563746f727922206e616d653d2273616d706c6573223e3c656e74727920747970653d226469726563746f727922206e616d653d227265706f7274696e67223e3c656e74727920747970653d2266696c6522206e616d653d224a467265652d7175616472616e742d6275646765742d6873716c2e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224a467265655f517561642e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224a4672656551756164466f72526567696f6e2e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c532e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c532e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f7a685f434e2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f7a685f434e2e70726f70657274696573222f3e3c2f656e7472793e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d2274657374223e3c656e74727920747970653d226469726563746f727922206e616d653d2264617368626f617264223e3c656e74727920747970653d2266696c6522206e616d653d226465706172746d656e74732e72756c652e78616374696f6e222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d2264617461736f7572636573223e3c656e74727920747970653d2266696c6522206e616d653d22626f6f6b732e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f44617461736f757263652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2271756572795f72756c652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2253616d706c65446174612e6d6f6e647269616e2e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d2253616d706c6544617461536368656d612e7a6970222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f636e2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f69742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f70742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f7a685f434e2e70726f70657274696573222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d22706c6174666f726d223e3c656e74727920747970653d2266696c6522206e616d653d2262757273742e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224275727374696e6748544d4c546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224275727374696e67546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6d706f6e656e74546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2248656c6c6f576f726c642e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22696e6465782e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d226a6462632e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224c6f6f70696e67546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d226d657373616765312e747874222f3e3c656e74727920747970653d2266696c6522206e616d653d224d756c7469436f6d706f6e656e74546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22706c6174666f726d2e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d22536574476c6f62616c4f7574707574546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22737562616374696f6e5f7368617265726573756c747365742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22737562616374696f6e5f757365636f6e6e2e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e546573745461726765742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d225574696c697479546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d225646534f7574707574546573745f66696c652e78616374696f6e222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d22746d70223e3c656e74727920747970653d2266696c6522206e616d653d2245646974537562736372697074696f6e2e747874222f3e3c656e74727920747970653d2266696c6522206e616d653d2247657441726368697665642e68746d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d2253617665537562736372697074696f6e2e68746d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d22536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e747874222f3e3c2f656e7472793e3c2f656e7472793e3c2f656e7472793e3c2f7265706f736974696f72793e0a3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c747265653e3c6272616e63682069643d222f736f6c7574696f6e222069734469723d2274727565223e3c6272616e6368546578743e2f3c2f6272616e6368546578743e3c6272616e63682069643d222f736f6c7574696f6e2f73616d706c6573222069734469723d2274727565223e3c6272616e6368546578743e73616d706c65733c2f6272616e6368546578743e3c6272616e63682069643d222f736f6c7574696f6e2f73616d706c65732f7265706f7274696e67222069734469723d2274727565223e3c6272616e6368546578743e7265706f7274696e673c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a467265655f517561642e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a467265655f517561642e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a4672656551756164466f72526567696f6e2e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a4672656551756164466f72526567696f6e2e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c532e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c532e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c532e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c532e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f74657374222069734469723d2274727565223e3c6272616e6368546578743e746573743c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e2e44535f53746f72653c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f2e44535f53746f72653c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f64617368626f617264222069734469723d2274727565223e3c6272616e6368546578743e64617368626f6172643c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e2e44535f53746f72653c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617368626f6172642f2e44535f53746f72653c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6465706172746d656e74732e72756c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617368626f6172642f6465706172746d656e74732e72756c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f64617461736f7572636573222069734469723d2274727565223e3c6272616e6368546578743e64617461736f75726365733c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e626f6f6b732e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f626f6f6b732e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f44617461736f757263652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f4d44585f44617461736f757263652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e71756572795f72756c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f71756572795f72756c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53616d706c6544617461536368656d612e7a69703c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f53616d706c6544617461536368656d612e7a69703c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f636e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f636e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f69742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f69742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f70742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f70742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f706c6174666f726d222069734469723d2274727565223e3c6272616e6368546578743e706c6174666f726d3c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e62757273742e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f62757273742e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4275727374696e6748544d4c546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4275727374696e6748544d4c546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4275727374696e67546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4275727374696e67546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6d706f6e656e74546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6d706f6e656e74546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e48656c6c6f576f726c642e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f48656c6c6f576f726c642e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e696e6465782e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f696e6465782e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6a6462632e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f6a6462632e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4c6f6f70696e67546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4c6f6f70696e67546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6d657373616765312e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f6d657373616765312e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e706c6174666f726d2e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f706c6174666f726d2e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e546573745461726765742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e546573745461726765742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e5574696c697479546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f5574696c697479546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e5646534f7574707574546573745f66696c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f5646534f7574707574546573745f66696c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f746d70222069734469723d2274727565223e3c6272616e6368546578743e746d703c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e45646974537562736372697074696f6e2e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f45646974537562736372697074696f6e2e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e47657441726368697665642e68746d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f47657441726368697665642e68746d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53617665537562736372697074696f6e2e68746d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f53617665537562736372697074696f6e2e68746d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c2f6272616e63683e3c2f6272616e63683e3c2f747265653e0a',FALSE,1218381033000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') -INSERT INTO PRO_SUBCONTENT VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0',5,'report','test/dashboard/departments.rule.xaction') -INSERT INTO PRO_SUBCONTPARMS VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0','aced0005740027746573742f64617368626f6172642f6465706172746d656e74732e72756c652e78616374696f6e','actionRef') -INSERT INTO PRO_SUBCONTPARMS VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0','aced000574002431336439393932312d363665652d313164642d386530302d396465393161633037336234','subscribe-name') -INSERT INTO PRO_SUBSCRIBE VALUES('13d99921-66ee-11dd-8e00-9de91ac073b4',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') -INSERT INTO PRO_SUBSCRIBE VALUES('8e0ad5f5-66ed-11dd-a681-61af1abf7cd0',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') -INSERT INTO PRO_SUBSCRIBE VALUES('c8db2456-66ed-11dd-bd52-5361aa4c2010',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +CREATE MEMORY TABLE USERS(USERNAME VARCHAR(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR(50) NOT NULL,ENABLED BOOLEAN NOT NULL,DESCRIPTION VARCHAR(100)) +CREATE MEMORY TABLE AUTHORITIES(AUTHORITY VARCHAR(50) NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR(100)) +CREATE MEMORY TABLE GRANTED_AUTHORITIES(USERNAME VARCHAR(50) NOT NULL,AUTHORITY VARCHAR(50) NOT NULL,CONSTRAINT FK_GRANTED_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME),CONSTRAINT FK_GRANTED_AUTHORITIES_AUTHORITIES FOREIGN KEY(AUTHORITY) REFERENCES AUTHORITIES(AUTHORITY)) +CREATE MEMORY TABLE DATASOURCE(NAME VARCHAR(50) NOT NULL PRIMARY KEY,MAXACTCONN INTEGER,DRIVERCLASS VARCHAR(50) NOT NULL,IDLECONN INTEGER,USERNAME VARCHAR(50) NOT NULL,PASSWORD VARCHAR(150) NOT NULL,URL VARCHAR(100) NOT NULL,QUERY VARCHAR(100),WAIT INTEGER) +CREATE MEMORY TABLE BDPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(50),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE BGCONTENTID(BGCONTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,BGUSER VARCHAR(100) NOT NULL) +CREATE MEMORY TABLE CONTENTITEM(CONTITEMID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,NAME VARCHAR(200) NOT NULL,PARENT_ID VARCHAR(100),PATH VARCHAR(1024) NOT NULL,TITLE VARCHAR(200) NOT NULL,MIMETYPE VARCHAR(100),URL VARCHAR(254),LATESTVERNUM INTEGER,EXTENSION VARCHAR(10) NOT NULL,WRITEMODE INTEGER NOT NULL,CONSTRAINT SYS_CT_61 UNIQUE(PATH)) +CREATE MEMORY TABLE CONTENTLOCATION(CONTENTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,NAME VARCHAR(200) NOT NULL,SOLNID VARCHAR(100) NOT NULL,DESCRIPTION VARCHAR(200) NOT NULL,DIRPATH VARCHAR(1024) NOT NULL,CONSTRAINT SYS_CT_65 UNIQUE(DIRPATH)) +CREATE MEMORY TABLE CONTITEMFILE(CONTIFILEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,OSFILENAME VARCHAR(200) NOT NULL,OSPATH VARCHAR(1024) NOT NULL,ACTNAME VARCHAR(100) NOT NULL,PARENT_ID VARCHAR(100),FILESIZE BIGINT,FILEDATETIME TIMESTAMP NOT NULL,ISINITIALIZED INTEGER,CONSTRAINT FK7FC3F44164D906F3 FOREIGN KEY(PARENT_ID) REFERENCES CONTENTITEM(CONTITEMID)) +CREATE MEMORY TABLE CPLXPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE DTPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE TIMESTAMP,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE LNGPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE BIGINT,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE LSPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARCHAR,PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE PARAMTYPESMAP(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(25),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY)) +CREATE MEMORY TABLE PRO_ACLS_LIST(ACL_ID VARCHAR(100) NOT NULL,ACL_MASK INTEGER NOT NULL,RECIP_TYPE INTEGER NOT NULL,RECIPIENT VARCHAR(255) NOT NULL,ACL_POSITION INTEGER NOT NULL,PRIMARY KEY(ACL_ID,ACL_POSITION)) +CREATE MEMORY TABLE PRO_FILES(FILE_ID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,PARENT VARCHAR(100),FILENAME VARCHAR(255) NOT NULL,FULLPATH VARCHAR(1024) NOT NULL,DATA VARBINARY(1000000000),DIRECTORY BOOLEAN NOT NULL,LASTMODIFIED BIGINT NOT NULL,CHILD_ID VARCHAR(100),CONSTRAINT SYS_CT_83 UNIQUE(FULLPATH),CONSTRAINT FK94A87E2569FABF5E FOREIGN KEY(CHILD_ID) REFERENCES PRO_FILES(FILE_ID),CONSTRAINT FK94A87E25CBBBB0EA FOREIGN KEY(PARENT) REFERENCES PRO_FILES(FILE_ID)) +CREATE MEMORY TABLE PRO_SCHEDULE(SCHEDULEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SCHEDTITLE VARCHAR(200) NOT NULL,SCHEDREF VARCHAR(1024) NOT NULL,SCHEDDESC VARCHAR(50) NOT NULL,CRONSTRING VARCHAR(256),REPEATCOUNT INTEGER,REPEATINTERVAL INTEGER,STARTDATE TIMESTAMP,ENDDATE TIMESTAMP,GROUPNAME VARCHAR(50),LAST_TRIGGER TIMESTAMP) +CREATE MEMORY TABLE PRO_SUBCONTENT(SUBCONTID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SUBCONTTYPE VARCHAR(255) NOT NULL,SUBCONTACTREF VARCHAR(1024) NOT NULL,CONSTRAINT SYS_CT_89 UNIQUE(SUBCONTACTREF)) +CREATE MEMORY TABLE PRO_SUBCONTPARMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(100) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FKF3CE4C47846761A FOREIGN KEY(ITEMID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) +CREATE MEMORY TABLE PRO_SUBCONT_SCHEDLIST(SCHEDULEID VARCHAR(100) NOT NULL,ELT VARCHAR(100) NOT NULL,SCHEDID INTEGER NOT NULL,PRIMARY KEY(SCHEDULEID,SCHEDID),CONSTRAINT FKF0D3FBD69E226721 FOREIGN KEY(ELT) REFERENCES PRO_SCHEDULE(SCHEDULEID),CONSTRAINT FKF0D3FBD62593BC9E FOREIGN KEY(SCHEDULEID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) +CREATE MEMORY TABLE PRO_SUBSCRIBE(SUBSCRID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,SUBSCRTYPE INTEGER NOT NULL,SUBSCRUSER VARCHAR(100) NOT NULL,SUBSCRTITLE VARCHAR(200) NOT NULL,SUBSCR_CONTID VARCHAR(100),SUBSCRDEST VARCHAR(200),CONSTRAINT FK5E7511F89D8AC376 FOREIGN KEY(SUBSCR_CONTID) REFERENCES PRO_SUBCONTENT(SUBCONTID)) +CREATE MEMORY TABLE PRO_SUBSCRPARMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE LONGVARBINARY,PARAMKEY VARCHAR(100) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FK95DADE9355DC7DE8 FOREIGN KEY(ITEMID) REFERENCES PRO_SUBSCRIBE(SUBSCRID)) +CREATE MEMORY TABLE PRO_SUBS_SCHEDLIST(SCHEDULEID VARCHAR(100) NOT NULL,ELT VARCHAR(100) NOT NULL,SCHEDID INTEGER NOT NULL,PRIMARY KEY(SCHEDULEID,SCHEDID),CONSTRAINT FK2A8C749B9E226721 FOREIGN KEY(ELT) REFERENCES PRO_SCHEDULE(SCHEDULEID),CONSTRAINT FK2A8C749B7329C46C FOREIGN KEY(SCHEDULEID) REFERENCES PRO_SUBSCRIBE(SUBSCRID)) +CREATE MEMORY TABLE RTELEMENT(INSTANCEID VARCHAR(100) NOT NULL PRIMARY KEY,REVISION INTEGER NOT NULL,PARID VARCHAR(254),PARTYPE VARCHAR(50),SOLNID VARCHAR(254),READONLY BOOLEAN,CREATED TIMESTAMP NOT NULL) +CREATE MEMORY TABLE SSPARAMS(ITEMID VARCHAR(100) NOT NULL,PARAMVALUE VARCHAR(254),PARAMKEY VARCHAR(50) NOT NULL,PRIMARY KEY(ITEMID,PARAMKEY),CONSTRAINT FK60E4AFE6FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID)) +CREATE MEMORY TABLE USER_SETTINGS(USER_SETTINGS_ID BIGINT NOT NULL PRIMARY KEY,USERNAME VARCHAR(50) NOT NULL,SETTING_NAME VARCHAR(100) NOT NULL,SETTING_VALUE VARCHAR(2048) NOT NULL) +ALTER TABLE BDPARAMS ADD CONSTRAINT FK61733C48FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE CONTENTITEM ADD CONSTRAINT FK692B5EEC44F32395 FOREIGN KEY(PARENT_ID) REFERENCES CONTENTLOCATION(CONTENTID) +ALTER TABLE CPLXPARAMS ADD CONSTRAINT FKD6D6E97FFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE DTPARAMS ADD CONSTRAINT FK7F994A16FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE LNGPARAMS ADD CONSTRAINT FKE304FCCBFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE LSPARAMS ADD CONSTRAINT FK89BC75CDFA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE PARAMTYPESMAP ADD CONSTRAINT FKD3EDA1B0FA34BFDC FOREIGN KEY(ITEMID) REFERENCES RTELEMENT(INSTANCEID) +ALTER TABLE PRO_ACLS_LIST ADD CONSTRAINT FKB65646C2B23C5D30 FOREIGN KEY(ACL_ID) REFERENCES PRO_FILES(FILE_ID) +CREATE USER SA PASSWORD "" +CREATE USER HIBUSER PASSWORD "PASSWORD" +CREATE USER PENTAHO_USER PASSWORD "PASSWORD" +GRANT DBA TO SA +GRANT DBA TO HIBUSER +GRANT DBA TO PENTAHO_USER +SET WRITE_DELAY 20 +SET SCHEMA PUBLIC +INSERT INTO USERS VALUES('admin','password',TRUE,NULL) +INSERT INTO USERS VALUES('cooldude','password',TRUE,'password1212') +INSERT INTO USERS VALUES('pat','password',TRUE,NULL) +INSERT INTO USERS VALUES('suzy','password',TRUE,NULL) +INSERT INTO USERS VALUES('tiffany','password',TRUE,NULL) +INSERT INTO AUTHORITIES VALUES('Administrator','Administrator') +INSERT INTO AUTHORITIES VALUES('Anonymous','User has not logged in') +INSERT INTO AUTHORITIES VALUES('Authenticated','User has logged in') +INSERT INTO AUTHORITIES VALUES('Business Analyst','Business Analyst Role') +INSERT INTO AUTHORITIES VALUES('Power User','Power User Role') +INSERT INTO AUTHORITIES VALUES('Report Author','Report Author Role') +INSERT INTO AUTHORITIES VALUES('ultimate','ultimate') +INSERT INTO GRANTED_AUTHORITIES VALUES('admin','Administrator') +INSERT INTO GRANTED_AUTHORITIES VALUES('admin','Authenticated') +INSERT INTO GRANTED_AUTHORITIES VALUES('suzy','Power User') +INSERT INTO GRANTED_AUTHORITIES VALUES('suzy','Authenticated') +INSERT INTO GRANTED_AUTHORITIES VALUES('pat','Business Analyst') +INSERT INTO GRANTED_AUTHORITIES VALUES('pat','Authenticated') +INSERT INTO GRANTED_AUTHORITIES VALUES('tiffany','Report Author') +INSERT INTO GRANTED_AUTHORITIES VALUES('tiffany','Authenticated') +INSERT INTO GRANTED_AUTHORITIES VALUES('cooldude','Authenticated') +INSERT INTO GRANTED_AUTHORITIES VALUES('cooldude','Power User') +INSERT INTO DATASOURCE VALUES('Hibernate',20,'org.hsqldb.jdbcDriver',5,'hibuser','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/hibernate','select * from users',1000) +INSERT INTO DATASOURCE VALUES('Quartz',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/quartz','select * from orders',1000) +INSERT INTO DATASOURCE VALUES('SampleData',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/sampledata','select * from orders',1000) +INSERT INTO DATASOURCE VALUES('SampleDataAdmin',20,'org.hsqldb.jdbcDriver',5,'pentaho_user','Encrypted 2be98afc86aa7f2e4bb18bd63c99dbdde','jdbc:hsqldb:file:src/test/resources/solution/system/data/sampledata','select * from orders',1000) +INSERT INTO CONTENTITEM VALUES('170521e0-7b5d-11dd-b851-9b2343f3bcd9',0,'MyXML.xml','170521df-7b5d-11dd-b851-9b2343f3bcd9','!CONTREPTEST.FOLDER_PATH!/MyXML.xml','!CONTREPTEST.ITEM_TITLE!','text/xml',NULL,0,'.xml',0) +INSERT INTO CONTENTLOCATION VALUES('170521df-7b5d-11dd-b851-9b2343f3bcd9',0,'!CONTREPTEST.FOLDER_NAME!','ca825b3b-eb03-11d9-ad29-005056c00008','!CONTREPTEST.FOLDER_DESCRIPTION!','!CONTREPTEST.FOLDER_PATH!') +INSERT INTO CONTITEMFILE VALUES('170792e1-7b5d-11dd-b851-9b2343f3bcd9',1,'170792e1-7b5d-11dd-b851-9b2343f3bcd9.xml','!CONTREPTEST.FOLDER_PATH!','!CONTREPTEST.ACTION_NAME!','170521e0-7b5d-11dd-b851-9b2343f3bcd9',27,'2008-09-05 11:12:43.953000000',-1) +INSERT INTO CONTITEMFILE VALUES('170792e2-7b5d-11dd-b851-9b2343f3bcd9',1,'170792e2-7b5d-11dd-b851-9b2343f3bcd9.xml','!CONTREPTEST.FOLDER_PATH!','!CONTREPTEST.ACTION_NAME_2!','170521e0-7b5d-11dd-b851-9b2343f3bcd9',28,'2008-09-05 11:12:43.953000000',-1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',-1,1,'Admin',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',-1,1,'cto',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',3,1,'dev',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',1,1,'Authenticated',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',0) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',1) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',2) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',3) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',4) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',5) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',6) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',7) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',8) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',9) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',10) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',11) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',12) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',13) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'suzy',14) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',3,0,'pat',15) +INSERT INTO PRO_ACLS_LIST VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',8,1,'Admin',16) +INSERT INTO PRO_FILES VALUES('6b1644df-6757-11dd-a492-c111aa2b74dc',1,NULL,'solution','/solution',NULL,TRUE,1214444693000,NULL) +INSERT INTO PRO_FILES VALUES('6b1c3850-6757-11dd-a492-c111aa2b74dc',1,'6b1644df-6757-11dd-a492-c111aa2b74dc','samples','/solution/samples',NULL,TRUE,1214444693000,'6b1644df-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c3851-6757-11dd-a492-c111aa2b74dc',129,'6b1c3850-6757-11dd-a492-c111aa2b74dc','reporting','/solution/samples/reporting',NULL,TRUE,1214444694000,'6b1c3850-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c3852-6757-11dd-a492-c111aa2b74dc',1,'6b1644df-6757-11dd-a492-c111aa2b74dc','test','/solution/test',NULL,TRUE,1218380602000,'6b1644df-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c5f63-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','dashboard','/solution/test/dashboard',NULL,TRUE,1218380623000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c5f64-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','datasources','/solution/test/datasources',NULL,TRUE,1214444693000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c5f65-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','platform','/solution/test/platform',NULL,TRUE,1214444691000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b1c5f66-6757-11dd-a492-c111aa2b74dc',1,'6b1c3852-6757-11dd-a492-c111aa2b74dc','tmp','/solution/test/tmp',NULL,TRUE,1218426075000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b264a77-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFree-quadrant-budget-hsql.png','/solution/samples/reporting/JFree-quadrant-budget-hsql.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000002b744558744372656174696f6e2054696d650046726920352041756720323030352031363a31333a3330202d303530309f930d620000000774494d4507d50805140d3001d1d982000000097048597300000b1200000b1201d2dd7efc0000000467414d410000b18f0bfc6105000017bb4944415478dad45a6b6c1cd775bef7ce9df7ecce3e49ee92122d51a21e966cd97212a548041bb153db305aa04150343f6220285a2028faf895feeb9f22010a1871fbaf3f1aa00960b4400ba705e2022d62bb501cbbb26cd99225511225527c2df7bdb33befb98fde21296a49d14a21c9527530d05eddb973ee39f73cbe736608f77e7f36d4cd7ea8030aee1ff1fbc385df3d1f4b43d3a38ae3d38c8192049871732ca92f7424ecad745eff33fedabfb53533c739ad0dd0fe6cb4126a94b2bd79beec49a6cc07219b280013b2568cc290794cc9624a25c973493e836492b4a8822540225632582bc206a696cc6aae54d0a19f001df3550f510e25c86d8d4b0a2201c91a60108218e0712339bda854f20443c820b2649a04ccc8a41bf53cb4bbc8eb03d88bb00209c2d052a1109f229c1e29867d1f4cdab193281f2fa0a3937c424daeb640c4f17c075546e531a62441f43b4f58b3b5e8dbfcd471e5daf73f2de3012c9fbeee7551218bd451336a27788e9a459b1006eb31b53220a192cfe4469c00423946ba464c88bc58ce69cce7ca6280b21ad7351a450067708770c3a4ab03ddc6dccc02c229e710a84ca23221b46a339ff2ac0aba548db054b0632f911a4c55142a996a117a3ec0ab81955783aa1dcd71dd90500f20ac24328463592463102428c0bac2e318c8827521c74d0ba961acdae500441da8c40ace9b3456d544c2bb47c2390f5e5a0a6b1e6972e2b095489d867ff4378bcf7fd5e2a9ff0078d39300841b6eb9ee53f0e6ed5b2ec6d75d0ec24df7636083c1363fdce4c3b74fa63f1caeffac0f6edde61b926c8ab43d5886b8f11d386f0e20c286550ecfbce51f3cf6e119191fde855e7a5afdecfccce252edc5179f3d7f7ea6b1ba7cf0c8d14ac97ee79d5366c6feca89e34b4bf5c51bd710c284c47edf3df9cd6f847de7d2ccd55ed7f9da7327c32039f7f18758514f9efceacd9db6edca874f8adf9ae1436704b76a056fdde5eb16d8387b3e6c896d1b6d3d97f529840032d47f3fbffcd4be7ed47d09fedd3f2fbffa92d5eb7673f99c5832705d5dd3242c71c65cd7cd64b3eb0f3abd9e9dcb6d328da28831aaebba1827491c06a16e1858423b1cfffa031cec6c9c5b9adf66227e4bbbe16787266e3bd61d1e04489265bdd8ab5f29168c9ffc878685572224e78be5300c354dcbdaf98d8512b7f32aa32c218908b27ca124b6f222c1885abac42489728a9004580c033f6b17284d384051c274551a168591987322617d48cc0d13254922cb58ec207c278e1255c5623a08b988558ce186edd7a309409638003080d4c497836eac66b09c91e284ca98638c599a2a36fc8172264178334284e1a2c85dd64dd38f4014b4a5dffed69f3f7dc068361b83bee3fbbe2454100918498c1204d1d2e262df7184c1539b73a0d697ae2f78a5b1cc52d0fc970bbf7a7a6c8f76f9efc9a01b5b7b8575eb01ae0115f51a61e07b9e9f3a8b0268f73f817fbad1cb8509109ed06a75a230322dfdc3d5d3a7ae5fb668266ba96ecf07fd6b2ecba8aad470253f48d6b084d69b032192105e7853c65cb0f261ec79a77ed8aafd6a1e6b491316aece9eb35462eaf2bb0bf3179ad274493dbf507ff7c2ec91dda3e066b40c87d8a757132462837112f87e12c741e0511227021678029158455d6f4088b813aead232b8d81cf85dfd24b8d45451de58cbeaffdfe7be1094768433db670a6c23d4ae31bf3731dc7111b2259e3fe6506b8951fedb4569bada6e0b6b8b8c438eb9065439dc492b02abd91d8e7f197fd2814e3a45fbf72f1d320f409891a8d26a544585e115ed33d4f97dea641f34b7fb26beae419aabcdba8bb02b1fcd08f235fedf9572fde10a050e3c14c33f06322300e400ac505588a77e925c614fef88d85efbd62534a3b9d4eb15444e23cd712c8fa918451e47b6e3e5f583b17d06a05227b944a5abb1392848d9435e1c38c715d45c1a02bab96acca4351960e48d0065092b5ec6642b9999d78afe7d9b62162a1db972c03e85aba6d1046fdbe3732921b4ada2927e6cf31e24b99fd0062ea36052c71649224d075555664117a240e154d1709ce8b8925a2630356b664877ffc8507fff69f16befba2b1991ba2840aac4b08c959da4e39e6eee81e39f02de9fcff463d8fbb7e6c5a2b17dab3d3d95d15b324267ffa0b0f0bfb0c9c6ebdd19244fe8640b3f2ff3a8f8f68a42cd524108f562bd7ae5c1b1dc9d5da7d5bb70c1dd51a8e0c13c32ec461a21bb21b045933e3b9fdac6dbb9eab2a9af00488b8efc7baa1077e68662c05f15edfd54ddd69f7453121128fc8ffe3e323a11751c6250409e4240ca9800f5d03946aa6c508f18210708215cc992c4ba0effa8a8c0cd3607184358b249eeb91ea78a5d76c98f9e2c1e9bddb149e5de9ac76398f661adcebde6864568d679f13a849b1084e2b9b951545d534e100414cbf517605284d54aa3d6780009b3a749026e1e1d1f13008344d31f3651115c2d53521bb04ca40a2493c561d8b091da954fc209031460886510c2114c90e22499525dd0e444c144ae5346b27c9e8f858c6b2e228743ddf324d9163dbed66369bc29e785c205cb3d118c96524415861446003a252a798b735dd74fb5d1121009876816b9aae4c8c635969777bdb143675300a718cecd9d6c2d7abc7a70f4faef90782afbf31ffea4b66fa9fad1e2f7c9b88f31f76aa9bd5c030caede467370b0338f4ef36a804c05010429b73c3dc37cb14be95e57af5c17706ed2dcebfde74f08f3ffae4d8b1a3a2046cb9f4a32b0b2f3fb3e7a76ff9a20910b8c52e5c6b4f291ecc82b3f5ee71b3084747009427c6aaf7167b3bd3423d9aab2593f9a5998b1745fe3f7cf080100f01926656049238a956471cc711965f9d5fea2c2e1d3e79a2db73def9f0faf3cf4c0c5ce1e4b2c0682c412c8b1c8f0584c4312b97ed3479a6e52d127ed79eef681279faa9c70567a1dfe9b72e1e3bf77667df1f8bf3c26b351bedf5039f36290717679d27a6644fc5d9dcc817a16dea3b04b5dd70778e81abd7e57cb7ef8cd41addca585ed3339d46d30bc958a5a4288a90fe7a1d9a8625068376afc85de190ed563757b4078e03254c93e4b1a94951750c069ee875786a5d94a20ca7a20e90c632eca63b1c7f613aaeca8933e0dc80affdeceaab2fea7c1d9d3910b58b22a7a55298087f463b09cc3f7792ffc695a9088c8114c9642aacb4d3ca9b80917626f0565f711bc66c666ee11802d86f753f7cb38017502c114284cdd7effcecad100ffabd56b3071e38250f641708c94640a7f9980711c4aa661d3874f0c12bfc80298cc99bef2c32ccf0c396e43713a7318f521f0c90e5afbd872a1aba48b4826459de5c46d33806a21bd9918970e9c7768fcd2dad3c020a278b6f0fde7c490c7e5c79fd879744bd0d9a3ff8d3daf56b7122f2f0b1cd65dec071635e1d2d6dce745a0d3d9317a527588b6bc2e484804740e11d098bcc4ad9cce5cba2260802d7cc64561616f3e5b2e882ea4bf3d9427165b9b66b62ac2469eb0a0b5a2f2a1e0185a19ac3951362b0ab387662224e85468850eeb88382aa88648c6555147f9a967604b69d759a69c928605c948f9aaadee2031e1185dd6ce5d2f1ef88c1cbe792173e392706d61ffcdef8d8a8aee9a5821dc6a270a2aaaecb92626432a66194474745bb5f28140d435387425a91b8a8a31f018545bb1e918118105f219d3504e53c5f288a4b0ced9bcbf2f6c670d7e4e4ed4c2444f757a23319f808280c45c50fa574205a11f92e0516fe6ce992e8cc1e01850bd69e670ffe201d8972e13b7f788fdc528599d777fefb23e3f17de2285910438c7892205d6731e16e9f7384f3d9b4cca44434225052d5c92fa4a97830b466619666ece0d265296b917e884431ad4b51df477641d260d2a8278d5568da200c94dd5551063c6c99ef596194c9155e7e4e0ce2daaa592aa3b479d8422c0c00561096ee6283ff6f94f643611c9d5a5a0d09890bf9561c7b499250ea46e1f966c78fe3863be80169d5f712f6b085bd1fb4f6ee3b0acfac364fcdcf898e50e230ab2b5fdb336501d2f3fdbf3e7f216fe8794511caffe8f967e57bdeefa153aa703e63ffc53347450375bdd79fca6f021b9806e0eb93bb1fb6845f80c2e0ec9be0bf5e134835f5b0a5b9ff74f805f0ca5fdda6b04063d147100f480a50b220e80084c1600538ab0f5bde9d68ff73c0ef00b304221f2c9f0164ebab047b02e4c7d3494902411f84ceb6a7d7141648236e1b55103be95251855396a2eef1ef021e02ab04e2007417c0e55f3e087d9efc16c05afa8292bae0eccf7758e03bc02ca617dde9ad49faaa4a34816aca41cb0059db767f4de1411dccfd7a8787cfbe011463ede510078c3c086d055d7c0b48b2282301fb1cc05ffef84e8ff797d26b93c6a67752f8f8b7c1de130f489f074c46610785179bed99056fac5490b0e4b46a3d3799da3b2963f4eebbef3ffd5b27b83fa050e224a18c2b185300f3f9ecd4de4735c1a58547c62eecae5442df9770fa217862bc2242584c1e7bf270e47b61e8afae2c75071e4c3fb5c594d18c653d6cb1ef9e520be78a23e2da98d8b76ff35ebfd769347ba5f2c8f4a1270a43f8fc4550120c3efaf4826ada8ac89eb20c157930e81f3d727478cdcccca5300ced6cc6b032b5a57906b543871fd7d5ad0ddf95cb40d5401801dd00bd569ab7a6b738e39ddac3f493bf2ab1f47d38045f3041ac9a86c90041921a46beefc1f1eae876791828958a2b2bb53c8358cb224eb7cb25908551d0e903d1cff55d30f9580a375be97315168597aaa959810251e2bbbd566395505a2e9506ae57ad5640da62d12421ead04ba37b21128776a1d0efb62d33a3e04c863246481445c36b7443777afd917259d50de803dff5489244fcd65f107a4ea72d6b76c94e8280c9286937a1a4ed296cc95b9fabb0b0eafcdc4279a4dc68346c4b0f22d123aee42c6369a576e6830f34d35a5d59cee7b212c247bef495fd7beeb502859ccc5eb9922f9566af5c2ee7332b0d2797b3abd52d8df76aadb66f6acfb9cf3e13277ef9ea8de9e969d3d086bd6f9004b3d7e64c3b2b451143104be8d0a143db37fad13f5cfacbefedf0e54158388e774042cea8eb8719cbbc2f861d26c6d8da17542e1c67f80dfb6d0bd6fffc67a7468673c6b958430949bf222228c6eb2b491251467ef2f3c69d2cfc3f1fbc2f7e56eaada307f6de585c1d29647d2ac56eefe0134fbef7ce2f4b13bb65491af47abae89f318612761deff9179fbfbb708ffcfee90f3fedb6ebd5c9fd95a239b7daae968bfba6f60daff9f57bef0d7add5c79b4902f5cba720526e1375ff95d156ff9e277fe933304a9bee38e8c97176717c627771d38b07f78c19d62786affb49dc91cf07d04816a6630421cc07a0dc8c2559e3896b5b3224378f97cafefe432a6a88d0af99288babb539871343151ddb77f4a4063b3567bfcc08156b3b92d8677edde9d3d72a4dfef2baa76e2cbc74565c0a930dc163ea572a5db7747f74c3084a70fefcf64f3db36ba93853bed66ab596fb47b93d5513f660ae4969d1bab54eab5ba8291aaea2286ef4abb1d2861b1d31fd46b4dd3ce144ba5200c82c0db9611fb7dc769b604728c8c6ab5953a0dfc5ca164685b7cbb3f7034dda010f5dbed8404ce20b0b35baacb3bc192a699f95cceb46c110c523c8802bfd976caa59ce3749d5e17e9e67d5458c092aa2886ae94cad556a36666edf1895ddbd6c858b17276bbdd09825855642e5992b4fd0b76c63456db03539791ac18322e57c676b0700bb496c0d2761138580535e02061ea916a796d4aa0941a81c4da9fb540d603bdb3d1d9fba57077b9e5a14491a599c5996c31d7a95d14e852b28ac36b6ef8f31ad2634c74dae00a0b5d7f108532dba273cdad419d4561a25b2689e37e3f78c67e6abbc22c45ebdbfe1e1e8290fe6f37d7d6dbc67185cfde2fbcdf2fa224cb566cc3b121a028e2a6766f7062c74552f429af45f350f4a1edbf28fa3bd2c7f6b92e8aa0ed435b24ae83c6b1d0588a2e965849a44891bbe42ef77ee919ca48c92523bbb12803395a50e0ecec70ce9e9939e73be7cce8adc3dea06fe52fe460c66423c6358c245a1da1d1db5735cd81049515c66660b3b5cf0c64c73073a56cafdb0bfcb078a51609f876fb6d9cd98e4f1744afb1df1217a20622a99e877c16b2939d58b9bc0267162a3fbff2cc2a2b779ea3cef5913a97102a44c7fcd04d0b343d3d9de36b48c301b1f667f8f0b72fbb27b3a1f3afc3f77e3ec1b0aec2f647e00c882b4b4c81a99219ece830e8bcecfe4ea3ea3530148865c13641794200c328c50a206708ce083d702db41f224f0f196605c82d839400570397816c15020a0e3e859577c156c8f3ae0dfd06ecfef32cf8b9f8263c4dd17360edaf532a24ca50ba4c18c32ea9bbd1bba849f20b1032c49b8532cb54a631acd6e1f1bd294d1bf78807ef3841ca31ce825ba4c62a71a4312ce9ee545affe0a4c7bb5be4fa8252518c3964f8d53bf0b3df9d113f674cd9288c230c372dfaa15abab858f1d120a6d944328eb8f765f77456441866793e9b4eadadadf91425c9c9745cfa9a339c2fcde1854a3b72ef3ff5dd9eaac793722e5f4ac4e599f6c335f5cf9fecd9a69e4823fee7db5d2d9d4e54ca634bcef6f6b6ef7b34cd246252ababf83e5c7df50adaf9630dedee90288a20822c93d0042ee10bb5d1fb27d91b83816e79ae65188669cefac5530ce739566d61c91ef4f7f60f8aa562b7ab44ea68fd7eb954ee763b47471dec9aef3b41247d155594aa80e540f3101a0df002c84c332da712e2e1eadc3cfee34511ad705dd3389e27ee08c7e3780e912a623777e8121996bf2885818fa8d0f39c442a198fc768086b7373113c8cc8b4ab288b0b8ba224a130689af55d271a11a954718a92380bded074843e11cfc84978f8c3bfffcdb25d4bebf901aaa73c9886aa1be56a395f2a37f6ead96cb6dd6adba6e5a1115f2cdcbafdc68b306ce9bdfb0f1e6412f1f9e5cb5beb8f0f15ebe2a5a54bcb631e8fcd8d8d5c32f6c9a3d65239576fb668dfb971ebad7462247a8412dede84a60ab2088893972fc0610bc6bde827f9b4745d27f9f243c29983e640e007c772f6fde0b89ce42a073ec31038fb62220e2ddbc6118aa818a790280ad878c471e5380e96b843e2058124333113591838e86892574fac468eb87fb8e17ec1e7f2697df6f093e2e2d2d2c23ccc9e5c53fbf8e3074033021f2be7134d450d9de03bdfbd315a6775751597148a622bd5f9d6c65aa3ddbff5e61b72c4112f08d80e4a9ae6d0f4348be5dac5e5b10d2f27cde142a52a8be254dfe5a99317507373b57ca1685906c770c90c22702af2d3195cb853299e6570a22d2c5d4866fb38511d27ea6acfa433b822488914cef0fc847e3dc9c5433314cb704ae78817a4bd7afddcf9738228735f3517ee591cdb9aa60d0686144be6d31c2e4e99643a32a4fdc06f1eec795e98cde60c73e0d80ecdb0dc44ce1156e359c125cac5f0436a69714ca19e34a41dd77db2b3b9b7b5932f177b8ab25baffff09db7671476a1398163d96ca16868fd4ea75d995f44ed13f92dc7767385625c127bbd81284a2cc304c33850a4297c113d9c110c9b906385dc737b2dc942c570d7ae5ec3cb18e8a8286559726736bc03cf4da5331cf200d45c6dde751d9ee3226a299d494b82a8e946229d3406039ee771198dd4c1d75428550481f35cfcc351a3c7c757e99324bcb5b9fdd9a34fe38964a3d17cedb5ebaf8c7bb44f976cdfd9d9d9e929dd956f7e6b7d7d4d4ea57ddbaed5c68ca4dd9d1d720e80efe58ad57a7dd71f68d77f707b648f24a1f6e1c176bd5daee4345543a301955c041f12b5f4abf7167a104dfe20890e4ee8d8166a1c869979f47098571152433bd1755cb46d26abfc2fd4f225154833c3411ef85e380cb548b494e1c8a81e534b3ae80770107d94827ffde32345b54ccd79fb27b767cdefd6837f6fee75aac5f4e7abeb85b9620ba5b45cbb79672c11e3defb7f88a5e3478dd6f2cae5dee1615f71effef46e64c9a26c27fbfbbf50b6692f2fd2035b482ec0cd1f8d554009fff2bdf9291206b2551cd7097cf7624c8419936b3bfe7013174d531e39a8036d0a3a22465337c2101876b8e57e381838919f1c7bb441368200da46922887629a234ef53109c72086d7945e60cbb3c54823341a54f9b2d7fb9c9916d3fbfcf48c806327de11a8fb67c5d9d9929c39767af821fda7fb6aa71fb06824078f3f803ffee665776d3674f52efcf8d740a2937e3229d0b4c1e2d4b9e75c79e5ddf7c9521cfa109ee619442f48e3e79744b7241f172a8ed974a92a30a9181784014d4d20fc8da7896c352904db65eb03da694ab4ba61e82acb5337befd0dea1436fd9f0e0501413ec79f91af5f14da3df9d19617709d7650efa8dab9c55257316d4bf7dcf0e6f75f17470c4f44753c6f52effce27e2976542c261972c244005fed44a7c91309464bfecff30a46044a3d3d18e8b857a35f470a7b2ac24946109e91cd8d80f6e19afb5fc83f5dc56ad3ae760000000049454e44ae426082',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b26bfa8-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFree_Quad.xaction','/solution/samples/reporting/JFree_Quad.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e20200a202020203c726573756c742d747970653e7265706f72743c2f726573756c742d747970653e20200a202020203c69636f6e3e4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574732f3e0a0a20203c7265736f75726365733e200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a4672656551756164466f72526567696f6e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e53514c20517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c7420747970653d22726573756c742d736574222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c6c6976653e747275653c2f6c6976653e20200a20202020202020203c71756572793e3c215b43444154415b73656c6563742020205155414452414e545f41435455414c532e524547494f4e2c2020205155414452414e545f41435455414c532e4445504152544d454e542c2020205155414452414e545f41435455414c532e504f534954494f4e5449544c452c2020205155414452414e545f41435455414c532e41435455414c2c2020205155414452414e545f41435455414c532e4255444745542c2020205155414452414e545f41435455414c532e56415249414e4345202066726f6d205155414452414e545f41435455414c53206f72646572206279205155414452414e545f41435455414c532e524547494f4e2c205155414452414e545f41435455414c532e4445504152544d454e545d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e437265617465205265706f7274205573696e6720517565727920526573756c74733c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d2271756572792d726573756c74222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6f75747075742d747970653e68746d6c3c2f6f75747075742d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b27aa09-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','JFreeQuadForRegion.xml','/solution/samples/reporting/JFreeQuadForRegion.xml','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a3c21444f4354595045207265706f7274205055424c494320222d2f2f4a467265655265706f72742f2f445444207265706f727420646566696e6974696f6e2f2f454e2f2f73696d706c652f76657273696f6e20302e382e35220d0a20202020202020202020202020202020202020202020202022687474703a2f2f6a667265657265706f72742e736f75726365666f7267652e6e65742f7265706f72742d3038352e647464223e0d0a3c212d2d0d0a2020546865207265706f7274206e65656473204a467265655265706f727420302e382e36206f7220746865206d6573736167652d6669656c640d0a2020636f6e74656e74732077696c6c206c6f6f6b2066756e6e792e0d0a2d2d3e0d0a3c7265706f727420626f74746f6d6d617267696e3d22333622206c6566746d617267696e3d22333622206e616d653d225175616472616e7420466f7220526567696f6e22206f7269656e746174696f6e3d22706f727472616974222070616765666f726d61743d224c4554544552222072696768746d617267696e3d2233362220746f706d617267696e3d223336223e0d0a20203c212d2d205468697320697320776861742069732063616c6c656420277469746c652720696e204a61737065725265706f727473202d2d3e0d0a20203c7061676568656164657220666f6e746e616d653d22417269616c2220666f6e7473697a653d223130223e0d0a202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d223135222077696474683d22313030252220783d22302220793d2232223e50656e7461686f2053616d706c65205265706f72743c2f6c6162656c3e0d0a202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d223135222077696474683d22313030252220783d22302220793d223137223e4a467265655265706f72743c2f6c6162656c3e0d0a20203c2f706167656865616465723e0d0a20203c70616765666f6f7465723e0d0a202020203c212d2d3c6d6573736167652d6669656c6420616c69676e6d656e743d2263656e7465722220666f6e746e616d653d22417269616c2220666f6e7473697a653d223130220d0a20206865696768743d223135222077696474683d22313030252220783d2230223e2428506167656f665061676573293c2f6d6573736167652d6669656c643e0d0a2d2d3e0d0a20203c2f70616765666f6f7465723e0d0a20203c7265706f72746865616465723e0d0a202020203c72656374616e676c6520636f6c6f723d22233030393939392220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223230222077696474683d22313030252220783d22302220793d2230222f3e0d0a202020203c6c6162656c20616c69676e6d656e743d226c6566742220636f6c6f723d2277686974652220666f6e746e616d653d22417269616c20556e69636f6465204d532220666f6e7473697a653d2231342220666f6e747374796c653d22626f6c6422206865696768743d2232302220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d22313030252220783d22302220793d2230223e526567696f6e616c205265706f72743c2f6c6162656c3e0d0a202020203c212d2d3c696d6167657265662064796e616d69633d2266616c736522206865696768743d22343022206b656570417370656374526174696f3d2266616c7365220d0a20207363616c653d2274727565220d0a20207372633d22687474703a2f2f6c6f63616c686f73743a383038302f70656e7461686f2f696d616765732f7175616472616e745f6c6f676f2e676966220d0a202077696474683d223330252220783d223730252220793d223235222f3e0d0a2d2d3e0d0a20203c2f7265706f72746865616465723e0d0a20203c67726f7570733e0d0a202020203c67726f7570206e616d653d22526567696f6e47726f7570223e0d0a2020202020203c6669656c64733e0d0a20202020202020203c6669656c643e524547494f4e3c2f6669656c643e0d0a2020202020203c2f6669656c64733e0d0a2020202020203c67726f757068656164657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231322220666f6e747374796c653d22626f6c64223e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d222330303939393922206865696768743d2231382220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d22313030252220783d22302220793d2235223e526567696f6e3a202428524547494f4e293c2f6d6573736167652d6669656c643e0d0a2020202020203c2f67726f75706865616465723e0d0a2020202020203c67726f7570666f6f74657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231322220666f6e747374796c653d22626f6c64222070616765627265616b2d61667465722d7072696e743d2274727565223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d22233030393939392220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223135222077696474683d22313030252220783d22302220793d2230222f3e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d22776869746522206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223535252220783d22302220793d2230223e2428524547494f4e2920546f74616c3c2f6d6573736167652d6669656c643e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e41637475616c2220666f726d61743d2224232c23233022206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223535252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e4275646765742220666f726d61743d2224232c23233022206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223730252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d22526567696f6e56617269616e63652220666f726d61743d2224232c23233022206865696768743d22313522206e616d653d2256617269616e636520526567696f6e204669656c642220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223835252220793d2230222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22353625222078323d22373025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22373125222078323d22383525222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22383625222078323d2231303025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22353625222078323d22373025222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22373125222078323d22383525222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e35222077696474683d22313425222078313d22383625222078323d2231303025222079313d223137222079323d223137222f3e0d0a20202020202020203c72656374616e676c6520636f6c6f723d227768697465222066696c6c3d227472756522206865696768743d223134222077696474683d22313030252220783d22302220793d223138222f3e0d0a2020202020203c2f67726f7570666f6f7465723e0d0a202020203c2f67726f75703e0d0a202020203c67726f7570206e616d653d224465706172746d656e7447726f7570223e0d0a2020202020203c6669656c64733e0d0a20202020202020203c6669656c643e524547494f4e3c2f6669656c643e0d0a20202020202020203c6669656c643e4445504152544d454e543c2f6669656c643e0d0a2020202020203c2f6669656c64733e0d0a2020202020203c67726f757068656164657220636f6c6f723d2277686974652220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231302220666f6e747374796c653d22626f6c6422207265706561743d2274727565223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d22234646363630302220647261773d2266616c7365222066696c6c3d227472756522206865696768743d223135222077696474683d22313030252220783d22302220793d2230222f3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d226c65667422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d22302220793d2230223e4465706172746d656e743c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d226c65667422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223430252220783d223135252220793d2230223e506f736974696f6e3c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223535252220793d2230223e41637475616c3c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223730252220793d2230223e4275646765743c2f6c6162656c3e0d0a20202020202020203c6c6162656c20616c69676e6d656e743d22726967687422206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223135252220783d223835252220793d2230223e56617269616e63653c2f6c6162656c3e0d0a20202020202020203c6d6573736167652d6669656c6420636f6c6f723d22626c61636b2220666f6e7473697a653d22313222206865696768743d223135222077696474683d22313030252220783d22302220793d223136223e24284445504152544d454e54293c2f6d6573736167652d6669656c643e0d0a2020202020203c2f67726f75706865616465723e0d0a2020202020203c212d2d0d0a2020202020204279207370656369666979696e6720612062616e642068656967687420746861742069732067726561746572207468616e2074686520757365642073697a652c2077650d0a202020202020656e666f72636520736f6d6520656d707479207370616365206265747765656e207468652067726f7570732e0d0a2020202020202d2d3e0d0a2020202020203c67726f7570666f6f74657220666f6e746e616d653d22417269616c2220666f6e7473697a653d2231312220666f6e747374796c653d22626f6c64223e0d0a20202020202020203c72656374616e676c6520636f6c6f723d2223363646463636222066696c6c3d227472756522206865696768743d223134222077696474683d223835252220783d223135252220793d2230222f3e0d0a20202020202020203c6c6162656c206865696768743d223134222077696474683d223430252220783d223135252220793d2230223e546f74616c3c2f6c6162656c3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e7441637475616c2220666f726d61743d2224232c23233022206865696768743d223134222077696474683d223135252220783d223535252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e744275646765742220666f726d61743d2224232c23233022206865696768743d223134222077696474683d223135252220783d223730252220793d2230222f3e0d0a20202020202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224465706172746d656e7456617269616e63652220666f726d61743d2224232c23233022206865696768743d22313422206e616d653d2256617269616e6365204465706172746d656e74204669656c64222077696474683d223135252220783d223835252220793d2230222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22353625222078323d22373025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22373125222078323d22383525222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22383625222078323d2231303025222079313d223136222079323d223136222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22353625222078323d22373025222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22373125222078323d22383525222079313d223137222079323d223137222f3e0d0a20202020202020203c6c696e6520636f6c6f723d22626c61636b22207765696768743d222e3235222077696474683d22313425222078313d22383625222078323d2231303025222079313d223137222079323d223137222f3e0d0a20202020202020203c72656374616e676c6520636f6c6f723d227768697465222066696c6c3d227472756522206865696768743d223134222077696474683d22313030252220783d22302220793d223138222f3e0d0a2020202020203c2f67726f7570666f6f7465723e0d0a202020203c2f67726f75703e0d0a20203c2f67726f7570733e0d0a20203c212d2d205468697320697320776861742069732063616c6c6564202764657461696c2720696e204a61737065725265706f727473202d2d3e0d0a20203c6974656d7320666f6e746e616d653d22417269616c2220666f6e7473697a653d2231302220766572746963616c2d616c69676e6d656e743d226d6964646c65223e0d0a202020203c737472696e672d6669656c64206669656c646e616d653d22504f534954494f4e5449544c4522206865696768743d2231352220766572746963616c2d616c69676e6d656e743d226d6964646c65222077696474683d223430252220783d223135252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d2241435455414c2220666f726d61743d2224232c23233022206865696768743d223135222077696474683d223135252220783d223535252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d224255444745542220666f726d61743d2224232c23233022206865696768743d223135222077696474683d223135252220783d223730252220793d2230222f3e0d0a202020203c6e756d6265722d6669656c6420616c69676e6d656e743d22726967687422206669656c646e616d653d2256415249414e43452220666f726d61743d2224232c23233022206865696768743d22313522206e616d653d2256617269616e6365204669656c64222077696474683d223135252220783d223835252220793d2230222f3e0d0a202020203c6c696e6520636f6c6f723d226772617922206865696768743d223022207765696768743d222e3235222077696474683d22383525222078313d22313525222078323d2231303025222079313d223136222079323d223136222f3e0d0a202020203c6c696e6520636f6c6f723d22776869746522206865696768743d223022207765696768743d222e3235222077696474683d22383525222078313d22313525222078323d2231303025222079313d223137222079323d223137222f3e0d0a20203c2f6974656d733e0d0a20203c66756e6374696f6e733e0d0a202020203c212d2d2054686973206d616b657320737572652c20746861742077652063616e206163636573732074686520706172616d6574657220617320696620697420776173206120636f6c756d6e2066726f6d20746865207461626c65202d2d3e0d0a202020203c70726f70657274792d726566206e616d653d22524547494f4e222f3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d22697356617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b56415249414e43452671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e6765436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e6365204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e697356617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d2269734465706172746d656e7456617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b4465706172746d656e7456617269616e63652671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e67654465706172746d656e74436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e6365204465706172746d656e74204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e69734465706172746d656e7456617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6d6973632e6265616e7368656c6c2e42534845787072657373696f6e22206e616d653d226973526567696f6e56617269616e63654e65676174697665223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d2265787072657373696f6e223e20202020202020202020204f626a6563742067657456616c7565282920202020202020202020207b202020202020202020202020204f626a6563742076616c7565203d2064617461526f772e676574282671756f743b526567696f6e56617269616e63652671756f743b293b202020202020202020202020206966202876616c756520696e7374616e63656f66204e756d626572203d3d2066616c736529202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b202020202020202020202020207d202020202020202020202020204e756d626572206e756d626572203d20284e756d626572292076616c75653b20202020202020202020202020696620286e756d6265722e646f75626c6556616c7565282920266c743b203029202020202020202020202020207b20202020202020202020202020202072657475726e20426f6f6c65616e2e545255453b202020202020202020202020207d2020202020202020202020202072657475726e20426f6f6c65616e2e46414c53453b20202020202020202020207d3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e456c656d656e74436f6c6f7246756e6374696f6e22206e616d653d226368616e6765526567696f6e436f6c6f72223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d22656c656d656e74223e56617269616e636520526567696f6e204669656c643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e6973526567696f6e56617269616e63654e656761746976653c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7254727565223e7265643c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d22636f6c6f7246616c7365223e626c61636b3c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e41637475616c223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e41435455414c3c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e427564676574223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e4255444745543c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d22526567696f6e56617269616e6365223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e56415249414e43453c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e526567696f6e47726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e7441637475616c223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e41435455414c3c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e74427564676574223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e4255444745543c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c65787072657373696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e4974656d53756d46756e6374696f6e22206e616d653d224465706172746d656e7456617269616e6365223e0d0a2020202020203c70726f706572746965733e0d0a20202020202020203c70726f7065727479206e616d653d226669656c64223e56415249414e43453c2f70726f70657274793e0d0a20202020202020203c70726f7065727479206e616d653d2267726f7570223e4465706172746d656e7447726f75703c2f70726f70657274793e0d0a2020202020203c2f70726f706572746965733e0d0a202020203c2f65787072657373696f6e3e0d0a202020203c66756e6374696f6e20636c6173733d226f72672e6a667265652e7265706f72742e66756e6374696f6e2e506167654f66506167657346756e6374696f6e22206e616d653d22506167656f665061676573222f3e0d0a20203c2f66756e6374696f6e733e0d0a20203c636f6e66696775726174696f6e3e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7461626c652e68746d6c2e426f6479467261676d656e74223e747275653c2f70726f70657274793e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7061676561626c652e7064662e456e636f64696e67223e4964656e746974792d483c2f70726f70657274793e0d0a202020203c70726f7065727479206e616d653d226f72672e6a667265652e7265706f72742e6d6f64756c65732e6f75747075742e7061676561626c652e7064662e456d626564466f6e7473223e747275653c2f70726f70657274793e0d0a20203c2f636f6e66696775726174696f6e3e0d0a3c2f7265706f72743e0d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b27f82a-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.png','/solution/samples/reporting/MDX_report.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000002c744558744372656174696f6e2054696d6500546875203133204f637420323030352031363a32343a3531202d303530300a0ba0930000000774494d4507d50a0d141a3a5bf3cf85000000097048597300000b1200000b1201d2dd7efc0000000467414d410000b18f0bfc61050000142d4944415478daec3a5b8c24d575f7d6bbbaabbafa31dd33d33d3d333bfb06766097c5c08271b043ec38584189e5c82806822547492c2bf948a2fce43b8a14e5238ee50f48ac28c2769404c9c89613c018300eec629659587697d9d9793ffa315ddd5dcf5b75ab6e4ef5f4ccce3ebd0b7608668f667aaa4f9d7bebbc1fb70633c6d04709b80f9a811b02df10f886c03704be21f00d816f08fcd1811b02ffaac3474e60bcfb4fce35111fa20ca31f342f97c2fb186cf60c8b29917748984d8b8e1f0dd3e502699c6d6b4265e5e52f8cfce054fe2b76b8abe672658335cc4896798e61ca28c552ad8b3e311e2cb9a21c060e27bfb588c74aacacd196cdc6729ce345ab1e9f1599c7b02144ed507c755ef8a0f594c04855b01d564885778ec9f34df288f7ecfe74fdcbdf1b157e42ef0f5ac254fcb17d9acb04b4ea731dcc4b34a231df0ca4523a6861e9f516298ace72902698f74571917021f6511c1d6f4919319cf152594603122932af0b21a767628c7f11e6edfdbc57687a64bc18ccad7347a79d6e141f775567b1d314caf8af9fa83d70d04fa5d39224bab61d234e05c679cef77d5951706f5c761c3b9d4e238cacaea5eb5a1846a2c88761280a02c2cc34cd5c361b8654148528a270579625200687c47d9ed97919fad7db3f7b170c5d88e9a12e405e85781b01bb18ef9c9ac192802bc39e1ffcf76b482864b8c09c75d7d9dd47ee3cb3beb2b2dcd87ff39ef2e0d0d157df0a3dba77f296817cf6c5e78f65f61da856067f78f47fd2ba1133500b4ba9a97cae30b173d4a9ad2d9c9e4e6bdaa14307a64f9f999e5eaa8e556f9ddc77012bdb0461e7311772cc2e27400f0f57f8bc945bc49bfaec5fe0cd1df0a6dcc945fd47a7043dcddf54f49528a771f8ef9e5a79f4d3f245dabdf0795b6bd12564bd275ccce845c9e6f2626c19105fbc20b9c46cbb922ede764b7ea0e9cb7a9efe9255db16fed3338ec0f37c4843dbb272f99c288a11a5ed4e077c3593d1619f336bfebf9e8e6e2b0b0fede21717960242c6c6476377b635fdcdb6f2d8f8ee9b62ac8201d4240812ce89ef4b8ac2e21890b033eb2b84f5be2625308a62b888a2081e7cde463d328c31e0398ec3fd14c036e8134cef7b14c71d17d7cd78b4b03eef9cd6246d243502b7dc009d6b23993abbc726d05581d0d3023c6c7565a5dbedc2535435e17e6d752d08c8e4e401cff34e3b8a867cd5f362aa8541007741a4752be3a51f0b2810836042c7218c3867ce9c92a58c80fd8861cb71d3699583bb316f394e4c5c190221a499826175db693543e398479120f231c35dcb2f0d641a2d1351ace774abd52a56aaa1dd351d5f129063114d173a365524542c0e2b853d332bad6a8e4d79a77947b875c176036ecfde3d5d335388ac7088148bc5ab080c8ac57fffed95473f233a8ea36bda86c61dd785f4238922502cb682ba8f6e2ef2b2c8d9960d892a97cb521ad5d73be0540305238cc08c31d06f5992bb2045f77d298e639c18aa6f7084f18521b3f16476097f0ce3ad8b84c225cc0f583ee5837f0002f7e23688901906885243c9825b6d7b767fc32d8779f23fd684200ce65682ca804088d7215d43ce083cf6080d68429653b99c0a5bc5f0830545121428e280370c033e83a45789e11714b1b1358d90e532550c143e8c39de26413e25e19e7c28ee47ddd2d2a9f2f05e7054afdd51b2194aa9633b8691d9a6288809002608fc86b8b8978fe0c3353bba9e62eb1e94cd28a372500e7a9087be018a696071227f6906d9522da85c687450b3cbf4b77ed0adb0676b635f104d7fd7be7ca932387035dfb812b4acf8e5137307f728767bcdf407474b03b5c5b757ea1d0e3c80e327c62a0daff96fcffcd97dbbff76df64b9f9fa4fcb1fbfdf25eef185770e576f5a5eabc741a46741f654366b2c2f37462a05a8252ca6984bc4505415713a63d14f4ed62684a7e3cc83359b40bd802a582c950c43b72c677828bf95d6fa36dee64c1c87f0df7c6bfaf73f95206c2ff602563438b8ed532ccba96b93f1023f0497abb599a1389a4802c4d9ae5f508588258907dc123883cf136797f68e0e82b93c2fc81a1a303567af8ca606c189e2880a90308524405cd7531479abba260e8c71a7ebab8a806d179c2255d0498c64a8b1a08ec47a3cfcc597f0b6ad52b17ff97e88bff974fbd3b7299059de833d3f2c6018fcc848e2fcfff89de544978f3f3effc20bd607cdd52f11bef8c5dc534ff52bd6476d3c64d731d9fcdec3f94e23842c3d752af8ddcf689d000b343e3e1d3c7024fdd24b1612b9e1123f3f17982efad43deacfdef4798c94341f87f189b7fdaf7ead08b9f399ef7522ca462ae2c25278e7c75273b3a1a6e3b595d02808a7dff6f6ee55621ecf9cf62c8f7de9910247e337def46055a3495599fbdcef18a7a6bca59550d1f8c559521e16230eeddb25ffe7d39deb92f83a041eab8a7e96d7f3dc2d07d9fe7171a5415f7bc52e0c420dc68f7d291f70dc408eb34dfa0fdf6adfff492d9713864b82a708375784affef1fca1bbd23acf5409ab792127e190443ee24a3972e86ed56c446d0f55f2389d954a55797795af59f8c00175fe1de79e23e9fd07d3390d4f1df56eb923b56b978cacc891f84a49e8d68353ef1245bd6e0fbd0e81bff18d464858a1288424eed8b1224293144b329e3de15a0ed806c13554e5b615ffe55fad763bb1a6731143228f3b3efad33f5a04022831505d0401c73192444c48fcdda739c0938081e531e7421e4e9a50011ffba94543264a98ff8e493c2649387e920129b4a787ef48bff882a5697c10c6b0d5f50b7ccd4b6c2bc9e42bcbfd1e23f093841f401daa6f9e95d8fdbfed7672abdb3d9ff9bb9d68db4ebda96de3d28b2e7cc805034048fb3371109ec73fff5c925fdbfd0daf7b62865e1a4d4c48cda67abd2b3f4450ad4adb0446e88927c63f6896feef007a2d74a2d9f0a25fe5c6633b242e3df99edae60f29f4b2f4d73f87a65ffaa039f965c2ed9f478f3cb94de0c0417ef7bd6d55f7505e41501d60f883e1cba348bd72a59be9a009a33fc37057ad0e34469d1015e4645b125d6d4fd49ba3d709d204a4087d362e86c0dbba7cbf67c8afaea2690be50454234812203ad003e52b12fffb0ccac8a8e5a106451f2f2298751ede7d79ca9a8d9e9a451287ec086538146224c7e848191dbc42f03df52e5a0f902a2248c77e8c8625f4f9bd48bf9c70ef4be030460fee48340a0611367b1e2b44bad8c76cd73710ffc5c1c4b680dc22b643941650c42e262e69e8cf2793b30540f2fd0304e484c9d7f81262a8d65f9b4c30ac87dc20065fa3bd449c106f9b19de97c0cf2e228b26fe0c767874d3563f5a4cbe3a51c2c72706d1cdf93efef925040d96192387a0afec3fef20b510b548c2c75d83e860a18f7f713961f48c83f808fdc13eb4716c73b289a62c4442246174a088eedeb4f6d13544303a6b263dd4c3fb50ba27f019131d6ba1384a46e1dd55f4c94d9e9379f80ff57f46b577df8fe4974210216803f96b6be3c0f860966b6c13a18082c5c46b6ba2c1ecd0a4c93b0ea37b1e47c93cbc9458b87bc7e3aeebd298692995f81e8db12a8b3e21a5c12181bfccc6ad56d3f7439ec35dc7ce65f381eb40533b323cbcb8b41090286be896dd11a5541486462ecfa1c0ecfa8a28f8812f4b0a63d427747c6c747975c9b34971b0d86d9bbc208694e68dbc20b2d586a9ab4a187811afc83c731d7f6c7c7cadb61a87a1202961184a8260fb5e31575054716e61d930322c0abd204aa9b2673b2363e3f5468d4b4e77a1d1e662c66cd731746d6093f944e04edb04f7732c6bbd1e49928c38b1493d81c5996c5e4b2997d11b8b09258a207b9e9b5255081de2266930088817046a2011422531743d4f3722f04cc7773113ad8e4d54caa2204a0ecfa1090f100ed75bed28249a24bbc42d72031c8e5d0fc621ec5976c8873e02eae4ec0f760e7c974b7a6b1c86be4b7c9e2b618e23c4f17c99faae1fc794788404718f98518278050b92477c9f38a552698bf79e4b3f64fc62fdf9ff2df48f788ebd7eb4d3e9e85adef75c49e6525aa6b6524fa724cf2531cfc3682609da912387b7af7cedd8abe55c69b1d1e485b8b3de125399fbefbbb76bd69f7bf9e88e4ad9f13b1092a0eceac8c4f858e5b5d75f2b1bc5a9d32777ecda5b5f5bf043f49bbff1ebc4b37ffcd2d16a7570adb6a2a732e07885c1cae44d7b8178a4503ef9eec962b1ecb866abed3cf85b9fc52cfce1f79fab4e543a5d5be6f98eede40a03876e9d3c7efc682e533e377f3a93c9a3c85f58ae7df6b71f9239f4c2b3ff353252ad3b5e0ac7b5f56eb1943f7cf0509f75b030bb02f8becfae0c71ef7dcac6e7cfc5bf37e26bd964f3eb35117ffddbbda4357bee6c18620815818f4be5aabe19b7b22c5fc937cece4ceb69bd596b4a9adc315b4a2a73cb4dfb3da77b666621974999ed56a954363bedcae048369f99999d514571bdd5115425c509a663df36798006fe89b74f16068a10a6bc08268cc574ba323c786ef65c4a915ba649636e40d757d79b070f1ee45874fcc49bb94c1e72112f26699d57a4ea48657efe9c20a59cae697ba45a1a9c5b5abcf5f63ba05d79ebe494aee52037e94696d15852c46ab5da63bc77a6552e575aad0ee4001643b2e1d1354046d705411e1c1a641cd252298e4b064e5e94f285ac2acaaaa64b100bca60aaa73b208676a05080642cc9b224a592136fccf185e2802aa5944c5211d46c8af59eac6774d07d3e5be0044e9195a1dea106c3385f185044259d4a412e540ca54fac6768c40c036a0507778786cb4272ac8eb2d9bc2cca292569fae099dcb66ea3f74e08e1e1f2d0c677d334e55ceee70a0cc6174525e07c102220b8a776e8721216b346260e2989222182acca4013323c12d4097542e46918f68ed741e03eb1e374d5941ad04012127c8f180738e425814551e265a02d861559363259e23b404cc240e613158ba224491ca5506b39c631555170efcc1d88b5b41150c263ce2544c1171e00cccf2fd86db3d6ececdebba75d5f6e38de4006fa50a11b925fbbf7c865055e5a5982b26476bb92ac76ccc6406928973588ef9e9b9bcdea19310c88a0763bcd1d3b7743795c5e5d9605d1b3a8aa49b6e38434bcfdf6dba3303837333d3ab27b696526ade98eeb8c94c7f5747a7965599524d7f4a46cdab72c2f20f9421eb1085c7d78a0da6aaf4a8a6a39cec85055d7f55a6d0561195312503e29f8edae9e2f804bcf2fcee5d50107fb38a49d847824a3673638ffa895a55ed27ae3d56304631c53d70f72ba1a7362216f98eb9d08e23d64a2a2d0c0b39c309fd76fbb6d7263e5cf8e1f4b49ea52ad36541a76ba2d4533200f599df5a353272ba5e2eaea6aa93408c6ac56c7cbc3a5374fbca1a7f4d9f9b952a95234d2b3738d23f71d0e7ce7a5575e191bdf59afaf6a69addd6a8f8c4fec1c1f9d7a6b4a4fa5d796e770aa3431589c393777d77d77434e7bfec51f170b4330864a9cbcda58ab54ab7b76ed7ce79d295ed42cb3e60478dff8c4c2ccd903f71e81b2f4f22b2f148d7c87e081b432bbb4343a36ba77cfeef316fef283694a29c76168533dc74e6b5ad2da425870c92bf9e45f04c23009c2a4268b1bcba062c5d098e364620132e886207e00e3fa844fde06c3fc83050122888724e5139f4531e4ab300844598e2885c88392e1382e9fbcef47c99b5151049d8ba2b8412c2b72108410f4b01510439eb16d1bbac0e4bf0468f23211734812a54d6205c2b8371131886a8c99e338b03649c3517276c5f31c109fb770bd5e87bd188b603185eedc762481efbdef075a8e06e1d0f0d0458dfd7aab090af03c4f4beb9e6341461ea994a10fafd7d78bd95ca3d5c868598f3819230f029b664b14845aa3094af1bd1aa8696c6c34a2e15a6d4dd30c4a7c4d539b663badaa8542de6cb7a15b5e6fd499a8427086341edf318e59bc56afa9721ad4220852d7b2c02906060aed761b046b9b2d123145e41cdb1fdf39011aaf356ab2a88892084c5a09717af33f03702230a4f2f6ffb66b2ebb4d035118aec77662c7d7380da6766851a14894168190900021c46dc18ac78047e23158b261830001a5b4698b0a6a811668499512c7777b3cb6394e802e90000924449a7f69d9d29c3933ff7cc773ba3620284331bc2c74ad564252f83e8e2932925645e9c7cd80a31021d6b61d45d14a652e0ce3916272a820f2d35401934e30018e158bf20ce036223113042e54088460a6b8dd8435845cc7e5391ea7d8759292a040a2e039f81d89009d038c09ca48e1d0bdb73ddbe1ebe5cf5600b30669e4f8e2e58c602f008b8e034c92187243faa5af0f6eaa711dab536239583b7c65efea775f9a5673611eaa3dcbdaa1a994660449a8c0e9da6a6deba69986b187bda9a913870cfdfb67eb6bab9befb7445edeb15af5d1833870704e5fbf72f9fefd7b18d380c75b1fb6ab6ad576dc63d3c739146d6c7950e444becb727c12fb2388bf74f1fc93b92771c7691c99de7cb7aaa82a2c4e637cd2a80b8b2fdff3e51ca5a195b0220b5b175fbd76656efe69e6c5655968b5db750d2aca8e3ed6383ad978f0f0b95a1538067ddcb53449f46df7c2b5ebcd85672ca1122a731d4f90c4aee51c18ab9d3975e6ebe87fc2d23fd7ffc9d21f8a0c6fbcdbf03d2fc9f393b3b3e8f77e3bacadbf66e992efc7b222e431c6883e3a791858fad59b4d7db466db5d70c53849745daf69da9bb7eb15aeb2d36a19e644b7bb0bcf67676680a59b2b2f757dacdb692b552df04349968db1830018b04bc1b4b49a1106b61f8633b327c16d5f341747b53ab82aec49cf053b944dc30096a659deb3762b828650d26e774e9c3a0de0b1b4b2a8ca1a38115b62a00e57aa72c36cf4475e042c2b52d1ed83be3714fd5abd1e27062036cbd3b25a057f1fe9b1b422831444e53403274b99ea3511014b6719357e7882a5cb4414e51e87c2d1a2aa40964ab9042702314cb33fd7c0d2194e1be31334c5208af015a9cfd28aa22a6a35cb92288c0cb3417f63e93822c6a1718aa2c1a8e0f0efb3b424caa2ac82a56529111b6689d92b10a83b77bbb76eee23d3427fd2a2fb3f8af9d4da7efcb8c9d0a85eaf15eb241fcc5bb57e3faad50981073c55959697960da3beb6baea47619ee5e7ce9dfed723fccb021301860408a66edc7e74761af25a34bff66c6330330c0986236a6e25e9b7bcef23edb73ead61c003af61c083ae61c083ae61c083ae61c083ae61c083ae2f788d524b31db0cfe0000000049454e44ae426082',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b27f82b-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.properties','/solution/samples/reporting/MDX_report.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d412063726f737320746162207265706f727420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520706167650d0a7469746c653d4f4c41502043726f7373746162205265706f72740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b281f3c-6757-11dd-a492-c111aa2b74dc',10,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report.xaction','/solution/samples/reporting/MDX_report.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f7265706f72742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e4d44585f7265706f72742e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e68746d6c3c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f727420747970653d22636f6e74656e74223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f7265706f72743e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c212d2d20736f6c7574696f6e2d66696c653e0a090909093c6c6f636174696f6e3e53616d706c65446174612e786d6c3c2f6c6f636174696f6e3e0a090909093c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e0a0909093c2f736f6c7574696f6e2d66696c65202d2d3e20200a2020202020203c75726c3e200a20202020202020203c6c6f636174696f6e3e73616d706c65732f7265706f7274696e672f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f75726c3e200a202020203c2f636174616c6f673e20200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a467265654d6f6e647269616e5175616472616e742e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e4f4c415020517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e50656e7461686f205265706f72743c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e20200a20202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e7422206d617070696e673d227265706f7274222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b28464d-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_de.properties','/solution/samples/reporting/MDX_report_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d44657220546162656c6c656e766572676c65696368207a6569677420646965206d6f6d656e74616e656e20756e642062756467657469657274656e20446174656e20665c753030666372206a6564652041627465696c756e6720676567656e5c7530306663626572206a6564657220526567696f6e2e2044657220426572696368742066725c753030653467742065696e656e204d6f64617269616e204f4c41502053657276657220616220756e642076657277656e646574204a467265655265706f72742c20756d206469657365205365697465207a752065727a657567656e2e0d0a7469746c653d4f4c41502043726f737374616220426572696368740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b286d5e-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_es.properties','/solution/samples/reporting/MDX_report_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d556e20696e666f726d65206465207461626c6173206372757a6164617320717565206d756573747261206c6f73206461746f732061637475616c65732079206465206661637475726163695c75303066336e206465206361646120646570617274616d656e746f2079206361646120726567695c75303066336e2e20456c20696e666f726d6520636f6e73756c746120756e207365727669646f72204f4c4150204d6f6e647269616e207920757361204a467265655265706f727420706172612067656e65726172206c6120705c753030653167696e610d0a7469746c653d496e666f726d65204f4c4150206465205461626c6173204372757a616461730d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b28946f-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_fr.properties','/solution/samples/reporting/MDX_report_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5461626c6561752063726f69735c753030453920717569206d6f6e747265206c65206275646765742070725c7530304539766973696f6e6e656c20657420725c7530304539616c69735c753030453920706f75722063686171756520645c753030453970617274656d656e742065742063686171756520725c753030453967696f6e2e204c6520726170706f727420696e746572726f676520756e2073657276657572204f4c4150204d6f6e647269616e206574207574696c697365204a467265655265706f727420706f757220675c75303045396e5c7530304539726572206c6120706167650d0a7469746c653d4f4c4150202d20446f63756d656e742061766563207461626c6561752063726f69735c75303045390d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2930b0-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_nl.properties','/solution/samples/reporting/MDX_report_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45656e2063726f737374616220726170706f7274206461742061637475656c6520656e206765627564676574746565726465206461746120766f6f7220656c6b6520616664656c696e6720696e20656c6b6520726567696f20746f6f6e742e2048657420726170706f7274206861616c742064617461206f70207569742065656e204d6f6e647269616e204f4c41502073657276657220656e206765627275696b74204a467265655265706f7274206f6d20646520706167696e612074652067656e65726572656e0d0a7469746c653d4f4c41502043726f737374616220526170706f72740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2930b1-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS.properties','/solution/samples/reporting/MDX_report_XLS.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4120737072656164736865657420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520584c532066696c652e0d0a7469746c653d4f4c41502043726f73737461622053707265616473686565740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2957c2-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS.xaction','/solution/samples/reporting/MDX_report_XLS.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f7265706f72745f584c532e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e4d44585f7265706f72742e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e786c733c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f727420747970653d22636f6e74656e74223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f7265706f72743e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c212d2d20736f6c7574696f6e2d66696c653e0a090909093c6c6f636174696f6e3e53616d706c65446174612e786d6c3c2f6c6f636174696f6e3e0a090909093c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e0a0909093c2f736f6c7574696f6e2d66696c65202d2d3e20200a2020202020203c75726c3e200a20202020202020203c6c6f636174696f6e3e73616d706c65732f7265706f7274696e672f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f75726c3e200a202020203c2f636174616c6f673e20200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e4a467265654d6f6e647269616e5175616472616e742e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e4f4c415020517565727920466f72205265706f727420446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e20200a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4a467265655265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e50656e7461686f205265706f72743c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c6461746120747970653d22726573756c742d73657422206d617070696e673d227265706f727444617461222f3e20200a20202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e7422206d617070696e673d227265706f7274222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b297ed3-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_de.properties','/solution/samples/reporting/MDX_report_XLS_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4469657365204b616c6b756c6174696f6e73746162656c6c65207a6569677420646965206d6f6d656e74616e656e20756e642062756467657469657274656e20446174656e20665c753030666372206a6564652041627465696c756e6720676567656e5c7530306663626572206a6564657220526567696f6e2e2044657220426572696368742066725c753030653467742065696e656e204d6f6e647269616e204f4c41502053657276657220616220756e642076657277656e646574204a467265655265706f72742c20756d2064696520584c5320446f6b756d656e7465207a752065727a657567656e2e0d0a7469746c653d4f4c41502043726f7373746162204b616c6b756c6174696f6e0d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b297ed4-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_es.properties','/solution/samples/reporting/MDX_report_XLS_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d556e6120686f6a6120646520635c75303065316c63756c6f20717565206d756573747261206c6f73206461746f732061637475616c65732079206465206661637475726163695c75303066336e2070617261206361646120646570617274616d656e746f2079206361646120726567695c75303066336e2e20456c20696e666f726d6520636f6e73756c746120756e207365727669646f72204d6f6e647269616e204f4c4150207920757361204a467265655265706f727420706172612067656e6572617220656c206172636869766f20584c532e0d0a7469746c653d486f6a6120646520635c75303065316c63756c6f204f4c4150206465207461626c6173206372757a616461730d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b29a5e5-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_fr.properties','/solution/samples/reporting/MDX_report_XLS_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d466575696c6c6520717569206d6f6e747265206c65206275646765742070725c7530304539766973696f6e6e656c20657420725c7530304539616c69735c753030453920706f75722063686171756520645c753030453970617274656d656e742065742063686171756520725c753030453967696f6e2e204c6520726170706f727420696e746572726f676520756e2073657276657572204f4c4150204d6f6e647269616e206574207574696c697365204a467265655265706f727420706f757220675c75303045396e5c7530304539726572206c65206669636869657220584c532e0d0a7469746c653d4f4c4150202d20466575696c6c6520457863656c2061766563207461626c6561752063726f69735c75303045390d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b29ccf6-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_nl.properties','/solution/samples/reporting/MDX_report_XLS_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45656e207370726561647368656574206469652064652061637475656c6520656e206765627564676574746565726465206461746120766f6f7220656c6b6520616664656c696e6720696e20656c6b6520726567696f20746f6f6e742e204465207370726561647368656574206861616c742064617461206f70207569742065656e204d6f6e647269616e204f4c41502073657276657220656e206765627275696b74204a467265655265706f7274206f6d2068657420584c532062657374616e642074652067656e65726572656e2e0d0a7469746c653d4f4c41502043726f73737461622053707265616473686565740d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b29ccf7-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_XLS_zh_CN.properties','/solution/samples/reporting/MDX_report_XLS_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75346530305c75346532615c75356262645c75383836385c75363633655c75373933615c75346538365c75366263665c75346532615c75386465385c75386438615c75353931615c75346532615c75353333615c75353764665c75373638345c75393065385c75393565385c75373638345c75356239655c75393634355c75353438635c75393838345c75376239375c75363537305c75363336655c75333030325c75386664395c75346532615c75363261355c75383836385c75363765355c7538626532204d6f6e647269616e204f4c4150207365727665725c75356537365c75346531345c75346637665c75373532384a467265655265706f72745c75363736355c75346561375c7537353166584c535c75363538375c75346566362e0d0a7469746c653d4f4c41505c75346561345c75353363395c75356262645c75383836380d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2a1b18-6757-11dd-a492-c111aa2b74dc',0,'6b1c3851-6757-11dd-a492-c111aa2b74dc','MDX_report_zh_CN.properties','/solution/samples/reporting/MDX_report_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75346530305c75346532615c75346561345c75353363395c75383836385c75373638345c75363261355c75383836385c75666630635c75363633655c75373933615c75346538365c75356266395c75346538655c75386465385c75386438615c75366263665c75346532615c75353333615c75353764665c75373638345c75393065385c75393565385c75373638345c75356239655c75393634355c75353438635c75393838345c75376239375c75363537305c75363336655c7533303032205c75386664395c75346532615c75363261355c75383836385c75363765355c7538626532204d6f6e647269616e204f4c4150207365727665725c75356537365c75346531345c75346637665c75373532384a467265655265706f72745c75363736355c75346561375c75373531665c75393837355c75393736320d0a7469746c653d4f4c41505c75346561345c75353363395c75383836385c75373638345c75363261355c75383836380d0a',FALSE,1214444693000,'6b1c3851-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2a1b19-6757-11dd-a492-c111aa2b74dc',0,'6b1c3852-6757-11dd-a492-c111aa2b74dc','.DS_Store','/solution/test/.DS_Store','000000014275643100001000000008000000100000000087000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000000002000000000000000200000001000010000073006f0075007200630065000000000000000000000000000000000000000000000000000000000000000000000000000000020000000b00640061007400610073006f0075007200630065007366776930626c6f6200000010000000000000000069636e76000100000000000b00640061007400610073006f00750072006300650073667773776c6f6e6700000087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000080b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000002000000001000000400000000100000080000000010000010000000001000002000000000100000400000000000000000100001000000000010000200000000001000040000000000100008000000000010001000000000001000200000000000100040000000000010008000000000001001000000000000100200000000000010040000000000001008000000000000101000000000000010200000000000001040000000000000108000000000000011000000000000001200000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000100b0000004500000087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104445344420000000100000000000000000000000000000000000000000000000200000020000000600000000000000000000000010000010000000001000002000000000100000400000000020000080000001800000000000000000100002000000000010000400000000001000080000000000100010000000000010002000000000001000400000000000100080000000000010010000000000001002000000000000100400000000000010080000000000001010000000000000102000000000000010400000000000001080000000000000110000000000000012000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',FALSE,1218380570000,'6b1c3852-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2a422a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f63-6757-11dd-a492-c111aa2b74dc','.DS_Store','/solution/test/dashboard/.DS_Store','00000001427564310000100000000800000010000000002500000000000000000000000000000000000000000000080000000800000000000000000000000000000000000000000200000000000000000000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000080b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000002000000001000000400000000100000080000000010000010000000001000002000000000100000400000000000000000100001000000000010000200000000001000040000000000100008000000000010001000000000001000200000000000100040000000000010008000000000001001000000000000100200000000000010040000000000001008000000000000101000000000000010200000000000001040000000000000108000000000000011000000000000001200000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000100b0000004500000025000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104445344420000000100000000000000000000000000000000000000000000000100000060000000000000000100000080000000010000010000000001000002000000000100000400000000020000080000001800000000000000000100002000000000010000400000000001000080000000000100010000000000010002000000000001000400000000000100080000000000010010000000000001002000000000000100400000000000010080000000000001010000000000000102000000000000010400000000000001080000000000000110000000000000012000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',FALSE,1218380623000,'6b1c5f63-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b2a422b-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f63-6757-11dd-a492-c111aa2b74dc','departments.rule.xaction','/solution/test/dashboard/departments.rule.xaction','0d0a3c616374696f6e2d73657175656e63653e0d0a0d0a093c6e616d653e6465706172746d656e74732e72756c652e78616374696f6e3c2f6e616d653e0d0a093c76657273696f6e3e313c2f76657273696f6e3e0d0a093c7469746c653e526567696f6e73206c6973743c2f7469746c653e0d0a093c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a093c646f63756d656e746174696f6e3e0d0a09093c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a09093c6465736372697074696f6e3e3c2f6465736372697074696f6e3e0d0a09093c68656c703e3c2f68656c703e0d0a09093c726573756c742d747970653e72756c653c2f726573756c742d747970653e0d0a093c2f646f63756d656e746174696f6e3e0d0a0d0a093c696e707574733e0d0a202020203c2f696e707574733e0d0a20200d0a093c6f7574707574733e0d0a09093c72756c652d726573756c7420747970653d226c697374222f3e0d0a093c2f6f7574707574733e0d0a20203c7265736f75726365732f3e0d0a20200d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020200d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a0909093c72756c652d726573756c7420747970653d226c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0d0a202020202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e6374204445504152544d454e542066726f6d205155414452414e545f41435455414c53206f72646572206279204445504152544d454e545d5d3e3c2f71756572793e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a0d0a',FALSE,1199678409000,'6b1c5f63-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b36ec5c-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','books.xml','/solution/test/datasources/books.xml','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a0d0a3c626f6f6b73746f72653e0d0a0d0a3c626f6f6b2063617465676f72793d22434f4f4b494e47223e0d0a20203c7469746c65206c616e673d22656e223e4576657279646179204974616c69616e3c2f7469746c653e0d0a20203c617574686f723e4769616461204465204c617572656e746969733c2f617574686f723e0d0a20203c796561723e323030353c2f796561723e0d0a20203c70726963653e33302e30303c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d224348494c4452454e223e0d0a20203c7469746c65206c616e673d22656e223e486172727920506f747465723c2f7469746c653e0d0a20203c617574686f723e4a204b2e20526f776c696e673c2f617574686f723e0d0a20203c796561723e323030353c2f796561723e0d0a20203c70726963653e32392e39393c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d22574542223e0d0a20203c7469746c65206c616e673d22656e223e585175657279204b69636b2053746172743c2f7469746c653e0d0a20203c617574686f723e4a616d6573204d63476f7665726e3c2f617574686f723e0d0a20203c617574686f723e50657220426f74686e65723c2f617574686f723e0d0a20203c617574686f723e4b757274204361676c653c2f617574686f723e0d0a20203c617574686f723e4a616d6573204c696e6e3c2f617574686f723e0d0a20203c617574686f723e5661696479616e617468616e204e61676172616a616e3c2f617574686f723e0d0a20203c796561723e323030333c2f796561723e0d0a20203c70726963653e34392e39393c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c626f6f6b2063617465676f72793d22574542223e0d0a20203c7469746c65206c616e673d22656e223e4c6561726e696e6720584d4c3c2f7469746c653e0d0a20203c617574686f723e4572696b20542e205261793c2f617574686f723e0d0a20203c796561723e323030333c2f796561723e0d0a20203c70726963653e33392e39353c2f70726963653e0d0a3c2f626f6f6b3e0d0a0d0a3c2f626f6f6b73746f72653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b37136d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','MDX_Datasource.xaction','/solution/test/datasources/MDX_Datasource.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4d44585f44617461736f757263652e78616374696f6e3c2f6e616d653e0a20203c7469746c653e416e204d44582044617461736f757263653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e45786572636973657320746865204d445820436f6e6e656374696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c6f7574707574733e200a202020203c72756c652d726573756c7420747970653d22726573756c742d736574222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c636174616c6f673e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f636174616c6f673e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e4d44584c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e517565727920466f72204f4c415020446174613c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c636174616c6f6720747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c747320747970653d22726573756c742d73657422206d617070696e673d2272756c652d726573756c74222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c6c6f636174696f6e3e6d6f6e647269616e3c2f6c6f636174696f6e3e20200a20202020202020203c71756572793e3c215b43444154415b77697468206d656d626572205b4d656173757265735d2e5b56617269616e63652050657263656e745d2061732027285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29272c20666f726d61745f737472696e67203d20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203e20322e30292c20227c232e3030257c7374796c653d27677265656e27222c20494966282828285b4d656173757265735d2e5b56617269616e63655d202f205b4d656173757265735d2e5b4275646765745d29202a203130302e3029203c20302e30292c20227c232e3030257c7374796c653d2772656427222c2022232e3030252229290a73656c6563742043726f73736a6f696e287b5b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b43656e7472616c5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b4561737465726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b536f75746865726e5d2c205b526567696f6e5d2e5b416c6c20526567696f6e735d2e5b5765737465726e5d7d2c207b5b4d656173757265735d2e5b41637475616c5d2c205b4d656173757265735d2e5b4275646765745d7d29204f4e20636f6c756d6e732c0a20204869657261726368697a6528556e696f6e287b5b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d7d2c205b4465706172746d656e745d2e5b416c6c204465706172746d656e74735d2e4368696c6472656e2929204f4e20726f77730a66726f6d205b5175616472616e7420416e616c797369735d5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b37618e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','query_rule.xaction','/solution/test/datasources/query_rule.xaction','0d0a3c616374696f6e2d73657175656e63653e0d0a0d0a093c6e616d653e71756572795f72756c65312e78616374696f6e3c2f6e616d653e0d0a093c76657273696f6e3e313c2f76657273696f6e3e0d0a093c7469746c653e43757272656e7420506f736974696f6e205469746c65733c2f7469746c653e0d0a093c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a093c646f63756d656e746174696f6e3e0d0a09093c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a09093c6465736372697074696f6e3e4a6176617363726970742071756572792072756c6520746573743c2f6465736372697074696f6e3e0d0a09093c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a09093c726573756c742d747970653e72756c653c2f726573756c742d747970653e0d0a093c2f646f63756d656e746174696f6e3e0d0a0d0a093c696e707574733e0d0a09093c6465707420747970653d22737472696e67223e0d0a090920203c64656661756c742d76616c75653e50726f6475637420446576656c6f706d656e743c2f64656661756c742d76616c75653e0d0a09093c2f646570743e0d0a20203c2f696e707574733e0d0a20200d0a093c6f7574707574733e0d0a09093c72756c652d726573756c7420747970653d226c697374222f3e0d0a093c2f6f7574707574733e0d0a20203c7265736f75726365732f3e0d0a20200d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6465707420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020200d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a0909093c72756c652d726573756c7420747970653d226c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0d0a202020202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420506f736974696f6e5469746c652066726f6d207175616472616e745f61637475616c73207768657265206465706172746d656e743d277b646570747d27206f7264657220627920506f736974696f6e5469746c655d5d3e3c2f71756572793e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b37618f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','SampleData.mondrian.xml','/solution/test/datasources/SampleData.mondrian.xml','3c3f786d6c2076657273696f6e3d22312e30223f3e0d0a3c536368656d61206e616d653d2253616d706c6544617461223e0d0a3c212d2d205368617265642064696d656e73696f6e73202d2d3e0d0a0d0a20203c44696d656e73696f6e206e616d653d22526567696f6e223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c20526567696f6e73223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d22526567696f6e2220636f6c756d6e3d22524547494f4e2220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a20203c44696d656e73696f6e206e616d653d224465706172746d656e74223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c204465706172746d656e7473223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d224465706172746d656e742220636f6c756d6e3d224445504152544d454e542220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a0d0a20203c44696d656e73696f6e206e616d653d22506f736974696f6e73223e0d0a202020203c48696572617263687920686173416c6c3d22747275652220616c6c4d656d6265724e616d653d22416c6c20506f736974696f6e73223e0d0a2020202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a2020202020203c4c6576656c206e616d653d22506f736974696f6e732220636f6c756d6e3d22504f534954494f4e5449544c452220756e697175654d656d626572733d2274727565222f3e0d0a202020203c2f4869657261726368793e0d0a20203c2f44696d656e73696f6e3e0d0a0d0a20203c43756265206e616d653d225175616472616e7420416e616c79736973223e0d0a202020203c5461626c65206e616d653d225155414452414e545f41435455414c53222f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d22526567696f6e2220736f757263653d22526567696f6e222f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d224465706172746d656e742220736f757263653d224465706172746d656e7422202f3e0d0a202020203c44696d656e73696f6e5573616765206e616d653d22506f736974696f6e732220736f757263653d22506f736974696f6e7322202f3e0d0a202020203c4d656173757265206e616d653d2241637475616c2220636f6c756d6e3d2241435455414c222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a202020203c4d656173757265206e616d653d224275646765742220636f6c756d6e3d22425544474554222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a202020203c4d656173757265206e616d653d2256617269616e63652220636f6c756d6e3d2256415249414e4345222061676772656761746f723d2273756d2220666f726d6174537472696e673d22232c2323232e3030222f3e0d0a3c212d2d202020203c43616c63756c617465644d656d626572206e616d653d2256617269616e63652050657263656e74222064696d656e73696f6e3d224d656173757265732220666f726d756c613d22285b4d656173757265735d2e5b56617269616e63655d2f5b4d656173757265735d2e5b4275646765745d292a31303022202f3e202d2d3e0d0a20203c2f437562653e0d0a0d0a3c2f536368656d613e0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3788a0-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','SampleDataSchema.zip','/solution/test/datasources/SampleDataSchema.zip','504b0304140008000800787535350000000000000000000000001700100053616d706c65446174612e6d6f6e647269616e2e786d6c55580c0009d1914564dd1245f601f601a5944d4fdb401086ef48fc87ede6422b1287bb0d5a628b464a4c6a3b5c50544decc1b1b46bd3fd40f0efbb8ee38f528a0af16d67fdbc33efcc68ddab67c1c9134a5554a5472f26537a75797ae2c6e90e059012047a3406f1c8d1070db4befb321e9378071233921502cb1a55643cb677a72784b87e1b3ce011e6f650a3c47eeef70225c874f74276a018e71ed5d22025c0f912c51665b8a7ec0d6948d5a2164e60cbf1a0fb63cdfc8885c94f364bd66c1153a7ff6f814fc8ffcc4fd28a1b614d46c1cdfc36a4c494c52f834d4e75a8a295709daecc7dc4753a57976f9af4f111a4b631fd19a33d7dacd9411d9d613f58b128590661728ce9376daf2a55e8e18c3ee2fa2ff8939e7b9dcef2ea369e2776cac93c590447bb9e996d5793814c42a9092b81bfa8a237fe5f95f70d5c2bc8f1d586aacac8b43fbf0f0d27dd82c3d8fbf4a0672d3c0875ec124119d9422cd50678dfe5c69d9d6d9e4bcc4157d2a3ca084a1e2a2940c75a1665eed1d1f968349a4ca7f41fb2d726cb71b0afd76bff26488e96bd03594099622f7cc7a2390b67c1c7a4f70f5e2d3f039e1a0e1ab366935ee5212bb47dac5bdf3d8b1e3d94a49a0c96f6e8d97d1bdc4cee5b78e30ca34d47365fbf5dd81aec349ad7b5decd7a15f76be93acd1b6d0fbf01504b070812e5414fd9010000c5050000504b010215031400080008007875353512e5414fd9010000c505000017000c000000000000000040a4810000000053616d706c65446174612e6d6f6e647269616e2e786d6c5558080009d1914564dd1245504b05060000000001000100510000002e0200000000',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b37afb1-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource.properties','/solution/test/datasources/XQ_Datasource.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b37fdd2-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource.xaction','/solution/test/datasources/XQ_Datasource.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e58515f44617461736f757263652e78616374696f6e3c2f6e616d653e0a20203c7469746c653e257469746c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e20200a202020203c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970653e72756c653c2f726573756c742d747970653e20200a202020203c69636f6e3e584d4c5f44617461736f757263652e706e673c2f69636f6e3e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c6f7574707574733e200a202020203c72756c652d726573756c7420747970653d22726573756c742d736574222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c646f63756d656e743e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e626f6f6b732e786d6c3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f646f63756d656e743e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e5851756572794c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d7265736f75726365733e200a20202020202020203c646f63756d656e7420747970653d227265736f75726365222f3e200a2020202020203c2f616374696f6e2d7265736f75726365733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c71756572792d726573756c7420747970653d22726573756c742d73657422206d617070696e673d2272756c652d726573756c74222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c71756572793e3c215b43444154415b2f626f6f6b73746f72652f626f6f6b5d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3824e3-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_cn.properties','/solution/test/datasources/XQ_Datasource_cn.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b636e5f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b636e5f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b384bf4-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_de.properties','/solution/test/datasources/XQ_Datasource_de.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d4469657365204e6f726d2076657277656e6465742065696e6520584d4c20416266726167652c20756d2065696e6520425c7530306663636865726c69737465207a75725c7530306663636b207a75206c69656665726e2e3c703e2044696520446174656e7175656c6c65206973742065696e20584d4c20446f6b756d656e742e0d0a7469746c653d58517565727920416266726167652065696e657220584d4c20446174656e7175656c6c650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b387305-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_es.properties','/solution/test/datasources/XQ_Datasource_es.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d45737461207265676c612075736120756e6120636f6e73756c746120584d4c2070617261206465766f6c76657220756e61204c69737461206465204c6962726f732e3c703e4c61206675656e7465206465206461746f7320657320756e20446f63756d656e746f20584d4c2e0d0a7469746c653d436f6e73756c74612058517565727920646520756e61204675656e7465206465204461746f7320584d4c0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b389a16-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_fr.properties','/solution/test/datasources/XQ_Datasource_fr.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a233c703e4c613d736f7572636520646520646f6e6ee965732065737420756e20646f63756d656e7420584d4c2e0d0a6465736372697074696f6e3d436574746520725c7530304538676c65207574696c69736520756e6520726571755c7530304541746520584d4c20706f757220657874726169726520756e65206c69737465206465206c69767265732e0d0a7469746c653d526571755c75303045417465205851756572792073757220756e6520736f7572636520646520646f6e6e5c7530304539657320584d4c0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b38c127-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_it.properties','/solution/test/datasources/XQ_Datasource_it.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b69745f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b69745f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b38e838-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_nl.properties','/solution/test/datasources/XQ_Datasource_nl.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d44657a6520726567656c206765627275696b742065656e20584d4c207175657279206f6d2065656e206c696a73742076616e20626f656b656e207465207665726b72696a67656e2e3c703e4465206461746162726f6e2069732065656e20584d4c20446f63756d656e742e0d0a7469746c653d5851756572792051756572792076616e2065656e20584d4c204461746162726f6e2e0d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b390f49-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_pt.properties','/solution/test/datasources/XQ_Datasource_pt.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5b70745f34315d20546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e3c703e546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e0d0a7469746c653d5b70745f34325d20585175657279205175657279206f6620616e20584d4c2044617461736f757263650d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b39365a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f64-6757-11dd-a492-c111aa2b74dc','XQ_Datasource_zh_CN.properties','/solution/test/datasources/XQ_Datasource_zh_CN.properties','230d0a2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a230d0a6465736372697074696f6e3d5c75386664395c75346532615c75383963345c75353231395c75346637665c7537353238584d4c5c75363765355c75386265325c75346565355c75383362375c75356639375c75346530305c75346532615c75346536365c75373638345c75353231375c75383836382e3c703e5c75363537305c75363336655c75366539305c75363632665c75346530305c7534653261584d4c5c75363538375c75363836332e0d0a7469746c653d5c75393438385c7535626639584d4c5c75363537305c75363336655c75366539305c75363765355c75386265325c75373638345851756572790d0a',FALSE,1214444691000,'6b1c5f64-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3d2dfb-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','burst.png','/solution/test/platform/burst.png','89504e470d0a1a0a0000000d4948445200000050000000500802000000017365fa0000000774494d4507d50813111f06c526f660000000097048597300002e2300002e230178a53f760000000467414d410000b18f0bfc610500003a364944415478da45bc67b025c9752696aefcadaa6b9f776d5efb1eef0d8019cc60382040d0800b924bad76978a60acb45248542842a15048bff44bfaa91f0a990d29b4ab5dad96028346f024b1188f9e9ee99eee69f35e3fefae37e5abd2e8d47d8d6577c7eb7befbb959599e79cef7c5f569ec4beeb2384149218fe43042b54fe854f30fc45b8fcab0826b4fc4422840966420a8c19c6848b02be891155445e38777663734f2a3a6d8630cd91a25022459856ab9e66188341ca0553082e341133a12d895c828444922825b58ab29b48310c17ea0ed16c5ca49cc75429c473f8068e8644d76511e0a8036da2a2a7e3ae6192289a2025cace2b051d9df61d13681cba3ded3e0c07c3b830869b6042a8aee9f0cd72c4124daf92a87c5bfe2fa743843fd55a354e5231fd0e74502152febefc1656a7d383b4f1381302eec510f531d61171a0f572500a6799d088e67a4e9890f2f6e54504be001d9344838f90664bb3a9c3ed740fd90d62fa4833a5c8cbde31e5d5cc24ca541e4197104f91148ae8988fa548f22c518a97bd2e6d86a6d63a1d242e0d05a660ace6d94996534acb0921949a9a814b2b9d8e56a9d31708b9ae2b1457a2b46a9ae667ce2e8e86a19c0e4f952da3c7d384a1c38c104b200d465b364574cac8f58bb56fbefd9465998349c28b02bef9fc5317b7760f894a0dcb5dbfb03a4919d3f5b279aacfae9e0f0b26a9a34c1f130dfea972a624d885239a64e015d2d264ade64551568e051c8e0fb00a301253039efe2907796a5fc6181804de4825b38ce3e9544c8daca8ae1bd351c06f9561c2bcf2d3f1e7790edf864660bec08f87a3706a7cf8a0b49253a9f01c2c0a7da2046b6573d42ddb6316366adf7ca6f6076f5f71067bdffbfa3a729c2f378e73a1b6f70e60704cb7ffbd77affd8ffffd3ffee7dfff284cc1351137ab71619533a857085cae99e09998990822826a187c5bf26a552b927c1c72e82f866ef00c89115109b87be966e5fc63ca4a1b623c8d3df05e743a7c54abd95922a64e5b8e869a863dfd5d79114cc874a610fabb5880ef90cbebab09b84551a8e97b986101a681c8c61a029f2494309310036b3a25a65199bbe0917ffe8bde478f924fbf38fcea257bccb5de30e31c460746b5df5e92c3c3bd63d952057fe78db3157fe168c290e660bbaac0bc9862dd414552da4babc05d90e4e938e2054c2fc784d57cddd1b322ec225510fc3860cb015322c1aa98e05f3969d95384d24c4cbdbb0ce3126f0cdd9a8e9194a684192ae1e957b13ebd08a26d300eb33c3f9d17f832050f76ec229710ab98d810698de6fcdb5fb9f2d273e717166635bdf1f191164a274c513b4277363a6f3c33ffc576980b06cd3926192572a3ab2d2d78f7b782fff43b173f3fb176fa101626f4059ac2ba09b8587a9359016fc760e7326e3900218289607a168c04e7224f4abc2026520942626a2c35c55452f56d78579a64da5b8c7e65a6e94c50135a81868d0a443f9ec275094a946853302bfdbe9c08390d6f85a70687f92c7241cbfb3188d8ebab8defbd733d9ee8e3b173b6b5f8ad372e6d0cb5e3802962c93c85a01b0679ab6175061caeb66da31feb7b23bcbe5add1e5858b89d941c8e754500eac13804694639b18451d306cb2851803b014ae2e9ed0090511a882c28ed02a821c1750bf8778a5753df54595648f9188cca4443c9e9cba99d31b5740f7e2c9ebd228b495ef0d3d08751698c0921dc8a9d832ffddd2491d34be1f7e56b0ca8e4365dff67f7b55f761b0f43ff51e0ee0cdcef3cd33888b57e446519de721cabaa4bfb636182c19413e52c0788b33d622d6c8f2d4af5f6a480d88221294d2754d319d675ba3c6b4f12f0678847510e550a62547011aa6448f8188c845805234e24bce6a7a644e871482af47738361d7619db650842c0b8b5b3ca59371a679fbcb272727432756c88162500bd307eeae9eb9d4e4f96ee51a6684dd74bf403b7b3c0fdc04575cbb24fd2da98cc2b67ce729b9ad7ec22f3f6b1f6950bb5fdb1482585e61843599a39061688667c9af5341b1933cdc66cb5662dcd590f0f2254a29d038385ee41eb4cd3b332339599f3146c2cc7128aa9b08d8a8851981ce3c2f9a5272fdac727874a40a3c52948310a774486a697883bb5c9e9387f357e4ced9957df78fb5bdffef5e7dfbf35199cecc9222e61709a62c18f0e8fbb102fd3a64adc9325aac1f5301d18d2a16198863b1b0a5f398bd4697a8d19bf55bb7eb95a6dda1b23ed42cbda1fa460b19ac79e3cef7ce3a5b91cd17637827933fc79af36d330e87ff655f3996bd5ef7f9c48666306f807b94a332b966d6b4f5daf164069c4d43630a60282aac0e343220b80a7779f9f5f5d58b9a26d7b2d636befa4f46f484590ca6419ba424a3205340a432e27ec71ce82f1d3e567ffc17ffb275f79e252ad3537f7f31bc732192a194f3379e91830bd044d6377eae7d3ffa011604b90d2b5579ebd723cc2426f4a7bceaa34abadea375eae7eef6bee73e74dddd31eb5955e48602cdf7cd25caecafef1f177bf7a6eab1374039623777dc9ada8ecf697d1f919edc70f914ef1a505779461a7e62dafbabff546f5dbcfd98bf346772cdfbd6cbf75ddbbb915ca2c42690fa6fb6b97ab4759e3e39d7877f3976f5e313e79d8064b10467e45234e51b7ecb5611b828b5f7d541a9a0d7bbd7b3be94b55fbf6c3110a4e101f61c5257a9caaa7b989d03235f053faa2191a07c42e9d83dedf39cc45d3f21c66189ee75ebb54fd9d57dc8a5562dfbb4f9887475974a4bdb2ee47e9e0f64e128dc971efd6b75e5bbf7774e058c02af8de440581fcce58cc7aece925e7ef7fb5f11ffedf2398a9b79eb57ee309c06ad13883cf79b5fe6e240e4ffefed7e63ebd35ba3554f3be0629ed5147168307dd74a832ea38c67892f1bc28ed38b56799a244c98f209b963ca2849ec7a84675627c703bfae861f6e18f7f500c1fccd48dac48cb009e46be2c51434e1b99728e72a053c763400f7ca752fff7bff5c4ef7cf5d20bd7ce5eba507ff5a9daf9054809ca317446d06295791abbbe6838b6b932ef6eee76c13d35660d226c3b6e9a8a1cb334c13e7632b7eec3ac1ac67ec8ce2ddb6f3fe334edf28e06452457731eb9df11fff477969ebb50f9f0eed872bc8db1a751cebbb789e83c71b6b171380a6318ed29312ab9bf2c333329bd9100fe6982cb53282ed392ad9bd9e4a87fd253e3cf55310ca331f8003e4d4230c0925f3c7607726a6d5a3a33a1d2b5d8d79f6adc3f4cfffa4efca32fe9c38e9952e3fc92deb419f00f9de9ffe2c3e88bdbfddbf77a1fdc9fdc7fb4f5c25a78ff20190e82d9861927c9781448dd3a6f98ae4389e717590ebdd9de4f405874997e6e5e33189ea4e483cfc7755464c390b7773bdd8926b35f6c43142759fb3e4d369598582a3b1ac500fb429512a374cd29fa9069369a927f75ca284e419b42f060192211abac8f64a6e91ae4ec52583cce45a7013c4d4a44198cbcf6fcb9efbe73ede94bb36f3cbdd013e4fe5e7e125690ee51eae479992a5b3e8ba5da3c2cd020cea2e8709457a23c4e850c032279914fcecc193b07a3f124c776bd41f0489a8e4365a18e4712c562808ccd40edf55522e82f3e0fa24e72b929bfff61d020f97b0f42c48c93203fd74c4eb6be201c4237ef0649942231e5fc68ead0d3de124c7e1593484db19a96fe0a36f75c0fe213800d6876e91525330504289de334e74e7f826f80d1c8efbf756979c9ffc9070fd324cc156ad9e6c5b38be03cbbed42127b90d130a19feef3c940dcbc1d3e61c4a837feeb7bed76d83b4fc37e1cbeac678ffa61b5616f1e1492eacc3466b07ae76b4b9380c705d9e8146798f679a1c741de1ff0a36e21264555a5956472304c6d47fbb71b11108dada35e78bc918d77100a84e454338a29be9caadb5349086f7ccf02d90079d4d0182fd3dba94f63aa11565a5c1665762ed1594e59e6af18c6d4991925ae865e7b7a7176b1facbfb3d18bc6dd2ed93ecd3fbe1c3834983b2e7d7ec7b5d4e85a20a1d1c6593b17406712d4f3d9bc70747dbc17181422feddf1aa6ef36b5bd2407ab24415e63e42b6bd5efbc557bb85bf413f1a89d2d9ae646988292ae83f02d9055a4f34ebe7b32b1746d7798df3d0a8328eb9c1c27dd07326f833f42e4f132094fc3133f1688a71e99e55336aacaf82d87aa4e59b702f160e1c7a024cb94f3d891a7ee001e8fb1cbd0da62fddd37aebefaccd9747768f2e4c26cd5ae78fd488e26d9284093284d26e9d2b26369da4e3b445cf433001c35eec5cb76b18ef7f67a3138dfb251ec04595d43b392eea771c2896bb9df5891b32edd1b17b7f7d230373525734d5e7762966629656b5efeac19e640ae30bd7d309964c5625d1ded3dc2c9269211000c9866aa7724d34a8673fdead9c1700c715ba6152030baf1facbd7c6e334cb3255a61a407e095cda7a9c654b77002e614cdda39c34680e2cf9ebaf9cbbbc54afd0e22f3e78f0cb8db6088aed2439b8d7cf27e930c93cdfcee344cff1463f9babe33c55364d2f2fd67c957f7c38f47b7d473b39570cf7c7b160b84ab2938c5fd3f39d0c8759b1dab0afd44442641e479f3f4a0c858f331ea6c96adced229de3ecc54a0a8a7023d67a31fffc30046ad1dbdf43c1ad4b672b8361df343529c5295f28b9a0c2c3f104f467a9a2c51483843a38ee01dbbff4d44bd1789c830253925a9a25f1bf0326b0a851d254c5c11b6c53fb8daf5d3c6a8f87eda14bf0c961d0cd0b65b1bd93f4242e802847820741a40a054925a74510a4ffe875fb698fafea9a47552ce3ace88f8f8eabd5ec892c1fa791e9f97bc3f125964b94b5d3ecea8c7675d69d849340d0ed7d0e4cf2200e6a683223266d9c372df9b44fdf1f028be60743981611a5996a7f6214dd79015948d56bf6601c01eb2e53ecd42f21f702b51425e8e2721453e96058ee1ffcc1dfdb7cb81d8e07e0c5a54b1360b0527a44e984f93367fff01ffed117b76f2195bff3e2da17bb838d83d1f219efc1e66041a979db08137c1c16b2a42fb8e1b983303710b7488e74f1db5f5dfec97b5b8fbae32f22f7f06084e2497fd2d9ee77e7f86889a818e3062bd65af8fad5596b943dc8d286a1afd5d9f1493f4858bf9f0380f793de0a4949de8e197fa1d67aa4dbbd51dca2221f456d8ef2ee9773f260c910b787dd30cf47204a80f78bc7ca083407bc2e0af178a10a97980cc2a3c8e34f3ef86032eacaa91c0497364f433857d06b1086d4f2677737bfb098184ce2937eb2d8b221fc77ba6157d145539b247cc136bb69a13450b6053885c0a4a0e8b5a7166e6d0e8edb415dd3d6f4ca5648781e6979af1f81b5c2966be822afe4c367bef3bc08a2f949b89125ad0a72300ea2819cc8860c36469d4c3796f920c379d5541717eb07bdb185c8c930fba23794497f297d6088ee83c9c08438b4cd3c2f3039c5abe96a8e285f4fc54f398a72c8e8b1eb969e7f9ab0a0bb4619c325a2035683438b3ceeee6ff03cf6311a1710096271ce79b4332a57f014398eb3242f1b9977ed31e063b96ea42aae5b33d91b4b2e7ad49b33489719b7a3da79435b612910d5393d858ef07c72d1a6eb6f9cbbf4e4c5ded10108c2a33c7667ec96e104e33e9f2494e2bb91c23ab946c39ec62febc63e130e300fccfbbda150592dded2f2dded7882a93ab736330e268ead91e93295ae317062d334a6d69e0e6c4a34807b60752a1a0190cad765d05aba75ba240b98edebac26e58c63d465deaae8409c75db08c23c88a569c08c66692e1389c69c2fe834cc31486fbbe2f22c78ee62edd1c31e40e32b4f5f980920be9b9fa59a86d33364e46bc86ce5941b2be7bd675eb87af3879fbcf7c5d165c4db989b4d633ed73abd6106b4240d36895a657cbe6a700ed0c248944e6211a4833512d7e46638da063e2e51beb6e4552b7465a1f2f2b5c5dffbf64b4837fbc3499a169e6bc569f67865636ae9d38102ef035b013f2c17ba20ef58bae394845107bf4d250911eda53ca0ec385120dfaefa6616cb11e7e0177373f57367e7e75b958a6dec8ed342a8f9334fbdfeeedff382feebe71d77c65b69b983c18911043384ccd8c6761686e3dd65349af5fcdab2f9d28bcf4e1eee8c364e3e9c6455108d961c28e9240a05453f8d4745764c6813dc9e09230d954fab59b6c54757c464233c8a44f008d0117110d59320690fe2e138b9b0beb2bbbdf9fbef3cb37130e8f482284a1ed38fc7d2979cae37ca53c496e5e841e150dba83010d9cc1465e8b3a9ede5544a12a9e1765eaec2bff5dcfa77bff5d473d7cf57156f60d6544c339c8c58cfbff107af7fed155b8f7e7effe4a307ddeec9681e5044a9194ce60dbd42e53e206c326822f5c6f77e6de5cddfdbf9f0b03d1ef8a6de35c88c9507b9ac0acae3f038e51352b46af38b88c2c885c9e6507e57eaebaebc7dd85659f4601c514d23a65d604b88c2f7cd738bd58a2134c3d2457a6665e6ce562f4e8aa97c20d345f7c77e7dfa9ca01c30b1ca4708a0a3c03485625c4e656fa92ee89c69d46154343f5fd52fcffbdffbeecb8e83febf9f3ffcf187f76edc6fdfdeef6f0d8379dd90399f748f1b6ab477e3e3e1ee6151c45d44b6118d535e2f178ed5f3165f54f1312196c6af2cdadbbd62e3bd8f47a393b5aab341f4953c8c74ede9abd71f3ddaa1a63b64b2824cb84a2681ee68c7c389cab3de60a8f2e251b91e8c75bf2e79d4f2c9eb4f2f5f5e727522a770223482d697e63ef9f244522d4d4a76ac6b7a893853c022d3652c045cd1a84da14bb2e5a5e5bd8313aa55441a820ad29418722908ab18f56fbe7519fcff677f79230f0549d13850d3442faa9292f9d9e2d1e69be7e207bff88bd59a1f6afc82654c98b63d89ee73d5a6eaad2246fd78ddd793acf818690ff7bb0777fe8226c74b4ec5f48d8b0ccfe1d9833cddb8b309505531b18f2c391a3955677f9c5de3e49190b3ac48d3fc51210535a8e980f4ffc6f36ba05e7ef4fea66e80bd9961d2c5f9eac1d1e1f2e2ca643c4ed2691e52c8b68d7c1251046e484108094125f14c438f8484e8a5b38bd7c711b6bc2660922415a1554d4a2fcd37ffcb3f7ef1ee5efc83f70e0f42fe28c88f33e952bca2e375475ff7ed59912d343491ca6830c0ddde0c469e86d634f4825bb9506b75b079586f2291f3c1d1a26fbdf9d2e55bdd8875c66b6f3f314be9e1bd3dc5ec4a1a75355a0d4537185fb9700e08b14ee5200c354af679e1285c64e9fd4c6abab1e6576a55746ec9bf79e7a8330cc298972be1e08f8c7a96012f5c0bdd7cd8497305241f222ace72528a61541210f896de10b802a303ffcd3966bb90d1cda5887ac80602e2ce68e2e5b5fc1ffcf6da9f7d1afee5fbe3a2b0b0e40c250e232e13dd829302b7548e45f2d2d23c37ac56d3de6b4fd438b7106e0bb91f774d36f99ae1a08c3e2062cbf518cf9f3edf98b9f5882c380eb33f7af4c53a47c1589ef03448e492249c175a3e51c349110d8f2745d3b7ecbc001dd22954cd34e72da379c11f4f82837bed973ddba638aab15f063138ee4cd51a4de2f9d92a82ccbfd438e946fd710c498b4ec148969287e9ba99149082e272414ee5e0e1d45af83ad61bd85dc14645586b67d666de78aaf2379f0cfeec4694704de6a003882c1f3149c33321c6392ab8e7bcfaceb5d66c353b9e7c7e92f6c67189058cd631f14db755af324b1ff4baab708941cf3fb30c9ee96779f3fafa8d7ff3d76a75b91a18335ffb6e4cd97cdaad033700ba2af308c9bd307181872881629e2a3521c6b9965f3de7c95160ef4dc0a67b587e3ec93a842caf369fbbbab0b6506d54cdb92ae83da3dd095fb93e7fedeab982394106194843ca518a70c148b9528fcb05106220e6b3e599cb27c2119aae0a7fbd66bdba2e7e7a27bb7b548db30c499812aee1e4cc5afdfc2c6610da93c044e6b7df7c2279b0fbf07e278a8abc48ad9ccf561ce538599a365c960613a21bad66a3e2e0c58ab6d0741fdd3ebcfaceab3b3ff808692e39ec6cfbabcb8b8b9ca5a2f7c5f5b7af8c7efcfe2cb3ef6e6e474aab69dce012d4ed80996716fce5b3b5d1edad30969f273935e9a5e59967e65b1ac91f6e1fed1ef686413c18f1e7ae2f0547e1edfde260d811d1a3efbc7aeec9b5337ffae3fba5c4a775105530ed656813f85991d8a0f9d9ff80589ee5b926d5dfbae8feed43d18bf5765cae7deb3a7bfa5ce3379ff11ab1d8dfcdc6476d2024dff98d173eba71eb6fbeec1d45792ef992ed0d29db2eb23aa2f076e19db7875b0f2eadd62f3f7bc6c3a256d541e89d79f5da173ffb65f7c1d13ce245928c8dc4bc7d2f3efcf4b9b72f25f7b6371fee69026f071107da4b29956c9f194f9d9b9969b9079fdc7f44f02147e7cfcf3e7561d10ac3de4ebbb7d5f3285170f78c8e847ee9fcecf6f6f1783c827c3b8ad9977b93572ed49e7a6afdf38d49bd86b3389e3e77b2dc8a95c0980c9fce3cff4fdcba7beeac7f69bed2157a90b35ea15f586dc5a9fd27bf361f46e2879f8f6f0e689b837a937ff8edcb1b9f1dab584c3262032b352a91669eabf8ab5ea3a5571a9e3fded8995ff4bd8b2b3b3ffd0c058967eaa4de3453a16edccf2ddb628031488f8b936cf8ea7a7de1d9f3777ff089659aed51f0458e3c06ec4d8daab36faef92d91fff2eea3896bbcf8f4ca0b97177a0f8f0f1e9d6c0e92fd301b20141bfa5e40515e9c5db69c4a6df700d043a6a994905c490504e6b75f9aed253a46c560046c04d29296d3d6f4398e459ffabdffe21b2f57df7dde630df38b9e0a339a4a369ea8b75668673b1e779314fb29b53dbff1d252ed38b347986a85336b3a315c8c75378d0310eb421c987a8f1a4eb375f9eb2f8d3edad1a86937348de2b9d79eeafef896413d150c06c978beeaf573acd16cfefa5a6156065f6ecd569d8f7a13028a91d248afbc5897205a7ebad71e69a46a699df60454eac5eb1707bb274d939e9ff166965aa0d6207cdc99a66d420a95db870353d7e2cc84bcebd7aa3980b2c9cfb6d88f3e6e4ba421622aa4c10b2c626478ecd75faabc7916521a3f37636193fcf9cf417aab772fb207fbe29301f0e72a538946750f727014d33474f1288a64ab6683c49d7895dc9b9905468d64924474d05e5d2d3ef9cb1fca04afcd37357fc6bdba103e1ad22c0dc1ffa4b6e6d5123f3da3345575f59636d83cc4cd163f2500a2d0f5ca577471eb680c821368244a1508c51661175bfe33af5cfa7ffffa567718e271be5a646f3e77e6ccb975b779ee7ffe67ff3b08078274c57cd3b66c7fd1afea9e15c73cee1c06ba61154591f39235321c0ba663679e3dbda01b0c6818dc53beb8641c2f9b076971ab9fdf38e6058f513e91c570cd504f93c2e25dcd180e4f46a8283646c2c4e49a6bc8700c3201e4f1a26611cb21fbc65a6a701381f5398a0cd7e81d26bcb5641cee32878779ea0e34fbb97913744dd5d90640cab2deeefe594dd15af3928e7e3109029179197dc77540e982a6b466bcaa69265b07cfcc783d4675a0be61dafbf2649149df162f5d59bb7373ab4e2abdd08a31a47692aa6cb6925cbdb8fc706b405594f10c8b504ac3718c38113c0be96ffdd17fde748828d314dee8f09fde0cec24b9f1b093076d14ef35b2bdabb86b89411775daf9310c1e87a3055ae8b868685c6519e3a0fe91656860a88378d40d46a218b61cac8ba2b1d612bd6474675f25a16660a52366620bc84e18386b756ebbc5de51ab6e49952cf95ed540eff72632cb5618ab2a16731160b4a96473a592f074388974490fc77190e527481558da068d79fedaf3d77efae9f6204475ac164cd311939c6048a788c74d5f5b596e3cd8ed033984e82dca07115a2919eb2ffd9385ba8619da1ff01fdc0cbb87493006b80f308fd6c55125ef3d8826110aaf5e681ab2b328219f13365f6148b4c338e4dc617ac8d898e799a19b15bb6b5452cb1e01f3ab99d69cbb77f36e01542c8a49513e43b41c9d7a9a050a70d1cb8e3b86254d072ff8d576186c9f0ceabadd0bf96e9c6f8302916a916a4b75880a0fa026cc08f29a87bdf880134504906d0eea93b1865168cdc51bf7fac34274b3b440a4652509f4aa62ecf7f9ac2bd75761cc432520156ba01f946652f7e21fdd38c88078fdec4e7cf75e8427f1ee4964f0f8ac8a4e92763b1a22991a54c4e3ce0ba6240bcdb35e25d9eae541565546ace9e36a0d7e5d6db68aca0c00dbb57aa5a568cbf1bc5655a5080d84a59b76b5a6982e41c76826b0750d0861ab5af1e4c2b7bfd97cee7995f64867ac2b4b773d8b699e5d5d76eb79017994630b258877f20c58b54f657f63ef9286cf3955cbb57caa6c8c9351fadab367376f6db94ad53597d322a2f6e20c95122571360e93a52aad35fcdda301c22ed02f209aac731c263d2d89c58bcbfa4e988cc78583f22a1f6f1443298bf2510bc8ad22ffcaaab3b8eefed9478f7e398e9628e266855935a2193584eb5a8586c10c1b24a1dc57acdea84b40259fc20785eb10c3a68e611a78703ca6d904552a82cbf828a8cc235af1b1395384e33161513ee8737e28cd431425e360a55a1f287b0367b5b4a011bf7869ee58908f32c164f1b5eb8bf6f07098a9c2a51b9df8e96462aed66fddca149857972d5e5c9f7136bbf1602ca547bfd8eafdfa6b674ffa8b07ed6c92082c87b472e60f12b8dbb878707f24e3dc62c31aee6c77b770da51f190f021a0f4b7cf372ebdbafebffce8f36a220ac358b4ab15cd0e25723506913ce1c500dc189b155d519b66419fe9598af393ed313351d0ed64fb7be54a6c6fe22e56a8ad656181f208c215f06a70ebe7fdcf3be391e84e123a89d64cb45cf3665c0b849fc68995e7382e3284676ad6b2eb1eeef507b908a2e1582a00da0ac639d3f4a85f995bb979ef50622bce27c25295aa9e0db28a6377c3dc60e53afd2bd7163fb8d5a53a9352076e1fab4289825654da0d429a9d58bc7d263fb08bb1a1a53ac9963de3abafccffe8471f5f2b04a17ac115596eee77ba1ed3304f3ba96ca1d44adb23916d98d675bf8afc0a99b1774e423a19fa2462b916528bc54847dc589bd9bbb1559ba9c821cf99c76e1eee0e7be944aa903976b5a7c9cd93a1eaa6beef3a9ed94bf98e6028156717c05bcc31222e362eea7ca1626f45bc4f64dda636d1b7bbd14a5594ebf118d880722ba83d109d445b728c2c4d68cd391e6babf5c9b50bad4fef76b992f4ec93bf03e803b22a0f0eed74e74ab6b7907724822988b94c6cc6bff3e6c2bffab77787a382275947aa8ac6d0b803d3a425a9968cea22057dde056de7b608270d9ee67254859cd29e688216106dba81f338cc07eec5d660cc49222b355fb94d1a0de2a3fe6e926f76c72b6e254a69c8953e37df0b937014678c5d99f50d646f49aeb57ca9d30ad337774700b45d0cda9d3408ce11aa6a3a76bd7e273c89f4c6ac9f26c94c531f4ea04f457b9c832aa9d5ccc3f664aeae5d3ddbf8e8ce09a8686691441563557067f26545060f044a80a0e52191a2c2d8f7de59ff6737eeeef58b852c6d33b9ec1a0e8d2c8bac7b4e3a2ab44046d474ab2d2b9b38c921e4489012d46da6d8f12ae58e3c331820aada613273718e34962a7737d99939642f727d2e79f8b0dd8e1307d7165bc79d74d5adec8e049bf0957a2b9c2dcc71f6e06028a8f975df2fa41a24c9f1681454ec4cb2999c48a318189921f0f58a73fb70d82f2015246a1cd65ce875298c8a82732e28d5c6110fc36ca733599f776dbd88418404d68b0ab044a649d4898b384f03553e584bb1487ff312db1c0f1eee0e573117482c1ac6322b166ceddad5352c716cea56135487d55441184d6ad86a394ecd37918fdc8a490efaa33c0c9294323a70679eb8765e6eb71996def5278e77c6cbbff53b479f7f89e3768ef020a41f4f0072d9a2aff591ce86905f9d9ba996295a6968b726e94addf039d9d81d81b4589eabdc3be9c94cf8d52ad7bd2f8e83798ac24876c344d3a965b17aad1647f1242a772954abc6380457d71b35aaf164f328033d4d8dd6cb8ae7b2c851da5339c00120738e5551a793069d24ede00c803c61305d4e45cdfa64e199f378e1e27118dbaee6f3c91289971a5eade2fbbec27904737ce5379feffdcd5d4485a1e14ea1198d853995d98b46bc755239732e8db2e2e020fcf0b3a383db45901ca56a97eb138440a07a3906fdf001775c9cf785f120904babf58b4d7710e5a304ed26cce7eaf575f7d1182598581596657127d09d9693f792b4e0446779212641360a5121344290699a9380dbb651a28de2db477212a654afbd88788a6542921e46021383cad824d1db4fcc0fdac17ea68e256917685c1480d0afbd76d1f1ace1c11ea49262d017bd9125ec6c90322dc1051f0ca3a597af460f8ee35e34c8735eab56d75a4b38b79f588a1f9c14d88891934e8e3a9da19507fd34d725914036ac0ac9500e39da2eb3f413e7cff86f7ddbdbbcbf2f5191d1a50b754faafdddf176acfad24c62f5dd37961f1ce67aa51e47c9689cced5adcf0fe20a6231485ec3b00c126582735aae461356e4c2f74d298563d3a35e0aac8b9af51719853ba7286e2b254d4da07cd042e16e7ff8282c810b38804e8a97cebafff89b9725d53ffd6cbfdc8d303a9915c582a61b796eda342864d409ce5d5df1179a47f7f7efa4e9c8f01693c21322f5f4d69cdbdde9606ce73a2b5854a9d3ae04a6dab71c137b4ecdae7692f456c22a7efdedb75f79f677bf4591f9feadfb2b94f6cca6efd97fb34b161667612ec69322a1facb671b8e668d121672d3602a2be86004bee146710121930b76f16c1524540ab2212b14d66d8b546d9e66e8b85beed0a59a7b5d65a14ada448d91c2a2483c97e514f5212a286f0267ae1adffaca19803b4ee87bfbb8d6b43eb9bd8ba2bc9e01cfcc0dcc4c5783f60c4d5bfedad307376fef0dc28a619e21d86858c66acd338071f31cf29d6df8155e24a14bf4116658e5a9c2dba9ec2662898b632e41bf5dbe76554f4637fef59feec72162fee27c4d08636fa0ddecd077d6ab56dd420524bbf8c957cedfbdd399849a57d5bbc334ce88028204e903a98493762fbf76b6566bd69c7a0bbca0daa8ced4d8fe89c0a659c411d59d4b04719c75c0c852e5145cb388c07f09065648cecedadffad6b39f7f7950f36cea379360f2f0eed6a2ae9e017838df8801732afaf161b80f7af0d9331b879da3de10724653b7fd9633ffca3972dc37966a3c2ca8a7fb3e1b0ad1e984b39eb5a3a495f2a3b11a2a96eb98b8da12640bc3bfb9371edfdb064e7910e0ada258f3bd90e97c9277b1bf33f157abeeec1927e88c5fbb3efbf3edc8e1a25923f7f641f5d0f2f142f90801f3728b373b1e64971634df353be382216919f4a023b2b87c7e420dfb0c2e4606ca6d1517124836e88d1c48a5639227ce365f7969fd5ffce01692fcf7bef3f2a3bbdbf7bfdc4f83e27cacaacb8dc8d021051f7422c3335796ed33cf9e3b7eb4e34270205b5946ed424dee0fa334309657505ad42e35cda6bdbd13372be697dbc1df6ef7e689365ba51507d7abe698b3ba690f59d564761fe0165b3bb25e69ccf68ef3e595c6cff7450b6907520b91018af8992bfe5ccbf072f1f961bc6892cd9e986e7ca5d33dc4a02949f9140089839e78fdc966ad6a6659d21df32c27b42c5910d470ce520eb439ccd5e99336c118761df3d5ebadf36766fecfbfbc8378f1c7ef5cf9db3b9d1f7db0a14bf60c805ac3baf2e6d5687ff4a09fdb88572cba38efbcffc92e9ee4cca8d88ec39aa6787832088bda5bef1879e45fbbec5e5ce5043ffc72b7058ebd7e764e45dd89424eebd6908fc6d9b0b58286d1443346d46964854e6a96e91f23bb27ccabcb331b3d4e29519a516df8612c78c15e3e63e98b33e9d64910a6228d039e23aa51cd02e6028e0946049aae081da7e8b75e996d87a2dd06d3943b73213b53cb6880e73b28d331e45f00f3d2999fbfe02d2e36fef58fef732eaf9e9f015df7d3f7bef4117e9d9103ac5e78e789fec3de070f7a411a6229001b4027b6c71c3127d02d6c33f508862379533fb3e84b0b379eff8ab6fcf668e716cac5703bfb706337177aca498cfd835cc3313f58ba54d78d87b1d7b7e7ac448b85e957eb6de47995fa4ccde6d4f86c84d628da8d7821b50bcb5e6f205fb856fdc956a6f5263ee7fbdc9a6e49624c27baa197299822c37660e426ca7ffd95a5bffab0ab9b46543e3fc77465be95447dd03fa9ca914a35aa2e2ebbafbe78fefffacb3b1957f30dfb1bafadff9b1fdeaa28f43553df92d25a9ff775e7279f6c4722a642b688f4ab2cccd17cb531bbe8ba15dddb1b8d94e20ece52cbf51d14a7b699114d88938796be9074469d22b1429e7b3ec15ae0cd3a26b5ad19ddac259546643540f886c4d7ab6ea84ce657a13f9e45ef04966d9a234e11c6cb0dbde6697631a8b61a7f7a279d27a92e8a3171393104e08f28eb0730d32b36836b7c97b42868f51a7835b02c4580f8496bba6f404e1f978baa43fff8779ffb5fbf7f334a0a8da9dffbe6f5ffe7c7b7eb76e502520f38ef58da9ffcfe2b9ffef4262659cb22cb1660231d496a2ae310316ce8d983218ad00321126e784046342d3ae88a34480eb7c1697bf7b63b39e912dfe2229b59c26e1dfc4d2dae1d0f62e62dd6eb733948a05c998e236afe8aa17d19a19459cde5e68934b86612566ef4c702bd76d93f3e4e1fec8d5617b58f8fa039dfc76a820dc8eae5e66abd2ca8715c1bcca913de1e45d7ced4bf3ce251b9ed9250d39c45a898960d0870e857cf557ef1f9c1f12085f7bff6e299fd5ebabfd36f2669bb9085c5fea3df7d6ee351f7e347032032c34cdce81583a2dc99df6ccdacb4a8bb3bd2b9f1a3cc38c82ab3666d69c1df7bb0bb72e1ecadc3442056ad55a3a37823c5ed80250b175c51b85e7d62f9561ae3e5f3a338d7cd3a9e9d03d9d6c4782f262ed5b0695b731565990b2d77f3382f69826d4829571c8c4deb877772805fd727e930df136c89e5132e0475c0b589ae83913d471ba67a21f0faac763c41837eacc30596335fee4a9b96791814655c6ef520af91a66f7ce5c50b3ffdf0d8e7458af24423bff1e6b533beb972f1f5cbab6b7ffee9bd9d50ad52b950a59ae95c5fb5f8d6389be8ff32a8c408bf36dbccdd059ec8868d42c4a906798f5690a3359b27c2194c9251a232677664d4ed9ad7208cf8b3ed24f597cea75161cf5499d2ba36a85add3a539d5bf5cc8afd9ffcd66a3fc147dd22cba4abb3609cbd7cc9fb9b87493fd1af40a28ad2344a3b859a5749a4b06486691a4596fa6eb9d7324ed48c8bfcaab7dfcb153017b7ba2c815a96bb43a4ad934122a682437dfbf9b907fddaeffea3fff8e79fdd71417fcf59575bf6d6601cb7a36b4f3f7f3cceeae1c113cb9531f59fb950bdf1d9c92aaffc286291e2ef5e6e6e8652525fc7dab5e7e7debb737c697dd66ed4470f0f787dee5e8fd1dafcc86c686e2d8424b37a51fa6e350ce8ec9cee78aec10aa7d2ac99c8b5aca5caa56beea57963180807891f7ed0ebf726419cb63c2392da8cc695696f0fd028c8ceaf5477873c4de384e88b240bc15b35c7d678011087139d16269f9c5dd43ffaecd0d008b5aa57a65bef042592e97a9a0a706f0b642625770f24d0e3a3dd7b7134fafd77aebe7ffff8deeee0c37b07cb0b4b941195b57795b7ba56eb3cec6913712ce881645f99679f0546ca9c73eeecb58bcb3b051944e1f995994aa5015cfe8bcdd1f0b06f316b74f60a40a46d589071802e51cd6655cf35dd202546dd92984618bff982f7d533f6524d6b5649ff68f2834ffa4c531c51a09305cf8a427be592f5de46c6858ce3fca98bb5479dbcd479329f71cc71b9d6086404a4509c25d142957b5a71f3e138cf386d3ef3473c8d65912a5e42f474cbad5caeeb1b6d1544e1d1c12696d9f72ef9370f063a958ff6c654e69b1bf7b3a4131be65cdd49a222db1932a39a60fd52d3fa65d41871f464a3593e643e53fdfeadec8975779e04bde32868343a8136664d9c674769beb0beae7bcd0203d780f4531d61cb66bae35afe62651ca1f979e3a515c3d5cbe43907dadfd27ef22033759ae56a141416ca86e3f16b67c8870f2720632771b1de92519206a36156e43e2e30434266907a94ca8b022fcfb0d138dcede4af7cfd65f23ffc37dfb9fcfa77ede61a617e9697c217707d920ad01cf06d24b23526b222190ec234cd3524750d635773672a3ce597cecf7cf165682337b4cc998673583dbf8f669e5d5b4a88bb549fbb9bd7123c37539d47eef2c4a81eb671e0da8386a7d69e5e76e70ec7a9d568390b337ecb377c6766a6babc5a39bb68d62c4d8225b3f24941b9ed84b0849795431068e358fa15068200b1929c6d1ca4eb0b7ac5224ce5b7768a6f3c3d8b4c5fe9d661a166b3714932b2b4c814a30838733f861840a2b7472eafd8bffdee65d5785a3a6bca68968584988d22312d27512d220c0b7f7494689636048948f482195f7d6ab5bb37faad779fff9fbebf5311fabe5199f7661e69f337dada1317ce0464b9ce2a17de79698f83012dcf6e8e79b5d274beb8d5a1399f7402554cb47ad5f2bc244e1c1f82d5acb62a17e6ede756dc67cfb9b656566a0276bebf957c762c37bafc97f7420f7322b84af37e2f7ebca79498ed505e98a361102540a3703c1e0e5e7a66195596adfae288da0e978c00a38430cef22489f3088becc6179beca89dfdf0a78f78f7218af6251f2159eedb118a11c66c9943daeb2a0214fce21afbec24ce31f9edaf5e7c78fbe037de7af2a7370e269171d5d349dd8eaaaddb5bfaea8cd9b0d45e1faf37ecfdfdd1ce7131e3ebac523d1953bdd272175b6d64683239e8723d38f1d77570dcd9ba3e63512a54a3ae1fc7529a2ce8454d5f170ac22769f70b9f7033c85e9eb56b3622898a5251a54904940b2049e0334d07246091c7418436bbc50bebe8868cc230cda8b334eff447239c15b643c7218a4b8745455ed00ff6d6b76ebf4f932d998f18053d21ca6203d3fdc37ff84ff3b4d8edb50b51981a035f3a18a46f3cb3d60f2524d8ec38fcfe474775461cddf7ce2fa5c9dc11a76f3c3977734bd944831cd458a9fcf4be78f5b26d49a5bbd647db72c1a51f1c144d5d0f9c1a71aa580089e0d59a7b65415bf4f5959a21cbfda8409a31643144c848e0ee4954e1021772d5131fdd0ffb9d88278141c43018eb949fa924e9b0f7d9217c9979158b194ed3c693ac24e740390220569a9e2759c5ce81e668940cc71155820c1ffe080d6e30d9531cf007265909456bf5995ffbfa33979e7e96606214c2af68410ce4c76ed41c4df24a3ff9ab1b3b351d7922eb6ac2a36a6b10ac35967b4323548d81b194551bef3fe2709ff90a0e22e5d7b45e0f694d608b46ccec510ab8c813d3b6cb2568ec943ab42c4d9ab3d9aa47afcc92afacd96127ee3d1a84ed7802241422314a57672d10b04d0da5499c8268988cd33cd83be95934aa3a65f5f524481f9ef073400c1855c01b44148f02a2620dde8441968c6d2d4172c448b2a3e148275aa4b2d32a7009b17df2e8bffaafffbbf6d18e1210fea84590d2ab6f3fd5bafbe0e8ca52e3f84ebb935744b98198bc78a1716b937699f76b0bee7b077840a954daf973d6bffc38b24ce57ad66e3faf1393d8401889d064a0310e37ab1bb333f67a9d2d58f2e6bd93951abb76f5acad1140a08351fed956328cc032241fc49ded2e3165c7664bb57a2cb4a79ada7040f07842551ac4e62866a02ee79b95ad836e554fda9d98151a2946a01f0cbde022d271184e32c8419330cab3b268921131ca84c8d2187090ea5ab91f11045021361edcc08a10220dcb28a2dcc4c3a37dba96a1dd1b7b3b05cb013c55f5e519f7fe211b87a2d914fd0cf70a0d997ab56675531c33c3354cc0c67126767ab8de60c01fc2a80014188579ae65db297f7d851ad2381a25450ced172d8f3417568fbbc97e27ecf772c89f613401e2a8e2d1bd9d7c65a94ff2f18a6dbdb7cd41c66b9a35188e47e36e27412bcda5aa9ddb7298213e9c28cc39e2e31080974786299224d7410ae7a87c7284152b2b379198ee4544be63c4a01c9596a7d9f40880b2a40d526191f12590eabbbd0f127c899250b08093791380d3f8b26f57add65335f728942b6b6e2fa67ff8edd69f7f16d7ea146efcd909320c6bff04cd79663757484f38a40956961173cdf9c9966a6d6e0770df451b481f96da4f7ef6f9dda89943be8e0baa1b0459713a1ef2c0cdb2758fc7c393a8e38a44d58d1c0682b32c48384ac23b9ff5b824ee72b96f258451837c20c04da20b17a08ff1f6f68182a850625a398f1930e5c795e418f781eb4db71b4f0bf104681388fe34c9ea269161d22fca7af08da252d6e8a7de936ee5e711b36aaeeed4e71af51b5d94f6b2272e35bef274c569e8ffc75f8d3425fa0ad9041de4a8a5b34e2204d2b0ad95eb48a18004e36915ddb60efb81531c7eb6135f5dad4c7ad1fece8396eece79d6ed1d3a63799b03cbf66642d50bb60e7c1ad4689af602c831b39ec61d0f7816487f2058b2c886dda4338054a4f3b40f6409b8633a6c9f4cfabcc81caf1a7350e8654d259beeb115423d2e2c96a7f56a20c278b93d938284426a1eb03bcdef70f46cddbc39e610a60bbaf4171be101b595f65285ec47f420504ccbad3cfbdf7e323e1c8842c85acd6c475259a48290d164c727b151f3c234cf0919c4f1fe30a9dbaad2129b9be31919f615b5f2e385f3cdfd9fddae2f548ff78371d46cce37b1046d608445e572a28ffbfc80752a224446bed2308f8f1eaa09c0083b7b65b67732704dad2b469217e52908942911ef9f0c60d840829fb87ae6a39b77833039dd3e7b5aae5afeb46d2b4d5234ad6293c06728a186ed659125e4a792828183499a726672f99427fff4fe31aa9c8b94ee307c37280f1a7035e233fce79f044baea674f6da53de8f3793b939ad6593f52af93cc0c32d450dad184631c7694ed6ea5aa7330492880be57b6c9c383ff9db76a7976f98f99299647bef17dec56632deef2f13b604249b1a711804162571d4d9df0897ce2e1cf64e88500fee8560b73866029811485d95138c0a199d161c82d0ffc57bbfcc4f0bb7caaaf2e92116a7dbe509a1a7271b70355d0d509247a1af9303444ea44e4f2bb1a9ef4aba13d104b9c4ae036b00c9be5b94d522f3beb9315218087a4503b0fce166e2d7d9cb67f5ab356c50e2bbf45fe968eba850a30411adc08061fca413e40075853047f95f7d7910940bced6c1717cc61f4246a5e37d1107eaf02ec16ea2a17acc3a3835041f436ac2d9c1d636d0a4b2de58b701b293ac1c928ea76b57393f2d963c3da48397b9564c2b3115639a3e2d03296b23d2386cd4bcfe288456aabe9384c04fa48fd103c932c93c864350384e734dd14f73a25821a2beaa9e3f2cac04e68a8b2a925b21b2349650401c2a0c727d495bf791af97fb78cfd7d11bd7ed6e10760d266210e9b2868a092f2b688cfe6442ab194f655e24613692b8c8b36c34eab7f3d5b53393ce21a8826d061cb1dc5747cba7bbc0af793b2c41154c3319a565a1d269017f59098a0d430ba31289a725fd10bbe4f4188bd2799f79e27cbd5629c75eaef4a8c13028e318481e2d8bb918301ec42602526ee91b4301823a1a0b95301b5113c98253f64859a7f5ab452a26b984f8a140c7295e696a2b1e31a93a3df803c264b1a21a40c42c8894726734ef24a3546742d6636d67203aa19d655444bd603491dce2d2d9deed1f6f3eea8fd32c0f375024515400f6e44179c048792c01fc2c50b969e557a7ad94c71f08a6017172cbb153623b0646449e9e39723ae04f6edeed0f46e8715d7479d207a6d8acf8ed5e5814ca66f898abd38ae3045913642f31ba09682d012d601628117928a75bd1416321cd675a31dd8a3a4ee4de487d72a28ea2b2b80f62249718e8d7bdbd74a6dcd4a414a07f67d81b8f749132d9bd73723001f59a64404c64dacd2613486041aef34e2fcbf24cc9c8000d5e24aa001415aaac931702fa41c4b44e6b7a70ccb472091a01589c7618ccdfaab98f8f01785cdc5496f100db45f5869726b93a2df780b68a7c3a27aa4ed04496db709532a68522e62249f769c399bb90979bdc88667a5ecd8d73a25323d71886fe121c109a62ca0dda4fc4ce3187645948f4b75bf293fbf151271b8cf2f27c852c7578b603161171d1ef6e45bdbce0a96249d887d9aff0e430eee7421842f60b51f18d93de8873319a06248c3f2fcf033aad5899e650f5b852f2f42c99c9242204bff0eaf33b5bbbe5490ee5a6f8c7272040acd621a2cbe35c280516cecb4a535c64c5b466a03c592357b6a27ae902a40203d4a999b02ab25b30576555a6ee28706fab4540ae576ad436a9015f618ea7d39a4e94b432c812a8e9b3c37e918cf3f12011d34db82a9ee01426b3b40a1e6f4e4f2aca10f350b00559949569e5188908534b01e78554a392d281cba266323d03a8d0ca078410541cfdbb00458f2b974ecb5a80fc4fc214ec3cd37406a3043c24cf04354ddb32282f0fc4284f3a115c9c16804c8b7c1847007b5a793f2021e50c32ce5ca4594aab12c567ea005d6e0e735eeedbb43133ca0a91b24eaa048af290208d4c463c1c65ed6e3c3a0e61a43ccb449aa9a2903c57797950922a620867c809334d5de4c9f28c9c8c46d08ca5e78ce594809961380565d32317f0f4bc89e9e884e4538f24bf2af027d3f2c95f9d6e302d309d1e384480d24e43609a96e0f7f039502868a962b3b0045cb33c6aa93c10649ac6c8b48c8b9a0a3160104ad3b1a643f281dff5c6caa99567c230d394840015847c000d49ae6af36c3048a1a922c86452ae3ec83457a70e974660799c0fa785cc1a5690ca3851e1b013c2b44e4681a641548292c955199390e005e44b40c11c2e663a12539208324eb7f3b2aefcb1633f2e4ac38f6b78907a5c2ead1b5a9ef3c7e71e60fcff03e53ba0e76351d11f0000000049454e44ae426082',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3da32c-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','BurstingHTMLTest.xaction','/solution/test/platform/BurstingHTMLTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0d0a3c616374696f6e2d73657175656e63653e200d0a20203c6e616d653e4275727374696e6748544d4c546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e4275727374696e67205465737420313c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e200d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e20200d0a202020203c6465736372697074696f6e3e4275727374696e672072756c6520746573742073656e64696e672048544d4c204174746163686d656e743c2f6465736372697074696f6e3e20200d0a202020203c68656c703e546869732062616420626f7920746573747320746865206162696c69747920746f206c6f6f7020616e642062757273742048544d4c3c2f68656c703e20200d0a202020203c69636f6e3e62757273742e706e673c2f69636f6e3e20200d0a202020203c726573756c742d747970653e7265706f72743c2f726573756c742d747970653e200d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e200d0a202020203c6f75747075742d7479706520747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e68746d6c3c2f64656661756c742d76616c75653e20200d0a2020202020203c736f75726365733e200d0a20202020202020203c726571756573743e747970653c2f726571756573743e200d0a2020202020203c2f736f75726365733e200d0a202020203c2f6f75747075742d747970653e20200d0a202020203c746f20747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200d0a202020203c2f746f3e20200d0a202020203c66726f6d20747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200d0a202020203c2f66726f6d3e20200d0a202020203c7375626a65637420747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e427572737420546573743c2f64656661756c742d76616c75653e20200d0a2020202020203c736f75726365733e200d0a20202020202020203c726571756573743e656d61696c2d7375626a6563743c2f726571756573743e200d0a2020202020203c2f736f75726365733e200d0a202020203c2f7375626a6563743e20200d0a202020203c61747461636820747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e7265706f72742d6f75747075743c2f64656661756c742d76616c75653e200d0a202020203c2f6174746163683e20200d0a202020203c6174746163682d6e616d6520747970653d22737472696e67223e200d0a2020202020203c64656661756c742d76616c75653e7265706f72742e68746d6c3c2f64656661756c742d76616c75653e200d0a202020203c2f6174746163682d6e616d653e20200d0a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20203c2f696e707574733e0d0a0d0a20203c6f7574707574733e200d0a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20203c2f6f7574707574733e0d0a0d0a20203c7265736f75726365733e200d0a202020203c7265706f72742d646566696e6974696f6e3e200d0a2020202020203c736f6c7574696f6e2d66696c653e200d0a20202020202020203c6c6f636174696f6e3e2f7265706f7274696e672f7175616472616e742d6275646765742d666f722d726567696f6e2d616e642d646570742d6873716c2e72707464657369676e3c2f6c6f636174696f6e3e20200d0a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200d0a2020202020203c2f736f6c7574696f6e2d66696c653e200d0a202020203c2f7265706f72742d646566696e6974696f6e3e200d0a20203c2f7265736f75726365733e0d0a20200d0a20203c616374696f6e733e200d0a202020203c616374696f6e2d646566696e6974696f6e3e200d0a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0d0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0d0a2020202020203c616374696f6e2d6f7574707574733e200d0a20202020202020203c72756c652d726573756c7420747970653d226c697374222f3e20200d0a20202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a20202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200d0a20202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420526567696f6e2c204465706172746d656e742066726f6d205155414452414e545f41435455414c5320776865726520526567696f6e3d275765737465726e275d5d3e3c2f71756572793e200d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a202020203c616374696f6e73206c6f6f702d6f6e3d2272756c652d726573756c74223e200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e636f6d706f6e656e742e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e200d0a202020202020202020203c6d6573736167652d68746d6c20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020202020202020203c746573743e666f726d61743c2f746573743e20200d0a202020202020202020203c70313e203c215b43444154415b0d0a0909202020203c68746d6c3e3c626f64793e3c7370616e207374796c653d22666f6e742d66616d696c793a7461686f6d612c617269656c3b636f6c6f723a233030303038303b666f6e742d7765696768743a626f6c64223e0d0a0909202020202048692c3c703e4865726520697320746865207265706f727420796f752072657175657374656420666f72207b307d20696e20746865207b317d20726567696f6e2e3c2f703e0d0a090920202020203c2f7370616e3e3c2f626f64793e3c2f68746d6c3e0d0a090920205d5d3e203c2f70313e20200d0a202020202020202020203c70323e4445504152544d454e543c2f70323e20200d0a202020202020202020203c70333e524547494f4e3c2f70333e20200d0a202020202020202020203c6e65776e616d653e6d6573736167652d68746d6c3c2f6e65776e616d653e200d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e47656e6572617465204d6573736167653c2f616374696f6e2d6e616d653e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c6d6573736167652d68746d6c20747970653d22737472696e67223e200d0a20202020202020203c64656661756c742d76616c75652f3e200d0a2020202020203c2f6d6573736167652d68746d6c3e20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574732f3e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200d0a202020202020202020203c746573743e7072696e74323c2f746573743e20200d0a202020202020202020203c70313e524547494f4e3c2f70313e20200d0a202020202020202020203c70323e4445504152544d454e543c2f70323e200d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5072696e742069743c2f616374696f6e2d6e616d653e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e424952545265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e7265706f72743c2f616374696f6e2d747970653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e20200d0a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e20200d0a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d7265736f75726365733e0d0a202020202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e0d0a20202020202020203c2f616374696f6e2d7265736f75726365733e0d0a20202020202020203c616374696f6e2d6f7574707574733e200d0a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20200d0a2020202020203c616374696f6e2d646566696e6974696f6e3e200d0a20202020202020203c636f6d706f6e656e742d6e616d653e456d61696c436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e656d61696c3c2f616374696f6e2d747970653e0d0a20202020202020203c616374696f6e2d696e707574733e200d0a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e20200d0a202020202020202020203c746f20747970653d22737472696e67222f3e20200d0a202020202020202020203c7375626a65637420747970653d22737472696e67222f3e20200d0a202020202020202020203c66726f6d20747970653d22737472696e67222f3e20200d0a202020202020202020203c6d6573736167652d68746d6c20747970653d22737472696e67222f3e20200d0a202020202020202020203c61747461636820747970653d22737472696e67222f3e20200d0a202020202020202020203c6174746163682d6e616d6520747970653d22737472696e67222f3e200d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a200d0a202020203c2f616374696f6e733e0d0a200d0a20203c2f616374696f6e733e200d0a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3dca3d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','BurstingTest.xaction','/solution/test/platform/BurstingTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e4275727374696e67546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e4275727374696e67205465737420313c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e4275727374696e672072756c6520746573743c2f6465736372697074696f6e3e20200a202020203c68656c703e546869732062616420626f7920746573747320746865206162696c69747920746f206c6f6f7020616e642062757273743c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c6f75747075742d7479706520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7064663c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e747970653c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f6f75747075742d747970653e20200a202020203c746f20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200a202020203c2f746f3e20200a202020203c66726f6d20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e726d616e736f6f724070656e7461686f2e6f72673c2f64656661756c742d76616c75653e200a202020203c2f66726f6d3e20200a202020203c7375626a65637420747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e427572737420546573743c2f64656661756c742d76616c75653e20200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e656d61696c2d7375626a6563743c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f7375626a6563743e20200a202020203c6d6573736167652d706c61696e20747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e5468697320656d61696c20776173206175746f6d61746963616c6c792067656e65726174656420627920612077686f6c652068656170206f66206e6f6f646c652d636f646528746d292e204e6f7420737572652077687920697420776f726b73202d20627574206865792077686f206b6e6f77732077687920616e797468696e6720776f726b73202d2072696768743f3c2f64656661756c742d76616c75653e200a202020203c2f6d6573736167652d706c61696e3e20200a202020203c61747461636820747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7265706f72742d6f75747075743c2f64656661756c742d76616c75653e200a202020203c2f6174746163683e20200a202020203c6174746163682d6e616d6520747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e7265706f72742e7064663c2f64656661756c742d76616c75653e200a202020203c2f6174746163682d6e616d653e20200a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365733e200a202020203c7265706f72742d646566696e6974696f6e3e200a2020202020203c736f6c7574696f6e2d66696c653e200a20202020202020203c6c6f636174696f6e3e2f7265706f7274696e672f7175616472616e742d6275646765742d666f722d726567696f6e2d616e642d646570742d6873716c2e72707464657369676e3c2f6c6f636174696f6e3e20200a20202020202020203c6d696d652d747970653e746578742f786d6c3c2f6d696d652d747970653e200a2020202020203c2f736f6c7574696f6e2d66696c653e200a202020203c2f7265706f72742d646566696e6974696f6e3e200a20203c2f7265736f75726365733e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c72756c652d726573756c7420747970653d226c697374222f3e20200a20202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200a20202020202020203c524547494f4e20747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e20200a20202020202020203c71756572793e3c215b43444154415b73656c6563742064697374696e637420526567696f6e2c204465706172746d656e742066726f6d205155414452414e545f41435455414c5320776865726520526567696f6e3d275765737465726e275d5d3e3c2f71756572793e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a202020203c616374696f6e73206c6f6f702d6f6e3d2272756c652d726573756c74223e200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e20200a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574732f3e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a202020202020202020203c746573743e7072696e74323c2f746573743e20200a202020202020202020203c70313e524547494f4e3c2f70313e20200a202020202020202020203c70323e4445504152544d454e543c2f70323e200a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202020203c616374696f6e2d6e616d653e5072696e742069743c2f616374696f6e2d6e616d653e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e424952545265706f7274436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e7265706f72743c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c6f75747075742d7479706520747970653d22737472696e67222f3e20200a202020202020202020203c524547494f4e20747970653d22737472696e67222f3e20200a202020202020202020203c4445504152544d454e5420747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c7265706f72742d646566696e6974696f6e20747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e200a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e456d61696c436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e656d61696c3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e200a202020202020202020203c7265706f72742d6f757470757420747970653d22636f6e74656e74222f3e20200a202020202020202020203c746f20747970653d22737472696e67222f3e20200a202020202020202020203c7375626a65637420747970653d22737472696e67222f3e20200a202020202020202020203c66726f6d20747970653d22737472696e67222f3e20200a202020202020202020203c6d6573736167652d706c61696e20747970653d22737472696e67222f3e20200a202020202020202020203c61747461636820747970653d22737472696e67222f3e20200a202020202020202020203c6174746163682d6e616d6520747970653d22737472696e67222f3e200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a202020203c2f616374696f6e733e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3df14e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ComponentTest.xaction','/solution/test/platform/ComponentTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e436f6d706f6e656e74546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e46697273742074657374206f6620746865205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e0d0a202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6170706c65733c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c726571756573743e74686546727569743c2f726571756573743e200d0a0909093c2f736f75726365733e0d0a202020203c2f66727569743e0d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a202020203c686f772d6d616e7920747970653d226c6f6e67223e0d0a2020202020203c64656661756c742d76616c75653e31303c2f64656661756c742d76616c75653e0d0a202020203c2f686f772d6d616e793e0d0a20203c2f696e707574733e0d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d22737472696e67222f3e0d0a20203c2f6f7574707574733e0d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e46697273742074657374206f66207468652054657374436f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c667275697420747970653d22737472696e67222f3e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67222f3e0d0a202020202020202020203c686f772d6d616e7920747970653d226c6f6e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6f72616e67657320747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020202020093c746573743e736f6d657468696e673c2f746573743e0d0a202020202020202020203c73657474696e67313e54686973206973207468652066697273742073657474696e673c2f73657474696e67313e0d0a202020202020202020203c73657474696e67323e5468697320697320746865207365636f6e642073657474696e673c2f73657474696e67323e0d0a202020202020202020203c73657474696e67333e54686973206973207468652074686972642073657474696e673c2f73657474696e67333e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3e185f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest.xaction','/solution/test/platform/ContentOutputTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e200a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e203c2f64656661756c742d76616c75653e200a202020203c2f434f4e54454e544f55545055543e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c636f6e74656e7420747970653d22737472696e67223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f636f6e74656e743e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c434f4e54454e544f555450555420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c636f6e74656e7420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e20200a2020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3e3f70-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_Bytearray.xaction','/solution/test/platform/ContentOutputTest_Bytearray.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e434f4e54454e544f55545055543c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f434f4e54454e544f55545055543e200a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c636f6e74656e7420747970653d22737472696e67223e0a2020202020203c64657374696e6174696f6e733e0a20202020202020203c726573706f6e73653e636f6e74656e743c2f726573706f6e73653e0a2020202020203c2f64657374696e6174696f6e733e0a202020203c2f636f6e74656e743e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c434f4e54454e544f555450555420747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c636f6e74656e7420747970653d226f626a656374222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e200a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e20200a2020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3e3f71-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_error1.xaction','/solution/test/platform/ContentOutputTest_error1.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220313c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574732f3e0d0a0d0a20203c6f7574707574733e0d0a202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20203c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574732f3e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3e6682-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentOutputTest_error2.xaction','/solution/test/platform/ContentOutputTest_error2.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220323c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a20203c6f757470757473202f3e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c746573746f757470757420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e202f3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3e8d93-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','ContentRepoOutputTest_file.xaction','/solution/test/platform/ContentRepoOutputTest_file.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a3c6f7574707574733e0d0a093c636f6e74656e7420747970653d22636f6e74656e74223e0d0a2020202009093c64657374696e6174696f6e733e0d0a202020200909093c66696c653e636f6e74656e747265706f3a746573742f436f6e74656e744f7574707574546573742e7478743c2f66696c653e0d0a2020202009093c2f64657374696e6174696f6e733e0d0a093c2f636f6e74656e743e200d0a3c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c636f6e74656e7420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3eb4a4-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','HelloWorld.xaction','/solution/test/platform/HelloWorld.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e48656c6c6f576f726c642e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e48656c6c6f20576f726c6420416374696f6e2053657175656e63653c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e546865206d6f737420626173696320416374696f6e2053657175656e636520446f63756d656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e48656c6c6f20576f726c642064656d6f6e7374726174657320746865206d6f737420626173696320416374696f6e2053657175656e636520646f63756d656e742e202049742075736573207468652048656c6c6f20576f726c6420436f6d706f6e656e742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574732f3e0d0a0d0a20203c6f7574707574732f3e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e48656c6c6f20576f726c6420416374696f6e3c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574732f3e0d0a20202020202020203c616374696f6e2d6f7574707574732f3e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e48656c6c6f576f726c64436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c71756f74653e283242207c7c2021324229205468617420697320746865207175657374696f6e3c2f71756f74653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3eb4a5-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','index.xml','/solution/test/platform/index.xml','3c696e6465783e0d0a093c6e616d653e424920506c6174666f726d2054657374733c2f6e616d653e0d0a093c6465736372697074696f6e3e416374696f6e7320616e64207265736f7572636573207573656420746f207465737420626173696320706c6174666f726d2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e0d0a093c69636f6e3e706c6174666f726d2e706e673c2f69636f6e3e0d0a093c76697369626c653e747275653c2f76697369626c653e0d0a3c2f696e6465783e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3edbb6-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','jdbc.properties','/solution/test/platform/jdbc.properties','2320436f7079726967687420323030362050656e7461686f20436f72706f726174696f6e2e2020416c6c207269676874732072657365727665642e200d0a23205468697320736f6674776172652077617320646576656c6f7065642062792050656e7461686f20436f72706f726174696f6e20616e642069732070726f766964656420756e64657220746865207465726d73200d0a23206f6620746865204d6f7a696c6c61205075626c6963204c6963656e73652c2056657273696f6e20312e312c206f7220616e79206c617465722076657273696f6e2e20596f75206d6179206e6f7420757365200d0a2320746869732066696c652065786365707420696e20636f6d706c69616e6365207769746820746865206c6963656e73652e20496620796f75206e656564206120636f7079206f6620746865206c6963656e73652c200d0a2320706c6561736520676f20746f20687474703a2f2f7777772e6d6f7a696c6c612e6f72672f4d504c2f4d504c2d312e312e7478742e20546865204f726967696e616c20436f6465206973207468652050656e7461686f200d0a2320424920506c6174666f726d2e202054686520496e697469616c20446576656c6f7065722069732050656e7461686f20436f72706f726174696f6e2e0d0a230d0a2320536f66747761726520646973747269627574656420756e64657220746865204d6f7a696c6c61205075626c6963204c6963656e7365206973206469737472696275746564206f6e20616e2022415320495322200d0a232062617369732c20574954484f55542057415252414e5459204f4620414e59204b494e442c206569746865722065787072657373206f722020696d706c6965642e20506c6561736520726566657220746f200d0a2320746865206c6963656e736520666f7220746865207370656369666963206c616e677561676520676f7665726e696e6720796f75722072696768747320616e64206c696d69746174696f6e732e0d0a756e69745465737444532f747970653d6a617661782e73716c2e44617461536f757263650d0a756e69745465737444532f6472697665723d6e756c6c0d0a756e69745465737444532f75726c3d6e756c6c0d0a756e69745465737444532f757365723d6e756c6c0d0a756e69745465737444532f70617373776f72643d6e756c6c0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3edbb7-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','LoopingTest.xaction','/solution/test/platform/LoopingTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4c6f6f70696e67546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63652077697468206d756c7469706c65206c6f6f70733c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c612d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226170706c65223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226f72616e6765223e53776565743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2267726170656672756974223e536f75723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f6d656772616e617465223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22636172726f74223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22637563756d626572223e4c6f6e673c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f7461746f223e44696d706c793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2262726f63636f6c69223e466c6f776572793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227a75636368696e69223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22626967206d6163223e536c6f7070793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2277686f70706572223e4c616d653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227461636f223e4772656173793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c72756e74696d653e72756e74696d652d613c2f72756e74696d653e200d0a0909093c2f736f75726365733e0d0a202020203c2f612d6d61703e0d0a202020200d0a202020203c622d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e7370686572653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e64696d706c793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e677261706566727569743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e59656c6c6f773c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e7370686572653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e64696d706c793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e636172726f743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e6f72616e67653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e636f6e653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e62756d70793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e637563756d6265723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e677265656e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e656c6c6970736f69643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e736d6f6f74683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e7a75636368696e693c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e677265656e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e656c6c6970736f69643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e73656d692d736d6f6f74683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226e616d65223e7461636f3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22636f6c6f72223e62726f776e3c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227368617065223e736164646c653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2274657874757265223e726f7567683c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a0909093c736f75726365733e0d0a090909093c72756e74696d653e72756e74696d652d613c2f72756e74696d653e200d0a0909093c2f736f75726365733e0d0a202020203c2f622d6d61703e0d0a202020200d0a202020203c632d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e6e616d653c2f64656661756c742d76616c75653e202020200d0a202020203c2f632d737472696e673e0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c616374696f6e73206c6f6f702d6f6e3d22612d6d6170223e0d0a202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e416374696f6e20313c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c612d6d617020747970653d2270726f70657274792d6d6170222f3e0d0a20202020202020203c622d6d617020747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20202020202020203c632d737472696e6720747970653d22737472696e67222f3e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020203c616374696f6e312d6f757420747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c746573743e6d657267653c2f746573743e0d0a20202020202020203c70313e612d6d61703c2f70313e0d0a20202020202020203c70323e622d6d61703c2f70323e0d0a20202020202020203c70333e632d737472696e673c2f70333e0d0a20202020202020203c6e65776e616d653e616374696f6e312d6f75743c2f6e65776e616d653e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020203c616374696f6e73206c6f6f702d6f6e3d22616374696f6e312d6f7574223e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e416374696f6e20323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c616374696f6e312d6f757420747970653d2270726f70657274792d6d6170222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c616374696f6e322d6f757420747970653d22737472696e672d6c697374222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e6765746b6579733c2f746573743e0d0a202020202020202020203c70313e616374696f6e312d6f75743c2f70313e0d0a202020202020202020203c6e65776e616d653e616374696f6e322d6f75743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e416374696f6e20333c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c616374696f6e322d6f757420747970653d22737472696e672d6c697374222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c7a2d6f757420747970653d22737472696e672d6c6973742220617070656e643d2274727565222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020200d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e72656e616d653c2f746573743e0d0a202020202020202020203c70313e616374696f6e322d6f75743c2f70313e0d0a202020202020202020203c6e65776e616d653e7a2d6f75743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a2020202020200d0a2020202020203c616374696f6e73206c6f6f702d6f6e3d227a2d6f7574223e0d0a2020202020202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020202020202020203c616374696f6e2d6e616d653e416374696f6e20343c2f616374696f6e2d6e616d653e0d0a2020202020202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d696e707574733e0d0a20202020202020202020202020203c7a2d6f757420747970653d22737472696e67222f3e0d0a2020202020202020202020203c2f616374696f6e2d696e707574733e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020202020202020203c6d736720747970653d22737472696e67222f3e0d0a2020202020202020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020200d0a2020202020202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020202020202020203c746573743e666f726d61743c2f746573743e0d0a20202020202020202020202020203c70313e54686973206973206120666f726d6174746564206d657373616765202d7b307d3c2f70313e0d0a20202020202020202020202020203c70323e7a2d6f75743c2f70323e0d0a20202020202020202020202020203c70333e7a2d6f75743c2f70333e0d0a20202020202020202020202020203c6e65776e616d653e6d73673c2f6e65776e616d653e0d0a2020202020202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a202020202020202020200d0a2020202020202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020202020202020203c616374696f6e2d6e616d653e416374696f6e20353c2f616374696f6e2d6e616d653e0d0a2020202020202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d696e707574733e0d0a20202020202020202020202020203c6d736720747970653d22737472696e672d6c697374222f3e0d0a2020202020202020202020203c2f616374696f6e2d696e707574733e0d0a2020202020200d0a2020202020202020202020203c616374696f6e2d6f7574707574733e0d0a2020202020202020202020203c2f616374696f6e2d6f7574707574733e0d0a2020202020200d0a2020202020202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020202020202020203c746573743e7072696e743c2f746573743e0d0a20202020202020202020202020203c70313e6d73673c2f70313e0d0a2020202020202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c2f616374696f6e2d646566696e6974696f6e3e2020202020200d0a202020202020202020200d0a2020202020203c2f616374696f6e733e0d0a2020203c2f616374696f6e733e200d0a0d0a2020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e416374696f6e20363c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c7a2d6f757420747970653d22737472696e672d6c697374222f3e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c746573743e7072696e743c2f746573743e0d0a20202020202020203c70313e7a2d6f75743c2f70313e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f29d8-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','message1.txt','/solution/test/platform/message1.txt','7468697320697320746865206d6573736167652074656d706c6174652c20796f7520666573746572696e6720626c6f62206f66207b307d',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f29d9-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','MultiComponentTest.xaction','/solution/test/platform/MultiComponentTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6170706c65733c2f64656661756c742d76616c75653e0d0a202020203c2f66727569743e0d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a20203c2f696e707574733e0d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d22737472696e67222f3e0d0a20203c2f6f7574707574733e0d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420313c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e46697273742074657374206f662074686520616374696f6e20636861696e3c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c667275697420747970653d22737472696e67223e0d0a2020202020202020202020203c64656661756c742d76616c75653e746f6d61746f3c2f64656661756c742d76616c75653e0d0a202020202020202020203c2f66727569743e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020202020202020203c64656661756c742d76616c75653e6368657272793c2f64656661756c742d76616c75653e0d0a202020202020202020203c2f6d6f72652d66727569743e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e65772d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e636f6e6361743c2f746573743e0d0a202020202020202020203c70313e66727569743c2f70313e0d0a202020202020202020203c70323e6d6f72652d66727569743c2f70323e0d0a202020202020202020203c6e65776e616d653e6e65772d66727569743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e494e464f524d4154494f4e3c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c646f63756d656e746174696f6e3e0d0a202020202020202020203c617574686f723e4a616d6573204469786f6e3c2f617574686f723e0d0a202020202020202020203c6465736372697074696f6e3e5365636f6e642074657374206f662074686520616374696f6e20636861696e3c2f6465736372697074696f6e3e0d0a202020202020202020203c68656c703e6a7573742074657374696e672e2e2e3c2f68656c703e0d0a20202020202020203c2f646f63756d656e746174696f6e3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6e65772d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e657765722d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e746f75707065723c2f746573743e0d0a202020202020202020203c70313e6e65772d66727569743c2f70313e0d0a202020202020202020203c6e65776e616d653e6e657765722d66727569743c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f50ea-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','MultiComponentTestLoop.xaction','/solution/test/platform/MultiComponentTestLoop.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e636520616e642061206c6f6f703c2f6465736372697074696f6e3e0d0a202020203c68656c703e7374696c6c206a7573742074657374696e672e2e2e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a20203c696e707574733e0d0a202020203c66727569742d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226b657931223e56616c7565312d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657932223e56616c7565322d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657933223e56616c7565332d413c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657934223e56616c7565342d413c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226b657931223e56616c7565312d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657932223e56616c7565322d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657933223e56616c7565332d423c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226b657934223e56616c7565342d423c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f66727569742d6d61703e0d0a202020200d0a202020203c6d6f72652d667275697420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e6f72616e6765733c2f64656661756c742d76616c75653e0d0a202020203c2f6d6f72652d66727569743e0d0a0d0a202020203c6d65737361676520747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c6d65737361676520747970653d2270726f70657274792d6d61702d6c697374222f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c7265736f75726365733e0d0a202020203c6d6573736167652d74656d706c6174653e0d0a2020202020203c736f6c7574696f6e2d66696c653e0d0a20202020202020203c6c6f636174696f6e3e6d6573736167652e7478743c2f6c6f636174696f6e3e0d0a20202020202020203c6d696d652d747970653e746578742f746578743c2f6d696d652d747970653e0d0a2020202020203c2f736f6c7574696f6e2d66696c653e0d0a202020203c2f6d6573736167652d74656d706c6174653e0d0a20203c2f7265736f75726365733e0d0a0d0a20203c616374696f6e73206c6f6f702d6f6e3d2266727569742d6d6170223e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420313c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c66727569742d6d617020747970653d2270726f70657274792d6d6170222f3e0d0a202020202020202020203c6d6f72652d667275697420747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e65772d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e636f6e6361743c2f746573743e0d0a202020202020202020203c70313e66727569742d6d61703c2f70313e0d0a202020202020202020203c70323e6d6f72652d66727569743c2f70323e0d0a202020202020202020203c6e65776e616d653e6e65772d66727569742d6d61703c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e5465737420323c2f616374696f6e2d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e54657374436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c616374696f6e2d747970653e546573743f3c2f616374696f6e2d747970653e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c6e65772d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c6e657765722d66727569742d6d617020747970653d22737472696e67222f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c746573743e746f75707065723c2f746573743e0d0a202020202020202020203c70313e6e65772d66727569742d6d61703c2f70313e0d0a202020202020202020203c6e65776e616d653e6e657765722d66727569742d6d61703c2f6e65776e616d653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f50eb-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','platform.png','/solution/test/platform/platform.png','89504e470d0a1a0a0000000d4948445200000050000000500803000000b9cf029f0000002c744558744372656174696f6e2054696d6500467269203239204a756c20323030352031383a32363a3239202d303530305b26eedf0000000774494d4507d5080215202a408c2899000000097048597300000af000000af00142ac34980000000467414d410000b18f0bfc610500000300504c5445fffffffffbf0ccff99ccff66ccff33ccffcce7e7d6ffffcc999999555555292929040404777777c0c0c0222222dddddd333333393939d7d7d71c1c1c0c0c0c5f5f5f3399cc3399ff6699991111118080804d4d4d3366666666996699ff99ccffccecff66ccff6699cccccccca6caf0b2b2b2f1f1f1161616666666e3e3e3eaeaea424242a0a0a496969686868699ccccccccfff8f8f8cbcbcb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f09ae8320000051f4944415478dabd986973da4810868791b41c43382cb0ca267114230411b661f7ffffb8edee91e66c2136456d7f8853127ad46f5fd320c41f9a94d99f3eca5a0a968c1fc79329d9e380c9a3810ff79062983e3086e4e263d3ecd8683c7e7cbea188fe8b0b99944992c82c76649c1abbaf2cb3d4b5c80befee70509334c62dcf0a6cfdc4f086d22e035e3a828b53d5da370c45084c46fd6193dc8727883a9e67f06f18c1fecc348d9b3b6b701538d3aa2c2bf85bb341617be778643f09effe506a53022f576ad709093ff757c4435127c649ba453ceb1f134619e05e95ca4f98c5a864301f2be09596b73f9ea2440741fc8290c333477828f7854b148cbc835a773c4a4d7213b851ea82aad0c9336631b1c0b9065ef4ab30d80494372503e85a92b54e9a108dc54c0341f251eb5504f45b292a6d1d7732e8884f1b2221162aa7eb109695d65b223028c530c7abd60dedcace024700d4b7ae80faaac1bf6d35081ca3e8bc155de66e88326c3a7dfdbaa5dedb961f91e4a0f592d4137da1fa302fde99f86269e73ace419603bd942347f45a1dda07e07a0d4e35261c958ec9ccafc3a06664d70fb3ee29b5d953905a5e2d4ad7768e02b64bda7740160f262d0a8899d67b0e78509753b70ca3e93aeede02a25755f70cd51ce71f54d5ac71721c0dae915d06f4047d15a2fc546ab1f478557e82977d82c71840d19f10932d7cd3efc906670e1051f5d2d15b75035b2d0e3e8f8da07d538d2ecc01823e3a7af38e97d7e1384ab808baef3a19d58e5ef29b7924d6cc4ca19648aa8dde30e4bd9ad9db042062657931c9f6fb2d60db6de823544f7e29ab95d6dbcbf32a314b5922c5ec6ff2f132e49f9f9684e59d28a12d7190e7a5850f311e04dac739ceab9b7a7de098bb07fead1a6cc4d7d6c72586468a7e47fd4163222161771b116f8139be5ad5cb9b31e28176c92340adc700fa78d27d0de3e883d5e4d58d1df49de9c74d3d1bd535ad5f7bf784b5360e0464c26456d1e072e781c9b55acff4548b89590084ffec77669cfc437aa99e573bed239d4e7951b43e0e01e1ef99d6bff97caa164fd6bf866eb4c497a230c4a457b2a413b0066776dd44f6787ac6629ede0bb2ef5af52da0a47577ee8d79ad577f0402b76efdb33e061d6bb39ca1e0dfd01465d92ed155b72434f43a81ab08c5cf212e43a273a060636ff0449eaacf064c9fa586d79e34cf8563dfa9f0050f1458cfb01c01e2a02fbc40342b7242eac6ce031e477481230456a519c94f6a5d123e6beb01b2500416a9768f14449c4b0b6c34f0553711f9ff1c02431f8363ea80290981270d9414c28223ae2c315836f758833d1e26b44ffc88893a6d19e36018c3651743d3951b96e8f898c5c01d8e2ad136c60596df452707abe030a05a848675783dab6f5887b97a29af399e794ec03737544b06a83be56c3a45792b7432a45a46406c57a79737d4adced1a0556f58e24970b684a5f9dc8d85ad3e37ddc346fbf8ceaa16bce172359b1fbef0d4545fe106d34b7c3ee2321b19d6e564d10dec4d137fd5ec53fd56e8539b238af60cf8c4b1ca7d6976a6acb1aad0fb6c68d26f1ee65b7d0fb12e567c1447f6bb50c6e15ad5136772a3fdea058a1e4a78700444f1b3d06387b13b80b16a8149e12b91db7463e2c8f3b11655b1ed8e329ddceeeb1cd91dc4b423be5525ac17bf8adc8f6062a508e6d7a27ed53f8ab7b2fc5914ef7ea71897ba79764766ba5f99b6d025d3179fe73cee54cf3daa97660d7a129c83ce40bbc747a74f276208780f32e9fbb130f35eca5def31d9038c93721ff1c66f8fac83b7850ffc368aed91f4de0b2b5d8ec4ff6aff025ffdb9d338b8f8370000000049454e44ae426082',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f77fc-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SetGlobalOutputTest.xaction','/solution/test/platform/SetGlobalOutputTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e53657420476c6f62616c205661726961626c653c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e64656275673c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e4d6172633c2f617574686f723e20200a202020203c6465736372697074696f6e3e53657473206120676c6f62616c207661726961626c652066726f6d20616e20616374696f6e2073657175656e63653c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a202020203c726573756c742d747970652f3e0a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c474c4f42414c5f5445535420747970653d22737472696e67223e200a2020202020203c64657374696e6174696f6e733e200a20202020202020203c676c6f62616c3e474c4f42414c5f544553543c2f676c6f62616c3e200a2020202020203c2f64657374696e6174696f6e733e200a202020203c2f474c4f42414c5f544553543e200a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a2020202020203c616374696f6e2d646566696e6974696f6e3e0a202020202020093c616374696f6e2d696e70757473202f3e0a20202020202020203c616374696f6e2d6f7574707574733e0a20202020202020202020093c474c4f42414c5f5445535420747970653d22737472696e67222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020200a20202020202020203c636f6d706f6e656e742d6e616d653e4a61766173637269707452756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202009093c7363726970743e3c215b43444154415b200a202020202020090920202020474c4f42414c5f54455354203d20225468697320697320612074657374223b0a09092020202020205d5d3e0a09092020202020203c2f7363726970743e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a202020202020093c616374696f6e2d696e707574733e0a20202020202020202020093c474c4f42414c5f5445535420747970653d22737472696e67222f3e0a202020202020093c2f616374696f6e2d696e707574733e0a202020202020093c616374696f6e2d6f7574707574733e0a2020202020200920203c6a756e6b20747970653d22737472696e6722202f3e0a202020202020093c2f616374696f6e2d6f7574707574733e0a20202020202020200a20202020202020203c636f6d706f6e656e742d6e616d653e4a61766173637269707452756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e72756c653c2f616374696f6e2d747970653e0a202020202020093c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202009093c7363726970743e3c215b43444154415b200a2020202020200909202020206f75742e7072696e746c6e2822476c6f62616c205661726961626c6520474c4f42414c5f544553543d22202b20474c4f42414c5f54455354293b0a2020202020200909202020206a756e6b203d20474c4f42414c5f544553543b0a09092020202020205d5d3e0a09092020202020203c2f7363726970743e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f9f0d-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','subaction_shareresultset.xaction','/solution/test/platform/subaction_shareresultset.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e537562616374696f6e2063616c6c20746f207368617265206120726573756c74207365743c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f722f3e20200a202020203c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c636f6e6e2f3e0a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e200a20200a202020203c616374696f6e733e200a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e476574204d445820436f6e6e656374696f6e3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574732f3e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c636174616c6f6720747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e7420747970653d2273716c2d636f6e6e656374696f6e22206d617070696e673d22636f6e6e222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e222f3e20202020202020200a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6c6976653e747275653c2f6c6976653e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a202020203c2f616374696f6e733e0a0a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3f9f0e-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','subaction_useconn.xaction','/solution/test/platform/subaction_useconn.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c7469746c653e537562616374696f6e2063616c6c20746f207465737420612073686172656420636f6e6e656374696f6e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e4552524f523c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f722f3e20200a202020203c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e20200a202020203c68656c702f3e20200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e0a20202020203c636f6e6e3e0a20202020202020203c736f75726365733e0a20202020202020202020203c726571756573743e636f6e6e3c2f726571756573743e0a20202020202020203c2f736f75726365733e0a20202020203c2f636f6e6e3e0a20203c2f696e707574733e0a0a20203c6f7574707574732f3e200a0a20203c7265736f75726365732f3e200a20200a202020203c616374696f6e733e200a2020202020203c616374696f6e2d646566696e6974696f6e3e200a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c212d2d2070617373656420696e2066726f6d20706172656e74202d2d3e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e222f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e200a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e200a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a202020203c2f616374696f6e733e0a0a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3fc61f-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest1.xaction','/solution/test/platform/SubActionConnectionTest1.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e642072657573657320697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e697072657061726564636f6d706f6e656e74733c2f706174683e0a20202020202020203c616374696f6e3e697072657061726564636f6d706f6e656e745f73716c5f617661696c61626c652e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e742f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b3fc620-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest2.xaction','/solution/test/platform/SubActionConnectionTest2.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c70726570617265645f636f6d706f6e656e7420747970653d2270726570617265645f636f6d706f6e656e74222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574732f3e200a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e697072657061726564636f6d706f6e656e74733c2f706174683e0a20202020202020203c616374696f6e3e697072657061726564636f6d706f6e656e745f73716c5f617661696c61626c652e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e742f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b401441-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest3.xaction','/solution/test/platform/SubActionConnectionTest3.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574732f3e200a2020202020203c616374696f6e2d6f7574707574733e0a2020202020202020203c636f6e6e2f3e0a2020202020202020203c71756572792d726573756c74732f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e706c6174666f726d3c2f706174683e0a20202020202020203c616374696f6e3e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b403b52-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionConnectionTest4.xaction','/solution/test/platform/SubActionConnectionTest4.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e537562416374696f6e436f6e6e656374696f6e546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e57696c6c20476f726d616e3c2f617574686f723e20200a202020203c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574732f3e0a0a20203c6f7574707574733e200a202020203c71756572792d726573756c74732f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a0a20203c616374696f6e733e200a0a202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e4765742053514c20436f6e6e656374696f6e3c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574732f3e0a20202020202020203c616374696f6e2d7265736f75726365733e0a202020202020202020203c636174616c6f6720747970653d227265736f75726365222f3e0a20202020202020203c2f616374696f6e2d7265736f75726365733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e2220747970653d2273716c2d636f6e6e656374696f6e222f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c6a6e64693e53616d706c65446174613c2f6a6e64693e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a0a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e0a202020202020202020203c636f6e6e2f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574732f3e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e200a20202020202020203c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e0a20202020202020203c706174683e706c6174666f726d3c2f706174683e0a20202020202020203c616374696f6e3e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f616374696f6e3e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a2020202020203c616374696f6e2d646566696e6974696f6e3e0a20202020202020203c636f6d706f6e656e742d6e616d653e53514c4c6f6f6b757052756c653c2f636f6d706f6e656e742d6e616d653e0a20202020202020203c616374696f6e2d747970653e5172792053656c6563746564205465727269746f727920616e642053656c65637465642050726f647563746c696e653c2f616374696f6e2d747970653e0a20202020202020203c616374696f6e2d696e707574733e0a202020202020202020203c70726570617265645f636f6d706f6e656e74206d617070696e673d22636f6e6e2220747970653d2273716c2d636f6e6e656374696f6e222f3e0a20202020202020203c2f616374696f6e2d696e707574733e0a20202020202020203c616374696f6e2d6f7574707574733e0a202020202020202020203c71756572792d726573756c74732f3e0a20202020202020203c2f616374696f6e2d6f7574707574733e0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a202020202020202020203c71756572793e3c215b43444154415b53454c454354204255444745542046524f4d205155414452414e545f41435455414c5320574845524520524547494f4e3d275765737465726e2720414e44204445504152544d454e543d2753616c6573275d5d3e3c2f71756572793e0a090920203c6c6976653e747275653c2f6c6976653e0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b403b53-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionTest.xaction','/solution/test/platform/SubActionTest.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e20546573742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e53696d706c652074657374206f6620537562416374696f6e20636f6d706f6e656e742e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c736f6c7574696f6e20747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e736f6c7574696f6e3c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f736f6c7574696f6e3e20200a202020203c7061746820747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e706174683c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f706174683e20200a202020203c737562616374696f6e20747970653d22737472696e67223e200a2020202020203c736f75726365733e200a20202020202020203c726571756573743e737562616374696f6e3c2f726571756573743e200a2020202020203c2f736f75726365733e200a202020203c2f737562616374696f6e3e20200a202020203c696e707574537472696e6720747970653d22737472696e67223e0a2020202020203c736f75726365733e0a20202020202020203c726571756573743e696e707574537472696e673c2f726571756573743e0a2020202020203c2f736f75726365733e0a202020203c2f696e707574537472696e673e0a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e200a2020202020203c636f6d706f6e656e742d6e616d653e537562416374696f6e436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e43616c6c2045787465726e616c20416374696f6e3c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e200a20202020202020203c736f6c7574696f6e20747970653d22737472696e67222f3e20200a20202020202020203c7061746820747970653d22737472696e67222f3e20200a20202020202020203c616374696f6e20747970653d22737472696e6722206d617070696e673d22737562616374696f6e222f3e20200a20202020202020203c696e707574537472696e6720747970653d22737472696e67222f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e200a20202020202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e200a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e2f3e200a202020203c2f616374696f6e2d646566696e6974696f6e3e0a200a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b406264-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','SubActionTestTarget.xaction','/solution/test/platform/SubActionTestTarget.xaction','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c616374696f6e2d73657175656e63653e200a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0a20203c7469746c653e537562616374696f6e2054657374205461726765742058414354494f4e3c2f7469746c653e0a20203c76657273696f6e3e313c2f76657273696f6e3e0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0a20203c646f63756d656e746174696f6e3e200a202020203c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e20200a202020203c6465736372697074696f6e3e58414354494f4e206265696e672063616c6c656420627920537562416374696f6e546573742e78616374696f6e3c2f6465736372697074696f6e3e20200a202020203c68656c703e546573742e3c2f68656c703e200a20203c2f646f63756d656e746174696f6e3e0a0a20203c696e707574733e200a202020203c696e707574537472696e6720747970653d22737472696e67223e0a2020202020203c736f75726365733e0a20202020202020203c726571756573743e696e707574537472696e673c2f726571756573743e0a2020202020203c2f736f75726365733e0a202020203c2f696e707574537472696e673e0a20203c2f696e707574733e0a0a20203c6f7574707574733e200a202020203c6f7574707574537472696e6720747970653d22737472696e67222f3e0a20203c2f6f7574707574733e0a0a20203c7265736f75726365732f3e0a20200a20203c616374696f6e733e200a202020203c616374696f6e2d646566696e6974696f6e3e0a2020202020203c636f6d706f6e656e742d6e616d653e5574696c697479436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0a2020202020203c616374696f6e2d747970653e436f707920506172616d657465723c2f616374696f6e2d747970653e0a2020202020203c616374696f6e2d696e707574733e0a20202020202020203c636f70792d66726f6d20747970653d22737472696e6722206d617070696e673d22696e707574537472696e67222f3e0a2020202020203c2f616374696f6e2d696e707574733e0a2020202020203c616374696f6e2d6f7574707574733e0a20202020202020203c636f70792d746f20747970653d22737472696e6722206d617070696e673d226f7574707574537472696e67222f3e0a2020202020203c2f616374696f6e2d6f7574707574733e0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0a20202020202020203c636f70793e0a202020202020202020203c66726f6d3e636f70792d66726f6d3c2f66726f6d3e0a202020202020202020203c72657475726e3e636f70792d746f3c2f72657475726e3e0a20202020202020203c2f636f70793e0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0a202020203c2f616374696f6e2d646566696e6974696f6e3e0a0a20203c2f616374696f6e733e200a3c2f616374696f6e2d73657175656e63653e',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b406265-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','UtilityTest.xaction','/solution/test/platform/UtilityTest.xaction','3c616374696f6e2d73657175656e636520786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e636522203e0d0a20203c6e616d653e5574696c697479546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e5574696c69747920546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e446f7567204d6f72616e3c2f617574686f723e0d0a202020203c6465736372697074696f6e3e54657374206f6620746865207574696c69747920636f6d706f6e656e742066756e6374696f6e616c6974793c2f6465736372697074696f6e3e0d0a202020203c68656c703e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c612d6d617020747970653d2270726f70657274792d6d61702d6c697374223e0d0a2020202020203c64656661756c742d76616c756520747970653d2270726f70657274792d6d61702d6c697374223e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d226170706c65223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d226f72616e6765223e53776565743c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2267726170656672756974223e536f75723c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f6d656772616e617465223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22636172726f74223e476f6f643c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22637563756d626572223e4c6f6e673c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d22706f7461746f223e44696d706c793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2262726f63636f6c69223e466c6f776572793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227a75636368696e69223e46756e6e793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a20202020202020203c70726f70657274792d6d61703e0d0a202020202020202020203c656e747279206b65793d22626967206d6163223e536c6f7070793c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d2277686f70706572223e4c616d653c2f656e7472793e0d0a202020202020202020203c656e747279206b65793d227461636f223e4772656173793c2f656e7472793e0d0a20202020202020203c2f70726f70657274792d6d61703e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f612d6d61703e0d0a202020200d0a202020203c612d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4120537472696e673c2f64656661756c742d76616c75653e202020200d0a202020203c2f612d737472696e673e0d0a0d0a202020203c622d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4220537472696e673c2f64656661756c742d76616c75653e202020200d0a202020203c2f622d737472696e673e0d0a0d0a202020203c632d737472696e6720747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c756520747970653d22737472696e67223e5468697320697320746865204d657373616765202d20506172616d207b307d20506172616d207b317d3c2f64656661756c742d76616c75653e202020200d0a202020203c2f632d737472696e673e0d0a0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c69737422202f3e0d0a0d0a20203c2f696e707574733e0d0a20200d0a20203c6f7574707574733e0d0a202020203c7a2d6f757420747970653d2270726f70657274792d6d61702d6c69737422202f3e0d0a20203c2f6f7574707574733e0d0a20200d0a20203c616374696f6e733e0d0a202020203c616374696f6e2d646566696e6974696f6e3e0d0a2020202020203c616374696f6e2d6e616d653e666f726d61743c2f616374696f6e2d6e616d653e0d0a2020202020203c636f6d706f6e656e742d6e616d653e5574696c697479436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a0d0a2020202020203c616374696f6e2d696e707574733e0d0a20202020202020203c612d737472696e6720747970653d22737472696e67222f3e0d0a20202020202020203c622d737472696e6720747970653d22737472696e67222f3e0d0a20202020202020203c632d737472696e6720747970653d22737472696e67222f3e0d0a0d0a20202020202020203c642d737472696e6720747970653d22737472696e67223e0d0a202020202020202020203c64656661756c742d76616c756520747970653d22737472696e67223e4420537472696e673c2f64656661756c742d76616c75653e202020200d0a20202020202020203c2f642d737472696e673e0d0a2020202020203c2f616374696f6e2d696e707574733e0d0a0d0a2020202020203c616374696f6e2d6f7574707574733e0d0a20202020202020203c616374696f6e312d6f757420747970653d22737472696e67222f3e0d0a2020202020203c2f616374696f6e2d6f7574707574733e0d0a0d0a2020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a20202020202020203c666f726d61743e0d0a202020202020202020203c666f726d61742d737472696e673e225468697320697320746865204d657373616765202d20506172616d207b307d20506172616d207b317d223c2f666f726d61742d737472696e673e0d0a202020202020202020203c6172673e612d737472696e673c2f6172673e0d0a202020202020202020203c6172673e622d737472696e673c2f6172673e0d0a202020202020202020203c72657475726e3e746d702d6f75743c2f72657475726e3e0d0a20202020202020203c2f666f726d61743e0d0a20202020202020203c636f70793e0d0a202020202020202020203c66726f6d3e746d702d6f75743c2f66726f6d3e0d0a202020202020202020203c72657475726e3e616374696f6e312d6f75743c2f72657475726e3e0d0a20202020202020203c2f636f70793e0d0a20202020202020203c7072696e743e0d0a202020202020202020203c64656c696d697465723e22202d20223c2f64656c696d697465723e0d0a202020202020202020203c6172673e746d702d6f75743c2f6172673e0d0a202020202020202020203c6172673e2220436f6e7374616e7420223c2f6172673e0d0a202020202020202020203c6172673e642d737472696e673c2f6172673e0d0a20202020202020203c2f7072696e743e0d0a2020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b408976-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f65-6757-11dd-a492-c111aa2b74dc','VFSOutputTest_file.xaction','/solution/test/platform/VFSOutputTest_file.xaction','3c616374696f6e2d73657175656e63653e0d0a20203c6e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6e616d653e0d0a20203c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e0d0a20203c76657273696f6e3e313c2f76657273696f6e3e0d0a20203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a0d0a20203c646f63756d656e746174696f6e3e0d0a202020203c617574686f723e4d617263204261746368656c6f723c2f617574686f723e0d0a202020203c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e0d0a202020203c68656c703e546573742e3c2f68656c703e0d0a20203c2f646f63756d656e746174696f6e3e0d0a0d0a20203c696e707574733e0d0a202020203c434f4e54454e544f555450555420747970653d22737472696e67223e0d0a2020202020203c64656661756c742d76616c75653e3c215b43444154415b546869732069732073616d706c65206f75747075742066726f6d2074686520636f6e74656e742d6f757470757420636f6d706f6e656e742e5d5d3e0d0a2020202020203c2f64656661756c742d76616c75653e0d0a202020203c2f434f4e54454e544f55545055543e0d0a20203c2f696e707574733e0d0a0d0a20203c6f7574707574733e0d0a202020203c636f6e74656e7420747970653d22636f6e74656e74223e0d0a2020202009093c64657374696e6174696f6e733e0d0a202020200909093c66696c653e7666732d66696c653a2f2f633a2f5646534f7574707574546573742e7465737446696c654f75747075742e7478743c2f66696c653e0d0a202020200909093c212d2d3c66696c653e7666732d6674703a2f2f6a6469786f6e3a6d7970617373776f72644070726f736f757263652e70656e7461686f2e6f72672f72656c656173652f5646534f7574707574546573742e7465737446696c654f75747075742e7478743c2f66696c653e2d2d3e0d0a2020202009093c2f64657374696e6174696f6e733e0d0a202020203c2f636f6e74656e743e200d0a093c2f6f7574707574733e0d0a0d0a20203c7265736f75726365732f3e0d0a0d0a20203c616374696f6e733e0d0a2020202020203c616374696f6e2d646566696e6974696f6e3e0d0a20202020202020203c616374696f6e2d6e616d653e436f6e74656e74204f757470757420546573743c2f616374696f6e2d6e616d653e0d0a20202020202020203c616374696f6e2d696e707574733e0d0a202020202020202020203c434f4e54454e544f555450555420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d696e707574733e0d0a20202020202020203c616374696f6e2d6f7574707574733e0d0a202020202020202020203c636f6e74656e7420747970653d22737472696e6722202f3e0d0a20202020202020203c2f616374696f6e2d6f7574707574733e0d0a20202020202020203c6c6f6767696e672d6c6576656c3e44454255473c2f6c6f6767696e672d6c6576656c3e0d0a20202020202020203c636f6d706f6e656e742d6e616d653e6f72672e70656e7461686f2e706c7567696e2e636f72652e436f6e74656e744f7574707574436f6d706f6e656e743c2f636f6d706f6e656e742d6e616d653e0d0a20202020202020203c636f6d706f6e656e742d646566696e6974696f6e3e0d0a202020202020202020203c6d696d652d747970653e746578742f68746d6c3c2f6d696d652d747970653e0d0a20202020202020203c2f636f6d706f6e656e742d646566696e6974696f6e3e0d0a2020202020203c2f616374696f6e2d646566696e6974696f6e3e0d0a20203c2f616374696f6e733e0d0a3c2f616374696f6e2d73657175656e63653e0d0a',FALSE,1214444689000,'6b1c5f65-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b408977-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','EditSubscription.txt','/solution/test/tmp/EditSubscription.txt','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b408978-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','GetArchived.html','/solution/test/tmp/GetArchived.html','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b40b089-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','RuntimeRepositoryTest.testRuntimeRepository.txt','/solution/test/tmp/RuntimeRepositoryTest.testRuntimeRepository.txt','214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a214d6573736167652e555345525f494e464f210a',FALSE,1218426075000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b40b08a-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','SaveSubscription.html','/solution/test/tmp/SaveSubscription.html','',FALSE,1218423891000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_FILES VALUES('6b44f64b-6757-11dd-a492-c111aa2b74dc',0,'6b1c5f66-6757-11dd-a492-c111aa2b74dc','SolutionRepositoryTest.testSolutionRepository.txt','/solution/test/tmp/SolutionRepositoryTest.testSolutionRepository.txt','3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c7265706f7369746f72793e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2273616d706c6573223e3c7469746c653e73616d706c65733c2f7469746c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d227265706f7274696e67223e3c706174683e7265706f7274696e673c2f706174683e3c7469746c653e7265706f7274696e673c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d227265706f7274223e3c66696c656e616d653e4a467265655f517561642e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e257469746c653c2f7469746c653e3c6465736372697074696f6e3e256465736372697074696f6e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f7265706f72742e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e4f4c41502043726f7373746162205265706f72743c2f7469746c653e3c6465736372697074696f6e3e412063726f737320746162207265706f727420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520706167653c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4d44585f7265706f72742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f7265706f72745f584c532e78616374696f6e3c2f66696c656e616d653e3c706174683e7265706f7274696e673c2f706174683e3c736f6c7574696f6e3e73616d706c65733c2f736f6c7574696f6e3e3c7469746c653e4f4c41502043726f73737461622053707265616473686565743c2f7469746c653e3c6465736372697074696f6e3e4120737072656164736865657420746861742073686f77732061637475616c20616e6420627564676574206461746120666f72206576657279206465706172746d656e74206163726f737320657665727920726567696f6e2e20546865207265706f727420717565726965732061204d6f6e647269616e204f4c41502073657276657220616e642075736573204a467265655265706f727420746f2067656e65726174652074686520584c532066696c652e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f4d44585f7265706f72742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2274657374223e3c7469746c653e746573743c2f7469746c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2264617368626f617264223e3c706174683e64617368626f6172643c2f706174683e3c7469746c653e64617368626f6172643c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e6465706172746d656e74732e72756c652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617368626f6172643c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e526567696f6e73206c6973743c2f7469746c653e3c6465736372697074696f6e3e3c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d747275653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d2264617461736f7572636573223e3c706174683e64617461736f75726365733c2f706174683e3c7469746c653e64617461736f75726365733c2f7469746c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e4d44585f44617461736f757263652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e416e204d44582044617461736f757263653c2f7469746c653e3c6465736372697074696f6e3e45786572636973657320746865204d445820436f6e6e656374696f6e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e71756572795f72756c652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e43757272656e7420506f736974696f6e205469746c65733c2f7469746c653e3c6465736372697074696f6e3e4a6176617363726970742071756572792072756c6520746573743c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d2272756c65223e3c66696c656e616d653e58515f44617461736f757263652e78616374696f6e3c2f66696c656e616d653e3c706174683e64617461736f75726365733c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e585175657279205175657279206f6620616e20584d4c2044617461736f757263653c2f7469746c653e3c6465736372697074696f6e3e546869732072756c65207573657320616e20584d4c20717565727920746f2072657475726e2061204c697374206f6620426f6f6b732e266c743b702667743b546865206461746120736f7572636520697320616e20584d4c20446f63756d656e742e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c69616d205365796c65723c2f617574686f723e3c69636f6e3e584d4c5f44617461736f757263652e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c44455222206e616d653d22706c6174666f726d2220706174683d22706c6174666f726d222076697369626c653d22747275652220646973706c6179747970653d2269636f6e73223e3c706174683e706c6174666f726d3c2f706174683e3c7469746c653e424920506c6174666f726d2054657374733c2f7469746c653e3c6465736372697074696f6e3e416374696f6e7320616e64207265736f7572636573207573656420746f207465737420626173696320706c6174666f726d2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f706c6174666f726d2e706e673c2f69636f6e3e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d227265706f7274223e3c66696c656e616d653e4275727374696e6748544d4c546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e4275727374696e67205465737420313c2f7469746c653e3c6465736372697074696f6e3e4275727374696e672072756c6520746573742073656e64696e672048544d4c204174746163686d656e743c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c69636f6e3e676574496d6167653f696d6167653d69636f6e732f62757273742e706e673c2f69636f6e3e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4275727374696e67546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e4275727374696e67205465737420313c2f7469746c653e3c6465736372697074696f6e3e4275727374696e672072756c6520746573743c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6d706f6e656e74546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e46697273742074657374206f6620746865205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220313c2f7469746c653e3c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e742054657374202d204572726f7220323c2f7469746c653e3c6465736372697074696f6e3e4572726f722068616e646c696e6720746573743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e48656c6c6f576f726c642e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e48656c6c6f20576f726c6420416374696f6e2053657175656e63653c2f7469746c653e3c6465736372697074696f6e3e546865206d6f737420626173696320416374696f6e2053657175656e636520446f63756d656e743c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4c6f6f70696e67546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63652077697468206d756c7469706c65206c6f6f70733c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4a616d6573204469786f6e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865204d756c7469706c65205465737420436f6d706f6e656e742053657175656e636520616e642061206c6f6f703c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d22747275652220646973706c6179747970653d22223e3c66696c656e616d653e536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e53657420476c6f62616c205661726961626c653c2f7469746c653e3c6465736372697074696f6e3e53657473206120676c6f62616c207661726961626c652066726f6d20616e20616374696f6e2073657175656e63653c2f6465736372697074696f6e3e3c617574686f723e4d6172633c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2063616c6c20746f207368617265206120726573756c74207365743c2f7469746c653e3c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2063616c6c20746f207465737420612073686172656420636f6e6e656374696f6e3c2f7469746c653e3c6465736372697074696f6e3e54657374204d445820495072657061726564436f6d706f6e656e7420696e746572666163652c20736861726520636f6e6e656374696f6e2066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e642072657573657320697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20436f6e6e656374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e5465737420537562416374696f6e20636f6d706f6e656e7420636f6e6e656374696f6e206d616e6167656d656e742e205468697320746573742063726561746573206120636f6e6e656374696f6e2077697468696e2061207375622d616374696f6e20616e6420646f6573206e6f7420736861726520697420696e2074686520616374696f6e2e3c2f6465736372697074696f6e3e3c617574686f723e57696c6c20476f726d616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e20546573742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f6620537562416374696f6e20636f6d706f6e656e742e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e537562416374696f6e546573745461726765742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e537562616374696f6e2054657374205461726765742058414354494f4e3c2f7469746c653e3c6465736372697074696f6e3e58414354494f4e206265696e672063616c6c656420627920537562416374696f6e546573742e78616374696f6e3c2f6465736372697074696f6e3e3c617574686f723e416e67656c6f20526f6472696775657a3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e5574696c697479546573742e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e5574696c69747920546573743c2f7469746c653e3c6465736372697074696f6e3e54657374206f6620746865207574696c69747920636f6d706f6e656e742066756e6374696f6e616c6974793c2f6465736372697074696f6e3e3c617574686f723e446f7567204d6f72616e3c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c66696c6520747970653d2246494c452e4143544956495459222076697369626c653d2266616c7365223e3c66696c656e616d653e5646534f7574707574546573745f66696c652e78616374696f6e3c2f66696c656e616d653e3c706174683e706c6174666f726d3c2f706174683e3c736f6c7574696f6e3e746573743c2f736f6c7574696f6e3e3c7469746c653e436f6e74656e74204f757470757420436f6d706f6e656e7420546573743c2f7469746c653e3c6465736372697074696f6e3e53696d706c652074657374206f662074686520636f6e74656e74206f757470757420636f6d706f6e656e743c2f6465736372697074696f6e3e3c617574686f723e4d617263204261746368656c6f723c2f617574686f723e3c70726f706572746965733e737562736372696261626c653d66616c73653c2f70726f706572746965733e3c2f66696c653e3c2f66696c653e3c66696c6520747970653d2246494c452e464f4c444552222076697369626c653d2266616c736522206e616d653d22746d70223e3c706174683e746d703c2f706174683e3c7469746c653e746d703c2f7469746c653e3c2f66696c653e3c2f66696c653e3c2f7265706f7369746f72793e0a3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c7265706f736974696f7279206c6f636174696f6e3d222f55736572732f6a616d65736469786f6e2f446f63756d656e74732f776f726b73706163652d76322f62692d706c6174666f726d2d7265706f7369746f72792f746573742d7372632f736f6c7574696f6e223e3c656e74727920747970653d226469726563746f727922206e616d653d22736f6c7574696f6e223e3c656e74727920747970653d226469726563746f727922206e616d653d2273616d706c6573223e3c656e74727920747970653d226469726563746f727922206e616d653d227265706f7274696e67223e3c656e74727920747970653d2266696c6522206e616d653d224a467265652d7175616472616e742d6275646765742d6873716c2e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224a467265655f517561642e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224a4672656551756164466f72526567696f6e2e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c532e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c532e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f584c535f7a685f434e2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f7265706f72745f7a685f434e2e70726f70657274696573222f3e3c2f656e7472793e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d2274657374223e3c656e74727920747970653d226469726563746f727922206e616d653d2264617368626f617264223e3c656e74727920747970653d2266696c6522206e616d653d226465706172746d656e74732e72756c652e78616374696f6e222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d2264617461736f7572636573223e3c656e74727920747970653d2266696c6522206e616d653d22626f6f6b732e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d224d44585f44617461736f757263652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2271756572795f72756c652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2253616d706c65446174612e6d6f6e647269616e2e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d2253616d706c6544617461536368656d612e7a6970222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f636e2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f64652e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f65732e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f66722e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f69742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f6e6c2e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f70742e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d2258515f44617461736f757263655f7a685f434e2e70726f70657274696573222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d22706c6174666f726d223e3c656e74727920747970653d2266696c6522206e616d653d2262757273742e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d224275727374696e6748544d4c546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224275727374696e67546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6d706f6e656e74546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d2248656c6c6f576f726c642e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22696e6465782e786d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d226a6462632e70726f70657274696573222f3e3c656e74727920747970653d2266696c6522206e616d653d224c6f6f70696e67546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d226d657373616765312e747874222f3e3c656e74727920747970653d2266696c6522206e616d653d224d756c7469436f6d706f6e656e74546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d224d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22706c6174666f726d2e706e67222f3e3c656e74727920747970653d2266696c6522206e616d653d22536574476c6f62616c4f7574707574546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22737562616374696f6e5f7368617265726573756c747365742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22737562616374696f6e5f757365636f6e6e2e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d22537562416374696f6e546573745461726765742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d225574696c697479546573742e78616374696f6e222f3e3c656e74727920747970653d2266696c6522206e616d653d225646534f7574707574546573745f66696c652e78616374696f6e222f3e3c2f656e7472793e3c656e74727920747970653d226469726563746f727922206e616d653d22746d70223e3c656e74727920747970653d2266696c6522206e616d653d2245646974537562736372697074696f6e2e747874222f3e3c656e74727920747970653d2266696c6522206e616d653d2247657441726368697665642e68746d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d2253617665537562736372697074696f6e2e68746d6c222f3e3c656e74727920747970653d2266696c6522206e616d653d22536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e747874222f3e3c2f656e7472793e3c2f656e7472793e3c2f656e7472793e3c2f7265706f736974696f72793e0a3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e0a3c747265653e3c6272616e63682069643d222f736f6c7574696f6e222069734469723d2274727565223e3c6272616e6368546578743e2f3c2f6272616e6368546578743e3c6272616e63682069643d222f736f6c7574696f6e2f73616d706c6573222069734469723d2274727565223e3c6272616e6368546578743e73616d706c65733c2f6272616e6368546578743e3c6272616e63682069643d222f736f6c7574696f6e2f73616d706c65732f7265706f7274696e67222069734469723d2274727565223e3c6272616e6368546578743e7265706f7274696e673c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a467265652d7175616472616e742d6275646765742d6873716c2e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a467265655f517561642e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a467265655f517561642e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4a4672656551756164466f72526567696f6e2e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4a4672656551756164466f72526567696f6e2e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c532e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c532e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c532e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c532e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f584c535f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f584c535f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f7265706f72745f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f73616d706c65732f7265706f7274696e672f4d44585f7265706f72745f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f74657374222069734469723d2274727565223e3c6272616e6368546578743e746573743c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e2e44535f53746f72653c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f2e44535f53746f72653c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f64617368626f617264222069734469723d2274727565223e3c6272616e6368546578743e64617368626f6172643c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e2e44535f53746f72653c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617368626f6172642f2e44535f53746f72653c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6465706172746d656e74732e72756c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617368626f6172642f6465706172746d656e74732e72756c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f64617461736f7572636573222069734469723d2274727565223e3c6272616e6368546578743e64617461736f75726365733c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e626f6f6b732e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f626f6f6b732e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d44585f44617461736f757263652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f4d44585f44617461736f757263652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e71756572795f72756c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f71756572795f72756c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f53616d706c65446174612e6d6f6e647269616e2e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53616d706c6544617461536368656d612e7a69703c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f53616d706c6544617461536368656d612e7a69703c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f636e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f636e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f64652e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f64652e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f65732e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f65732e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f66722e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f66722e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f69742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f69742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f6e6c2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f6e6c2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f70742e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f70742e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e58515f44617461736f757263655f7a685f434e2e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f64617461736f75726365732f58515f44617461736f757263655f7a685f434e2e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f706c6174666f726d222069734469723d2274727565223e3c6272616e6368546578743e706c6174666f726d3c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e62757273742e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f62757273742e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4275727374696e6748544d4c546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4275727374696e6748544d4c546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4275727374696e67546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4275727374696e67546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6d706f6e656e74546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6d706f6e656e74546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f4279746561727261792e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f6572726f72312e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e744f7574707574546573745f6572726f72322e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f436f6e74656e745265706f4f7574707574546573745f66696c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e48656c6c6f576f726c642e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f48656c6c6f576f726c642e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e696e6465782e786d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f696e6465782e786d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6a6462632e70726f706572746965733c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f6a6462632e70726f706572746965733c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4c6f6f70696e67546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4c6f6f70696e67546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e6d657373616765312e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f6d657373616765312e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4d756c7469436f6d706f6e656e74546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f4d756c7469436f6d706f6e656e74546573744c6f6f702e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e706c6174666f726d2e706e673c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f706c6174666f726d2e706e673c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f536574476c6f62616c4f7574707574546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f737562616374696f6e5f7368617265726573756c747365742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f737562616374696f6e5f757365636f6e6e2e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374312e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374322e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374332e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e436f6e6e656374696f6e54657374342e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e537562416374696f6e546573745461726765742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f537562416374696f6e546573745461726765742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e5574696c697479546573742e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f5574696c697479546573742e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e5646534f7574707574546573745f66696c652e78616374696f6e3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f706c6174666f726d2f5646534f7574707574546573745f66696c652e78616374696f6e3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c6272616e63682069643d222f736f6c7574696f6e2f746573742f746d70222069734469723d2274727565223e3c6272616e6368546578743e746d703c2f6272616e6368546578743e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e45646974537562736372697074696f6e2e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f45646974537562736372697074696f6e2e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e47657441726368697665642e68746d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f47657441726368697665642e68746d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e53617665537562736372697074696f6e2e68746d6c3c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f53617665537562736372697074696f6e2e68746d6c3c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c6c6561662069734469723d2266616c7365223e3c6c656166546578743e536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e7478743c2f6c656166546578743e3c706174683e2f736f6c7574696f6e2f746573742f746d702f536f6c7574696f6e5265706f7369746f7279546573742e74657374536f6c7574696f6e5265706f7369746f72792e7478743c2f706174683e3c6c696e6b3e233c2f6c696e6b3e3c2f6c6561663e3c2f6272616e63683e3c2f6272616e63683e3c2f6272616e63683e3c2f747265653e0a',FALSE,1218381033000,'6b1c5f66-6757-11dd-a492-c111aa2b74dc') +INSERT INTO PRO_SUBCONTENT VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0',5,'report','test/dashboard/departments.rule.xaction') +INSERT INTO PRO_SUBCONTPARMS VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0','aced0005740027746573742f64617368626f6172642f6465706172746d656e74732e72756c652e78616374696f6e','actionRef') +INSERT INTO PRO_SUBCONTPARMS VALUES('8e07efc4-66ed-11dd-a681-61af1abf7cd0','aced000574002431336439393932312d363665652d313164642d386530302d396465393161633037336234','subscribe-name') +INSERT INTO PRO_SUBSCRIBE VALUES('13d99921-66ee-11dd-8e00-9de91ac073b4',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') +INSERT INTO PRO_SUBSCRIBE VALUES('8e0ad5f5-66ed-11dd-a681-61af1abf7cd0',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') +INSERT INTO PRO_SUBSCRIBE VALUES('c8db2456-66ed-11dd-bd52-5361aa4c2010',0,1,'Admin','MyMonthlySubscriptionTest','8e07efc4-66ed-11dd-a681-61af1abf7cd0','c:/') diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java index 06087d494c4..e4b2d6ba488 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java @@ -1,9 +1,27 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ + package org.pentaho.platform.api.scheduler2; import java.io.Serializable; import java.util.Map; -import java.util.Date; - public interface IJob { IJobTrigger getJobTrigger(); @@ -11,4 +29,5 @@ public interface IJob { String getJobId(); String getJobName(); JobState getState(); + String getUserName(); } From 2ff8211e2737162bff62480573ab8c85512d20bf Mon Sep 17 00:00:00 2001 From: wilseyler Date: Sat, 14 Oct 2023 21:37:01 -0400 Subject: [PATCH 31/59] [BACKLOG-37897] - Update of pentaho.xml to support email sources --- .../pentaho-solutions/system/pentaho.xml | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml index 13b5002593c..33d54ae1ceb 100644 --- a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml +++ b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml @@ -40,28 +40,34 @@ server.log DEBUG - + + pentaho + + net.sf.ehcache.hibernate.SingletonEhCacheProvider From a05a6f155393e448fdaf53c28e07c81689bd18f5 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Wed, 18 Oct 2023 10:43:08 -0400 Subject: [PATCH 32/59] BACKLOG-38036 - Fixed assembly so that "scheduler-plugin" will be included in the pentaho-solution/system folder --- assemblies/pentaho-solutions/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assemblies/pentaho-solutions/pom.xml b/assemblies/pentaho-solutions/pom.xml index 319ed66e3ea..6175504358e 100644 --- a/assemblies/pentaho-solutions/pom.xml +++ b/assemblies/pentaho-solutions/pom.xml @@ -98,6 +98,13 @@ zip ${prepared.plugins.directory} + + pentaho + pentaho-scheduler-plugin + ${project.version} + zip + ${prepared.plugins.directory} + pentaho pentaho-pdi-platform-plugin-package From 3f84c1617a5bb3eee87f0485d59130ad0cb79559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duarte=20Cunha=20Lea=CC=83o?= Date: Thu, 19 Oct 2023 19:37:44 +0100 Subject: [PATCH 33/59] [BACKLOG-37873] Added ability for a theme to indicate it is responsive - Responsive themes will have CSS class `responsive-theme` be added to the html element - Allows responsive primitives' CSS rules to be shared across themes and between the `responsive` and the new `responsive-content` CSS classes --- .../org/pentaho/platform/api/ui/Theme.java | 25 ++++++++++++++++++- .../src/main/webapp/js/themeResources.js | 14 +++++++---- .../web/html/themes/PluginThemeResolver.java | 3 ++- .../platform/web/servlet/ThemeServlet.java | 6 +++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/org/pentaho/platform/api/ui/Theme.java b/api/src/main/java/org/pentaho/platform/api/ui/Theme.java index a390b30a184..806e505d77d 100644 --- a/api/src/main/java/org/pentaho/platform/api/ui/Theme.java +++ b/api/src/main/java/org/pentaho/platform/api/ui/Theme.java @@ -26,7 +26,7 @@ /** * Theme encapsulates a collection of ThemeResources and a root directory to access them from. - * + * * User: nbaker Date: 5/15/11 */ public class Theme implements Serializable { @@ -42,6 +42,7 @@ public class Theme implements Serializable { private String themeRootDir; private boolean hidden; private String id; + private boolean responsive; public Theme( String id, String name, String rootDir ) { this.id = id; @@ -111,4 +112,26 @@ public String getId() { public void setId( String id ) { this.id = id; } + + /** + * Gets a value that indicates whether the theme is responsive. + * @return `true` if responsive; `false`, otherwise. + */ + public boolean getResponsive() { + return responsive; + } + + /** + * Sets whether the theme is responsive. + *

+ * Responsive themes enable certain CSS classes, e.g. `responsive`, to behave in a responsive manner. + *

+ * When the current theme is responsive, the CSS class `responsive-theme` is added to the HTML document's root + * element, `html`. + * + * @param responsive `true` if responsive; `false`, otherwise. + */ + public void setResponsive( boolean responsive ) { + this.responsive = responsive; + } } diff --git a/assemblies/pentaho-war/src/main/webapp/js/themeResources.js b/assemblies/pentaho-war/src/main/webapp/js/themeResources.js index a84e23211fe..3c4314d5e83 100644 --- a/assemblies/pentaho-war/src/main/webapp/js/themeResources.js +++ b/assemblies/pentaho-war/src/main/webapp/js/themeResources.js @@ -34,11 +34,11 @@ window.onload = function () { } if(window.core_theme_tree){ - includeResources(core_theme_tree); + includeResources(core_theme_tree, true); } if(window.module_theme_tree){ - includeResources(module_theme_tree); + includeResources(module_theme_tree, false); } function addStylesheet(url) { @@ -56,10 +56,14 @@ function addScript(url) { document.getElementsByTagName('head')[0].appendChild(script); } -function includeResources(resourceTree) { +function includeResources(resourceTree, isCore) { var activeTheme = resourceTree && resourceTree[active_theme]; if(!activeTheme) { return; } - + + if(isCore && activeTheme.responsive) { + document.documentElement.classList.add("responsive-theme"); + } + var cssPat = /\.css$/; var resources = activeTheme.resources; for(var i = 0; i < resources.length; i++){ @@ -67,7 +71,7 @@ function includeResources(resourceTree) { var basePath = CONTEXT_PATH + activeTheme.rootDir; if(cssPat.test(baseName)){ addStylesheet(basePath + baseName); - + // Check to see if we're in a mobile device, if so add a "-mobile" if(navigator.userAgent.match(/(iPad|iPod|iPhone)/) != null){ addStylesheet(basePath + baseName.replace('.css', '') + '-mobile.css'); diff --git a/extensions/src/main/java/org/pentaho/platform/web/html/themes/PluginThemeResolver.java b/extensions/src/main/java/org/pentaho/platform/web/html/themes/PluginThemeResolver.java index 00da56345b7..b834b787d5f 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/html/themes/PluginThemeResolver.java +++ b/extensions/src/main/java/org/pentaho/platform/web/html/themes/PluginThemeResolver.java @@ -48,7 +48,7 @@ * Plugins that specify a "root_theme_folder" will have this folder's subfolders added as themes. If the themes are also * in the "system_themes' plugin setting they will be added as system-level themes. If there's already a system theme by * that name loaded it will be overridden. - * + * * User: nbaker Date: 5/15/11 */ public class PluginThemeResolver implements IThemeResolver { @@ -138,6 +138,7 @@ private void findPluginThemes( String pluginId ) { Theme theme = new Theme( themeId, themeName, "content/" + pluginId + "/" + rootThemeFolder + "/" + themeId + "/" ); theme.setHidden( "true".equals( themeNode.attributeValue( "hidden" ) ) ); + theme.setResponsive( "true".equals( themeNode.attributeValue( "responsive" ) ) ); if ( "true".equals( themeNode.attributeValue( "system" ) ) ) { moduleThemeInfo.getSystemThemes().add( theme ); diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/ThemeServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/ThemeServlet.java index f7bb0840b10..348d720eb12 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/ThemeServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/ThemeServlet.java @@ -41,7 +41,7 @@ /** * Writes out the current Theme Tree out as Javascript. The current system and active module theme information is turned * into a JSON object for use by the web client - * + * * User: nbaker Date: 5/24/11 */ public class ThemeServlet extends ServletBase { @@ -66,7 +66,7 @@ public void handleRequest( HttpServletRequest req, HttpServletResponse resp ) th // look for a passed in theme context (content generator, other named area) String moduleName = req.getParameter( "context" ); OutputStream out = resp.getOutputStream(); - resp.setContentType( "text/javascript" ); //$NON-NLS-1$ + resp.setContentType( "text/javascript" ); //$NON-NLS-1$ resp.setHeader( "Cache-Control", "no-cache" ); //$NON-NLS-1$ IUserSettingService settingsService = PentahoSystem.get( IUserSettingService.class, getPentahoSession( req ) ); @@ -107,6 +107,8 @@ public void handleRequest( HttpServletRequest req, HttpServletResponse resp ) th themeObject = new JSONObject(); root.put( theme.getId(), themeObject ); themeObject.put( "rootDir", theme.getThemeRootDir() ); + themeObject.put( "responsive", theme.getResponsive() ); + for ( ThemeResource res : theme.getResources() ) { themeObject.append( "resources", res.getLocation() ); } From 6e2dc3db82ff4cb7c50f3dbb63a036a998ccb68e Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Tue, 31 Oct 2023 10:33:22 -0400 Subject: [PATCH 34/59] [BACKLOG-38801] SCHEDULER - Change developer mode options to production ready. --- user-console/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user-console/pom.xml b/user-console/pom.xml index 41bf79677b0..367a428f91e 100644 --- a/user-console/pom.xml +++ b/user-console/pom.xml @@ -374,9 +374,9 @@ org.pentaho.mantle.MantleApplication ${gwt.outputDirectory} -Xms512m -Xmx1024m - - + From ba7f15adf8e94c6a8ff14104b07caf269763a60d Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 31 Oct 2023 17:49:22 -0400 Subject: [PATCH 35/59] [BACKLOG-39088] - Fixed issue with obtaining a IScheduler object and conversion of classes to interfaces --- .../main/java/org/pentaho/platform/api/scheduler2/IJob.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java index e4b2d6ba488..67a33f2cc01 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java +++ b/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java @@ -21,6 +21,7 @@ package org.pentaho.platform.api.scheduler2; import java.io.Serializable; +import java.util.Date; import java.util.Map; public interface IJob { @@ -30,4 +31,6 @@ public interface IJob { String getJobName(); JobState getState(); String getUserName(); + Date getNextRun(); + Date getLastRun(); } From 6433d3f1e31020c3f7dbe83c2c9b2faf69a6189a Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Wed, 1 Nov 2023 15:56:25 -0400 Subject: [PATCH 36/59] [BACKLOG-38633] SCHEDULER - Evaluate and fix if necessary references to the old scheduler REST services --- .../java/org/pentaho/mantle/client/ui/PerspectiveManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 7bef0d51318..113885078f8 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -115,7 +115,7 @@ private Collection getMenuItems(){ } private void init() { - final String url = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/canSchedule/?ts=" + System.currentTimeMillis(); //$NON-NLS-1$ + final String url = MantleUtils.getSchedulerPluginContextURL() + "api/scheduler/canSchedule?ts=" + System.currentTimeMillis(); //$NON-NLS-1$ RequestBuilder builder = new RequestBuilder( RequestBuilder.GET, url ); builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$ builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" ); From d12ab871813da9ef71401f4a230cfb6fae7bfba2 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar-Ojeda <713962+e-cuellar@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:48:02 -0400 Subject: [PATCH 37/59] Revert "[BACKLOG-38801] SCHEDULER - Change developer mode options to production ready." --- user-console/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user-console/pom.xml b/user-console/pom.xml index 367a428f91e..41bf79677b0 100644 --- a/user-console/pom.xml +++ b/user-console/pom.xml @@ -374,9 +374,9 @@ org.pentaho.mantle.MantleApplication ${gwt.outputDirectory} -Xms512m -Xmx1024m - + - --> From 73d360ed9a5c6178924abfb619d636024ede5613 Mon Sep 17 00:00:00 2001 From: Tim Kafalas tkafalas Date: Tue, 31 Oct 2023 10:48:31 -0400 Subject: [PATCH 38/59] [BACKLOG-39083] Add old commons-dbcp and commons-pool jars back to CE build. Needed by jackrabbit. --- core/pom.xml | 25 +++++++++++++++++++++++++ pom.xml | 6 +++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 4d5350f986a..c48a913edb4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -125,6 +125,31 @@ + + + commons-dbcp + commons-dbcp + ${commons-dbcp.version} + compile + + + * + * + + + + + commons-pool + commons-pool + ${commons-pool.version} + compile + + + * + * + + + commons-io commons-io diff --git a/pom.xml b/pom.xml index c5ac90c20c4..0cead470be5 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,6 @@ 4.1.1 3.6.1 1.06 - 1.20 2.4.8 1.9.3 2018 @@ -58,7 +57,9 @@ 1 1.0 3.2.4 - 54.1.1 + 63.1 + 1.4 + 1.5.7 2.1 0.9.46 3.0.8 @@ -161,7 +162,6 @@ 1.0.13 2.8 1.2.5 - 3.7.2 4.4 1.41.4 1.0 From 464240f1bd82132556bb67bb46a69825752efc64 Mon Sep 17 00:00:00 2001 From: Ezequiel Cuellar Date: Fri, 10 Nov 2023 09:52:49 -0500 Subject: [PATCH 39/59] [BACKLOG-39120] Move all scheduler related interfaces from scheduler module into api in pentaho-platform --- .../IBackgroundExecutionStreamProvider.java | 0 .../api/scheduler2/IBlockoutManager.java | 0 .../api/scheduler2/IComplexJobTrigger.java | 0 .../api/scheduler2/ICronJobTrigger.java | 0 .../pentaho/platform/api/scheduler2/IJob.java | 0 .../platform/api/scheduler2/IJobFilter.java | 0 .../platform/api/scheduler2/IJobRequest.java | 0 .../platform/api/scheduler2/IJobResult.java | 0 .../api/scheduler2/IJobScheduleParam.java | 0 .../api/scheduler2/IJobScheduleRequest.java | 0 .../platform/api/scheduler2/IJobTrigger.java | 0 .../api/scheduler2/IScheduleSubject.java | 0 .../platform/api/scheduler2/IScheduler.java | 22 ++++++++-------- .../api/scheduler2/ISchedulerListener.java | 0 .../api/scheduler2/ISchedulerResource.java | 0 .../api/scheduler2/ISimpleJobTrigger.java | 0 .../platform/api/scheduler2/JobState.java | 0 .../api/scheduler2/SchedulerException.java | 0 .../wrappers/DayOfMonthWrapper.java | 0 .../scheduler2/wrappers/DayOfWeekWrapper.java | 0 .../scheduler2/wrappers/HourlyWrapper.java | 0 .../api/scheduler2/wrappers/ITimeWrapper.java | 0 .../scheduler2/wrappers/MinuteWrapper.java | 0 .../scheduler2/wrappers/MonthlyWrapper.java | 0 .../scheduler2/wrappers/SecondWrapper.java | 0 .../scheduler2/wrappers/YearlyWrapper.java | 0 .../platform/api/util/QuartzActionUtil.java | 19 ++++++++++++++ .../scheduler2/recur/ITimeRecurrence.java | 0 .../recur/IncrementalRecurrence.java | 0 .../scheduler2/recur/QualifiedDayOfMonth.java | 0 .../scheduler2/recur/QualifiedDayOfWeek.java | 0 .../scheduler2/recur/RecurrenceList.java | 0 .../recur/SequentialRecurrence.java | 0 .../org/pentaho/platform/util/ActionUtil.java | 26 +++++++++---------- 34 files changed, 43 insertions(+), 24 deletions(-) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IScheduleSubject.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java (92%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerListener.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/SchedulerException.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java (100%) create mode 100644 api/src/main/java/org/pentaho/platform/api/util/QuartzActionUtil.java rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java (100%) rename {scheduler => api}/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java (100%) diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IBackgroundExecutionStreamProvider.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IBlockoutManager.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/ICronJobTrigger.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJob.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobFilter.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobRequest.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobResult.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleParam.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobScheduleRequest.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IJobTrigger.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduleSubject.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduleSubject.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduleSubject.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduleSubject.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java similarity index 92% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java index 7fd699834c6..a9ede7eba75 100644 --- a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java +++ b/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java @@ -27,7 +27,7 @@ import java.util.Map; import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.util.ActionUtil; +import org.pentaho.platform.api.util.QuartzActionUtil; /** * An object that allows for the scheduling of IActions on the Pentaho platform @@ -36,24 +36,24 @@ */ public interface IScheduler { - String RESERVEDMAPKEY_ACTIONCLASS = ActionUtil.QUARTZ_ACTIONCLASS; - String RESERVEDMAPKEY_ACTIONUSER = ActionUtil.QUARTZ_ACTIONUSER; + String RESERVEDMAPKEY_ACTIONCLASS = QuartzActionUtil.QUARTZ_ACTIONCLASS; + String RESERVEDMAPKEY_ACTIONUSER = QuartzActionUtil.QUARTZ_ACTIONUSER; - String RESERVEDMAPKEY_ACTIONID = ActionUtil.QUARTZ_ACTIONID; + String RESERVEDMAPKEY_ACTIONID = QuartzActionUtil.QUARTZ_ACTIONID; - String RESERVEDMAPKEY_STREAMPROVIDER = ActionUtil.QUARTZ_STREAMPROVIDER; + String RESERVEDMAPKEY_STREAMPROVIDER = QuartzActionUtil.QUARTZ_STREAMPROVIDER; - String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = ActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; + String RESERVEDMAPKEY_STREAMPROVIDER_INPUTFILE = QuartzActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; - String RESERVEDMAPKEY_UIPASSPARAM = ActionUtil.QUARTZ_UIPASSPARAM; + String RESERVEDMAPKEY_UIPASSPARAM = QuartzActionUtil.QUARTZ_UIPASSPARAM; - String RESERVEDMAPKEY_LINEAGE_ID = ActionUtil.QUARTZ_LINEAGE_ID; + String RESERVEDMAPKEY_LINEAGE_ID = QuartzActionUtil.QUARTZ_LINEAGE_ID; - String RESERVEDMAPKEY_RESTART_FLAG = ActionUtil.QUARTZ_RESTART_FLAG; + String RESERVEDMAPKEY_RESTART_FLAG = QuartzActionUtil.QUARTZ_RESTART_FLAG; - String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = ActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; + String RESERVEDMAPKEY_AUTO_CREATE_UNIQUE_FILENAME = QuartzActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; - String RESERVEDMAPKEY_APPEND_DATE_FORMAT = ActionUtil.QUARTZ_APPEND_DATE_FORMAT; + String RESERVEDMAPKEY_APPEND_DATE_FORMAT = QuartzActionUtil.QUARTZ_APPEND_DATE_FORMAT; enum SchedulerStatus { RUNNING, PAUSED, STOPPED diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerListener.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerListener.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerListener.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerListener.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/ISchedulerResource.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/ISimpleJobTrigger.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/JobState.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SchedulerException.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/SchedulerException.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/SchedulerException.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/SchedulerException.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfMonthWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/DayOfWeekWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/HourlyWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/ITimeWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MinuteWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/MonthlyWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/SecondWrapper.java diff --git a/scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java rename to api/src/main/java/org/pentaho/platform/api/scheduler2/wrappers/YearlyWrapper.java diff --git a/api/src/main/java/org/pentaho/platform/api/util/QuartzActionUtil.java b/api/src/main/java/org/pentaho/platform/api/util/QuartzActionUtil.java new file mode 100644 index 00000000000..50b43f2ef23 --- /dev/null +++ b/api/src/main/java/org/pentaho/platform/api/util/QuartzActionUtil.java @@ -0,0 +1,19 @@ +package org.pentaho.platform.api.util; + +public class QuartzActionUtil { + + public static final String QUARTZ_ACTIONCLASS = "ActionAdapterQuartzJob-ActionClass"; //$NON-NLS-1$ + public static final String QUARTZ_ACTIONUSER = "ActionAdapterQuartzJob-ActionUser"; //$NON-NLS-1$ + public static final String QUARTZ_ACTIONID = "ActionAdapterQuartzJob-ActionId"; //$NON-NLS-1$ + public static final String QUARTZ_STREAMPROVIDER = "ActionAdapterQuartzJob-StreamProvider"; //$NON-NLS-1$ + public static final String QUARTZ_STREAMPROVIDER_INPUT_FILE = + "ActionAdapterQuartzJob-StreamProvider-InputFile"; //$NON-NLS-1$ + public static final String QUARTZ_STREAMPROVIDER_INLINE_INPUT_FILE = "input file ="; //$NON-NLS-1$ + public static final String QUARTZ_STREAMPROVIDER_INLINE_OUTPUT_FILE = ":output file="; //$NON-NLS-1$ + public static final String QUARTZ_UIPASSPARAM = "uiPassParam"; //$NON-NLS-1$ + public static final String QUARTZ_LINEAGE_ID = "lineage-id"; //$NON-NLS-1$ + public static final String QUARTZ_RESTART_FLAG = "ActionAdapterQuartzJob-Restart"; //$NON-NLS-1$ + public static final String QUARTZ_AUTO_CREATE_UNIQUE_FILENAME = "autoCreateUniqueFilename"; //$NON-NLS-1$ + public static final String QUARTZ_APPEND_DATE_FORMAT = "appendDateFormat"; //$NON-NLS-1$ + +} diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/ITimeRecurrence.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/IncrementalRecurrence.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfMonth.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/QualifiedDayOfWeek.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/RecurrenceList.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java b/api/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java rename to api/src/main/java/org/pentaho/platform/scheduler2/recur/SequentialRecurrence.java diff --git a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java index 374f93daa04..23d41012e39 100644 --- a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java +++ b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java @@ -30,6 +30,7 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData; +import org.pentaho.platform.api.util.QuartzActionUtil; import org.pentaho.platform.api.workitem.IWorkItemLifecycleEventPublisher; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.util.messages.Messages; @@ -45,19 +46,18 @@ public class ActionUtil { private static final Log logger = LogFactory.getLog( ActionUtil.class ); - public static final String QUARTZ_ACTIONCLASS = "ActionAdapterQuartzJob-ActionClass"; //$NON-NLS-1$ - public static final String QUARTZ_ACTIONUSER = "ActionAdapterQuartzJob-ActionUser"; //$NON-NLS-1$ - public static final String QUARTZ_ACTIONID = "ActionAdapterQuartzJob-ActionId"; //$NON-NLS-1$ - public static final String QUARTZ_STREAMPROVIDER = "ActionAdapterQuartzJob-StreamProvider"; //$NON-NLS-1$ - public static final String QUARTZ_STREAMPROVIDER_INPUT_FILE = - "ActionAdapterQuartzJob-StreamProvider-InputFile"; //$NON-NLS-1$ - public static final String QUARTZ_STREAMPROVIDER_INLINE_INPUT_FILE = "input file ="; //$NON-NLS-1$ - public static final String QUARTZ_STREAMPROVIDER_INLINE_OUTPUT_FILE = ":output file="; //$NON-NLS-1$ - public static final String QUARTZ_UIPASSPARAM = "uiPassParam"; //$NON-NLS-1$ - public static final String QUARTZ_LINEAGE_ID = "lineage-id"; //$NON-NLS-1$ - public static final String QUARTZ_RESTART_FLAG = "ActionAdapterQuartzJob-Restart"; //$NON-NLS-1$ - public static final String QUARTZ_AUTO_CREATE_UNIQUE_FILENAME = "autoCreateUniqueFilename"; //$NON-NLS-1$ - public static final String QUARTZ_APPEND_DATE_FORMAT = "appendDateFormat"; //$NON-NLS-1$ + public static final String QUARTZ_ACTIONCLASS = QuartzActionUtil.QUARTZ_ACTIONCLASS; + public static final String QUARTZ_ACTIONUSER = QuartzActionUtil.QUARTZ_ACTIONUSER; + public static final String QUARTZ_ACTIONID = QuartzActionUtil.QUARTZ_ACTIONID; + public static final String QUARTZ_STREAMPROVIDER = QuartzActionUtil.QUARTZ_STREAMPROVIDER; + public static final String QUARTZ_STREAMPROVIDER_INPUT_FILE = QuartzActionUtil.QUARTZ_STREAMPROVIDER_INPUT_FILE; + public static final String QUARTZ_STREAMPROVIDER_INLINE_INPUT_FILE = QuartzActionUtil.QUARTZ_STREAMPROVIDER_INLINE_INPUT_FILE; + public static final String QUARTZ_STREAMPROVIDER_INLINE_OUTPUT_FILE = QuartzActionUtil.QUARTZ_STREAMPROVIDER_INLINE_OUTPUT_FILE; + public static final String QUARTZ_UIPASSPARAM = QuartzActionUtil.QUARTZ_UIPASSPARAM; + public static final String QUARTZ_LINEAGE_ID = QuartzActionUtil.QUARTZ_LINEAGE_ID; + public static final String QUARTZ_RESTART_FLAG = QuartzActionUtil.QUARTZ_RESTART_FLAG; + public static final String QUARTZ_AUTO_CREATE_UNIQUE_FILENAME = QuartzActionUtil.QUARTZ_AUTO_CREATE_UNIQUE_FILENAME; + public static final String QUARTZ_APPEND_DATE_FORMAT = QuartzActionUtil.QUARTZ_APPEND_DATE_FORMAT; public static final String INVOKER_ACTIONPARAMS = "actionParams"; public static final String INVOKER_ACTIONCLASS = "actionClass"; //$NON-NLS-1$ From 16caff1688356a5fdd16bfbdeff4d051d2af284d Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Fri, 10 Nov 2023 19:05:50 -0500 Subject: [PATCH 40/59] [BACKLOG-39120] Move all scheduler related interfaces from scheduler --- .../http/api/proxies/BlockStatusProxy.java | 94 ------------ .../api/resources/ComplexJobTriggerProxy.java | 135 ------------------ .../proxies/BlockStatusProxyTest.java | 30 ---- 3 files changed, 259 deletions(-) delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/ComplexJobTriggerProxy.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java deleted file mode 100644 index 78b1133e2b5..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/proxies/BlockStatusProxy.java +++ /dev/null @@ -1,94 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.proxies; - -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import javax.xml.bind.annotation.XmlRootElement; - -/** - * @author wseyler - * - */ -@XmlRootElement -public class BlockStatusProxy { - Boolean totallyBlocked; - Boolean partiallyBlocked; - - public BlockStatusProxy() { - this( false, false ); - } - - public BlockStatusProxy( Boolean totallyBlocked, Boolean partiallyBlocked ) { - super(); - this.totallyBlocked = totallyBlocked; - this.partiallyBlocked = partiallyBlocked; - } - - public Boolean getTotallyBlocked() { - return totallyBlocked; - } - - public void setTotallyBlocked( Boolean totallyBlocked ) { - this.totallyBlocked = totallyBlocked; - } - - public Boolean getPartiallyBlocked() { - return partiallyBlocked; - } - - public void setPartiallyBlocked( Boolean partiallyBlocked ) { - this.partiallyBlocked = partiallyBlocked; - } - - @Override public boolean equals( Object o ) { - if ( this == o ) { - return true; - } - - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - BlockStatusProxy that = (BlockStatusProxy) o; - - return new EqualsBuilder() - .append( totallyBlocked, that.totallyBlocked ) - .append( partiallyBlocked, that.partiallyBlocked ) - .isEquals(); - } - - @Override public int hashCode() { - return new HashCodeBuilder( 17, 37 ) - .append( totallyBlocked ) - .append( partiallyBlocked ) - .toHashCode(); - } - - @Override public String toString() { - return new ToStringBuilder( this ) - .append( "partiallyBlocked", partiallyBlocked ) - .append( "totallyBlocked", totallyBlocked ) - .toString(); - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/ComplexJobTriggerProxy.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/ComplexJobTriggerProxy.java deleted file mode 100644 index 2fd5f29c639..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/ComplexJobTriggerProxy.java +++ /dev/null @@ -1,135 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import javax.xml.bind.annotation.XmlRootElement; -import java.util.Date; - -@XmlRootElement -public class ComplexJobTriggerProxy { - - int[] daysOfWeek = new int[0]; - int[] daysOfMonth = new int[0]; - int[] weeksOfMonth = new int[0]; - int[] monthsOfYear = new int[0]; - int[] years = new int[0]; - - Date startTime; - Date endTime; - String uiPassParam; - String cronString; - String cronDescription; - private long repeatInterval = 0; - - public long getRepeatInterval() { - return repeatInterval; - } - public void setRepeatInterval( long repeatIntervalSeconds ) { - this.repeatInterval = repeatIntervalSeconds; - } - - public Date getStartTime() { - return startTime; - } - - public void setStartTime( Date startTime ) { - this.startTime = startTime; - } - - public Date getEndTime() { - return endTime; - } - - public void setEndTime( Date endTime ) { - this.endTime = endTime; - } - - public int[] getDaysOfWeek() { - return daysOfWeek; - } - - public void setDaysOfWeek( int[] daysOfWeek ) { - if ( ( daysOfWeek != null ) && ( daysOfWeek.length > 0 ) ) { - setDaysOfMonth( null ); - } - this.daysOfWeek = daysOfWeek == null ? new int[0] : daysOfWeek; - } - - public int[] getDaysOfMonth() { - return daysOfMonth; - } - - public void setDaysOfMonth( int[] daysOfMonth ) { - if ( ( daysOfMonth != null ) && ( daysOfMonth.length > 0 ) ) { - setDaysOfWeek( null ); - } - this.daysOfMonth = daysOfMonth == null ? new int[0] : daysOfMonth; - } - - public int[] getWeeksOfMonth() { - return weeksOfMonth; - } - - public void setWeeksOfMonth( int[] weeksOfMonth ) { - this.weeksOfMonth = weeksOfMonth == null ? new int[0] : weeksOfMonth; - } - - public int[] getMonthsOfYear() { - return monthsOfYear; - } - - public void setMonthsOfYear( int[] monthsOfYear ) { - this.monthsOfYear = monthsOfYear == null ? new int[0] : monthsOfYear; - } - - public int[] getYears() { - return years; - } - - public void setYears( int[] years ) { - this.years = years == null ? new int[0] : years; - } - - public String getUiPassParam() { - return uiPassParam; - } - - public void setUiPassParam( String uiPassParam ) { - this.uiPassParam = uiPassParam; - } - - public String getCronString() { - return cronString; - } - - public void setCronString( String cronString ) { - this.cronString = cronString; - } - - public String getCronDescription() { - return cronDescription; - } - - public void setCronDescription( String cronDescription ) { - this.cronDescription = cronDescription; - } - -} diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java b/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java deleted file mode 100644 index 59d841a38eb..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/proxies/BlockStatusProxyTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources.proxies; - -import org.pentaho.platform.web.http.api.proxies.BlockStatusProxy; -import org.pentaho.test.BeanTester; - -public class BlockStatusProxyTest extends BeanTester { - public BlockStatusProxyTest() { - super( BlockStatusProxy.class ); - } -} From 813c372506383a2ca74711b6e3ef379725c3b15e Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Fri, 10 Nov 2023 19:20:28 -0500 Subject: [PATCH 41/59] [BACKLOG-39120] Move all scheduler related classes from scheduler module to scheduler-plugin --- .../SchedulerOutputPathResolver.java | 137 ------------------ 1 file changed, 137 deletions(-) delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java deleted file mode 100644 index 6e937a052c0..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/SchedulerOutputPathResolver.java +++ /dev/null @@ -1,137 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; -import org.pentaho.platform.api.usersettings.IUserSettingService; -import org.pentaho.platform.api.usersettings.pojo.IUserSetting; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.repository.RepositoryFilenameUtils; -import org.pentaho.platform.repository2.ClientRepositoryPaths; - -/** - * @author Rowell Belen - */ -public class SchedulerOutputPathResolver { - - final String DEFAULT_SETTING_KEY = "default-scheduler-output-path"; - - private static final Log logger = LogFactory.getLog( SchedulerOutputPathResolver.class ); - - private IUnifiedRepository repository = PentahoSystem.get( IUnifiedRepository.class ); - private IPentahoSession pentahoSession = PentahoSessionHolder.getSession(); - - private IUserSettingService getSettingsService() { - if ( settingsService == null ) { - settingsService = PentahoSystem.get( IUserSettingService.class, pentahoSession ); - } - return settingsService; - } - - private IUserSettingService settingsService; - private IJobScheduleRequest scheduleRequest; - - public SchedulerOutputPathResolver( IJobScheduleRequest scheduleRequest ) { - this.scheduleRequest = scheduleRequest; - } - - public String resolveOutputFilePath() { - - String fileName = RepositoryFilenameUtils.getBaseName( scheduleRequest.getInputFile() ); // default file name - if ( !StringUtils.isEmpty( scheduleRequest.getJobName() ) ) { - fileName = scheduleRequest.getJobName(); // use job name as file name if exists - } - String fileNamePattern = "/" + fileName + ".*"; - - String outputFilePath = scheduleRequest.getOutputFile(); - if ( outputFilePath != null && outputFilePath.endsWith( fileNamePattern ) ) { - // we are creating a schedule with a completed path already, strip off the pattern and validate the folder is valid - outputFilePath = outputFilePath.substring( 0, outputFilePath.indexOf( fileNamePattern ) ); - } - if ( StringUtils.isNotBlank( outputFilePath ) && isValidOutputPath( outputFilePath ) ) { - return outputFilePath + fileNamePattern; // return if valid - } - - // evaluate fallback output paths - String[] fallBackPaths = new String[] { getUserSettingOutputPath(), // user setting - getSystemSettingOutputPath(), // system setting - getUserHomeDirectoryPath() // home directory - }; - - for ( String path : fallBackPaths ) { - if ( StringUtils.isNotBlank( path ) && isValidOutputPath( path ) ) { - return path + fileNamePattern; // return the first valid path - } - } - - return null; // it should never reach here - } - - protected boolean isValidOutputPath( String path ) { - try { - RepositoryFile repoFile = repository.getFile( path ); - if ( repoFile != null && repoFile.isFolder() ) { - return true; - } - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return false; - } - - protected String getUserSettingOutputPath() { - try { - IUserSetting userSetting = getSettingsService().getUserSetting( DEFAULT_SETTING_KEY, null ); - if ( userSetting != null && StringUtils.isNotBlank( userSetting.getSettingValue() ) ) { - return userSetting.getSettingValue(); - } - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - - protected String getSystemSettingOutputPath() { - try { - return PentahoSystem.getSystemSettings().getSystemSetting( DEFAULT_SETTING_KEY, null ); - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - - protected String getUserHomeDirectoryPath() { - try { - return ClientRepositoryPaths.getUserHomeFolderPath( pentahoSession.getName() ); - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - -} From 4fb9809082e3aeeca164c4450fa1642ffcc53c99 Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Sat, 11 Nov 2023 22:10:36 -0500 Subject: [PATCH 42/59] update the code after merge from master --- .../org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java index 1ff302964f9..2fb0e9ddbba 100644 --- a/api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java +++ b/api/src/main/java/org/pentaho/platform/api/scheduler2/IComplexJobTrigger.java @@ -36,5 +36,6 @@ public interface IComplexJobTrigger extends IJobTrigger { YearlyWrapper getYearlyRecurrences(); DayOfWeekWrapper getDayOfWeekRecurrences(); + void setMinuteRecurrence( Integer... recurrence ); } From daeff09b8787b6be1fdc54253a2de6c59782abd4 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 14 Nov 2023 15:17:43 -0500 Subject: [PATCH 43/59] [BACKLOG-39119] - Move of JobRequest, JobScheduleParam, and ScheduleExportUtil out of pentaho-platform --- .../platform/api/scheduler2/IScheduler.java | 2 + .../platform/api/util/IExportHelper.java | 21 +- .../api/util/IPentahoPlatformExporter.java | 29 +- .../pentaho-solutions/system/importExport.xml | 4 + .../exporter/PentahoPlatformExporter.java | 44 +- .../services/exporter/ScheduleExportUtil.java | 161 ---- .../importer/SolutionImportHandler.java | 39 +- .../scheduler2/action/ActionRunner.java | 0 .../action/DefaultActionInvoker.java | 4 +- .../action/SchedulerOutputPathResolver.java | 0 .../scheduler2/messsages/Messages.java | 0 .../http/api/resources/JobScheduleParam.java | 163 ---- .../api/resources/services/FileService.java | 81 +- .../exporter/PentahoPlatformExporterTest.java | 404 +++++++++ .../importer/SolutionImportHandlerTest.java | 813 ++++++++++++++++++ pom.xml | 1 - scheduler/.gitignore | 6 - scheduler/LICENSE.txt | 504 ----------- scheduler/pom.xml | 224 ----- .../RepositoryCleanerSystemListener.java | 225 ----- .../services/repository/RepositoryGcJob.java | 44 - .../scheduler2/messsages/messages.properties | 46 - .../messsages/messages_de.properties | 44 - .../messsages/messages_fr.properties | 44 - .../messsages/messages_ja.properties | 44 - .../messsages/messages_zh_CN.properties | 46 - 26 files changed, 1312 insertions(+), 1681 deletions(-) rename extensions/src/test/java/org/pentaho/platform/web/http/api/resources/JobRequestTest.java => api/src/main/java/org/pentaho/platform/api/util/IExportHelper.java (64%) rename extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java => api/src/main/java/org/pentaho/platform/api/util/IPentahoPlatformExporter.java (57%) delete mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java rename {scheduler => extensions}/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java (100%) rename {scheduler => extensions}/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java (97%) rename {scheduler => extensions}/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java (100%) rename {scheduler => extensions}/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java (100%) delete mode 100644 extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java create mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java create mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java delete mode 100644 scheduler/.gitignore delete mode 100644 scheduler/LICENSE.txt delete mode 100644 scheduler/pom.xml delete mode 100644 scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java delete mode 100644 scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties delete mode 100644 scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties diff --git a/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java index a9ede7eba75..ad3ad0cc5b6 100644 --- a/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java +++ b/api/src/main/java/org/pentaho/platform/api/scheduler2/IScheduler.java @@ -321,6 +321,8 @@ void fireJobCompleted( final IAction actionBean, final String actionUser, ISchedulerResource createSchedulerResource(); + IJobRequest createJobRequest(); + /** * A default implementation which doesn't do anything and exists for the backward compatibility sake. * @param jobParams scheduling job parameters diff --git a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/JobRequestTest.java b/api/src/main/java/org/pentaho/platform/api/util/IExportHelper.java similarity index 64% rename from extensions/src/test/java/org/pentaho/platform/web/http/api/resources/JobRequestTest.java rename to api/src/main/java/org/pentaho/platform/api/util/IExportHelper.java index 30ea508c96a..33e4475cbac 100644 --- a/extensions/src/test/java/org/pentaho/platform/web/http/api/resources/JobRequestTest.java +++ b/api/src/main/java/org/pentaho/platform/api/util/IExportHelper.java @@ -14,25 +14,12 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ -package org.pentaho.platform.web.http.api.resources; +package org.pentaho.platform.api.util; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Created by rfellows on 11/10/15. - */ -public class JobRequestTest { - - @Test - public void testConstructor() throws Exception { - JobRequest jr = new JobRequest(); - jr.setJobId( "jobId" ); - assertEquals( "jobId", jr.getJobId() ); - } +public interface IExportHelper { + public void doExport( Object exportArg ); } diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java b/api/src/main/java/org/pentaho/platform/api/util/IPentahoPlatformExporter.java similarity index 57% rename from extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java rename to api/src/main/java/org/pentaho/platform/api/util/IPentahoPlatformExporter.java index f2216bf8fe0..90f4c088dba 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobRequest.java +++ b/api/src/main/java/org/pentaho/platform/api/util/IPentahoPlatformExporter.java @@ -14,33 +14,12 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ -package org.pentaho.platform.web.http.api.resources; - -import org.pentaho.platform.api.scheduler2.IJobRequest; - -import javax.xml.bind.annotation.XmlRootElement; -import java.io.Serializable; - -@XmlRootElement -public class JobRequest implements Serializable, IJobRequest { - - private static final long serialVersionUID = 6111578259094385262L; - - private String jobId; - - public JobRequest() { - } - - public String getJobId() { - return jobId; - } - - public void setJobId( String jobId ) { - this.jobId = jobId; - } +package org.pentaho.platform.api.util; +public interface IPentahoPlatformExporter { + void addExportHelper( IExportHelper helper ); } diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/importExport.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/importExport.xml index 6e5a45f22ef..0a3195e3ff8 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/importExport.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/importExport.xml @@ -206,6 +206,10 @@ + + + + diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java index 84e92a2877c..b68f6b2169c 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporter.java @@ -41,6 +41,8 @@ import org.pentaho.platform.api.usersettings.IAnyUserSettingService; import org.pentaho.platform.api.usersettings.IUserSettingService; import org.pentaho.platform.api.usersettings.pojo.IUserSetting; +import org.pentaho.platform.api.util.IExportHelper; +import org.pentaho.platform.api.util.IPentahoPlatformExporter; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.core.system.TenantUtils; import org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService; @@ -75,6 +77,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -82,7 +85,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -public class PentahoPlatformExporter extends ZipExportProcessor { +public class PentahoPlatformExporter extends ZipExportProcessor implements IPentahoPlatformExporter { private static final Logger log = LoggerFactory.getLogger( PentahoPlatformExporter.class ); @@ -94,7 +97,6 @@ public class PentahoPlatformExporter extends ZipExportProcessor { public static final String METASTORE = "metastore"; public static final String METASTORE_BACKUP_EXT = ".mzip"; - private File exportFile; protected ZipOutputStream zos; private IScheduler scheduler; @@ -105,6 +107,8 @@ public class PentahoPlatformExporter extends ZipExportProcessor { private IMetaStore metastore; private IUserSettingService userSettingService; + private List exportHelpers = new ArrayList<>(); + public PentahoPlatformExporter( IUnifiedRepository repository ) { super( ROOT, repository, true ); setUnifiedRepository( repository ); @@ -115,6 +119,16 @@ public File performExport() throws ExportException, IOException { return this.performExport( null ); } + public void addExportHelper( IExportHelper helper ) { + exportHelpers.add( helper ); + } + + public void runExportHelpers() { + for ( IExportHelper helper : exportHelpers ) { + helper.doExport( getExportManifest() ); + } + } + /** * Performs the export process, returns a zip File object * @@ -127,7 +141,7 @@ public File performExport( RepositoryFile exportRepositoryFile ) throws ExportEx exportRepositoryFile = getUnifiedRepository().getFile( ROOT ); // create temp file - exportFile = File.createTempFile( EXPORT_TEMP_FILENAME_PREFIX, EXPORT_TEMP_FILENAME_EXT ); + File exportFile = File.createTempFile( EXPORT_TEMP_FILENAME_PREFIX, EXPORT_TEMP_FILENAME_EXT ); exportFile.deleteOnExit(); zos = new ZipOutputStream( new FileOutputStream( exportFile ) ); @@ -136,7 +150,7 @@ public File performExport( RepositoryFile exportRepositoryFile ) throws ExportEx exportDatasources(); exportMondrianSchemas(); exportMetadataModels(); - exportSchedules(); + runExportHelpers(); exportUsersAndRoles(); exportMetastore(); @@ -307,28 +321,6 @@ protected boolean parseXmlaEnabled( String dataSourceInfo ) { return xmlaEnabled == null ? false : Boolean.parseBoolean( xmlaEnabled.replace( "\"", "" ) ); } - protected void exportSchedules() { - log.debug( "export schedules" ); - try { - List jobs = getScheduler().getJobs( null ); - for ( IJob job : jobs ) { - if ( job.getJobName().equals( "PentahoSystemVersionCheck" ) ) { - // don't bother exporting the Version Checker schedule, it gets created automatically on server start - // if it doesn't exist and fails if you try to import it due to a null ActionClass - continue; - } - try { - IJobScheduleRequest scheduleRequest = ScheduleExportUtil.createJobScheduleRequest( job ); - getExportManifest().addSchedule( scheduleRequest ); - } catch ( IllegalArgumentException e ) { - log.warn( e.getMessage(), e ); - } - } - } catch ( SchedulerException e ) { - log.error( Messages.getInstance().getString( "PentahoPlatformExporter.ERROR_EXPORTING_JOBS" ), e ); - } - } - protected void exportUsersAndRoles() { log.debug( "export users & roles" ); diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java deleted file mode 100644 index 64556b7117d..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/exporter/ScheduleExportUtil.java +++ /dev/null @@ -1,161 +0,0 @@ -/*! - * - * 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-2022 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.exporter; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang.ArrayUtils; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.ICronJobTrigger; -import org.pentaho.platform.api.scheduler2.IBlockoutManager; -import org.pentaho.platform.api.scheduler2.IJob; - -import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.plugin.services.messages.Messages; -import org.pentaho.platform.repository.RepositoryFilenameUtils; -import org.pentaho.platform.web.http.api.resources.JobScheduleParam; -import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; - -public class ScheduleExportUtil { - - public static final String RUN_PARAMETERS_KEY = "parameters"; - - public ScheduleExportUtil() { - // to get 100% coverage - } - - public static IJobScheduleRequest createJobScheduleRequest( IJob job ) { - if ( job == null ) { - throw new IllegalArgumentException( - Messages.getInstance().getString( "ScheduleExportUtil.JOB_MUST_NOT_BE_NULL" ) ); - } - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); //$NON-NLS-1$ - assert scheduler != null; - IJobScheduleRequest schedule = scheduler.createJobScheduleRequest(); - schedule.setJobName( job.getJobName() ); - schedule.setDuration( job.getJobTrigger().getDuration() ); - schedule.setJobState( job.getState() ); - - Map jobParams = job.getJobParams(); - - Object streamProviderObj = jobParams.get( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER ); - RepositoryFileStreamProvider streamProvider = null; - if ( streamProviderObj instanceof RepositoryFileStreamProvider ) { - streamProvider = (RepositoryFileStreamProvider) streamProviderObj; - } else if ( streamProviderObj instanceof String ) { - String inputFilePath = null; - String outputFilePath = null; - String inputOutputString = (String) streamProviderObj; - String[] tokens = inputOutputString.split( ":" ); - if ( !ArrayUtils.isEmpty( tokens ) && tokens.length == 2 ) { - inputFilePath = tokens[ 0 ].split( "=" )[ 1 ].trim(); - outputFilePath = tokens[ 1 ].split( "=" )[ 1 ].trim(); - - streamProvider = new RepositoryFileStreamProvider( inputFilePath, outputFilePath, true ); - } - } - - if ( streamProvider != null ) { - schedule.setInputFile( streamProvider.getInputFilePath() ); - schedule.setOutputFile( streamProvider.getOutputFilePath() ); - } else { - // let's look to see if we can figure out the input and output file - String directory = (String) jobParams.get( "directory" ); - String transName = (String) jobParams.get( "transformation" ); - String jobName = (String) jobParams.get( "job" ); - String artifact = transName == null ? jobName : transName; - - if ( directory != null && artifact != null ) { - String outputFile = RepositoryFilenameUtils.concat( directory, artifact ); - outputFile += "*"; - - if ( artifact.equals( jobName ) ) { - artifact += ".kjb"; - } else { - artifact += ".ktr"; - } - String inputFile = RepositoryFilenameUtils.concat( directory, artifact ); - schedule.setInputFile( inputFile ); - schedule.setOutputFile( outputFile ); - } - } - - for ( String key : jobParams.keySet() ) { - Serializable serializable = jobParams.get( key ); - if ( RUN_PARAMETERS_KEY.equals( key ) ) { - if ( schedule.getPdiParameters() == null ) { - schedule.setPdiParameters( new HashMap() ); - } - schedule.getPdiParameters().putAll( (Map) serializable ); - } else { - JobScheduleParam param = new JobScheduleParam(); - if ( serializable instanceof String ) { - String value = (String) serializable; - if ( IScheduler.RESERVEDMAPKEY_ACTIONCLASS.equals( key ) ) { - schedule.setActionClass( value ); - } else if ( IBlockoutManager.TIME_ZONE_PARAM.equals( key ) ) { - schedule.setTimeZone( value ); - } - param = new JobScheduleParam( key, (String) serializable ); - } else if ( serializable instanceof Number ) { - param = new JobScheduleParam( key, (Number) serializable ); - } else if ( serializable instanceof Date ) { - param = new JobScheduleParam( key, (Date) serializable ); - } else if ( serializable instanceof Boolean ) { - param = new JobScheduleParam( key, (Boolean) serializable ); - } - schedule.getJobParameters().add( param ); - } - } - - if ( job.getJobTrigger() instanceof ISimpleJobTrigger ) { - ISimpleJobTrigger jobTrigger = (ISimpleJobTrigger) job.getJobTrigger(); - schedule.setSimpleJobTrigger( jobTrigger ); - - } else if ( job.getJobTrigger() instanceof IComplexJobTrigger ) { - IComplexJobTrigger jobTrigger = (IComplexJobTrigger) job.getJobTrigger(); - // force it to a cron trigger to get the auto-parsing of the complex trigger - ICronJobTrigger cron = scheduler.createCronJobTrigger(); - cron.setCronString( jobTrigger.getCronString() ); - cron.setStartTime( jobTrigger.getStartTime() ); - cron.setEndTime( jobTrigger.getEndTime() ); - cron.setDuration( jobTrigger.getDuration() ); - cron.setUiPassParam( jobTrigger.getUiPassParam() ); - schedule.setCronJobTrigger( cron ); - } else if ( job.getJobTrigger() instanceof ICronJobTrigger ) { - ICronJobTrigger jobTrigger = (ICronJobTrigger) job.getJobTrigger(); - schedule.setCronJobTrigger( jobTrigger ); - } else { - // don't know what this is, can't export it - throw new IllegalArgumentException( Messages.getInstance().getString( - "PentahoPlatformExporter.UNSUPPORTED_JobTrigger", job.getJobTrigger().getClass().getName() ) ); - - } - return schedule; - } - -} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java index 6b2887b8f4d..4d836539734 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandler.java @@ -20,22 +20,6 @@ package org.pentaho.platform.plugin.services.importer; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - import com.google.common.annotations.VisibleForTesting; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; @@ -54,6 +38,7 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobRequest; import org.pentaho.platform.api.scheduler2.IJobScheduleParam; import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; import org.pentaho.platform.api.scheduler2.IScheduler; @@ -80,13 +65,27 @@ import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetadata; import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian; import org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper; -import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.plugin.services.messages.Messages; +import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; -import org.pentaho.platform.web.http.api.resources.JobRequest; import org.pentaho.platform.web.http.api.resources.services.FileService; import javax.ws.rs.core.Response; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; public class SolutionImportHandler implements IPlatformImportHandler { @@ -334,7 +333,7 @@ protected void importSchedules( List scheduleList ) throws } if ( overwriteFile && jobExists ) { - JobRequest jobRequest = new JobRequest(); + IJobRequest jobRequest = scheduler.createJobRequest(); jobRequest.setJobId( job.getJobId() ); schedulerResource.removeJob( jobRequest ); jobExists = false; @@ -776,7 +775,7 @@ public Response createSchedulerJob( ISchedulerResource scheduler, IJobScheduleRe throws IOException { Response rs = scheduler != null ? (Response) scheduler.createJob( jobScheduleRequest ) : null; if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) { - JobRequest jobRequest = new JobRequest(); + IJobRequest jobRequest = PentahoSystem.get( IScheduler.class, "IScheduler2", null ).createJobRequest(); jobRequest.setJobId( rs.getEntity().toString() ); scheduler.pauseJob( jobRequest ); } diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java rename to extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java similarity index 97% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java rename to extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java index 6986d1535fb..878d104221f 100644 --- a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java +++ b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java @@ -31,6 +31,7 @@ import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.engine.security.SecurityHelper; +import org.pentaho.platform.scheduler2.action.ActionRunner; import org.pentaho.platform.scheduler2.messsages.Messages; import org.pentaho.platform.util.ActionUtil; import org.pentaho.platform.util.StringUtil; @@ -152,7 +153,8 @@ protected IActionInvokeStatus invokeActionImpl( final IAction actionBean, ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_STREAMPROVIDER ); ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_UIPASSPARAM ); - final ActionRunner actionBeanRunner = new ActionRunner( actionBean, actionUser, params, streamProvider ); + final org.pentaho.platform.scheduler2.action.ActionRunner + actionBeanRunner = new ActionRunner( actionBean, actionUser, params, streamProvider ); final IActionInvokeStatus status = new ActionInvokeStatus(); status.setStreamProvider( streamProvider ); diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java rename to extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java diff --git a/scheduler/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java similarity index 100% rename from scheduler/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java rename to extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java deleted file mode 100644 index 591fd9f3bbe..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/JobScheduleParam.java +++ /dev/null @@ -1,163 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.web.http.api.resources; - -import org.pentaho.platform.api.scheduler2.IJobScheduleParam; - -import java.io.Serializable; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class JobScheduleParam implements Serializable, IJobScheduleParam { - - private static final long serialVersionUID = -4214459740606299083L; - - private static final SimpleDateFormat isodatetime = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ" ); //$NON-NLS-1$ - - String name; - - String type; - - List stringValue = new ArrayList(); - - public JobScheduleParam() { - } - - public JobScheduleParam( String name, String value ) { - this.name = name; - this.type = "string"; //$NON-NLS-1$ - stringValue.add( value ); - } - - public JobScheduleParam( String name, Number value ) { - this.name = name; - this.type = "number"; //$NON-NLS-1$ - stringValue.add( value != null ? value.toString() : null ); - } - - public JobScheduleParam( String name, Date value ) { - this.name = name; - this.type = "date"; //$NON-NLS-1$ - stringValue.add( value != null ? isodatetime.format( value ) : null ); - } - - public JobScheduleParam( String name, Boolean value ) { - this.name = name; - this.type = "boolean"; //$NON-NLS-1$ - stringValue.add( value != null ? value.toString() : null ); - } - - public String getName() { - return name; - } - - public void setName( String name ) { - this.name = name; - } - - public String getType() { - return type; - } - - public void setType( String type ) { - this.type = type; - } - - public List getStringValue() { - return stringValue; - } - - public void setStringValue( List value ) { - this.stringValue = value; - } - - public Serializable getValue() { - Serializable object = null; - if ( type.equals( "string" ) ) { //$NON-NLS-1$ - if ( stringValue.size() > 0 ) { - object = stringValue.get( 0 ); - } - } else if ( type.equals( "number" ) ) { //$NON-NLS-1$ - if ( stringValue.size() > 0 ) { - - if ( !( stringValue.get( 0 ).indexOf( "." ) < 0 ) ) { //$NON-NLS-1$ - // Parse DOUBLE/FLOAT - object = Double.parseDouble( stringValue.get( 0 ) ); - - if ( (Double) object <= Float.MAX_VALUE ) { - object = Float.parseFloat( stringValue.get( 0 ) ); - } - } else { - // Parse LONG/INT - object = Long.parseLong( stringValue.get( 0 ) ); - - if ( (Long) object <= Integer.MAX_VALUE ) { - object = Integer.parseInt( stringValue.get( 0 ) ); - } - } - } - } else if ( type.equals( "boolean" ) ) { //$NON-NLS-1$ - if ( stringValue.size() > 0 ) { - object = Boolean.valueOf( stringValue.get( 0 ) ); - } - } else if ( type.equals( "date" ) ) { //$NON-NLS-1$ - if ( stringValue.size() > 0 ) { - try { - object = isodatetime.parse( stringValue.get( 0 ) ); - } catch ( ParseException e ) { - throw new IllegalArgumentException( e ); - } - } - } else if ( type.equals( "string[]" ) ) { //$NON-NLS-1$ - object = new String[stringValue.size()]; - int i = 0; - for ( String string : stringValue ) { - ( (String[]) object )[i++] = string; - } - } else if ( type.equals( "number[]" ) ) { //$NON-NLS-1$ - object = new Number[stringValue.size()]; - int i = 0; - for ( String string : stringValue ) { - ( (Number[]) object )[i++] = string.indexOf( "." ) < 0 ? Integer.parseInt( string ) : Float.parseFloat( string ); //$NON-NLS-1$ - } - } else if ( type.equals( "boolean[]" ) ) { //$NON-NLS-1$ - object = new Boolean[stringValue.size()]; - int i = 0; - for ( String string : stringValue ) { - ( (Boolean[]) object )[i++] = Boolean.valueOf( string ); - } - } else if ( type.equals( "date[]" ) ) { //$NON-NLS-1$ - object = new Date[stringValue.size()]; - int i = 0; - for ( String string : stringValue ) { - try { - ( (Date[]) object )[i++] = isodatetime.parse( string ); - } catch ( ParseException e ) { - throw new IllegalArgumentException( e ); - } - } - } - return object; - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java index fa3203a941e..5b50b27e828 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java +++ b/extensions/src/main/java/org/pentaho/platform/web/http/api/resources/services/FileService.java @@ -20,37 +20,6 @@ package org.pentaho.platform.web.http.api.resources.services; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.nio.channels.IllegalSelectorException; -import java.security.GeneralSecurityException; -import java.security.InvalidParameterException; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; - -import javax.ws.rs.core.StreamingOutput; - import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.BooleanUtils; @@ -72,6 +41,13 @@ import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryAccessDeniedException; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData; +import org.pentaho.platform.api.repository2.unified.webservices.LocaleMapDto; +import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileAclAceDto; +import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileAclDto; +import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; +import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileTreeDto; +import org.pentaho.platform.api.repository2.unified.webservices.StringKeyStringValueDto; +import org.pentaho.platform.api.util.IPentahoPlatformExporter; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.plugin.services.exporter.PentahoPlatformExporter; @@ -83,9 +59,9 @@ import org.pentaho.platform.plugin.services.importexport.ExportException; import org.pentaho.platform.plugin.services.importexport.ExportHandler; import org.pentaho.platform.plugin.services.importexport.IRepositoryImportLogger; +import org.pentaho.platform.plugin.services.importexport.ImportSession; import org.pentaho.platform.plugin.services.importexport.SimpleExportProcessor; import org.pentaho.platform.plugin.services.importexport.ZipExportProcessor; -import org.pentaho.platform.plugin.services.importexport.ImportSession; import org.pentaho.platform.repository.RepositoryDownloadWhitelist; import org.pentaho.platform.repository2.ClientRepositoryPaths; import org.pentaho.platform.repository2.locale.PentahoLocale; @@ -93,14 +69,8 @@ import org.pentaho.platform.repository2.unified.fileio.RepositoryFileOutputStream; import org.pentaho.platform.repository2.unified.jcr.PentahoJcrConstants; import org.pentaho.platform.repository2.unified.webservices.DefaultUnifiedRepositoryWebService; -import org.pentaho.platform.api.repository2.unified.webservices.LocaleMapDto; import org.pentaho.platform.repository2.unified.webservices.PropertiesWrapper; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileAclAceDto; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileAclDto; import org.pentaho.platform.repository2.unified.webservices.RepositoryFileAdapter; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileDto; -import org.pentaho.platform.api.repository2.unified.webservices.RepositoryFileTreeDto; -import org.pentaho.platform.api.repository2.unified.webservices.StringKeyStringValueDto; import org.pentaho.platform.security.policy.rolebased.actions.AdministerSecurityAction; import org.pentaho.platform.security.policy.rolebased.actions.PublishAction; import org.pentaho.platform.security.policy.rolebased.actions.RepositoryCreateAction; @@ -116,6 +86,36 @@ import org.pentaho.platform.web.http.messages.Messages; import org.pentaho.platform.web.servlet.HttpMimeTypeListener; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.channels.IllegalSelectorException; +import java.security.GeneralSecurityException; +import java.security.InvalidParameterException; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; + public class FileService { public static final Integer MODE_OVERWRITE = 1; @@ -159,7 +159,7 @@ public void systemRestore( final InputStream fileUpload, String overwriteFile, boolean overwriteFileFlag = !"false".equals( overwriteFile ); boolean applyAclSettingsFlag = !"false".equals( applyAclSettings ); boolean overwriteAclSettingsFlag = "true".equals( overwriteAclSettings ); - IRepositoryImportLogger importLogger = null; + IRepositoryImportLogger importLogger; Level level = Level.ERROR; ByteArrayOutputStream importLoggerStream = new ByteArrayOutputStream(); String importDirectory = "/"; @@ -1935,7 +1935,8 @@ protected Collator getCollator( int strength ) { private PentahoPlatformExporter getBackupExporter() { if ( backupExporter == null ) { - backupExporter = new PentahoPlatformExporter( getRepository() ); + backupExporter = + (PentahoPlatformExporter) PentahoSystem.get( IPentahoPlatformExporter.class, "IPentahoPlatformExporter", null ); } return backupExporter; diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java new file mode 100644 index 00000000000..a0ad4a779ad --- /dev/null +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/exporter/PentahoPlatformExporterTest.java @@ -0,0 +1,404 @@ +/*! + * + * 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-2021 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.plugin.services.exporter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.pentaho.database.model.IDatabaseConnection; +import org.pentaho.metadata.repository.IMetadataDomainRepository; +import org.pentaho.metastore.api.IMetaStore; +import org.pentaho.platform.api.engine.IPentahoSession; +import org.pentaho.platform.api.engine.IUserRoleListService; +import org.pentaho.platform.api.mt.ITenant; +import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; +import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; +import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.IJob; +import org.pentaho.platform.api.scheduler2.IJobTrigger; +import org.pentaho.platform.api.scheduler2.SchedulerException; +import org.pentaho.platform.api.usersettings.IAnyUserSettingService; +import org.pentaho.platform.api.usersettings.pojo.IUserSetting; +import org.pentaho.platform.engine.core.system.PentahoSessionHolder; +import org.pentaho.platform.engine.core.system.PentahoSystem; +import org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService; +import org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalog; +import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; +import org.pentaho.platform.plugin.services.importexport.RoleExport; +import org.pentaho.platform.plugin.services.importexport.UserExport; +import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.DatabaseConnection; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetaStore; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian; +import org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper; +import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; +import org.pentaho.platform.security.policy.rolebased.RoleBindingStruct; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; + +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.any; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.anyBoolean; + +public class PentahoPlatformExporterTest { + + PentahoPlatformExporter exporterSpy; + PentahoPlatformExporter exporter; + IUnifiedRepository repo; + IScheduler scheduler; + IPentahoSession session; + IMondrianCatalogService mondrianCatalogService; + MondrianCatalogRepositoryHelper mondrianCatalogRepositoryHelper; + + ExportManifest exportManifest; + + @Before + public void setUp() throws Exception { + repo = mock( IUnifiedRepository.class ); + scheduler = mock( IScheduler.class ); + session = mock( IPentahoSession.class ); + mondrianCatalogService = mock( IMondrianCatalogService.class ); + mondrianCatalogRepositoryHelper = mock( MondrianCatalogRepositoryHelper.class ); + exportManifest = spy( new ExportManifest() ); + + PentahoSessionHolder.setSession( session ); + exporterSpy = spy( new PentahoPlatformExporter( repo ) ); + exporterSpy.setExportManifest( exportManifest ); + + doReturn( "session name" ).when( session ).getName(); + exporter = new PentahoPlatformExporter( repo ); + } + + @After + public void tearDown() { + PentahoSystem.clearObjectFactory(); + } + + @Test + @Ignore + public void testExportSchedules() throws Exception { + List jobs = new ArrayList<>(); + IComplexJobTrigger trigger = mock( IComplexJobTrigger.class ); + IJobTrigger unknownTrigger = mock( IJobTrigger.class ); + + IJob job1 = mock( IJob.class ); + IJob job2 = mock( IJob.class ); + IJob job3 = mock( IJob.class ); + jobs.add( job1 ); + jobs.add( job2 ); + jobs.add( job3 ); + + when( scheduler.getJobs( null ) ).thenReturn( jobs ); + when( job1.getJobName() ).thenReturn( "job 1" ); + when( job2.getJobName() ).thenReturn( "job 2" ); + when( job2.getJobTrigger() ).thenReturn( trigger ); + when( job3.getJobName() ).thenReturn( "job 3" ); + when( job3.getJobTrigger() ).thenReturn( unknownTrigger ); +// exporterSpy.exportSchedules(); + + verify( scheduler ).getJobs( null ); + assertEquals( 1, exporterSpy.getExportManifest().getScheduleList().size() ); + } + + @Test + public void testExportSchedules_SchedulereThrowsException() throws Exception { + when( scheduler.getJobs( null ) ).thenThrow( new SchedulerException( "bad" ) ); + +// exporterSpy.exportSchedules(); + + verify( scheduler ).getJobs( null ); + assertEquals( 0, exporterSpy.getExportManifest().getScheduleList().size() ); + } + + @Test + public void testExportUsersAndRoles() { + IUserRoleListService mockDao = mock( IUserRoleListService.class ); + IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); + UserDetailsService userDetailsService = mock( UserDetailsService.class ); + PentahoSystem.registerObject( mockDao ); + PentahoSystem.registerObject( userSettingService ); + PentahoSystem.registerObject( userDetailsService ); + + IRoleAuthorizationPolicyRoleBindingDao roleBindingDao = mock( IRoleAuthorizationPolicyRoleBindingDao.class ); + PentahoSystem.registerObject( roleBindingDao ); + + String tenantPath = "path"; + when( session.getAttribute( IPentahoSession.TENANT_ID_KEY ) ).thenReturn( tenantPath ); + + List userList = new ArrayList<>(); + String user = "testUser"; + String role = "testRole"; + + userList.add( user ); + when( mockDao.getAllUsers( ArgumentMatchers.any( ITenant.class ) ) ).thenReturn( userList ); + + List roleList = new ArrayList<>(); + roleList.add( role ); + when( mockDao.getAllRoles() ).thenReturn( roleList ); + + Map> map = new HashMap<>(); + List permissions = new ArrayList<>(); + permissions.add( "read" ); + map.put( "testRole", permissions ); + RoleBindingStruct struct = mock( RoleBindingStruct.class ); + struct.bindingMap = map; + when( roleBindingDao.getRoleBindingStruct( nullable( String.class ) ) ).thenReturn( struct ); + + ArgumentCaptor userCaptor = ArgumentCaptor.forClass( UserExport.class ); + ArgumentCaptor roleCaptor = ArgumentCaptor.forClass( RoleExport.class ); + ExportManifest manifest = mock( ExportManifest.class ); + exporter.setExportManifest( manifest ); + + List settings = new ArrayList<>(); + IUserSetting setting = mock( IUserSetting.class ); + settings.add( setting ); + when( userSettingService.getUserSettings( user ) ).thenReturn( settings ); + when( userSettingService.getGlobalUserSettings() ).thenReturn( settings ); + + List authList = new ArrayList<>(); + UserDetails userDetails = new User( "testUser", "testPassword", true, true, true, true, authList ); + when( userDetailsService.loadUserByUsername( nullable( String.class ) ) ).thenReturn( userDetails ); + + exporter.exportUsersAndRoles(); + + verify( manifest ).addUserExport( userCaptor.capture() ); + verify( manifest ).addRoleExport( roleCaptor.capture() ); + verify( userSettingService ).getGlobalUserSettings(); + verify( manifest ).addGlobalUserSetting( ArgumentMatchers.any( ExportManifestUserSetting.class ) ); + assertEquals( settings.size(), userCaptor.getValue().getUserSettings().size() ); + + UserExport userExport = userCaptor.getValue(); + assertEquals( "testUser", userExport.getUsername() ); + RoleExport roleExport = roleCaptor.getValue(); + assertEquals( "testRole", roleExport.getRolename() ); + } + + @Test + public void testExportMetadata_noModels() throws Exception { + IMetadataDomainRepository mdr = mock( IMetadataDomainRepository.class ); + exporter.setMetadataDomainRepository( mdr ); + + exporter.exportMetadataModels(); + assertEquals( 0, exporter.getExportManifest().getMetadataList().size() ); + } + + @Test + public void testExportMetadata() throws Exception { + IMetadataDomainRepository mdr = mock( IMetadataDomainRepository.class ); + + Set domainIds = new HashSet<>(); + domainIds.add( "test1" ); + + when( mdr.getDomainIds() ).thenReturn( domainIds ); + exporterSpy.setMetadataDomainRepository( mdr ); + exporterSpy.zos = mock( ZipOutputStream.class ); + + Map inputMap = new HashMap<>(); + InputStream is = mock( InputStream.class ); + when( is.read( ArgumentMatchers.any( byte[].class ) ) ).thenReturn( -1 ); + inputMap.put( "test1", is ); + + doReturn( inputMap ).when( exporterSpy ).getDomainFilesData( "test1" ); + + exporterSpy.exportMetadataModels(); + assertEquals( 1, exporterSpy.getExportManifest().getMetadataList().size() ); + + assertEquals( "test1", exporterSpy.getExportManifest().getMetadataList().get( 0 ).getDomainId() ); + assertEquals( PentahoPlatformExporter.METADATA_PATH_IN_ZIP + "test1.xmi", + exporterSpy.getExportManifest().getMetadataList().get( 0 ).getFile() ); + } + + @Test + public void testExportDatasources() throws Exception { + + IDatasourceMgmtService svc = mock( IDatasourceMgmtService.class ); + exporterSpy.setDatasourceMgmtService( svc ); + + List datasources = new ArrayList<>(); + IDatabaseConnection conn = mock( org.pentaho.database.model.DatabaseConnection.class ); + when( conn.getName() ).thenReturn( "aDatasourceName" ); + IDatabaseConnection icon = mock( IDatabaseConnection.class ); + datasources.add( conn ); + datasources.add( icon ); + + when( svc.getDatasources() ).thenReturn( datasources ); + + exporterSpy.exportDatasources(); + + assertEquals( 1, exporterSpy.getExportManifest().getDatasourceList().size() ); + DatabaseConnection exportedDatabaseConnection = exporterSpy.getExportManifest().getDatasourceList().get( 0 ); + assertEquals( "aDatasourceName", exportedDatabaseConnection.getName() ); + } + + @Test + public void testParseXmlaEnabled() throws Exception { + String dsInfo = "DataSource=SampleData;Provider=mondrian;EnableXmla=\"false\""; + assertFalse( exporterSpy.parseXmlaEnabled( dsInfo ) ); + + dsInfo = "DataSource=SampleData;Provider=mondrian;EnableXmla=\"true\""; + assertTrue( exporterSpy.parseXmlaEnabled( dsInfo ) ); + + dsInfo = "DataSource=SampleData;Provider=mondrian"; + assertFalse( exporterSpy.parseXmlaEnabled( dsInfo ) ); + + dsInfo = "DataSource=SampleData;EnableXmla=\"true\";Provider=mondrian"; + assertTrue( exporterSpy.parseXmlaEnabled( dsInfo ) ); + } + + @Test + public void testExportMondrianSchemas_noCatalogs() throws Exception { + PentahoSystem.registerObject( mondrianCatalogService ); + exporterSpy.setMondrianCatalogRepositoryHelper( mondrianCatalogRepositoryHelper ); + + exporterSpy.exportMondrianSchemas(); + + verify( exportManifest, never() ).addMondrian( ArgumentMatchers.any( ExportManifestMondrian.class ) ); + verify( mondrianCatalogRepositoryHelper, never() ).getModrianSchemaFiles( nullable( String.class ) ); + } + + @Test + public void testExportMondrianSchemas() throws Exception { + final String catalogName = "test"; + String dataSourceInfo = "EnableXmla=\"true\""; + + executeExportMondrianSchemasForDataSourceInfo( catalogName, dataSourceInfo ); + + verify( exportManifest ).addMondrian( ArgumentMatchers.any( ExportManifestMondrian.class ) ); + verify( mondrianCatalogRepositoryHelper ).getModrianSchemaFiles( nullable( String.class ) ); + assertEquals( catalogName, exportManifest.getMondrianList().get( 0 ).getCatalogName() ); + assertTrue( exportManifest.getMondrianList().get( 0 ).isXmlaEnabled() ); + verify( exporterSpy.zos ).putNextEntry( ArgumentMatchers.any( ZipEntry.class ) ); + } + + @Test + public void testExportMondrianSchemas_AdditionalParametersSaved() throws Exception { + final String parameterName = "AdditionalParameter"; + final String parameterValue = "TestValue"; + final String expectedParameterValue = "TestValue"; + final String dataSourceInfo = "EnableXmla=\"true\";" + parameterName + "=" + parameterValue; + String catalogName = "test"; + + executeExportMondrianSchemasForDataSourceInfo( catalogName, dataSourceInfo ); + + String returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( parameterName ); + assertNotNull( returnedParameterValue ); + assertEquals( returnedParameterValue, expectedParameterValue ); + } + + @Test + public void testPerformExportMondrianSchemas_XmlUnsafeDataSourceInfoSaved() throws IOException { + + final String dataSourceInfo = "DataSource=\""DS "Test's" & <Fun>"\";" + + "DynamicSchemaProcessor=\""DSP's & "Other" <stuff>"\";"; + + final String dataSourceExpectedValue = "\"DS \"Test's\" & \""; + final String dynamicSchemaProcessorExpectedValue = "\"DSP's & \"Other\" \""; + + executeExportMondrianSchemasForDataSourceInfo( "", dataSourceInfo ); + + String returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( "DataSource" ); + assertNotNull( returnedParameterValue ); + assertEquals( returnedParameterValue, dataSourceExpectedValue ); + + returnedParameterValue = exportManifest.getMondrianList().get( 0 ).getParameters().get( "DynamicSchemaProcessor" ); + assertNotNull( returnedParameterValue ); + assertEquals( returnedParameterValue, dynamicSchemaProcessorExpectedValue ); + + } + + private void executeExportMondrianSchemasForDataSourceInfo( String catalogName, String dataSourceInfo ) throws IOException { + PentahoSystem.registerObject( mondrianCatalogService ); + exporterSpy.setMondrianCatalogRepositoryHelper( mondrianCatalogRepositoryHelper ); + + List catalogs = new ArrayList<>(); + MondrianCatalog catalog = new MondrianCatalog( catalogName, dataSourceInfo, null, null ); + catalogs.add( catalog ); + when( mondrianCatalogService.listCatalogs( ArgumentMatchers.any( IPentahoSession.class ), ArgumentMatchers.anyBoolean() ) ).thenReturn( catalogs ); + + Map inputMap = new HashMap<>(); + InputStream is = mock( InputStream.class ); + when( is.read( ArgumentMatchers.any( byte[].class ) ) ).thenReturn( -1 ); + inputMap.put( catalogName, is ); + when( mondrianCatalogRepositoryHelper.getModrianSchemaFiles( catalogName ) ).thenReturn( inputMap ); + exporterSpy.zos = mock( ZipOutputStream.class ); + + exporterSpy.exportMondrianSchemas(); + } + + @Test + public void testExportMetaStore() throws Exception { + exporterSpy.zos = mock( ZipOutputStream.class ); + IMetaStore metastore = mock( IMetaStore.class ); + exporterSpy.setRepoMetaStore( metastore ); + ExportManifest manifest = mock( ExportManifest.class ); + exporterSpy.setExportManifest( manifest ); + + exporterSpy.exportMetastore(); + verify( exporterSpy.zos ).putNextEntry( ArgumentMatchers.any( ZipEntry.class ) ); + verify( manifest ).setMetaStore( ArgumentMatchers.any( ExportManifestMetaStore.class ) ); + } + + @Test + public void testIsExportCandidate() throws Exception { + assertTrue( exporter.isExportCandidate( "/etc" ) ); + assertTrue( exporter.isExportCandidate( "/etc/operations_mart" ) ); + assertTrue( exporter.isExportCandidate( "/etc/operations_mart/someSubFolder" ) ); + + assertTrue( exporter.isExportCandidate( "/public" ) ); + assertTrue( exporter.isExportCandidate( "/home" ) ); + + assertFalse( exporter.isExportCandidate( "/etc/someRandomFolder" ) ); + assertFalse( exporter.isExportCandidate( "/etc/someRandomFolder/someSubFOlder" ) ); + assertFalse( exporter.isExportCandidate( "/etc/mondrian" ) ); + assertFalse( exporter.isExportCandidate( "/etc/metadata" ) ); + assertFalse( exporter.isExportCandidate( "/etc/metastore" ) ); + assertFalse( exporter.isExportCandidate( "/etc/olap-servers" ) ); + assertFalse( exporter.isExportCandidate( "/etc/models" ) ); + assertFalse( exporter.isExportCandidate( "/etc/pdi" ) ); + } +} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java new file mode 100644 index 00000000000..dcf8f5aa64a --- /dev/null +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/importer/SolutionImportHandlerTest.java @@ -0,0 +1,813 @@ +/*! + * + * 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-2021 Hitachi Vantara. All rights reserved. + * + */ + +package org.pentaho.platform.plugin.services.importer; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.logging.Log; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.ArgumentMatchers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.pentaho.platform.api.engine.IAuthorizationPolicy; +import org.pentaho.platform.api.engine.IPentahoSession; +import org.pentaho.platform.api.engine.security.userroledao.AlreadyExistsException; +import org.pentaho.platform.api.engine.security.userroledao.IUserRoleDao; +import org.pentaho.platform.api.mimetype.IMimeType; +import org.pentaho.platform.api.mimetype.IPlatformMimeResolver; +import org.pentaho.platform.api.mt.ITenant; +import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; +import org.pentaho.platform.api.repository2.unified.RepositoryFile; +import org.pentaho.platform.api.scheduler2.ICronJobTrigger; +import org.pentaho.platform.api.scheduler2.IJobScheduleParam; +import org.pentaho.platform.api.scheduler2.IJobScheduleRequest; +import org.pentaho.platform.api.scheduler2.IScheduler; +import org.pentaho.platform.api.scheduler2.ISchedulerResource; +import org.pentaho.platform.api.scheduler2.ISimpleJobTrigger; +import org.pentaho.platform.api.scheduler2.JobState; +import org.pentaho.platform.api.usersettings.IAnyUserSettingService; +import org.pentaho.platform.api.usersettings.IUserSettingService; +import org.pentaho.platform.api.usersettings.pojo.IUserSetting; +import org.pentaho.platform.engine.core.system.PentahoSessionHolder; +import org.pentaho.platform.engine.core.system.PentahoSystem; +import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting; +import org.pentaho.platform.plugin.services.importexport.ImportSession; +import org.pentaho.platform.plugin.services.importexport.ImportSession.ManifestFile; +import org.pentaho.platform.plugin.services.importexport.ImportSource.IRepositoryFileBundle; +import org.pentaho.platform.plugin.services.importexport.RepositoryFileBundle; +import org.pentaho.platform.plugin.services.importexport.RoleExport; +import org.pentaho.platform.plugin.services.importexport.UserExport; +import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest; +import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetaStore; +import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao; + +import javax.ws.rs.core.Response; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class SolutionImportHandlerTest { + + private SolutionImportHandler importHandler; + + private IUserRoleDao userRoleDao; + private IUnifiedRepository repository; + private IRoleAuthorizationPolicyRoleBindingDao roleAuthorizationPolicyRoleBindingDao; + private IPlatformMimeResolver mockMimeResolver; + + @Before + public void setUp() throws Exception { + userRoleDao = mockToPentahoSystem( IUserRoleDao.class ); + repository = mockToPentahoSystem( IUnifiedRepository.class ); + roleAuthorizationPolicyRoleBindingDao = mockToPentahoSystem( IRoleAuthorizationPolicyRoleBindingDao.class ); + + List mimeTypes = new ArrayList<>(); + try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ) ) { + mockMimeResolver = mock( IPlatformMimeResolver.class ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( IPlatformMimeResolver.class ) ) + .thenReturn( mockMimeResolver ); + importHandler = spy( new SolutionImportHandler( mimeTypes ) ); + } + + when( importHandler.getImportSession() ).thenReturn( mock( ImportSession.class ) ); + when( importHandler.getLogger() ).thenReturn( mock( Log.class ) ); + } + + private T mockToPentahoSystem( Class cl ) { + T t = mock( cl ); + PentahoSystem.registerObject( t ); + return t; + } + + @Test + public void testImportUsers_oneUserManyRoles() { + List users = new ArrayList<>(); + UserExport user = new UserExport(); + user.setUsername( "scrum master" ); + user.setRole( "coder" ); + user.setRole( "product owner" ); + user.setRole( "cat herder" ); + user.setPassword( "password" ); + users.add( user ); + + Map> rolesToUsers = importHandler.importUsers( users ); + + Assert.assertEquals( 3, rolesToUsers.size() ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "product owner" ).get( 0 ) ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "cat herder" ).get( 0 ) ); + + String[] strings = {}; + + verify( userRoleDao ).createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ); + + // should not set the password or roles explicitly if the createUser worked + verify( userRoleDao, never() ) + .setUserRoles( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.any( strings.getClass() ) ); + verify( userRoleDao, never() ) + .setPassword( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ) ); + } + + @Test + public void testImportUsers_manyUserManyRoles() { + List users = new ArrayList<>(); + UserExport user = new UserExport(); + user.setUsername( "scrum master" ); + user.setRole( "coder" ); + user.setRole( "product owner" ); + user.setRole( "cat herder" ); + user.setPassword( "password" ); + users.add( user ); + + UserExport user2 = new UserExport(); + user2.setUsername( "the dude" ); + user2.setRole( "coder" ); + user2.setRole( "awesome" ); + user2.setPassword( "password" ); + users.add( user2 ); + + Map> rolesToUsers = importHandler.importUsers( users ); + + Assert.assertEquals( 4, rolesToUsers.size() ); + Assert.assertEquals( 2, rolesToUsers.get( "coder" ).size() ); + Assert.assertEquals( 1, rolesToUsers.get( "product owner" ).size() ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "product owner" ).get( 0 ) ); + Assert.assertEquals( 1, rolesToUsers.get( "cat herder" ).size() ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "cat herder" ).get( 0 ) ); + Assert.assertEquals( 1, rolesToUsers.get( "awesome" ).size() ); + Assert.assertEquals( "the dude", rolesToUsers.get( "awesome" ).get( 0 ) ); + + String[] strings = {}; + + verify( userRoleDao ).createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ); + + verify( userRoleDao ).createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "the dude" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ); + + // should not set the password or roles explicitly if the createUser worked + verify( userRoleDao, never() ) + .setUserRoles( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.any( strings.getClass() ) ); + verify( userRoleDao, never() ) + .setPassword( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ) ); + } + + @Test + public void testImportUsers_userAlreadyExists() { + List users = new ArrayList<>(); + UserExport user = new UserExport(); + user.setUsername( "scrum master" ); + user.setRole( "coder" ); + user.setPassword( "password" ); + users.add( user ); + String[] strings = {}; + + when( userRoleDao.createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ) ).thenThrow( new AlreadyExistsException( "already there" ) ); + + importHandler.setOverwriteFile( true ); + Map> rolesToUsers = importHandler.importUsers( users ); + + Assert.assertEquals( 1, rolesToUsers.size() ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); + + verify( userRoleDao ).createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ); + + // should set the password or roles explicitly if the createUser failed + verify( userRoleDao ) + .setUserRoles( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.any( strings.getClass() ) ); + verify( userRoleDao ).setPassword( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ) ); + } + + @Test + public void testImportUsers_userAlreadyExists_overwriteFalse() { + List users = new ArrayList<>(); + UserExport user = new UserExport(); + user.setUsername( "scrum master" ); + user.setRole( "coder" ); + user.setPassword( "password" ); + users.add( user ); + String[] strings = {}; + + when( userRoleDao.createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ) ).thenThrow( new AlreadyExistsException( "already there" ) ); + + importHandler.setOverwriteFile( false ); + Map> rolesToUsers = importHandler.importUsers( users ); + + Assert.assertEquals( 1, rolesToUsers.size() ); + Assert.assertEquals( "scrum master", rolesToUsers.get( "coder" ).get( 0 ) ); + + verify( userRoleDao ).createUser( + ArgumentMatchers.any( ITenant.class ), + ArgumentMatchers.eq( "scrum master" ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( strings.getClass() ) ); + + // should set the password or roles explicitly if the createUser failed + verify( userRoleDao, never() ) + .setUserRoles( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.any( strings.getClass() ) ); + verify( userRoleDao, never() ) + .setPassword( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ) ); + } + + @Test + public void testImportRoles() { + String roleName = "ADMIN"; + List permissions = new ArrayList<>(); + + RoleExport role = new RoleExport(); + role.setRolename( roleName ); + role.setPermission( permissions ); + + List roles = new ArrayList<>(); + roles.add( role ); + + Map> roleToUserMap = new HashMap<>(); + final List adminUsers = new ArrayList<>(); + adminUsers.add( "admin" ); + adminUsers.add( "root" ); + roleToUserMap.put( roleName, adminUsers ); + + String[] userStrings = adminUsers.toArray( new String[] {} ); + + importHandler.importRoles( roles, roleToUserMap ); + + verify( userRoleDao ).createRole( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.eq( roleName ), ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( userStrings.getClass() ) ); + verify( roleAuthorizationPolicyRoleBindingDao ) + .setRoleBindings( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.eq( roleName ), + ArgumentMatchers.eq( permissions ) ); + } + + @Test + public void testImportRoles_roleAlreadyExists() { + String roleName = "ADMIN"; + List permissions = new ArrayList<>(); + + RoleExport role = new RoleExport(); + role.setRolename( roleName ); + role.setPermission( permissions ); + + List roles = new ArrayList<>(); + roles.add( role ); + + Map> roleToUserMap = new HashMap<>(); + final List adminUsers = new ArrayList<>(); + adminUsers.add( "admin" ); + adminUsers.add( "root" ); + roleToUserMap.put( roleName, adminUsers ); + + String[] userStrings = adminUsers.toArray( new String[] {} ); + + when( userRoleDao.createRole( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( userStrings.getClass() ) ) ) + .thenThrow( new AlreadyExistsException( "already there" ) ); + + importHandler.setOverwriteFile( true ); + importHandler.importRoles( roles, roleToUserMap ); + + verify( userRoleDao ).createRole( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( userStrings.getClass() ) ); + + // even if the roles exists, make sure we set the permissions on it Mockito.anyway... they might have changed + verify( roleAuthorizationPolicyRoleBindingDao ) + .setRoleBindings( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.eq( roleName ), ArgumentMatchers.eq( + permissions ) ); + + } + + @Test + public void testImportRoles_roleAlreadyExists_overwriteFalse() { + String roleName = "ADMIN"; + List permissions = new ArrayList<>(); + + RoleExport role = new RoleExport(); + role.setRolename( roleName ); + role.setPermission( permissions ); + + List roles = new ArrayList<>(); + roles.add( role ); + + Map> roleToUserMap = new HashMap<>(); + final List adminUsers = new ArrayList<>(); + adminUsers.add( "admin" ); + adminUsers.add( "root" ); + roleToUserMap.put( roleName, adminUsers ); + + String[] userStrings = adminUsers.toArray( new String[] {} ); + + when( userRoleDao.createRole( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( userStrings.getClass() ) ) ) + .thenThrow( new AlreadyExistsException( "already there" ) ); + + importHandler.setOverwriteFile( false ); + importHandler.importRoles( roles, roleToUserMap ); + + verify( userRoleDao ).createRole( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ), + ArgumentMatchers.any( userStrings.getClass() ) ); + + // even if the roles exists, make sure we set the permissions on it Mockito.anyway... they might have changed + verify( roleAuthorizationPolicyRoleBindingDao, never() ) + .setRoleBindings( ArgumentMatchers.any( ITenant.class ), ArgumentMatchers.eq( roleName ), ArgumentMatchers.eq( + permissions ) ); + + } + + @Test + public void testImportMetaStore() { + String path = "/path/to/file.zip"; + ExportManifestMetaStore manifestMetaStore = new ExportManifestMetaStore( path, + "metastore", + "description of the metastore" ); + importHandler.cachedImports = new HashMap<>(); + + importHandler.importMetaStore( manifestMetaStore, true ); + Assert.assertEquals( 1, importHandler.cachedImports.size() ); + Assert.assertNotNull( importHandler.cachedImports.get( path ) ); + } + + @Test + public void testImportMetaStore_nullMetastoreManifest() { + ExportManifest manifest = spy( new ExportManifest() ); + + importHandler.cachedImports = new HashMap<>(); + importHandler.importMetaStore( manifest.getMetaStore(), true ); + Assert.assertEquals( 0, importHandler.cachedImports.size() ); + } + + @Test + public void testImportUserSettings() throws Exception { + UserExport user = new UserExport(); + user.setUsername( "pentaho" ); + user.addUserSetting( new ExportManifestUserSetting( "theme", "crystal" ) ); + user.addUserSetting( new ExportManifestUserSetting( "language", "en_US" ) ); + IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); + PentahoSystem.registerObject( userSettingService ); + importHandler.setOverwriteFile( true ); + + importHandler.importUserSettings( user ); + verify( userSettingService ).setUserSetting( "pentaho", "theme", "crystal" ); + verify( userSettingService ).setUserSetting( "pentaho", "language", "en_US" ); + } + + @Test + public void testImportUserSettings_NoOverwrite() { + UserExport user = new UserExport(); + user.setUsername( "pentaho" ); + user.addUserSetting( new ExportManifestUserSetting( "theme", "crystal" ) ); + user.addUserSetting( new ExportManifestUserSetting( "language", "en_US" ) ); + IAnyUserSettingService userSettingService = mock( IAnyUserSettingService.class ); + PentahoSystem.registerObject( userSettingService ); + importHandler.setOverwriteFile( false ); + + IUserSetting existingSetting = mock( IUserSetting.class ); + when( userSettingService.getUserSetting( "pentaho", "theme", null ) ).thenReturn( existingSetting ); + when( userSettingService.getUserSetting( "pentaho", "language", null ) ).thenReturn( null ); + + importHandler.importUserSettings( user ); + verify( userSettingService, never() ).setUserSetting( "pentaho", "theme", "crystal" ); + verify( userSettingService ).setUserSetting( "pentaho", "language", "en_US" ); + verify( userSettingService ).getUserSetting( "pentaho", "theme", null ); + verify( userSettingService ).getUserSetting( "pentaho", "language", null ); + } + + @Test + public void testImportGlobalUserSetting() { + importHandler.setOverwriteFile( true ); + List settings = new ArrayList<>(); + settings.add( new ExportManifestUserSetting( "language", "en_US" ) ); + settings.add( new ExportManifestUserSetting( "showHiddenFiles", "false" ) ); + IUserSettingService userSettingService = mock( IUserSettingService.class ); + PentahoSystem.registerObject( userSettingService ); + + importHandler.importGlobalUserSettings( settings ); + + verify( userSettingService ).setGlobalUserSetting( "language", "en_US" ); + verify( userSettingService ).setGlobalUserSetting( "showHiddenFiles", "false" ); + verify( userSettingService, never() ) + .getGlobalUserSetting( ArgumentMatchers.nullable( String.class ), ArgumentMatchers.nullable( String.class ) ); + } + + @Test + public void testImportGlobalUserSetting_noOverwrite() { + importHandler.setOverwriteFile( false ); + List settings = new ArrayList<>(); + settings.add( new ExportManifestUserSetting( "language", "en_US" ) ); + settings.add( new ExportManifestUserSetting( "showHiddenFiles", "false" ) ); + IUserSettingService userSettingService = mock( IUserSettingService.class ); + PentahoSystem.registerObject( userSettingService ); + IUserSetting setting = mock( IUserSetting.class ); + when( userSettingService.getGlobalUserSetting( "language", null ) ).thenReturn( null ); + when( userSettingService.getGlobalUserSetting( "showHiddenFiles", null ) ).thenReturn( setting ); + + importHandler.importGlobalUserSettings( settings ); + + verify( userSettingService ).setGlobalUserSetting( "language", "en_US" ); + verify( userSettingService, never() ) + .setGlobalUserSetting( ArgumentMatchers.eq( "showHiddenFiles" ), ArgumentMatchers.nullable( String.class ) ); + verify( userSettingService ).getGlobalUserSetting( "language", null ); + verify( userSettingService ).getGlobalUserSetting( "showHiddenFiles", null ); + + } + + @Test + @Ignore + public void testImportSchedules() throws Exception { + List schedules = new ArrayList<>(); + IJobScheduleRequest scheduleRequest = Mockito.spy( new FakeJobSchedluerRequest() ); + schedules.add( scheduleRequest ); + + Response response = mock( Response.class ); + when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); + when( response.getEntity() ).thenReturn( "job id" ); + + doReturn( response ).when( importHandler ) + .createSchedulerJob( ArgumentMatchers.any( ISchedulerResource.class ), ArgumentMatchers.eq( scheduleRequest ) ); + + try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); + MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { + IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); + IScheduler iSchedulerMock = mock( IScheduler.class ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IAuthorizationPolicy.class ) ) ) + .thenReturn( iAuthorizationPolicyMock ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IScheduler.class ), ArgumentMatchers.anyString(), ArgumentMatchers.eq( null ) ) ) + .thenReturn( iSchedulerMock ); + when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); + pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) + .thenReturn( mock( IPentahoSession.class ) ); + + importHandler.importSchedules( schedules ); + + verify( importHandler ) + .createSchedulerJob( ArgumentMatchers.any( ISchedulerResource.class ), ArgumentMatchers.eq( scheduleRequest ) ); + Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); + } + } + + @Test + @Ignore + public void testImportSchedules_FailsToCreateSchedule() throws Exception { + List schedules = new ArrayList<>(); + IJobScheduleRequest scheduleRequest = Mockito.spy( new FakeJobSchedluerRequest() ); + scheduleRequest.setInputFile( "/home/admin/scheduledTransform.ktr" ); + scheduleRequest.setOutputFile( "/home/admin/scheduledTransform*" ); + schedules.add( scheduleRequest ); + + Mockito.doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( + ArgumentMatchers.any( ISchedulerResource.class ), ArgumentMatchers.eq( scheduleRequest ) ); + + try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); + MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { + IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); + IScheduler iSchedulerMock = mock( IScheduler.class ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IAuthorizationPolicy.class ) ) ) + .thenReturn( iAuthorizationPolicyMock ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IScheduler.class ), ArgumentMatchers.anyString(), ArgumentMatchers.eq( null ) ) ) + .thenReturn( iSchedulerMock ); + when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); + pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) + .thenReturn( mock( IPentahoSession.class ) ); + + importHandler.importSchedules( schedules ); + Assert.assertEquals( 0, ImportSession.getSession().getImportedScheduleJobIds().size() ); + } + } + + @Test + @Ignore + public void testImportSchedules_FailsToCreateScheduleWithSpace() throws Exception { + List schedules = new ArrayList<>(); + IJobScheduleRequest scheduleRequest = Mockito.spy( new FakeJobSchedluerRequest() ); + scheduleRequest.setInputFile( "/home/admin/scheduled Transform.ktr" ); + scheduleRequest.setOutputFile( "/home/admin/scheduled Transform*" ); + schedules.add( scheduleRequest ); + + ScheduleRequestMatcher throwMatcher = + new ScheduleRequestMatcher( "/home/admin/scheduled Transform.ktr", "/home/admin/scheduled Transform*" ); + Mockito.doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( + ArgumentMatchers.any( ISchedulerResource.class ), ArgumentMatchers.argThat( throwMatcher ) ); + + Response response = mock( Response.class ); + when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); + when( response.getEntity() ).thenReturn( "job id" ); + ScheduleRequestMatcher goodMatcher = + new ScheduleRequestMatcher( "/home/admin/scheduled_Transform.ktr", "/home/admin/scheduled_Transform*" ); + doReturn( response ).when( importHandler ).createSchedulerJob( ArgumentMatchers.any( ISchedulerResource.class ), + ArgumentMatchers.argThat( goodMatcher ) ); + + try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); + MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { + IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); + IScheduler iSchedulerMock = mock( IScheduler.class ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IAuthorizationPolicy.class ) ) ).thenReturn( iAuthorizationPolicyMock ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IScheduler.class ), ArgumentMatchers.anyString(), ArgumentMatchers.eq( null ) ) ) + .thenReturn( iSchedulerMock ); + when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); + pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ).thenReturn( mock( IPentahoSession.class ) ); + importHandler.importSchedules( schedules ); + verify( importHandler, times( 2 ) ).createSchedulerJob( + ArgumentMatchers.any( ISchedulerResource.class ), ArgumentMatchers.any( IJobScheduleRequest.class ) ); + Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); + } + } + + @Test + @Ignore + public void testImportSchedules_FailsToCreateScheduleWithSpaceOnWindows() throws Exception { + String sep = File.separator; + System.setProperty( "file.separator", "\\" ); + List schedules = new ArrayList<>(); + IJobScheduleRequest scheduleRequest = Mockito.spy( new FakeJobSchedluerRequest() ); + scheduleRequest.setInputFile( "/home/admin/scheduled Transform.ktr" ); + scheduleRequest.setOutputFile( "/home/admin/scheduled Transform*" ); + schedules.add( scheduleRequest ); + + ScheduleRequestMatcher throwMatcher = + new ScheduleRequestMatcher( "/home/admin/scheduled Transform.ktr", "/home/admin/scheduled Transform*" ); + Mockito.doThrow( new IOException( "error creating schedule" ) ).when( importHandler ).createSchedulerJob( + ArgumentMatchers.nullable( ISchedulerResource.class ), ArgumentMatchers.argThat( throwMatcher ) ); + + Response response = mock( Response.class ); + when( response.getStatus() ).thenReturn( Response.Status.OK.getStatusCode() ); + when( response.getEntity() ).thenReturn( "job id" ); + ScheduleRequestMatcher goodMatcher = + new ScheduleRequestMatcher( "/home/admin/scheduled_Transform.ktr", "/home/admin/scheduled_Transform*" ); + doReturn( response ).when( importHandler ).createSchedulerJob( ArgumentMatchers.nullable( ISchedulerResource.class ), + ArgumentMatchers.argThat( goodMatcher ) ); + + try ( MockedStatic pentahoSystemMockedStatic = Mockito.mockStatic( PentahoSystem.class ); + MockedStatic pentahoSessionHolderMockedStatic = Mockito.mockStatic( PentahoSessionHolder.class ) ) { + IAuthorizationPolicy iAuthorizationPolicyMock = mock( IAuthorizationPolicy.class ); + IScheduler iSchedulerMock = mock( IScheduler.class ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IAuthorizationPolicy.class ) ) ) + .thenReturn( iAuthorizationPolicyMock ); + pentahoSystemMockedStatic.when( () -> PentahoSystem.get( ArgumentMatchers.eq( IScheduler.class ), ArgumentMatchers.anyString(), ArgumentMatchers.eq( null ) ) ) + .thenReturn( iSchedulerMock ); + when( iSchedulerMock.getStatus() ).thenReturn( mock( IScheduler.SchedulerStatus.class ) ); + pentahoSessionHolderMockedStatic.when( PentahoSessionHolder::getSession ) + .thenReturn( mock( IPentahoSession.class ) ); + + importHandler.importSchedules( schedules ); + verify( importHandler, times( 2 ) ) + .createSchedulerJob( ArgumentMatchers.nullable( ISchedulerResource.class ), ArgumentMatchers.nullable( IJobScheduleRequest.class ) ); + Assert.assertEquals( 1, ImportSession.getSession().getImportedScheduleJobIds().size() ); + System.setProperty( "file.separator", sep ); + } + } + + private static class ScheduleRequestMatcher implements ArgumentMatcher { + private final String input; + private final String output; + + public ScheduleRequestMatcher( String input, String output ) { + this.input = input; + this.output = output; + } + + @Override public boolean matches( IJobScheduleRequest jsr ) { + boolean matchedInput = input.equals( FilenameUtils.separatorsToUnix( jsr.getInputFile() ) ); + boolean matchedOutput = output.equals( FilenameUtils.separatorsToUnix( jsr.getOutputFile() ) ); + return matchedInput && matchedOutput; + } + } + + @Test + public void testGetFile() { + RepositoryFileImportBundle importBundle = new RepositoryFileImportBundle(); + importBundle.setPath( "/BASE_PATH/" ); + + RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).build(); + IRepositoryFileBundle fileBundle = new RepositoryFileBundle( repoFile, null, "parentDir", null, "UTF-8", null ); + fileBundle.setPath( "SUB_PATH/" ); + + RepositoryFile expectedFile = new RepositoryFile.Builder( "EXPECTED_FILE" ).build(); + when( repository.getFile( "/BASE_PATH/SUB_PATH/FILE_NAME" ) ).thenReturn( expectedFile ); + } + + @Test + public void testIsFileHidden() { + IMimeType hiddenMime = mock( IMimeType.class ); + IMimeType visibleMime = mock( IMimeType.class ); + when( hiddenMime.isHidden() ).thenReturn( true ); + when( visibleMime.isHidden() ).thenReturn( false ); + ManifestFile manifestFile = mock( ManifestFile.class ); + RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).hidden( true ).build(); + + when( manifestFile.isFileHidden() ).thenReturn( true ); + Assert.assertTrue( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); + + when( manifestFile.isFileHidden() ).thenReturn( false ); + Assert.assertFalse( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); + + when( manifestFile.isFileHidden() ).thenReturn( null ); + Assert.assertTrue( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); + + repoFile = new RepositoryFile.Builder( "FILE_NAME" ).hidden( false ).build(); + Assert.assertFalse( importHandler.isFileHidden( repoFile, manifestFile, "SOURCE_PATH" ) ); + + when( mockMimeResolver.resolveMimeTypeForFileName( "SOURCE_PATH" ) ).thenReturn( hiddenMime ); + Assert.assertTrue( importHandler.isFileHidden( null, manifestFile, "SOURCE_PATH" ) ); + + when( mockMimeResolver.resolveMimeTypeForFileName( "SOURCE_PATH" ) ).thenReturn( visibleMime ); + Assert.assertEquals( RepositoryFile.HIDDEN_BY_DEFAULT, importHandler.isFileHidden( null, manifestFile, "SOURCE_PATH" ) ); + } + + @Test + public void testIsSchedulable() { + ManifestFile manifestFile = mock( ManifestFile.class ); + RepositoryFile repoFile = new RepositoryFile.Builder( "FILE_NAME" ).schedulable( true ).build(); + + when( manifestFile.isFileSchedulable() ).thenReturn( true ); + Assert.assertTrue( importHandler.isSchedulable( repoFile, manifestFile ) ); + + when( manifestFile.isFileSchedulable() ).thenReturn( false ); + Assert.assertFalse( importHandler.isSchedulable( repoFile, manifestFile ) ); + + when( manifestFile.isFileSchedulable() ).thenReturn( null ); + Assert.assertTrue( importHandler.isSchedulable( repoFile, manifestFile ) ); + + Assert.assertEquals( RepositoryFile.SCHEDULABLE_BY_DEFAULT, importHandler.isSchedulable( null, manifestFile ) ); + } + + @Test + public void testFileIsScheduleInputSource() { + ExportManifest manifest = mock( ExportManifest.class ); + List scheduleRequests = new ArrayList<>(); + for ( int i = 0; i < 10; i++ ) { + IJobScheduleRequest jobScheduleRequest = new FakeJobSchedluerRequest(); + jobScheduleRequest.setInputFile( "/public/test/file" + i ); + scheduleRequests.add( jobScheduleRequest ); + } + Assert.assertFalse( importHandler.fileIsScheduleInputSource( manifest, null ) ); + + when( manifest.getScheduleList() ).thenReturn( scheduleRequests ); + + Assert.assertFalse( importHandler.fileIsScheduleInputSource( manifest, "/public/file" ) ); + Assert.assertTrue( importHandler.fileIsScheduleInputSource( manifest, "/public/test/file3" ) ); + Assert.assertTrue( importHandler.fileIsScheduleInputSource( manifest, "public/test/file3" ) ); + } + @After + public void tearDown() throws Exception { + ImportSession.getSession().getImportedScheduleJobIds().clear(); + PentahoSystem.clearObjectFactory(); + } + private class FakeJobSchedluerRequest implements IJobScheduleRequest { + private String inputFile; + @Override public void setJobId( String jobId ) { + + } + + @Override public String getJobId() { + return null; + } + + @Override public void setJobName( String jobName ) { + + } + + @Override public void setDuration( long duration ) { + + } + + @Override public void setJobState( JobState state ) { + + } + + @Override public void setInputFile( String inputFilePath ) { + inputFile = inputFilePath; + } + + @Override public void setOutputFile( String outputFilePath ) { + + } + + @Override public Map getPdiParameters() { + return null; + } + + @Override public void setPdiParameters( Map stringStringHashMap ) { + + } + + @Override public void setActionClass( String value ) { + + } + + @Override public String getActionClass() { + return null; + } + + @Override public void setTimeZone( String value ) { + + } + + @Override public String getTimeZone() { + return null; + } + + @Override public void setSimpleJobTrigger( ISimpleJobTrigger jobTrigger ) { + + } + + @Override public ISimpleJobTrigger getSimpleJobTrigger() { + return null; + } + + @Override public void setCronJobTrigger( ICronJobTrigger cron ) { + + } + + @Override public String getInputFile() { + return null; + } + + @Override public String getJobName() { + return null; + } + + @Override public String getOutputFile() { + return null; + } + + @Override public List getJobParameters() { + return null; + } + + @Override public void setJobParameters( List parameters ) { + + } + + @Override public long getDuration() { + return 0; + } + + @Override public JobState getJobState() { + return null; + } + + @Override public ICronJobTrigger getCronJobTrigger() { + return null; + } + } +} diff --git a/pom.xml b/pom.xml index 2e3ccbd68b8..acdce5eead5 100644 --- a/pom.xml +++ b/pom.xml @@ -283,7 +283,6 @@ core repository - scheduler extensions tomcat-logs diff --git a/scheduler/.gitignore b/scheduler/.gitignore deleted file mode 100644 index f906fbd66f7..00000000000 --- a/scheduler/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/bin -/dist -/.classpath -/lib -/test-lib -/eclipse-bin diff --git a/scheduler/LICENSE.txt b/scheduler/LICENSE.txt deleted file mode 100644 index e0a7ee59bff..00000000000 --- a/scheduler/LICENSE.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/scheduler/pom.xml b/scheduler/pom.xml deleted file mode 100644 index 766cd90be83..00000000000 --- a/scheduler/pom.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - 4.0.0 - - pentaho - pentaho-platform-ce-parent - 10.1.0.0-SNAPSHOT - - pentaho-platform-scheduler - 10.1.0.0-SNAPSHOT - - ${basedir}/../license/styles/javadoc_style_license_header.xml - ${basedir}/../license/templates/LGPL-2.1.txt - - - - - com.sun.mail - javax.mail - ${mail.version} - - - * - * - - - - - - org.glassfish.metro - webservices-api - ${webservices.version} - compile - - - * - * - - - - - org.glassfish.metro - webservices-rt - ${webservices.version} - compile - - - * - * - - - - - pentaho - pentaho-platform-api - ${project.version} - compile - - - pentaho - pentaho-platform-core - ${project.version} - compile - - - pentaho - pentaho-versionchecker - ${project.version} - compile - - - com.cronutils - cron-utils - 9.1.6 - - - org.osgi - org.osgi.core - test - - - junit - junit - ${junit.version} - test - - - org.jmock - jmock-junit4 - ${jmock.version} - test - - - org.jmock - jmock-legacy - ${jmock.version} - test - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito - ${powermock.version} - test - - - org.mockito - mockito-core - ${mockito-core.version} - test - - - org.springframework - spring-tx - - - org.springframework.security - spring-security-core - - - pentaho - pentaho-platform-core - ${project.version} - tests - test - - - * - * - - - - - org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} - - - * - * - - - test - - - - - org.springframework - spring-test - test - - - org.springframework - spring-web - test - - - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} - test - - - org.hamcrest - hamcrest-core - ${hamcrest-core.version} - test - - - org.codehaus.enunciate - enunciate-jersey-rt - ${enunciate-jersey-rt.version} - compile - - - com.sun.xml.bind - jaxb-impl - - - org.codehaus.jackson - jackson-mapper-asl - - - - - - - - com.mycila - license-maven-plugin - - - maven-jar-plugin - - - test-jar - package - - test-jar - - - - - true - true - - - ${source.jdk.version} - ${target.jdk.version} - - - - - - - - - diff --git a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java deleted file mode 100644 index 10d84f364a8..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryCleanerSystemListener.java +++ /dev/null @@ -1,225 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.repository; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.engine.IPentahoSystemListener; -import org.pentaho.platform.api.scheduler2.IComplexJobTrigger; -import org.pentaho.platform.api.scheduler2.IJob; -import org.pentaho.platform.api.scheduler2.IJobFilter; -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.engine.core.system.PentahoSystem; -import org.pentaho.platform.util.StringUtil; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * This is a 5.4-only class. To use it, update systemListeners.xml by adding the following section: - *

- * <bean id="repositoryCleanerSystemListener"
- * class="org.pentaho.platform.plugin.services.repository.RepositoryCleanerSystemListener">
- * <property name="gcEnabled" value="true"/>
- * <property name="execute" value="now"/>
- * </bean>
- * 
- * gcEnabled is a non-mandatory parameter, true by default. Use it to turn off the listener without - * removing its description from the XML-file - * execute is a parameter, that describes a time pattern of GC procedure. Supported values are: - *
    - *
  • now - for one time execution
  • - *
  • weekly - for every Monday execution
  • - *
  • monthly - for every first day of month execution
  • - *
- * Note, that periodic executions will be planned to start at 0:00. If an execution was not started at that time, - * e.g. the server was shut down, then it will be started as soon as the scheduler is restored. - * - * @author Andrey Khayrutdinov - */ -public class RepositoryCleanerSystemListener implements IPentahoSystemListener, IJobFilter { - - private final Log logger = LogFactory.getLog( RepositoryCleanerSystemListener.class ); - - enum Frequency { - NOW( "now" ) { - @Override public IJobTrigger createTrigger() { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - return (IJobTrigger) scheduler.createSimpleJobTrigger( new Date(), - new Date( Long.MAX_VALUE ), 0, 1 ); - } - }, - - WEEKLY( "weekly" ) { - @Override public IJobTrigger createTrigger() { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - // execute each first day of week at 0 hours - return (IJobTrigger) scheduler.createComplexTrigger( null, null, null, IComplexJobTrigger.SUNDAY, 0 ); - } - }, - - MONTHLY( "monthly" ) { - @Override public IJobTrigger createTrigger() { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); - - // execute each first day of month at 0 hours - return (IJobTrigger) scheduler.createComplexTrigger( null, null, 1, null, 0 ); - } - }; - - private final String value; - - Frequency( String value ) { - this.value = value; - } - - public abstract IJobTrigger createTrigger(); - - public static Frequency fromString( String name ) { - for ( Frequency frequency : values() ) { - if ( frequency.value.equalsIgnoreCase( name ) ) { - return frequency; - } - } - return null; - } - - String getValue() { - return value; - } - } - - private boolean gcEnabled = true; - private String execute; - - @Override - public boolean startup( IPentahoSession session ) { - IScheduler scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", session ); - if ( scheduler == null ) { - logger.error( "Cannot obtain an instance of IScheduler2" ); - return false; - } - - try { - List jobs = scheduler.getJobs( this ); - if ( gcEnabled ) { - if ( jobs.isEmpty() ) { - scheduleJob( scheduler ); - } else { - rescheduleIfNecessary( scheduler, jobs ); - } - } else { - if ( !jobs.isEmpty() ) { - unscheduleJob( scheduler, jobs ); - } - } - } catch ( SchedulerException e ) { - logger.error( "Scheduler error", e ); - } - return true; - } - - private IJobTrigger findJobTrigger() { - if ( StringUtil.isEmpty( execute ) ) { - logger.error( "\"execute\" property is not specified!" ); - return null; - } - - Frequency frequency = Frequency.fromString( execute ); - if ( frequency == null ) { - logger.error( "Unknown value for property \"execute\": " + execute ); - return null; - } - - return frequency.createTrigger(); - } - - private void scheduleJob( IScheduler scheduler ) throws SchedulerException { - IJobTrigger trigger = findJobTrigger(); - if ( trigger != null ) { - logger.info( "Creating new job with trigger: " + trigger ); - scheduler.createJob( RepositoryGcJob.JOB_NAME, RepositoryGcJob.class, null, trigger ); - } - } - - private void rescheduleIfNecessary( IScheduler scheduler, List jobs ) throws SchedulerException { - IJobTrigger trigger = findJobTrigger(); - if ( trigger == null ) { - return; - } - - List matched = new ArrayList( jobs.size() ); - for ( IJob job : jobs ) { - IJobTrigger tr = job.getJobTrigger(); - // unfortunately, JobTrigger does not override equals - if ( trigger.getClass() != tr.getClass() ) { - logger.info( "Removing job with id: " + job.getJobId() ); - scheduler.removeJob( job.getJobId() ); - } else { - matched.add( job ); - } - } - - if ( matched.isEmpty() ) { - logger.info( "Need to re-schedule job" ); - scheduleJob( scheduler ); - } - } - - private void unscheduleJob( IScheduler scheduler, List jobs ) throws SchedulerException { - for ( IJob job : jobs ) { - logger.info( "Removing job with id: " + job.getJobId() ); - scheduler.removeJob( job.getJobId() ); - } - } - - - @Override - public void shutdown() { - // nothing to do - } - - @Override - public boolean accept( IJob job ) { - return RepositoryGcJob.JOB_NAME.equals( job.getJobName() ); - } - - - public boolean isGcEnabled() { - return gcEnabled; - } - - public void setGcEnabled( boolean gcEnabled ) { - this.gcEnabled = gcEnabled; - } - - public String getExecute() { - return execute; - } - - public void setExecute( String execute ) { - this.execute = execute; - } -} diff --git a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java b/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java deleted file mode 100644 index 81a3c4a31bb..00000000000 --- a/scheduler/src/main/java/org/pentaho/platform/plugin/services/repository/RepositoryGcJob.java +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.services.repository; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openide.util.NotImplementedException; -import org.pentaho.platform.api.action.IAction; -//import org.pentaho.platform.repository2.unified.jcr.RepositoryCleaner; - -/** - * @author Andrey Khayrutdinov - */ -public class RepositoryGcJob implements IAction { - public static final String JOB_NAME = "RepositoryGcJob"; - - private static final Log logger = LogFactory.getLog( RepositoryGcJob.class ); - - @Override - public void execute() throws Exception { -// logger.info( "Starting repository GC" ); -// new RepositoryCleaner().gc(); -// logger.info( "Repository GC has been finished" ); - throw new NotImplementedException(); - } -} diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties deleted file mode 100644 index 52a96b5bfb7..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages.properties +++ /dev/null @@ -1,46 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have been run \ - remotely: {1} - -QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing -QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing -QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=You don't have scheduling permissions for this file.\nContact your administrator for assistance. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Due to user/role changes, job "{0}" is not able to be executed by "{1}" -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} - -schedulerEmailFromName=Pentaho Scheduler -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger - -Unknown=Unknown - -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Running action "{0}" in background locally: {1} - -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=File written by XActions must be cleaned up by external means: {0} - -ActionInvoker.ERROR_0004_ACTION_FAILED=Action "{0}" failed to execute -ActionInvoker.ERROR_0005_ACTION_NULL=Action is null, cannot invoke -ActionInvoker.ERROR_0006_ACTION_NULL=Action "{0}" is not supported -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Map is null, cannot return stream provider -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Cannot get repository file "{0}": {1} diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties deleted file mode 100644 index 86c334439b8..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_de.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Ung\u00fcltiger Cron-Ausdruck. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Eigenschaft "{0}" oder "{1}" muss in der Aufgabendatenzuordnung festgesetzt werden, -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Fehler beim Erstellen einer Instanz der Aktion "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=Klasse {0} muss eine Instanz von "{1}" sein -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Aktion "{0}" als Quartz-Aufgabe ausf\u00fchren fehlgeschlagen -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status f\ufffdr Aktion "{0}" ist nicht verf\ufffdgbar; Die Aktion kann \ -# remote ausgef\ufffdhrt worden sein: {1} -# -QuartzJobKey.ERROR_0000=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, jobName nicht vorhanden -QuartzJobKey.ERROR_0001=Erstellen des Aufgabenschl\u00fcssels nicht m\u00f6glich, Benutzername nicht vorhanden -QuartzJobKey.ERROR_0002=In jobId "{0}" fehlen Daten -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz konnte f\u00fcr Aufgabe "{0}" keinen Zeitplan festlegen -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Ausl\u00f6ser ist ein unzul\u00e4ssiger Typ -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Aktion darf nicht Null sein -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz konnte die Aufgaben nicht auflisten. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz konnte die Aufgabe nicht anhalten. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz konnte die Aufgaben nicht fortsetzen. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Quartz-Zeitplanstatus kann nicht abgerufen werden. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Aufgabe "{0}" kann nicht abgerufen werden -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Planer wurde beim Starten nicht ordnungsgem\u00e4\u00df initialisiert -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Laden von Quartz.properties von Klassenpfad fehlgeschlagen. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Instanziieren von Objekt nicht m\u00f6glich -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Datenquellobjekt nicht abrufbar -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Beim Erstellen der Quartz-Tabellen ist ein SQL-Fehler aufgetreten -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Quartz-Initialisierungsskript system/quartz/quartzinit.sql kann nicht gefunden werden -JobParamsAdapter.ERROR_0001=Typ {0} wird von {1} nicht unterst\u00fctzt -# -schedulerEmailFromName=Pentaho-Planer -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Es wurde versucht, ein IBlockOutTrigger-Objekt hinzuzuf\u00fcgen, das keine Instanz des Ausl\u00f6sers ist -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Sperre "{0}" konnte nicht gesucht werden -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Es kann kein g\u00fcltiger Wiederholungsintervall vom bereitgestellten Ausl\u00f6ser analysiert werden -# -Unknown=Unbekannt -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Sie haben keine Berechtigungen, um diese Datei zu planen.\nWenden Sie sich wegen Unterst\u00fctzung an den Administrator. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=Aufgrund Benutzer- oder Rollen\u00e4nderungen kann Job {0} nicht von {1} ausgef\u00fchrt werden. -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Aktion {0} wird im Hintergrund lokal ausgef\u00fchrt: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Von XActions geschriebene Datei muss extern bereinigt werden: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=Ausf\u00fchren der Aktion {0} fehlgeschlagen -ActionInvoker.ERROR_0005_ACTION_NULL=Aktion ist null, Fortfahren nicht m\u00f6glich ... -ActionInvoker.ERROR_0006_ACTION_NULL=Aktion {0} wird nicht unterst\u00fctzt -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Zuordnung ist null, Stream-Anbieter kann nicht zur\u00fcckgegeben werden -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Repository-Datei {0} nicht abrufbar: {1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties deleted file mode 100644 index 41a9d7e312f..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_fr.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Expression cron non valide. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=La propri\u00e9t\u00e9 {0} ou {1} doit \u00eatre d\u00e9finie dans le mappage des donn\u00e9es de t\u00e2che. -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Impossible de cr\u00e9er une instance de l'action {0}: {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=la classe {0} doit \u00eatre une instance de {1} -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u00c9chec d'ex\u00e9cution de l'action {0} en tant que t\u00e2che quartz -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=L'\ufffdtat de l'action "{0}" n'est pas disponible; L'action peut avoir \ufffdt\ufffd \ -# ex\ufffdcut\ufffde \ufffd distance: {1} -# -QuartzJobKey.ERROR_0000=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, jobName est manquant -QuartzJobKey.ERROR_0001=Impossible de g\u00e9n\u00e9rer la cl\u00e9 de t\u00e2che, username est manquant -QuartzJobKey.ERROR_0002=Donn\u00e9es manquantes dans jobId {0}. -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=\u00c9chec de la planification de la t\u00e2che {0} par quartz -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=D\u00e9clencheur est un type non conforme -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=L'action ne peut pas \u00eatre nulle -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Impossible pour Quartz de lister les t\u00e2ches -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Impossible pour Quartz de mettre les t\u00e2ches en pause -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Impossible pour Quartz de reprendre les t\u00e2ches -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Impossible d'obtenir le statut du planificateur Quartz. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Impossible d'obtenir la t\u00e2che {0} -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Le planificateur n'a pas \u00e9t\u00e9 correctement initialis\u00e9 lors du d\u00e9marrage. -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u00c9chec du chargement de quartz.properties depuis le Classpath. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Impossible d'instancier l'objet -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Impossible d'obtenir l'objet de la source de donn\u00e9es -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=Erreur SQL lors de la cr\u00e9ation des tables Quartz -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Impossible de trouver le script d'initialisation Quartz system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} non pris en charge par {1} -# -schedulerEmailFromName=Planificateur Pentaho -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Tentative d'ajout d'un objet IBlockOutTrigger qui n'est pas une instance de d\u00e9clencheur -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Impossible de localiser le blocage avec le nom : {0} -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Impossible d'analyser un intervalle de p\u00e9riodicit\u00e9 valide \u00e0 partir du d\u00e9clencheur fourni. -# -Unknown=Inconnu -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=Vous n'\u00eates pas autoris\u00e9 \u00e0 planifier ce fichier.\nPour obtenir de l'aide, contactez votre administrateur. -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=En raison de changements d'utilisateur/de r\u00f4le, la t\u00e2che \u00ab\u00a0{0}\u00a0\u00bb ne peut pas \u00eatre ex\u00e9cut\u00e9e par \u00ab\u00a0{1}\u00a0\u00bb -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=Ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb en arri\u00e8re-plan localement\u00a0: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=Le fichier \u00e9crit par XActions doit \u00eatre nettoy\u00e9 par des moyens externes\u00a0: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=\u00c9chec de l'ex\u00e9cution de l'action \u00ab\u00a0{0}\u00a0\u00bb -ActionInvoker.ERROR_0005_ACTION_NULL=L'action est nulle, impossible de l'appeler -ActionInvoker.ERROR_0006_ACTION_NULL=L'action \u00ab\u00a0{0}\u00a0\u00bb n'est pas prise en charge -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=Le mappage est nul, impossible de revenir au fournisseur de flux -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=Impossible d'obtenir le fichier du r\u00e9f\u00e9rentiel \u00ab\u00a0{0}\u00a0\u00bb\u00a0:{1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties deleted file mode 100644 index 7463353f5cb..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_ja.properties +++ /dev/null @@ -1,44 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=Invalid cron expression. -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=Property "{0}" or "{1}" must be set in the job data map -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=Failed to create an instance of action "{0}": {1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=class {0} must be an instance of "{1}" -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=Action "{0}" failed to run as a quartz job -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=Status for action "{0}" is not available; the action may have \ -# been run remotely: {1} -# -QuartzJobKey.ERROR_0000=Cannot generate job key, jobName is missing -QuartzJobKey.ERROR_0001=Cannot generate job key, username is missing -QuartzJobKey.ERROR_0002=Missing data in jobId "{0}". -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz failed to schedule job "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=Trigger is an illegal type -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=Action cannot be null -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz failed to list jobs. -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz failed to pause job. -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz failed to resume job. -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=Unable to get Quartz scheduler status. -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=Failed to get job "{0}" -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=Scheduler was not properly initialized at startup -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=Loading quartz.properties from classpath failed. -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=Unable to instantiate object -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=Unable to get datasource object -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=SQL Error creating Quartz tables -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=Cannot find Quartz initialization script system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001=Type {0} not supported by {1} -# -schedulerEmailFromName=Pentaho\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30fc -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=Attempted to add a IBlockOutTrigger object that is not an instance of Trigger -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=Unable to locate block out with name: "{0}" -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=Can not parse a valid recurrence interval from the provided Trigger -# -Unknown=Unknown -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30ea\u30f3\u30b0\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n\u7ba1\u7406\u8005\u306b\u554f\u3044\u5408\u308f\u305b\u3066\u304f\u3060\u3055\u3044\u3002 -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u30e6\u30fc\u30b6\u30fc/\u30ed\u30fc\u30eb\u306e\u5909\u66f4\u306b\u3088\u308a\u3001\u30b8\u30e7\u30d6 "{0}" \u306f "{1}" \u3067\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u3092\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u30ed\u30fc\u30ab\u30eb\u3067\u5b9f\u884c\u3057\u3066\u3044\u307e\u3059: {1} -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=XActions\u306b\u3088\u3063\u3066\u66f8\u304d\u8fbc\u307e\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u5916\u90e8\u306e\u624b\u6bb5\u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059: {0} -ActionInvoker.ERROR_0004_ACTION_FAILED=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306e\u5b9f\u884c\u306b\u5931\u6557\u3057\u307e\u3057\u305f -ActionInvoker.ERROR_0005_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3\u304cnull\u3067\u3001\u547c\u3073\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.ERROR_0006_ACTION_NULL=\u30a2\u30af\u30b7\u30e7\u30f3 "{0}" \u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093 -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u30de\u30c3\u30d7\u304cnull\u3067\u3059\u3002\u30b9\u30c8\u30ea\u30fc\u30e0\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8fd4\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u30ea\u30dd\u30b8\u30c8\u30ea\u30d5\u30a1\u30a4\u30eb "{0}" \u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093: {1} -# diff --git a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties b/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties deleted file mode 100644 index 8cd2eb3fd00..00000000000 --- a/scheduler/src/main/resources/org/pentaho/platform/scheduler2/messsages/messages_zh_CN.properties +++ /dev/null @@ -1,46 +0,0 @@ -ComplexJobTrigger.ERROR_0001_InvalidCronExpression=cron \u8868\u8fbe\u5f0f\u65e0\u6548\u3002 -ActionAdapterQuartzJob.ERROR_0001_REQUIRED_PARAM_MISSING=\u5fc5\u987b\u5728\u4f5c\u4e1a\u6570\u636e\u6620\u5c04\u4e2d\u8bbe\u7f6e\u5c5e\u6027 "{0}" \u6216 "{1}" -ActionAdapterQuartzJob.ERROR_0002_FAILED_TO_CREATE_ACTION=\u521b\u5efa\u64cd\u4f5c "{0}" \u7684\u5b9e\u4f8b\u5931\u8d25\uff1a{1} -ActionAdapterQuartzJob.ERROR_0003_ACTION_WRONG_TYPE=\u7c7b {0} \u5fc5\u987b\u662f "{1}" \u7684\u5b9e\u4f8b -ActionAdapterQuartzJob.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u4f5c\u4e3a quartz \u4f5c\u4e1a\u8fd0\u884c\u5931\u8d25 -ActionAdapterQuartzJob.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} -ActionAdapterQuartzJob.WARN_0002_NO_STATUS=\u64cd\u4f5c\u72b6\u6001 "{0}" \u4e0d\u53ef\u7528\uff1b\u8be5\u64cd\u4f5c\u53ef\u80fd\u5df2\u8fdc\u7a0b\u8fd0\u884c #\uff1a{1} -# -QuartzJobKey.ERROR_0000=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0cjobName \u4e22\u5931 -QuartzJobKey.ERROR_0001=\u65e0\u6cd5\u751f\u6210\u4f5c\u4e1a\u952e\uff0c\u7528\u6237\u540d\u4e22\u5931 -QuartzJobKey.ERROR_0002=jobId "{0}" \u4e2d\u7684\u6570\u636e\u4e22\u5931\u3002 -QuartzScheduler.ERROR_0001_FAILED_TO_SCHEDULE_JOB=Quartz \u672a\u80fd\u5b89\u6392\u4f5c\u4e1a "{0}" -QuartzScheduler.ERROR_0002_TRIGGER_WRONG_TYPE=\u89e6\u53d1\u5668\u4e3a\u975e\u6cd5\u7c7b\u578b -QuartzScheduler.ERROR_0003_ACTION_IS_NULL=\u64cd\u4f5c\u4e0d\u80fd\u4e3a\u7a7a\u503c -QuartzScheduler.ERROR_0004_FAILED_TO_LIST_JOBS=Quartz \u5217\u51fa\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0005_FAILED_TO_PAUSE_JOB=Quartz \u6682\u505c\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0005_FAILED_TO_RESUME_JOB=Quartz \u7ee7\u7eed\u4f5c\u4e1a\u5931\u8d25\u3002 -QuartzScheduler.ERROR_0006_FAILED_TO_GET_SCHEDULER_STATUS=\u65e0\u6cd5\u83b7\u53d6 Quartz \u8c03\u5ea6\u7a0b\u5e8f\u72b6\u6001\u3002 -QuartzScheduler.ERROR_0007_FAILED_TO_GET_JOB=\u83b7\u53d6\u4f5c\u4e1a "{0}" \u5931\u8d25 -QuartzScheduler.ERROR_0008_SCHEDULING_IS_NOT_ALLOWED=\u60a8\u6ca1\u6709\u6b64\u6587\u4ef6\u7684\u8c03\u5ea6\u6743\u9650\u3002\n\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u4ee5\u83b7\u53d6\u5e2e\u52a9\u3002 -QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE=\u7531\u4e8e\u7528\u6237/\u89d2\u8272\u7684\u66f4\u6539\uff0c\u4f5c\u4e1a "{0}" \u4e0d\u80fd\u7531 "{1}" \u6267\u884c -EmbeddedQuartzSystemListener.ERROR_0001_Scheduler_Not_Initialized=\u5728\u542f\u52a8\u65f6\u672a\u6b63\u786e\u521d\u59cb\u5316\u8c03\u5ea6\u7a0b\u5e8f -EmbeddedQuartzSystemListener.ERROR_0004_LOAD_PROPERTIES_FROM_CLASSPATH=\u4ece\u7c7b\u8def\u5f84\u52a0\u8f7d quartz.properties \u5931\u8d25\u3002 -EmbeddedQuartzSystemListener.ERROR_0005_UNABLE_TO_INSTANTIATE_OBJECT=\u65e0\u6cd5\u5b9e\u4f8b\u5316\u5bf9\u8c61 -EmbeddedQuartzSystemListener.ERROR_0006_UNABLE_TO_GET_DATASOURCE=\u65e0\u6cd5\u83b7\u53d6\u6570\u636e\u6e90\u5bf9\u8c61 -EmbeddedQuartzSystemListener.ERROR_0007_SQLERROR=\u521b\u5efa Quartz \u8868\u65f6\u51fa\u73b0 SQL \u9519\u8bef -EmbeddedQuartzSystemListener.ERROR_0008_UNABLE_TO_FIND_INIT_SCRIPT=\u627e\u4e0d\u5230 Quartz \u521d\u59cb\u5316\u811a\u672c system/quartz/quartzinit.sql -JobParamsAdapter.ERROR_0001={1} \u4e0d\u652f\u6301\u7c7b\u578b {0} -# -schedulerEmailFromName=Pentaho \u8ba1\u5212\u7a0b\u5e8f -PentahoBlockoutManager.ERROR_0001_WRONG_BLOCKER_TYPE=\u5df2\u5c1d\u8bd5\u6dfb\u52a0\u975e\u89e6\u53d1\u5668\u5b9e\u4f8b\u7684 IBlockOutTrigger \u5bf9\u8c61 -PentahoBlockoutManager.ERROR_0002_CANT_CREATE_BLOCKOUT=\u65e0\u6cd5\u4f7f\u7528\u540d\u79f0 "{0}" \u627e\u5230\u963b\u6b62 -PentahoBlockoutManager.ERROR_0003_CANT_PARSE_RECURRENCE_INTERVAL=\u65e0\u6cd5\u4ece\u63d0\u4f9b\u7684\u89e6\u53d1\u5668\u89e3\u6790\u6709\u6548\u7684\u5b9a\u671f\u95f4\u9694 -# -Unknown=\u672a\u77e5 -# -ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY=\u5728\u540e\u53f0\u672c\u5730\u8fd0\u884c\u64cd\u4f5c "{0}"\uff1a{1} -# -ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE=\u7531 XActions \u5199\u5165\u7684\u6587\u4ef6\u5fc5\u987b\u901a\u8fc7\u5916\u90e8\u65b9\u5f0f\u6e05\u9664\uff1a{0} -# -ActionInvoker.ERROR_0004_ACTION_FAILED=\u64cd\u4f5c "{0}" \u6267\u884c\u5931\u8d25 -ActionInvoker.ERROR_0005_ACTION_NULL=\u64cd\u4f5c\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8c03\u7528 -ActionInvoker.ERROR_0006_ACTION_NULL=\u4e0d\u652f\u6301\u64cd\u4f5c "{0}" -ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP=\u6620\u5c04\u4e3a\u7a7a\u503c\uff0c\u65e0\u6cd5\u8fd4\u56de\u6d41\u63d0\u4f9b\u7a0b\u5e8f -ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE=\u65e0\u6cd5\u83b7\u53d6\u5b58\u50a8\u5e93\u6587\u4ef6 "{0}"\uff1a{1} -# From 8e08018cfb417d268a6e777bb39ad74cb35b79e2 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Fri, 17 Nov 2023 09:45:54 -0500 Subject: [PATCH 44/59] [BACKLOG-39119] - Removal of quartz.properties from pentaho-platform (moved to pentaho-scheduler-plugin) --- .../quartz/h2-quartz-schema-updated.sql | 228 --------- .../system/quartz/quartz.properties | 450 ------------------ 2 files changed, 678 deletions(-) delete mode 100644 assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/h2-quartz-schema-updated.sql delete mode 100644 assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/quartz.properties diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/h2-quartz-schema-updated.sql b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/h2-quartz-schema-updated.sql deleted file mode 100644 index 7b3f9fdad1c..00000000000 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/h2-quartz-schema-updated.sql +++ /dev/null @@ -1,228 +0,0 @@ -CREATE TABLE QRTZ_CALENDARS ( - CALENDAR_NAME VARCHAR (200) NOT NULL , - CALENDAR IMAGE NOT NULL -); - -CREATE TABLE QRTZ_CRON_TRIGGERS ( - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - CRON_EXPRESSION VARCHAR (120) NOT NULL , - TIME_ZONE_ID VARCHAR (80) -); - -CREATE TABLE QRTZ_FIRED_TRIGGERS ( - ENTRY_ID VARCHAR (95) NOT NULL , - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - IS_VOLATILE BOOLEAN NOT NULL , - INSTANCE_NAME VARCHAR (200) NOT NULL , - FIRED_TIME BIGINT NOT NULL , - PRIORITY INTEGER NOT NULL , - STATE VARCHAR (16) NOT NULL, - JOB_NAME VARCHAR (200) NULL , - JOB_GROUP VARCHAR (200) NULL , - IS_STATEFUL BOOLEAN NULL , - REQUESTS_RECOVERY BOOLEAN NULL -); - -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( - TRIGGER_GROUP VARCHAR (200) NOT NULL -); - -CREATE TABLE QRTZ_SCHEDULER_STATE ( - INSTANCE_NAME VARCHAR (200) NOT NULL , - LAST_CHECKIN_TIME BIGINT NOT NULL , - CHECKIN_INTERVAL BIGINT NOT NULL -); - -CREATE TABLE QRTZ_LOCKS ( - LOCK_NAME VARCHAR (40) NOT NULL -); - -CREATE TABLE QRTZ_JOB_DETAILS ( - JOB_NAME VARCHAR (200) NOT NULL , - JOB_GROUP VARCHAR (200) NOT NULL , - DESCRIPTION VARCHAR (250) NULL , - JOB_CLASS_NAME VARCHAR (250) NOT NULL , - IS_DURABLE BOOLEAN NOT NULL , - IS_VOLATILE BOOLEAN NOT NULL , - IS_STATEFUL BOOLEAN NOT NULL , - REQUESTS_RECOVERY BOOLEAN NOT NULL , - JOB_DATA IMAGE NULL -); - -CREATE TABLE QRTZ_JOB_LISTENERS ( - JOB_NAME VARCHAR (200) NOT NULL , - JOB_GROUP VARCHAR (200) NOT NULL , - JOB_LISTENER VARCHAR (200) NOT NULL -); - -CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - REPEAT_COUNT BIGINT NOT NULL , - REPEAT_INTERVAL BIGINT NOT NULL , - TIMES_TRIGGERED BIGINT NOT NULL -); - -CREATE TABLE QRTZ_BLOB_TRIGGERS ( - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - BLOB_DATA IMAGE NULL -); - -CREATE TABLE QRTZ_TRIGGER_LISTENERS ( - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - TRIGGER_LISTENER VARCHAR (200) NOT NULL -); - -CREATE TABLE QRTZ_TRIGGERS ( - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - JOB_NAME VARCHAR (200) NOT NULL , - JOB_GROUP VARCHAR (200) NOT NULL , - IS_VOLATILE BOOLEAN NOT NULL , - DESCRIPTION VARCHAR (250) NULL , - NEXT_FIRE_TIME BIGINT NULL , - PREV_FIRE_TIME BIGINT NULL , - PRIORITY INTEGER NULL , - TRIGGER_STATE VARCHAR (16) NOT NULL , - TRIGGER_TYPE VARCHAR (8) NOT NULL , - START_TIME BIGINT NOT NULL , - END_TIME BIGINT NULL , - CALENDAR_NAME VARCHAR (200) NULL , - MISFIRE_INSTR SMALLINT NULL , - JOB_DATA IMAGE NULL -); - -ALTER TABLE QRTZ_CALENDARS ADD - CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY - ( - CALENDAR_NAME - ); - -ALTER TABLE QRTZ_CRON_TRIGGERS ADD - CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_FIRED_TRIGGERS ADD - CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY - ( - ENTRY_ID - ); - -ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS ADD - CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY - ( - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_SCHEDULER_STATE ADD - CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY - ( - INSTANCE_NAME - ); - -ALTER TABLE QRTZ_LOCKS ADD - CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY - ( - LOCK_NAME - ); - -ALTER TABLE QRTZ_JOB_DETAILS ADD - CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY - ( - JOB_NAME, - JOB_GROUP - ); - -ALTER TABLE QRTZ_JOB_LISTENERS ADD - CONSTRAINT PK_QRTZ_JOB_LISTENERS PRIMARY KEY - ( - JOB_NAME, - JOB_GROUP, - JOB_LISTENER - ); - -ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD - CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_TRIGGER_LISTENERS ADD - CONSTRAINT PK_QRTZ_TRIGGER_LISTENERS PRIMARY KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP, - TRIGGER_LISTENER - ); - -ALTER TABLE QRTZ_TRIGGERS ADD - CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_CRON_TRIGGERS ADD - CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - -ALTER TABLE QRTZ_JOB_LISTENERS ADD - CONSTRAINT FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS FOREIGN KEY - ( - JOB_NAME, - JOB_GROUP - ) REFERENCES QRTZ_JOB_DETAILS ( - JOB_NAME, - JOB_GROUP - ) ON DELETE CASCADE; - -ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD - CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - -ALTER TABLE QRTZ_TRIGGER_LISTENERS ADD - CONSTRAINT FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS FOREIGN KEY - ( - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - -ALTER TABLE QRTZ_TRIGGERS ADD - CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY - ( - JOB_NAME, - JOB_GROUP - ) REFERENCES QRTZ_JOB_DETAILS ( - JOB_NAME, - JOB_GROUP - ); - -INSERT INTO QRTZ_LOCKS VALUES('TRIGGER_ACCESS'); -INSERT INTO QRTZ_LOCKS VALUES('JOB_ACCESS'); -INSERT INTO QRTZ_LOCKS VALUES('CALENDAR_ACCESS'); -INSERT INTO QRTZ_LOCKS VALUES('STATE_ACCESS'); -INSERT INTO QRTZ_LOCKS VALUES('MISFIRE_ACCESS'); -COMMIT; diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/quartz.properties b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/quartz.properties deleted file mode 100644 index 8a9a3f21083..00000000000 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/quartz/quartz.properties +++ /dev/null @@ -1,450 +0,0 @@ -# Copyright 2008 - 2017 Hitachi Vantara. All rights reserved. -# This software was developed by Hitachi Vantara and is provided under the terms -# of the Mozilla Public License, Version 1.1, or any later version. You may not use -# this file except in compliance with the license. If you need a copy of the license, -# please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho -# BI Platform. The Initial Developer is Pentaho Corporation. -# -# Software distributed under the Mozilla Public License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to -# the license for the specific language governing your rights and limitations. -# Properties file for use by StdSchedulerFactory -# to create a Quartz Scheduler Instance. -# -# Instances of the specified JobStore, ThreadPool and Logger classes will -# be created by name, and then any additional properties specified for them -# in this file will be set on the instance by calling an equivalent 'set' -# method. (see below for more examples) -# -# =========================================================================== -# Configure Main Scheduler Properties ====================================== -# =========================================================================== -# -# The general pattern for defining the scheduler's main properties is: -# -# org.quartz.scheduler.instanceName = SCHED_NAME -# org.quartz.scheduler.instanceId = INSTANCE_ID -# org.quartz.scheduler.threadName = THREAD_NAME -# org.quartz.scheduler.rmi.export = false -# org.quartz.scheduler.rmi.proxy = false -# org.quartz.scheduler.rmi.registryHost = localhost -# org.quartz.scheduler.rmi.registryPort = 1099 -# org.quartz.scheduler.rmi.createRegistry = never -# org.quartz.scheduler.userTransactionURL = USER_TX_LOCATION -# org.quartz.scheduler.wrapJobExecutionInUserTransaction = JOBS_IN_USER_TX -# org.quartz.scheduler.idleWaitTime = IDLE_WAIT_TIME -# org.quartz.scheduler.dbFailureRetryInterval = DB_FAILURE_RETRY_INTERVAL -# org.quartz.scheduler.classLoadHelper.class = CLASS_LOAD_HELPER_CLASS -# org.quartz.context.key.SOME_KEY = SOME_VALUE -# -# -# "SCHED_NAME" can be any string, and has no meaning to the scheduler itself - -# but rather serves as a mechanism for client code to distinguish schedulers -# when multiple instances are used within the same program. If you are using -# the clustering features, you must use the same name for every instance in -# the cluster that is 'logically' the same Scheduler. -# -# "INSTANCE_ID" can be any string, and but must be unique for all schedulers -# working as if they are the same 'logical' Scheduler within a cluster. -# you may use the value "AUTO" as the instanceId if you wish the Id to be -# generated for you. -# -# "THREAD_NAME" can be any String that is a valid name for a java thread. If -# this property is not specified, the thread will receive the scheduler's -# name ("org.quartz.scheduler.instanceName"). -# -# "USER_TX_LOCATION" should be set to the JNDI URL at which Quartz can locate -# the Application Server's UserTransaction manager. The default value (if not -# specified) is "java:comp/UserTransaction" - which works for almost all -# Application Servers. Websphere users may need to set this property to -# "jta/usertransaction". This is only used if Quartz is configured to use -# JobStoreCMT, and "JOBS_IN_USER_TX" is set to true. -# -# "JOBS_IN_USER_TX" should be set to "true" if you want Quartz to start a -# UserTransaction before calling execute on your job. The Tx will commit after -# the job's execute method completes, and the JobDataMap is updated (if it is -# a StatefulJob). The default value is "false". -# -# "IDLE_WAIT_TIME" is the amount of time in milliseconds that the scheduler -# will wait before re-queries for available triggers when the scheduler is otherwise -# idle. Normally you should not have to 'tune' this parameter, unless you're using -# XA transactions, and are having problems with delayed firings of triggers that -# should fire immediately. -# -# "DB_FAILURE_RETRY_INTERVAL" is the amount of time in milliseconds that the -# scheduler will wait between re-tries when it has detected a loss of -# connectivity to the database (obviously not meaningful with RamJobStore) -# -# "CLASS_LOAD_HELPER_CLASS" defaults to the most robust approach, which is to -# use the "org.quartz.simpl.CascadingClassLoadHelper" class - which in turn -# uses every other ClassLoadHelper class until one works. You should probably -# not find the need to specify any other class for this property, though strange -# things seem to happen within application servers. All of the current -# ClassLoadHelper implementation can be found in the "org.quartz.simpl" package. -# -# "SOME_KEY" and "SOME_VALUE" represent a name-value pair that will be placed -# into the "scheduler context" as strings. (see Scheduler.getContext()). -# So for example, the setting "org.quartz.context.key.MyKey = MyValue" would -# perform the equivalent of scheduler.getContext().put("MyKey", "MyValue"). -# -# -# RMI notes: -# -# If you want the Quartz Scheduler exported via RMI as a server then set -# the 'rmi.export' flag to true. You must also then specify a host and -# port for the rmiregistry process - which is typically 'localhost' port 1099. -# -# Set the 'rmi.createRegistry' flag according to how you want Quartz to cause -# the creation of an RMI Registry. Use "false" or "never" if you don't want -# Quartz to create a registry. Use "true" or "as_needed" if you want Quartz -# to first attempt to use an existing registry, and then fall back to creating -# one. Use "always" if you want Quartz to attempt creating a Registry, and -# then fall back to using an existing one. -# If a registry is created, it will be bound to port number in the given -# the 'rmi.registryPort' property, and 'rmi.registryHost' should be "localhost". -# -# If you want to connect (use) a remotely served scheduler, then set the -# 'rmi.proxy' flag to true. You must also then specify a host and port -# for the rmiregistry process - which is typically 'localhost' port 1099. -# -# You cannot specify a 'true' value for both 'export' and 'proxy' - if you -# do, the 'export' option will be ignored. A value of 'false' for both -# 'export' and 'proxy' properties is of course valid. -# -# -org.quartz.scheduler.instanceName = PentahoQuartzScheduler -org.quartz.scheduler.instanceId = 1 -org.quartz.scheduler.rmi.export = false -org.quartz.scheduler.rmi.proxy = false -org.quartz.scheduler.wrapJobExecutionInUserTransaction = false -# -# =========================================================================== -# Configure ThreadPool ===================================================== -# =========================================================================== -# -# The general pattern for defining a thread pool is the following: -# -# org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool -# org.quartz.threadPool.threadCount = THREAD_COUNT -# org.quartz.threadPool.threadPriority = THREAD_PRIO -# -# optional parameters for SimpleThreadPool are: -# -# org.quartz.threadPool.makeThreadsDaemons = DAEMON_THREADS -# org.quartz.threadPool.threadsInheritGroupOfInitializingThread = INHERIT_GRP -# org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = INHERIT_LDR -# -# or -# -# org.quartz.threadPool.class = com.mycompany.goo.FooThreadPool -# org.quartz.threadPool.somePropOfFooThreadPool = someValue -# -# "THREAD_COUNT" can be any positive integer, although you should realize that -# only numbers between 1 and 100 are very practical. This is the number of -# threads that are available for concurrent execution of jobs. If you only -# have a few jobs that fire a few times a day, then 1 thread is plenty! If you -# have tens of thousands of jobs, with many firing every minute, then you -# probably want a thread count more like 50 or 100 (this highly depends on the -# nature of the work that your jobs perform, and your systems resources!) -# -# "THREAD_PRIO" can be any int between Thread.MIN_PRIORITY (1) and -# Thread.MAX_PRIORITY (10). The default is Thread.NORM_PRIORITY (5). -# -# "DAEMON_THREADS" can be set to "true" to have the threads in the pool created -# as daemon threads. Default is "false". -# -# "INHERIT_GRP" can be "true" or "false", and defaults to true. -# -# "INHERIT_LDR" can be "true" or "false", and defaults to false. -# -org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool -org.quartz.threadPool.threadCount = 10 -org.quartz.threadPool.threadPriority = 5 -org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true -# -# =========================================================================== -# Configure JobStore ======================================================= -# =========================================================================== -# -# The general pattern for defining a JobStore is one of the following: -# -# org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore -# org.quartz.jobStore.misfireThreshold = MISFIRE_THRESHOLD -# -# or -# -# org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore. -# Where JobStoreClass is one of: -# - JobStoreTX is for standalone-Quartz implementations -# - JobStoreCMT is for appserver-based container-managed -# transaction Quartz implementations -# -# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore. -# Where DriverDelegateClass is one of: -# - StdJDBCDelegate (for many JDBC-compliant drivers) -# - MSSQLDelegate (for Microsoft SQL Server drivers) -# - PostgreSQLDelegate (for PostgreSQL drivers) -# - WebLogicDelegate (for WebLogic drivers) -# - oracle.OracleDelegate (for Oracle drivers) -# -# org.quartz.jobStore.useProperties = USE_PROPERTIES -# org.quartz.jobStore.dataSource = DS_NAME -# org.quartz.jobStore.tablePrefix = TABLE_PREFIX -# org.quartz.jobStore.isClustered = IS_CLUSTERED -# org.quartz.jobStore.selectWithLockSQL = LOCKING_SELECT_STATEMENT -# org.quartz.jobStore.dontSetAutoCommitFalse = DONT_TURN_OFF_AUTO_COMMIT -# org.quartz.jobStore.maxMisfiresToHandleAtATime = MAX_MISFIRE_HANDLE -# org.quartz.jobStore.txIsolationLevelSerializable = SERIALIZABLE_ISOLATION -# -# If you're using JobStoreCMT then you need this param also: -# -# org.quartz.jobStore.nonManagedTXDataSource = NON_MANAGED_TX_DS_NAME -# -# And, if you're using JobStoreCMT, then these params are optional: -# -# org.quartz.jobStore.dontSetNonManagedTXConnectionAutoCommitFalse = DONT_TURN_OFF_AUTO_COMMIT -# org.quartz.jobStore.txIsolationLevelReadCommitted = READ_COMMITTED_ISOLATION -# -# -# or, for a custom JobStore implementation: -# -# org.quartz.jobStore.class = com.mycompany.goo.FooJobStore -# org.quartz.jobStore.somePropOfFooJobStore = someValue -# -# -# The value of "MISFIRE_THRESHOLD" should be the number of milliseconds the -# scheduler will 'tolerate' a trigger to pass its next-fire-time by, before -# being considered "misfired". The default value (if you don't make an entry -# of this property in your configuration) is 60000 (60 seconds). -# -# The value of "MAX_MISFIRE_HANDLE" is the maximum number of misfired triggers -# that the misfire handlingthread will try to recover at one time (within one -# transaction). If unspecified, the default is 20. -# -# The "USE_PROPERTIES" flag (true or false value - defaults to false) instructs -# JDBCJobStore that all values in JobDataMaps will be Strings, and therefore -# can be stored as name-value pairs, rather than storing more complex objects -# in their serialized form in the BLOB column. This is much safer in the long -# term, as you avoid the class versioning issues that there are with -# serializing your non-String classes into a BLOB. -# -# JDBCJobStore's "DS_NAME" must be the name of one the datasources -# defined in this file. JobStoreCMT _requires_ a datasource that contains -# container-managed-transaction-capable connections. Typically this means a -# datasource that is managed by an application server, and used by Quartz by -# specifying the JNDI url of the datasource. -# -# JobStoreCMT also _requires_ a (second) datasource that contains connections -# that will not be part of container-managed transactions. -# "NON_MANAGED_TX_DS_NAME" must be the name of one the datasources defined in -# this file. - This datasource must contain non-container-transaction managed -# connections. -# -# JDBCJobStore's "TABLE_PREFIX" property is a string equal to the prefix -# given to Quartz's tables that were created in your database. -# -# JDBCJobStore's "IS_CLUSTERED" property must be set to either "true" or -# "false". If unset, the default is "false". This property must be set -# to "true" if you are having multiple instances of Quartz use the same -# set of database tables... otherwise you will experience havoc. Also -# note that each instance in the cluster MUST have a unique "instance id" -# (the "org.quartz.scheduler.instanceId" property), but should have the -# same "scheduler instance name" ("org.quartz.scheduler.instanceName"). -# -# * NOTE: Never run clustering on separate machines, unless their clocks are -# synchronized using some form of time-sync service (daemon) that runs -# very regularly (the clocks must be within a second of each other). -# See http://www.boulder.nist.gov/timefreq/service/its.htm if you are -# unfamiliar with how to do this. -# -# Also: never fire-up a non-clustered instance against the same set -# of tables that any other instance is running against. You will -# get serious data corruption, and eratic behavior. -# -# -# JDBCJobStore's "LOCKING_SELECT_STATEMENT" property must be a SQL string -# that selects a row in the "LOCKS" table and places a lock on it. If not -# set, the default is "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE", -# which works for most databases. The "{0}" is replaced during run-time -# with the TABLE_PREFIX that you configured above. -# -# "DONT_TURN_OFF_AUTO_COMMIT" tells Quartz not to call setAutoCommit(false) -# on connections obtained from the DataSource(s). This can be helpful -# in a few situations, such as if you have a driver that complains if -# it is called when it is already off. This property defaults to false. -# -# "SERIALIZABLE_ISOLATION" tells Quartz (when using JobStoreTX or CMT) to call -# setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); on JDBC -# connections. This can be helpful to prevent lock timeouts with some databases -# under high load, and "longer"-lasting transactions. -# -# "READ_COMMITTED_ISOLATION" tells Quartz (When using JobStoreCMT) to call -# setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); on the -# non-managed JDBC connections. This can be helpful to prevent lock timeouts -# with some databases (such as DB2) under high load, and "longer"-lasting -# transactions. -# -#org.quartz.jobStore.misfireThreshold = 60000 -#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate -#org.quartz.jobStore.useProperties = false -#org.quartz.jobStore.dataSource = myDS -#org.quartz.jobStore.tablePrefix = QRTZ5_ -#org.quartz.jobStore.isClustered = false - -# Job Store -org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX - -#_replace_jobstore_properties - -org.quartz.jobStore.misfireThreshold = 60000 -org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -org.quartz.jobStore.useProperties = false -org.quartz.jobStore.dataSource = myDS -org.quartz.jobStore.tablePrefix = QRTZ5_ -org.quartz.jobStore.isClustered = false - -# =========================================================================== -# Configure Datasources ==================================================== -# =========================================================================== -# -# (only needed when using JDBCJobStore, or a plugin that requires JDBC) -# -# -- If your Scheduler is very busy (i.e. nearly always executing the same -# number of jobs as the size of the thread pool, then you should probably -# set the number of connections in the DataSource to be the size of the -# thread pool + 1 -# -# The general pattern for defining a DataSource is one of the following: -# -# org.quartz.dataSource.NAME.driver = DRIVER_CLASS_NAME -# org.quartz.dataSource.NAME.URL = DB_URL -# org.quartz.dataSource.NAME.user = DB_USER -# org.quartz.dataSource.NAME.password = DB_PASSWORD -# org.quartz.dataSource.NAME.maxConnections = DB_POOL_SIZE -# org.quartz.dataSource.NAME.validationQuery= VALIDATION_QUERY -# -# or -# -# org.quartz.dataSource.NAME.jndiURL = DB_JNDI_URL -# -# or -# org.quartz.dataSource.NAME.jndiURL = DB_JNDI_URL -# org.quartz.dataSource.NAME.jndiAlwaysLookup = DB_JNDI_ALWAYS_LOOKUP -# org.quartz.dataSource.NAME.java.naming.factory.initial = JNDI_CTXT_FACTORY -# org.quartz.dataSource.NAME.java.naming.provider.url = JNDI_PROVIDER_URL -# org.quartz.dataSource.NAME.java.naming.security.principal = JNDI_PRINCIPAL -# org.quartz.dataSource.NAME.java.naming.security.credentials = JNDI_CREDENTIALS -# -# -# The DataSource's "NAME" can be anything you want, and has no meaning other -# than being able to 'define' a DataSource here, and assign it by name to the -# JDBCJobStore. -# -# With the two types of DataSource definition shown above, a DataSource can -# either be created with the given database connection information, or can -# be "logically mapped" to use a DataSource that is managed by an application -# server an made available via JNDI. -# -# "DRIVER_CLASS_NAME" must be the java class name of the JDBC driver for your -# database. -# -# "DB_URL" must be the connection URL (host, port, etc.) for connection to your -# database. -# -# "DB_USER" is the user name to use when connecting to your database. -# -# "DB_USER" is the password to use when connecting to your database. -# -# "DB_POOL_SIZE" is the maximum number of connections that the DataSource can -# create in it's pool of connections. -# -# "VALIDATION_QUERY" is an optional SQL query string that the DataSource -# can use to detect and replace failed/corrupt connections. For example an -# oracle user might choose "select table_name from user_tables" - which is a -# query that should never fail - unless the connection is actually bad. -# -# "DB_JNDI_URL" is the JNDI URL for a DataSource that is managed by your -# application server. Additionally, you can provide the class name of the -# JNDI InitialContextFactory that you wish to use, the provider's URL, and -# a username & password for connecting to the JNDI provider, if it is not -# the default provider of your environment. -# -# "DB_JNDI_ALWAYS_LOOKUP" can be "true" or "false" - if the property is not -# set, the default is "false". This option tells Quartz whether or not it -# should always lookup the DataSource under the JNDI tree each time it -# needs to get a connection from it. If set to (the default) "false", -# Quartz will "hold on to" the DataSource after looking it up only once. -# - -org.quartz.dataSource.myDS.jndiURL = Quartz - -# -#org.quartz.dataSource.myDS.jndiURL=jdbc/PAWS -#org.quartz.dataSource.myDS.jndiAlwaysLookup=false -#org.quartz.dataSource.myDS.java.naming.factory.initial=com.evermind.server.rmi.RMIInitialContextFactory -#org.quartz.dataSource.myDS.java.naming.provider.url=ormi://localhost -#org.quartz.dataSource.myDS.java.naming.security.principal=admin -#org.quartz.dataSource.myDS.java.naming.security.credentials=123 -# -# =========================================================================== -# Configure SchedulerPlugins =============================================== -# =========================================================================== -# -# The general pattern for defining a SchedulerPlugin is the following: -# -# org.quartz.plugin.NAME.class = PLUGIN_CLASS_NAME -# -# If the plugin class has properties you want set via some "setter" methods -# on the class, name the properties and values as such -# -# org.quartz.plugin.NAME.propName = propValue -# -# ...where "propName" corrisponds to a "setPropName" method on the plugin -# class. Only primitive data type values (including Strings) are supported. -# -# -# Configure Plugins ========================================================= -# -#org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin -#org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy} -#org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9} -# -#org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin -#org.quartz.plugin.jobInitializer.fileName = data/my_job_data.xml -#org.quartz.plugin.jobInitializer.overWriteExistingJobs = false -#org.quartz.plugin.jobInitializer.failOnFileNotFound = true -# -#org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin -#org.quartz.plugin.shutdownhook.cleanShutdown = true -# -# =========================================================================== -# Configure Listeners =============================================== -# =========================================================================== -# -# The general pattern for defining a "Global" TriggerListener is: -# -# org.quartz.triggerListener.NAME.class = TRIGGER_LISTENER_CLASS_NAME -# -# The general pattern for defining a "Global" JobListener is the following: -# -# org.quartz.jobListener.NAME.class = JOB_LISTENER_CLASS_NAME -# -# "NAME" becomes the listener's name, and a "setName(String)" method is -# reflectively found and called on the class that is instantiated. -# -# If the listener class has properties you want set via some "setter" methods -# on the class, name the properties and values as such -# -# org.quartz.triggerListener.NAME.propName = propValue -# or -# org.quartz.jobListener.NAME.propName = propValue -# -# ...where "propName" corrisponds to a "setPropName" method on the listener -# class. Only primitive data type values (including Strings) are supported. -# -# -# Configure Plugins ========================================================= -# -#org.quartz.triggerListener.dummy.class = org.quartz.examples.DumbTriggerListener - - From 5c6ccc5f1d8830f593f07477a4c04827c339a46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duarte=20Cunha=20Lea=CC=83o?= Date: Mon, 20 Nov 2023 17:53:02 +0000 Subject: [PATCH 45/59] [BACKLOG-37872] Fixed not being able to use OBF or SuperDevMode mode and to schedule a file from the file browser - Changed the signature of the create schedule global hook to `pho.createSchedule( repositoryFileId, repositoryFilePath )` so that it can be called from a different GWT compilation module (mantle calling scheduler) --- .../client/solutionbrowser/SolutionBrowserPanel.java | 11 +++++++---- .../client/solutionbrowser/filelist/FileCommand.java | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java index 0c9bd208a40..5fd95bb706c 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/SolutionBrowserPanel.java @@ -12,7 +12,7 @@ * 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-2021 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. */ package org.pentaho.mantle.client.solutionbrowser; @@ -47,7 +47,6 @@ import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.TreeListener; import com.google.gwt.user.client.ui.Widget; -import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback; import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox; import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox; import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; @@ -830,7 +829,11 @@ public InfoDialog( String title, String message, boolean isHTML, boolean autoHid } } - private native void createSchedule( final RepositoryFile repositoryFile )/*-{ - $wnd.pho.createSchedule( repositoryFile ); + private void createSchedule( final RepositoryFile repositoryFile ) { + createSchedule( repositoryFile.getId(), repositoryFile.getPath() ); + } + + private native void createSchedule( final String repositoryFileId, final String repositoryFilePath )/*-{ + $wnd.pho.createSchedule( repositoryFileId, repositoryFilePath ); }-*/; } diff --git a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java index 0bb98a699e3..8c40da3454b 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/solutionbrowser/filelist/FileCommand.java @@ -14,7 +14,7 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -22,7 +22,6 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.PopupPanel; - import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile; import org.pentaho.mantle.client.commands.ExportFileCommand; import org.pentaho.mantle.client.commands.FilePropertiesCommand; @@ -113,8 +112,12 @@ public void execute() { } } - private native void createSchedule( final RepositoryFile repositoryFile )/*-{ - $wnd.pho.createSchedule( repositoryFile ); + private void createSchedule( final RepositoryFile repositoryFile ) { + createSchedule( repositoryFile.getId(), repositoryFile.getPath() ); + } + + private native void createSchedule( final String repositoryFileId, final String repositoryFilePath )/*-{ + $wnd.pho.createSchedule( repositoryFileId, repositoryFilePath ); }-*/; } From fa95689deb927c5f5d51405c2791c159648030a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duarte=20Cunha=20Lea=CC=83o?= Date: Mon, 20 Nov 2023 20:44:47 +0000 Subject: [PATCH 46/59] [BACKLOG-37872] Fixed not being able to use OBF or SuperDevMode mode and to open the schedule perspective --- .../mantle/client/ui/PerspectiveManager.java | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java index 113885078f8..46cab1dc7ee 100644 --- a/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java +++ b/user-console/src/main/java/org/pentaho/mantle/client/ui/PerspectiveManager.java @@ -441,10 +441,51 @@ private void showOpenedPerspective( boolean browserChecked, boolean schedulesChe private void showSchedulesPerspective() { DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); - showSchedulesPerspective( contentDeck ); + + GWT.runAsync( new RunAsyncCallback() { + + public void onSuccess() { + // Use a SimplePanel to hold the returned element, + // and add it as a child widget if it is not there yet. + SimplePanel activePerspectiveWidget = (SimplePanel) findPerspectiveWidget( contentDeck, activePerspective ); + boolean isFirstTime = activePerspectiveWidget == null; + if ( isFirstTime ) { + // Setup + activePerspectiveWidget = new SimplePanel(); + activePerspectiveWidget.getElement().setId( activePerspective.getId() ); + + contentDeck.add( activePerspectiveWidget ); + } + + com.google.gwt.dom.client.Element element = + getSchedulesPerspectiveElement( activePerspectiveWidget.getElement() ); + + if ( isFirstTime ) { + activePerspectiveWidget.getElement().appendChild( element ); + } + + contentDeck.showWidget( contentDeck.getWidgetIndex( activePerspectiveWidget ) ); + } + + public void onFailure( Throwable reason ) { + } + } ); + setCheckMMenuItem( false, true ); } + private static Widget findPerspectiveWidget( DeckPanel contentDeck, IPluginPerspective perspective ) { + int count = contentDeck.getWidgetCount(); + for ( int i = 0; i < count; i++ ) { + Widget widget = contentDeck.getWidget( i ); + if ( perspective.getId().equals( widget.getElement().getId() ) ) { + return widget; + } + } + + return null; + } + private void showAdminPerspective( boolean browserChecked, boolean schedulesChecked ) { DeckPanel contentDeck = MantleApplication.getInstance().getContentDeck(); if ( MantleApplication.getInstance().getContentDeck() @@ -485,8 +526,9 @@ private void hijackContentArea( IPluginPerspective perspective ) { perspectiveActivated( frameElement ); } - public native void showSchedulesPerspective( DeckPanel contentDeck ) /*-{ - return $wnd.pho.showSchedulesPerspective( contentDeck ); + public native com.google.gwt.dom.client.Element getSchedulesPerspectiveElement( + com.google.gwt.dom.client.Element containerElement ) /*-{ + return $wnd.pho.getSchedulesPerspectiveElement(containerElement); }-*/; private native void perspectiveActivated( Element frameElement ) From 7a26f06fbc1ead2fc7c728d7e15d2dc4cf3b9c48 Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Mon, 4 Dec 2023 15:08:43 -0500 Subject: [PATCH 47/59] [BACKLOG-37905] - Consume email and group in scheduler email dialog panel --- .../api/scheduler2/IEmailGroupResolver.java | 8 ++++++++ .../system/pentahoObjects.spring.xml | 9 +++++++++ .../java/org/pentaho/platform/util/ActionUtil.java | 13 ++++++++++--- .../platform/util/DefaultEmailGroupResolver.java | 10 ++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/org/pentaho/platform/api/scheduler2/IEmailGroupResolver.java create mode 100644 core/src/main/java/org/pentaho/platform/util/DefaultEmailGroupResolver.java diff --git a/api/src/main/java/org/pentaho/platform/api/scheduler2/IEmailGroupResolver.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IEmailGroupResolver.java new file mode 100644 index 00000000000..c15ac7f9fe1 --- /dev/null +++ b/api/src/main/java/org/pentaho/platform/api/scheduler2/IEmailGroupResolver.java @@ -0,0 +1,8 @@ +package org.pentaho.platform.api.scheduler2; + +import java.util.List; + +public interface IEmailGroupResolver { + + String resolve( String param ); +} diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml index 855244e75b6..72de277cb42 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/pentahoObjects.spring.xml @@ -317,4 +317,13 @@ not directly from the PentahoObjectFactory. -->
+ + + + + + + + diff --git a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java index 23d41012e39..ecdaf1331d5 100644 --- a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java +++ b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java @@ -30,6 +30,7 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData; +import org.pentaho.platform.api.scheduler2.IEmailGroupResolver; import org.pentaho.platform.api.util.QuartzActionUtil; import org.pentaho.platform.api.workitem.IWorkItemLifecycleEventPublisher; import org.pentaho.platform.engine.core.system.PentahoSystem; @@ -430,9 +431,15 @@ public static void sendEmail( Map actionParams, Map Date: Mon, 4 Dec 2023 15:50:38 -0500 Subject: [PATCH 48/59] [BACKLOG-38225][BACKLOG-39275][BACKLOG-39299] Refactor Worker Nodes ActionInvokers Classes - deleting LocalActionInvoker and any references, not used in pentaho-platform only in worker-nodes --- .../plugin/action/LocalActionInvoker.java | 111 ---------------- .../plugin/action/LocalActionInvokerTest.java | 122 ------------------ .../solution/system/pentahoObjects.spring.xml | 2 - 3 files changed, 235 deletions(-) delete mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/action/LocalActionInvoker.java delete mode 100644 extensions/src/test/java/org/pentaho/platform/plugin/action/LocalActionInvokerTest.java diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/action/LocalActionInvoker.java b/extensions/src/main/java/org/pentaho/platform/plugin/action/LocalActionInvoker.java deleted file mode 100644 index 2ca9aacbda4..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/plugin/action/LocalActionInvoker.java +++ /dev/null @@ -1,111 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.action; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.action.IActionInvokeStatus; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.plugin.action.messages.Messages; -import org.pentaho.platform.scheduler2.action.DefaultActionInvoker; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; - -import java.io.Serializable; -import java.util.Map; - -/** - * A more specific implementation of {@link DefaultActionInvoker} for use within a worker node, that massages the - * param {@link Map} keys such that they are generic, and not scheduler specific. - */ -public class LocalActionInvoker extends DefaultActionInvoker { - - private static final Log logger = LogFactory.getLog( org.pentaho.platform.plugin.action.LocalActionInvoker.class ); - - /** - * Gets the stream provider from the {@code INVOKER_STREAMPROVIDER} key within the {@code params} {@link Map} or - * builds it from the input file and output dir {@link Map} values. Returns {@code null} if information needed to - * build the stream provider is not present in the {@code map}, which is perfectly ok for some - * {@link org.pentaho.platform.api.action.IAction} types. - * - * @param params the {@link Map} or parameters needed to invoke the {@link org.pentaho.platform.api.action.IAction} - * @return a {@link IBackgroundExecutionStreamProvider} represented in the {@code params} {@link Map} - */ - @Override - protected IBackgroundExecutionStreamProvider getStreamProvider( final Map params ) { - - if ( params == null ) { - logger.warn( Messages.getInstance().getMapNullCantReturnSp() ); - return null; - } - IBackgroundExecutionStreamProvider streamProvider = null; - - final Object objsp = params.get( ActionUtil.INVOKER_STREAMPROVIDER ); - if ( objsp != null && IBackgroundExecutionStreamProvider.class.isAssignableFrom( objsp.getClass() ) ) { - streamProvider = (IBackgroundExecutionStreamProvider) objsp; - if ( streamProvider instanceof RepositoryFileStreamProvider ) { - params.put( ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE, ( (RepositoryFileStreamProvider) streamProvider ) - .getInputFilePath() ); - params.put( ActionUtil.INVOKER_STREAMPROVIDER_OUTPUT_FILE_PATTERN, ( (RepositoryFileStreamProvider) - streamProvider ).getOutputFilePath() ); - params.put( ActionUtil.INVOKER_STREAMPROVIDER_UNIQUE_FILE_NAME, ( (RepositoryFileStreamProvider) - streamProvider ).autoCreateUniqueFilename() ); - } - } else { - final String inputFile = params.get( ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE ) == null ? null : params.get( - ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE ).toString(); - final String outputFilePattern = params.get( ActionUtil.INVOKER_STREAMPROVIDER_OUTPUT_FILE_PATTERN ) == null - ? null : params.get( ActionUtil.INVOKER_STREAMPROVIDER_OUTPUT_FILE_PATTERN ).toString(); - boolean hasInputFile = !StringUtils.isEmpty( inputFile ); - boolean hasOutputPattern = !StringUtils.isEmpty( outputFilePattern ); - if ( hasInputFile && hasOutputPattern ) { - boolean autoCreateUniqueFilename = params.get( ActionUtil.INVOKER_STREAMPROVIDER_UNIQUE_FILE_NAME ) == null - || params.get( ActionUtil.INVOKER_STREAMPROVIDER_UNIQUE_FILE_NAME ).toString().equalsIgnoreCase( "true" ); - streamProvider = new RepositoryFileStreamProvider( inputFile, outputFilePattern, autoCreateUniqueFilename ); - // put in the map for future lookup - params.put( ActionUtil.INVOKER_STREAMPROVIDER, streamProvider ); - } else { - if ( logger.isWarnEnabled() ) { - logger.warn( Messages.getInstance().getMissingParamsCantReturnSp( String.format( "%s, %s", - ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE, ActionUtil.INVOKER_STREAMPROVIDER_OUTPUT_FILE_PATTERN ), - params ) ); //$NON-NLS-1$ - } - } - } - return streamProvider; - } - - /** - * {@inheritDoc} - */ - @Override - public IActionInvokeStatus invokeAction( final IAction actionBean, - final String actionUser, - final Map params ) throws Exception { - ActionUtil.prepareMap( params ); - // call getStreamProvider, in addition to creating the provider, this method also adds values to the map that - // serialize the stream provider and make it possible to deserialize and recreate it for remote execution. - getStreamProvider( params ); - return super.invokeAction( actionBean, actionUser, params ); - } -} diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/action/LocalActionInvokerTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/action/LocalActionInvokerTest.java deleted file mode 100644 index 8e09e5307c0..00000000000 --- a/extensions/src/test/java/org/pentaho/platform/plugin/action/LocalActionInvokerTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.plugin.action; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.pentaho.platform.api.action.ActionInvocationException; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.plugin.action.builtin.ActionSequenceAction; -import org.pentaho.platform.action.ActionInvokeStatus; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.web.http.api.resources.RepositoryFileStreamProvider; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -public class LocalActionInvokerTest { - private LocalActionInvoker defaultActionInvoker; - - @Before - public void setup() { - defaultActionInvoker = new LocalActionInvoker(); - } - - @Test - public void invokeActionLocallyTest() throws Exception { - Map testMap = new HashMap<>(); - testMap.put( ActionUtil.QUARTZ_ACTIONCLASS, "one" ); - testMap.put( ActionUtil.QUARTZ_ACTIONUSER, "two" ); - IAction iaction = ActionUtil.createActionBean( ActionSequenceAction.class.getName(), null ); - ActionInvokeStatus actionInvokeStatus = - (ActionInvokeStatus) defaultActionInvoker.invokeAction( iaction, "aUser", testMap ); - Assert.assertFalse( actionInvokeStatus.requiresUpdate() ); - } - - @Test - public void invokeActionTest() throws Exception { - Map testMap = new HashMap<>(); - testMap.put( ActionUtil.QUARTZ_ACTIONCLASS, "one" ); - testMap.put( ActionUtil.QUARTZ_ACTIONUSER, "two" ); - IAction iaction = ActionUtil.createActionBean( ActionSequenceAction.class.getName(), null ); - ActionInvokeStatus actionInvokeStatus = - (ActionInvokeStatus) defaultActionInvoker.invokeAction( iaction, "aUser", testMap ); - Assert.assertFalse( actionInvokeStatus.requiresUpdate() ); - } - - @Test( expected = ActionInvocationException.class ) - public void invokeActionLocallyWithNullsThrowsExceptionTest() throws Exception { - defaultActionInvoker.invokeAction( null, "aUser", null ); - } - - - @Test - public void getStreamProviderNullTest() { - Map paramMap = new HashMap<>(); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER, null ); - IBackgroundExecutionStreamProvider iBackgroundExecutionStreamProvider = defaultActionInvoker.getStreamProvider( paramMap ); - Assert.assertNull( iBackgroundExecutionStreamProvider ); - } - - @Test - public void getStreamProviderNullWithInputFileTest() throws IOException { - Map paramMap = new HashMap<>(); - File inputFile = new File( "example.txt" ); - BufferedWriter output = new BufferedWriter( new FileWriter( inputFile ) ); - output.write( "TEST TEXT" ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER, null ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE, inputFile ); - IBackgroundExecutionStreamProvider iBackgroundExecutionStreamProvider = defaultActionInvoker.getStreamProvider( paramMap ); - Assert.assertNull( iBackgroundExecutionStreamProvider ); - } - - @Test - public void getStreamProviderWithInputAndOutputFileTest() throws IOException { - Map paramMap = new HashMap<>(); - RepositoryFileStreamProvider repositoryFileStreamProvider = new RepositoryFileStreamProvider(); - File inputFile = new File( "example.txt" ); - BufferedWriter output = new BufferedWriter( new FileWriter( inputFile ) ); - output.write( "TEST TEXT" ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER, repositoryFileStreamProvider ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER_INPUT_FILE, inputFile ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER_OUTPUT_FILE_PATTERN, inputFile ); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER_UNIQUE_FILE_NAME, true ); - IBackgroundExecutionStreamProvider iBackgroundExecutionStreamProvider = defaultActionInvoker.getStreamProvider( paramMap ); - Assert.assertEquals( iBackgroundExecutionStreamProvider, repositoryFileStreamProvider ); - } - - - @Test - public void getStreamProviderTest() { - Map paramMap = new HashMap<>(); - RepositoryFileStreamProvider repositoryFileStreamProvider = new RepositoryFileStreamProvider(); - paramMap.put( ActionUtil.INVOKER_STREAMPROVIDER, repositoryFileStreamProvider ); - IBackgroundExecutionStreamProvider iBackgroundExecutionStreamProvider = defaultActionInvoker.getStreamProvider( paramMap ); - Assert.assertEquals( repositoryFileStreamProvider, iBackgroundExecutionStreamProvider ); - } -} diff --git a/extensions/src/test/resources/solution/system/pentahoObjects.spring.xml b/extensions/src/test/resources/solution/system/pentahoObjects.spring.xml index 395a8200296..19a37089599 100644 --- a/extensions/src/test/resources/solution/system/pentahoObjects.spring.xml +++ b/extensions/src/test/resources/solution/system/pentahoObjects.spring.xml @@ -11,8 +11,6 @@ PentahoSystem which is initialized after Spring xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" default-lazy-init="true"> - - From 1f0242c644f6e4d0b1d2f77623710982644c25e4 Mon Sep 17 00:00:00 2001 From: Nicholas Jordan Date: Mon, 4 Dec 2023 15:59:56 -0500 Subject: [PATCH 49/59] [BACKLOG-38225][BACKLOG-39275][BACKLOG-39299] Address Duplicate Classes in Artifacts pentaho-scheduler-core, pentaho-platform-extensions, pentaho-platform-scheduler - deleting package here in pentaho-platform/extensions/src/main/java/org/pentaho/platform/scheduler2 - identical package will be in pentaho-scheduler-plugin/core/src/main/java/org/pentaho/platform/scheduler2 --- .../scheduler2/action/ActionRunner.java | 270 ------------------ .../action/DefaultActionInvoker.java | 184 ------------ .../action/SchedulerOutputPathResolver.java | 209 -------------- .../scheduler2/messsages/Messages.java | 70 ----- 4 files changed, 733 deletions(-) delete mode 100644 extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java delete mode 100644 extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java diff --git a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java deleted file mode 100644 index 5b3950d59c5..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/ActionRunner.java +++ /dev/null @@ -1,270 +0,0 @@ -/*! - * - * 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-2020 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.action; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.action.ActionInvocationException; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.action.IPostProcessingAction; -import org.pentaho.platform.api.action.IStreamingAction; -import org.pentaho.platform.api.action.IVarArgsAction; -import org.pentaho.platform.api.repository.IContentItem; -import org.pentaho.platform.api.repository2.unified.ISourcesStreamEvents; -import org.pentaho.platform.api.repository2.unified.IStreamListener; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.engine.core.output.FileContentItem; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.services.solution.ActionSequenceCompatibilityFormatter; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.util.beans.ActionHarness; -import org.pentaho.platform.util.messages.LocaleHelper; -import org.pentaho.platform.workitem.WorkItemLifecycleEventUtil; -import org.pentaho.platform.workitem.WorkItemLifecyclePhase; - -import java.io.OutputStream; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.Callable; - -public class ActionRunner implements Callable { - - private static final Log logger = LogFactory.getLog( ActionRunner.class ); - - private Map params; - private IAction actionBean; - private IBackgroundExecutionStreamProvider streamProvider; - private String actionUser; - - private String outputFilePath = null; - private boolean streamComplete = false; - private Object lock = new Object(); - - public ActionRunner( final IAction actionBean, final String actionUser, final Map params, final - IBackgroundExecutionStreamProvider streamProvider ) { - this.actionBean = actionBean; - this.actionUser = actionUser; - this.params = params; - this.streamProvider = streamProvider; - } - - public Boolean call() throws ActionInvocationException { - final String workItemName = ActionUtil.extractName( params ); - try { - final ExecutionResult result = callImpl(); - if ( result.isSuccess() ) { - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.SUCCEEDED ); - } else { - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED ); - } - return result.updateRequired(); - } catch ( final Throwable t ) { - // ensure that the main thread isn't blocked on lock - synchronized ( lock ) { - lock.notifyAll(); - } - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, t.toString() ); - // We should not distinguish between checked and unchecked exceptions here. All job execution failures - // should result in a rethrow of the exception - throw new ActionInvocationException( Messages.getInstance().getActionFailedToExecute( actionBean //$NON-NLS-1$ - .getClass().getName() ), t ); - } - } - - private ExecutionResult callImpl() throws Exception { - boolean executionStatus = true; - - final Object locale = params.get( LocaleHelper.USER_LOCALE_PARAM ); - if ( locale instanceof Locale ) { - LocaleHelper.setThreadLocaleOverride( (Locale) locale ); - } else { - LocaleHelper.setThreadLocaleOverride( new Locale( (String) locale ) ); - } - // sync job params to the action bean - ActionHarness actionHarness = new ActionHarness( actionBean ); - - final Map actionParams = new HashMap<>(); - actionParams.putAll( params ); - if ( streamProvider != null ) { - actionParams.put( "inputStream", streamProvider.getInputStream() ); - } - actionHarness.setValues( actionParams, new ActionSequenceCompatibilityFormatter() ); - - if ( actionBean instanceof IVarArgsAction ) { - actionParams.remove( "inputStream" ); - actionParams.remove( "outputStream" ); - ( (IVarArgsAction) actionBean ).setVarArgs( actionParams ); - } - - boolean waitForFileCreated = false; - OutputStream stream = null; - - if ( streamProvider != null ) { - actionParams.remove( "inputStream" ); - if ( actionBean instanceof IStreamingAction ) { - streamProvider.setStreamingAction( (IStreamingAction) actionBean ); - } - - // BISERVER-9414 - validate that output path still exist - SchedulerOutputPathResolver resolver = - new SchedulerOutputPathResolver( streamProvider.getOutputPath(), actionUser ); - String outputPath = resolver.resolveOutputFilePath(); - - if ( outputPath == null ) { - return new ExecutionResult( true, false ); - } - - actionParams.put( "useJcr", Boolean.TRUE ); - actionParams.put( "jcrOutputPath", outputPath.substring( 0, outputPath.lastIndexOf( "/" ) ) ); - - if ( !outputPath.equals( streamProvider.getOutputPath() ) ) { - streamProvider.setOutputFilePath( outputPath ); // set fallback path - // Job output path requires update. The update triggers a new job that will fulfill the execution. - return new ExecutionResult( true, true ); - } - - stream = streamProvider.getOutputStream(); - if ( stream instanceof ISourcesStreamEvents ) { - ( (ISourcesStreamEvents) stream ).addListener( new IStreamListener() { - public void fileCreated( final String filePath ) { - synchronized ( lock ) { - outputFilePath = filePath; - lock.notifyAll(); - } - } - - @Override - public void streamComplete() { - synchronized ( lock ) { - lock.notifyAll(); - streamComplete = true; - } - } - } ); - waitForFileCreated = true; - } - actionParams.put( "outputStream", stream ); - actionHarness.setValues( actionParams ); - } - - actionBean.execute(); - executionStatus = actionBean.isExecutionSuccessful(); - if ( stream != null ) { - IOUtils.closeQuietly( stream ); - } - - if ( waitForFileCreated ) { - synchronized ( lock ) { - while ( outputFilePath == null && !streamComplete ) { - lock.wait( 1000 ); - } - } - ActionUtil.sendEmail( actionParams, params, outputFilePath ); - deleteFileIfEmpty(); - } - if ( actionBean instanceof IPostProcessingAction ) { - closeContentOutputStreams( (IPostProcessingAction) actionBean ); - markContentAsGenerated( (IPostProcessingAction) actionBean ); - } - - // Create the ExecutionResult to return the status and whether the update is required or not - return new ExecutionResult( false, executionStatus ); - } - - @VisibleForTesting - void deleteFileIfEmpty() { - if ( outputFilePath == null ) { - return; - } - IUnifiedRepository repo = PentahoSystem.get( IUnifiedRepository.class ); - RepositoryFile file = repo.getFile( outputFilePath ); - if ( file.getFileSize().equals( 0L ) ) { - repo.deleteFile( file.getId(), true, null ); - } - } - - private void closeContentOutputStreams( IPostProcessingAction actionBean ) { - for ( IContentItem contentItem : actionBean.getActionOutputContents() ) { - contentItem.closeOutputStream(); - } - } - - private void markContentAsGenerated( IPostProcessingAction actionBean ) { - IUnifiedRepository repo = PentahoSystem.get( IUnifiedRepository.class ); - String lineageId = (String) params.get( ActionUtil.QUARTZ_LINEAGE_ID ); - for ( IContentItem contentItem : actionBean.getActionOutputContents() ) { - RepositoryFile sourceFile = getRepositoryFileSafe( repo, contentItem.getPath() ); - // add metadata if we have access and we have file - if ( sourceFile != null ) { - Map metadata = repo.getFileMetadata( sourceFile.getId() ); - metadata.put( ActionUtil.QUARTZ_LINEAGE_ID, lineageId ); - repo.setFileMetadata( sourceFile.getId(), metadata ); - } else { - String fileName = getFSFileNameSafe( contentItem ); - logger.warn( Messages.getInstance().getSkipRemovingOutputFile( fileName ) ); - } - } - } - - private RepositoryFile getRepositoryFileSafe( IUnifiedRepository repo, String path ) { - try { - return repo.getFile( path ); - } catch ( Exception e ) { - logger.debug( Messages.getInstance().getCannotGetRepoFile( path, e.getMessage() ) ); - return null; - } - } - - private String getFSFileNameSafe( IContentItem contentItem ) { - if ( contentItem instanceof FileContentItem ) { - return ( (FileContentItem) contentItem ).getFile().getName(); - } - return null; - } - - /** - * Class to hold the result of the invoke Action - */ - private class ExecutionResult { - private boolean updateRequired; - private boolean isSuccess; - - public ExecutionResult( Boolean updateRequired, Boolean isSuccess ) { - this.updateRequired = updateRequired; - this.isSuccess = isSuccess; - } - public Boolean updateRequired() { - return updateRequired; - } - - public Boolean isSuccess() { - return isSuccess; - } - - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java deleted file mode 100644 index 878d104221f..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/DefaultActionInvoker.java +++ /dev/null @@ -1,184 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.action; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.action.ActionInvokeStatus; -import org.pentaho.platform.api.action.ActionInvocationException; -import org.pentaho.platform.api.action.IAction; -import org.pentaho.platform.api.action.IActionInvokeStatus; -import org.pentaho.platform.api.action.IActionInvoker; -import org.pentaho.platform.api.scheduler2.IBackgroundExecutionStreamProvider; -import org.pentaho.platform.api.scheduler2.IScheduler; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.scheduler2.action.ActionRunner; -import org.pentaho.platform.scheduler2.messsages.Messages; -import org.pentaho.platform.util.ActionUtil; -import org.pentaho.platform.util.StringUtil; -import org.pentaho.platform.util.messages.LocaleHelper; -import org.pentaho.platform.workitem.WorkItemLifecyclePhase; -import org.pentaho.platform.workitem.WorkItemLifecycleEventUtil; - -import java.io.Serializable; -import java.util.Map; - -/** - * A concrete implementation of the {@link IActionInvoker} interface that invokes the {@link IAction} locally. - */ -public class DefaultActionInvoker implements IActionInvoker { - - private static final Log logger = LogFactory.getLog( DefaultActionInvoker.class ); - - /** - * Gets the stream provider from the {@code RESERVEDMAPKEY_STREAMPROVIDER} key within the {@code params} {@link Map}. - * - * @param params the {@link Map} or parameters needed to invoke the {@link IAction} - * @return a {@link IBackgroundExecutionStreamProvider} represented in the {@code params} {@link Map} - */ - protected IBackgroundExecutionStreamProvider getStreamProvider( final Map params ) { - if ( params == null ) { - logger.warn( Messages.getInstance().getMapNullCantReturnSp() ); - return null; - } - - final Object obj = params.get( IScheduler.RESERVEDMAPKEY_STREAMPROVIDER ); - return ( obj instanceof IBackgroundExecutionStreamProvider ) ? (IBackgroundExecutionStreamProvider) obj : null; - } - - /** - * - * Validates that the conditions required for the {@link IAction} to be invoked are true, throwing an - * {@link ActionInvocationException}, if the conditions are not met. - * - * @param actionBean The {@link IAction} to be invoked - * @param actionUser The user invoking the {@link IAction} - * @param params the {@link Map} or parameters needed to invoke the {@link IAction} - * @return the {@link IActionInvokeStatus} object containing information about the action invocation - * @throws ActionInvocationException when conditions needed to invoke the {@link IAction} are not met - */ - public void validate( final IAction actionBean, final String actionUser, - final Map params ) throws ActionInvocationException { - - final String workItemName = ActionUtil.extractName( params ); - - if ( actionBean == null || params == null ) { - final String failureMessage = Messages.getInstance().getCantInvokeNullAction(); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, failureMessage ); - throw new ActionInvocationException( failureMessage ); - } - - if ( !isSupportedAction( actionBean ) ) { - final String failureMessage = Messages.getInstance().getUnsupportedAction( actionBean.getClass().getName() ); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, failureMessage ); - throw new ActionInvocationException( failureMessage ); - } - } - - /** - * Invokes the provided {@link IAction} as the provided {@code actionUser}. - * - * @param actionBean the {@link IAction} being invoked - * @param actionUser The user invoking the {@link IAction} - * @param params the {@link Map} or parameters needed to invoke the {@link IAction} - * @return the {@link IActionInvokeStatus} object containing information about the action invocation - * @throws Exception when the {@code IAction} cannot be invoked for some reason. - */ - @Override - public IActionInvokeStatus invokeAction( final IAction actionBean, - final String actionUser, - final Map params ) throws Exception { - validate( actionBean, actionUser, params ); - return invokeActionImpl( actionBean, actionUser, params ); - } - - /** - * Invokes the provided {@link IAction} as the provided {@code actionUser}. - * - * @param actionBean the {@link IAction} being invoked - * @param actionUser The user invoking the {@link IAction} - * @param params the {@link Map} or parameters needed to invoke the {@link IAction} - * @return the {@link IActionInvokeStatus} object containing information about the action invocation - * @throws Exception when the {@code IAction} cannot be invoked for some reason. - */ - protected IActionInvokeStatus invokeActionImpl( final IAction actionBean, - final String actionUser, - final Map params ) throws Exception { - - final String workItemName = ActionUtil.extractName( params ); - - if ( actionBean == null || params == null ) { - final String failureMessage = Messages.getInstance().getCantInvokeNullAction(); - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, failureMessage ); - throw new ActionInvocationException( failureMessage ); - } - - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.IN_PROGRESS ); - - if ( logger.isDebugEnabled() ) { - logger.debug( Messages.getInstance().getRunningInBackgroundLocally( actionBean.getClass().getName(), params ) ); - } - - // set the locale, if not already set - if ( params.get( LocaleHelper.USER_LOCALE_PARAM ) == null || StringUtils.isEmpty( - params.get( LocaleHelper.USER_LOCALE_PARAM ).toString() ) ) { - params.put( LocaleHelper.USER_LOCALE_PARAM, LocaleHelper.getLocale() ); - } - - // remove the scheduling infrastructure properties - ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_ACTIONCLASS ); - ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_ACTIONID ); - ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_ACTIONUSER ); - // build the stream provider - final IBackgroundExecutionStreamProvider streamProvider = getStreamProvider( params ); - ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_STREAMPROVIDER ); - ActionUtil.removeKeyFromMap( params, ActionUtil.INVOKER_UIPASSPARAM ); - - final org.pentaho.platform.scheduler2.action.ActionRunner - actionBeanRunner = new ActionRunner( actionBean, actionUser, params, streamProvider ); - final IActionInvokeStatus status = new ActionInvokeStatus(); - status.setStreamProvider( streamProvider ); - - boolean requiresUpdate = false; - try { - if ( ( StringUtil.isEmpty( actionUser ) ) || ( actionUser.equals( "system session" ) ) ) { //$NON-NLS-1$ - // For now, don't try to run quartz jobs as authenticated if the user - // that created the job is a system user. See PPP-2350 - requiresUpdate = SecurityHelper.getInstance().runAsAnonymous( actionBeanRunner ); - } else { - requiresUpdate = SecurityHelper.getInstance().runAsUser( actionUser, actionBeanRunner ); - } - } catch ( final Throwable t ) { - WorkItemLifecycleEventUtil.publish( workItemName, params, WorkItemLifecyclePhase.FAILED, t.toString() ); - status.setThrowable( t ); - } - status.setRequiresUpdate( requiresUpdate ); - // Set the execution Status - status.setExecutionStatus( actionBean.isExecutionSuccessful() ); - return status; - } - - @Override - public boolean isSupportedAction( IAction action ) { - return true; // supports all - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java deleted file mode 100644 index 27e860efcf7..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/scheduler2/action/SchedulerOutputPathResolver.java +++ /dev/null @@ -1,209 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.action; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; - -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang.BooleanUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.pentaho.platform.api.engine.IAuthorizationPolicy; -import org.pentaho.platform.api.engine.IPentahoSession; -import org.pentaho.platform.api.repository.IClientRepositoryPathsStrategy; -import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; -import org.pentaho.platform.api.repository2.unified.RepositoryFile; -import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; -import org.pentaho.platform.api.scheduler2.SchedulerException; -import org.pentaho.platform.api.usersettings.IUserSettingService; -import org.pentaho.platform.api.usersettings.pojo.IUserSetting; -import org.pentaho.platform.engine.core.system.PentahoSessionHolder; -import org.pentaho.platform.engine.core.system.PentahoSystem; -import org.pentaho.platform.engine.security.SecurityHelper; -import org.pentaho.platform.scheduler2.messsages.Messages; - -/** - * @author Rowell Belen - */ -public class SchedulerOutputPathResolver { - - final String DEFAULT_SETTING_KEY = "default-scheduler-output-path"; - public static final String SCHEDULER_ACTION_NAME = "org.pentaho.scheduler.manage"; - - private static final Log logger = LogFactory.getLog( SchedulerOutputPathResolver.class ); - private static final List permissions = new ArrayList(); - - private String jobName; - private String outputDirectory; - private String actionUser; - - static { - // initialize permissions - permissions.add( RepositoryFilePermission.READ ); - permissions.add( RepositoryFilePermission.WRITE ); - } - - public SchedulerOutputPathResolver( final String outputPathPattern, final String actionUser ) { - this.jobName = FilenameUtils.getBaseName( outputPathPattern ); - this.outputDirectory = FilenameUtils.getPathNoEndSeparator( outputPathPattern ); - this.actionUser = actionUser; - } - - public String resolveOutputFilePath() { - - final String fileNamePattern = "/" + this.jobName + ".*"; - final String outputFilePath = "/" + this.outputDirectory; - - // Enclose validation logic in the context of the job creator's session, not the current session - final Callable callable = new Callable() { - @Override - public String call() throws Exception { - - if ( StringUtils.isNotBlank( outputFilePath ) && isValidOutputPath( outputFilePath ) - && isPermitted( outputFilePath ) ) { - return outputFilePath + fileNamePattern; // return if valid - } - - // evaluate fallback output paths - String[] fallBackPaths = new String[] { getUserSettingOutputPath(), // user setting - getSystemSettingOutputPath(), // system setting - getUserHomeDirectoryPath() // home directory - }; - - for ( String path : fallBackPaths ) { - if ( StringUtils.isNotBlank( path ) && isValidOutputPath( path ) ) { - return path + fileNamePattern; // return the first valid path - } - } - - return null; // it should never reach here because the user directory is the ultimate fallback - } - }; - - return runAsUser( callable ); - } - - private String runAsUser( Callable callable ) { - try { - if ( callable != null ) { - return SecurityHelper.getInstance().runAsUser( this.actionUser, callable ); - } - } catch ( Exception e ) { - logger.error( e.getMessage(), e ); - } - - return null; - } - - private boolean isValidOutputPath( String path ) throws SchedulerException { - try { - RepositoryFile repoFile = getRepository().getFile( path ); - if ( repoFile != null && repoFile.isFolder() ) { - boolean scheduleAllowed = isScheduleAllowed( repoFile.getId() ); - if ( scheduleAllowed ) { - return true; - } else { - throw new SchedulerException( Messages.getInstance().getString( - "QuartzScheduler.ERROR_0009_SCHEDULING_IS_NOT_ALLOWED_AFTER_CHANGE", this.jobName, this.actionUser ) ); - } - } - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return false; - } - - private String getUserSettingOutputPath() { - try { - IUserSetting userSetting = getUserSettingService().getUserSetting( DEFAULT_SETTING_KEY, null ); - if ( userSetting != null && StringUtils.isNotBlank( userSetting.getSettingValue() ) ) { - return userSetting.getSettingValue(); - } - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - - private String getSystemSettingOutputPath() { - try { - return PentahoSystem.getSystemSettings().getSystemSetting( DEFAULT_SETTING_KEY, null ); - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - - private String getUserHomeDirectoryPath() { - try { - IClientRepositoryPathsStrategy pathsStrategy = - PentahoSystem.get( IClientRepositoryPathsStrategy.class, getScheduleCreatorSession() ); - return pathsStrategy.getUserHomeFolderPath( getScheduleCreatorSession().getName() ); - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return null; - } - - private IPentahoSession getScheduleCreatorSession() { - return PentahoSessionHolder.getSession(); - } - - private IUnifiedRepository getRepository() { - return PentahoSystem.get( IUnifiedRepository.class, getScheduleCreatorSession() ); - } - - private IUserSettingService getUserSettingService() { - return PentahoSystem.get( IUserSettingService.class, getScheduleCreatorSession() ); - } - - private IAuthorizationPolicy getAuthorizationPolicy() { - return PentahoSystem.get( IAuthorizationPolicy.class, getScheduleCreatorSession() ); - } - - private boolean isScheduleAllowed( final Serializable repositoryId ) { - boolean canSchedule = false; - canSchedule = getAuthorizationPolicy().isAllowed( SCHEDULER_ACTION_NAME ); - if ( canSchedule ) { - Map metadata = getRepository().getFileMetadata( repositoryId ); - if ( metadata.containsKey( RepositoryFile.SCHEDULABLE_KEY ) ) { - canSchedule = BooleanUtils.toBoolean( (String) metadata.get( RepositoryFile.SCHEDULABLE_KEY ) ); - } - } - - return canSchedule; - } - - private boolean isPermitted( final String path ) { - try { - return getRepository().hasAccess( path, EnumSet.copyOf( permissions ) ); - } catch ( Exception e ) { - logger.warn( e.getMessage(), e ); - } - return false; - } -} diff --git a/extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java b/extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java deleted file mode 100644 index 181e42d6bd9..00000000000 --- a/extensions/src/main/java/org/pentaho/platform/scheduler2/messsages/Messages.java +++ /dev/null @@ -1,70 +0,0 @@ -/*! - * - * 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-2018 Hitachi Vantara. All rights reserved. - * - */ - -package org.pentaho.platform.scheduler2.messsages; - -import org.pentaho.platform.util.StringUtil; -import org.pentaho.platform.util.messages.MessagesBase; - -import java.util.Map; - -public class Messages extends MessagesBase { - - private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$ - - private static Messages instance = new Messages(); - - private Messages() { - super( BUNDLE_NAME ); - } - - public static Messages getInstance() { - return instance; - } - - public String getRunningInBackgroundLocally( final String actionIdentifier, final Map params ) { - return getString( "ActionInvoker.INFO_0001_RUNNING_IN_BG_LOCALLY", actionIdentifier, - StringUtil.getMapAsPrettyString( params ) ); - } - - public String getUnsupportedAction( final String action ) { - return getErrorString( "ActionInvoker.ERROR_0006_ACTION_NULL", action ); - } - - public String getCantInvokeNullAction() { - return getErrorString( "ActionInvoker.ERROR_0005_ACTION_NULL" ); - } - - public String getActionFailedToExecute( final String actionIdentifier ) { - return getErrorString( "ActionInvoker.ERROR_0004_ACTION_FAILED", actionIdentifier ); - } - - public String getSkipRemovingOutputFile( final String fileName ) { - return getString( "ActionInvoker.WARN_0001_SKIP_REMOVING_OUTPUT_FILE", fileName ); - } - - public String getCannotGetRepoFile( final String fileName, final String msg ) { - return getErrorString( "ActionInvoker.ERROR_0010_CANNOT_GET_REPO_FILE", fileName, msg ); - } - - public String getMapNullCantReturnSp() { - return getErrorString( "ActionInvoker.ERROR_0008_MAP_NULL_CANT_RETURN_SP" ); - } -} From aa52bd659e67f1d9cd1ee46b9f75af6f229c6e4e Mon Sep 17 00:00:00 2001 From: Nicholas Jordan Date: Mon, 4 Dec 2023 19:58:48 -0500 Subject: [PATCH 50/59] [BACKLOG-38225][BACKLOG-39275] Address Duplicate Classes in Artifacts pentaho-scheduler-core, pentaho-platform-extensions, pentaho-platform-scheduler - extension/pom.xml remove out pentaho-platform-scheduler deps, obsolete --- extensions/pom.xml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/extensions/pom.xml b/extensions/pom.xml index 86102dc7e32..b51872af066 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -1999,12 +1999,6 @@ ${project.version} compile - - pentaho - pentaho-platform-scheduler - ${project.version} - compile - pentaho pentaho-platform-core @@ -2031,19 +2025,6 @@ - - pentaho - pentaho-platform-scheduler - ${project.version} - tests - test - - - * - * - - - From 638c6e0884d639aec486fd735aba290ca0f127c3 Mon Sep 17 00:00:00 2001 From: wilseyler Date: Wed, 6 Dec 2023 23:38:08 -0500 Subject: [PATCH 51/59] [BACKLOG-39323] - Fixed issue where exporting scheduler created an empty exportManifest.xml --- .../importexport/exportManifest/ExportManifestUtil.java | 6 ++++-- .../exportManifest/bindings/JobScheduleRequest.java | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java index 1c1945022fc..5ce214e8bda 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java @@ -75,8 +75,10 @@ private static List fromSchedulerToBindingRequestJobParameters private static SimpleJobTrigger fromSchedulerToBindingRequestJobTrigger( ISimpleJobTrigger incomingJobTrigger ) { SimpleJobTrigger outgoingJobTrigger = new SimpleJobTrigger(); - outgoingJobTrigger.setRepeatCount( incomingJobTrigger.getRepeatCount() ); - outgoingJobTrigger.setRepeatInterval( incomingJobTrigger.getRepeatInterval() ); + if ( incomingJobTrigger != null ) { + outgoingJobTrigger.setRepeatCount( incomingJobTrigger.getRepeatCount() ); + outgoingJobTrigger.setRepeatInterval( incomingJobTrigger.getRepeatInterval() ); + } return outgoingJobTrigger; } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java index fe8ecdc0458..d479e254aee 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/bindings/JobScheduleRequest.java @@ -332,10 +332,10 @@ public void setPdiParameters( Map pdiParameters ) { } public void setJobParameters( List jobParameters ) { - if ( jobParameters != this.jobParameters ) { - this.jobParameters.clear(); + if ( jobParameters != getJobParameters()) { + getJobParameters().clear(); if ( jobParameters != null ) { - this.jobParameters.addAll( jobParameters ); + getJobParameters().addAll( jobParameters ); } } } From b55b1cda7916e48e94c7eae34fb38b9805b6330e Mon Sep 17 00:00:00 2001 From: wilseyler Date: Tue, 12 Dec 2023 11:39:28 -0500 Subject: [PATCH 52/59] [BACKLOG-39323] - Fixed issue where exporting a ktr schedule created an empty exportManifest.xml --- .../importexport/exportManifest/ExportManifestUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java index 5ce214e8bda..59d73b4610c 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/importexport/exportManifest/ExportManifestUtil.java @@ -84,7 +84,9 @@ private static SimpleJobTrigger fromSchedulerToBindingRequestJobTrigger( ISimple private static CronJobTrigger fromSchedulerToBindingRequestCronJobTrigger( ICronJobTrigger incomingCronJobTrigger ) { CronJobTrigger outgoingCronJobTrigger = new CronJobTrigger(); - outgoingCronJobTrigger.setCronString( incomingCronJobTrigger.getCronString() ); + if ( incomingCronJobTrigger != null ) { + outgoingCronJobTrigger.setCronString( incomingCronJobTrigger.getCronString() ); + } return outgoingCronJobTrigger; } From 812069c40814afb463974eae2e733e9dbe76a531 Mon Sep 17 00:00:00 2001 From: Peter Rinehart Date: Mon, 11 Dec 2023 14:51:47 -0500 Subject: [PATCH 53/59] [BACKLOG-39324] Created PentahoPluginWSSpringServlet to handle jaxws endpoints in plugins. Endpoints must be defined in a plugin.ws.spring.xml file within the plugin, endpoint path must be of the form webservices/plugins//. Updated filter to handle relocating scheduler web service endpoint. --- .../applicationContext-spring-security.xml | 2 +- .../src/main/webapp/WEB-INF/web.xml | 12 ++ .../servlet/PentahoPluginWSSpringServlet.java | 167 ++++++++++++++++++ 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 extensions/src/main/java/org/pentaho/platform/web/servlet/PentahoPluginWSSpringServlet.java diff --git a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/applicationContext-spring-security.xml b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/applicationContext-spring-security.xml index 07f909036ce..42f8a09c2ab 100644 --- a/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/applicationContext-spring-security.xml +++ b/assemblies/pentaho-solutions/src/main/resources/pentaho-solutions/system/applicationContext-spring-security.xml @@ -391,7 +391,7 @@ - + diff --git a/assemblies/pentaho-war/src/main/webapp/WEB-INF/web.xml b/assemblies/pentaho-war/src/main/webapp/WEB-INF/web.xml index 1b73585f799..e55f5a4467b 100644 --- a/assemblies/pentaho-war/src/main/webapp/WEB-INF/web.xml +++ b/assemblies/pentaho-war/src/main/webapp/WEB-INF/web.xml @@ -341,6 +341,13 @@ org.pentaho.platform.web.servlet.PentahoWSSpringServlet + + jaxwsPluginEndpoint-spring + jaxwsPluginEndpoint-spring + JAX-WS endpoint for plugins + org.pentaho.platform.web.servlet.PentahoPluginWSSpringServlet + + jaxrsEndpoint-spring JAX-RS endpoint @@ -380,6 +387,11 @@ /webservices/* + + jaxwsPluginEndpoint-spring + /webservices/plugins/* + + jaxrsEndpoint-spring /api/* diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/PentahoPluginWSSpringServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/PentahoPluginWSSpringServlet.java new file mode 100644 index 00000000000..c3757b7390a --- /dev/null +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/PentahoPluginWSSpringServlet.java @@ -0,0 +1,167 @@ +/*! + * 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) 2023 Hitachi Vantara. All rights reserved. + */ + +package org.pentaho.platform.web.servlet; + +import com.sun.xml.ws.transport.http.servlet.ServletAdapterList; +import com.sun.xml.ws.transport.http.servlet.SpringBinding; +import com.sun.xml.ws.transport.http.servlet.WSServletDelegate; +import org.pentaho.platform.api.engine.IPlatformPlugin; +import org.pentaho.platform.engine.core.system.PentahoSystem; +import org.pentaho.platform.plugin.services.pluginmgr.PentahoSystemPluginManager; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.web.context.support.XmlWebApplicationContext; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PentahoPluginWSSpringServlet extends HttpServlet { + + private Pattern uriPattern = Pattern.compile( ".*/webservices/plugins/([-\\w]+)/.+" ); + Map delegateMap = new HashMap<>(); + ServletAdapterList adapters = new ServletAdapterList(); + public void init( ServletConfig servletConfig ) throws ServletException { + super.init( servletConfig ); + } + + @SuppressWarnings( "unchecked" ) + protected WSServletDelegate createPluginWSDelegate( String pluginPath, ClassLoader pluginClassLoader ) { + ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); + try { + // this needs to be set because when the Spring service tries to create the webservice endpoint, something + // buried in the webservice implementation tries to use the thread's classloader to instantiate the object + Thread.currentThread().setContextClassLoader( pluginClassLoader ); + ApplicationContext appContext = getAppContext( pluginPath, pluginClassLoader ); + + Set bindings = new LinkedHashSet<>(); + + bindings.addAll( appContext.getBeansOfType( SpringBinding.class ).values() ); + + adapters = new ServletAdapterList(); + for ( SpringBinding binding : bindings ) { + binding.create( adapters ); + } + + return new WSServletDelegate( adapters, getServletContext() ); + } finally { + Thread.currentThread().setContextClassLoader( origClassLoader ); + } + } + + public ServletAdapterList getAdapters() { + return adapters; + } + + protected ApplicationContext getAppContext( String pluginPath, ClassLoader pluginClassLoader ) { + XmlWebApplicationContext wac = new XmlWebApplicationContext() { + @Override + protected Resource getResourceByPath( String path ) { + return new FileSystemResource( new File( path ) ); + } + + @Override + protected DefaultListableBeanFactory createBeanFactory() { + DefaultListableBeanFactory beanFactory = super.createBeanFactory(); + beanFactory.setBeanClassLoader( pluginClassLoader ); + return beanFactory; + } + }; + + wac.setServletContext( getServletContext() ); + wac.setServletConfig( getServletConfig() ); + wac.setNamespace( getServletName() ); + wac.setClassLoader( pluginClassLoader ); + + String springFile = pluginPath + File.separator + "plugin.ws.spring.xml"; //$NON-NLS-1$ //$NON-NLS-2$ + wac.setConfigLocations( springFile ); + wac.refresh(); + + return wac; + } + + protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException { + WSServletDelegate delegate = delegateMap.get( request.getRequestURI() ); + if ( null == delegate ) { + delegate = getWsServletDelegate( request ); + delegateMap.put( request.getRequestURI(), delegate ); + } + delegate.doPost( request, response, getServletContext() ); +} + + protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException { + WSServletDelegate delegate = delegateMap.get( request.getRequestURI() ); + if ( null == delegate ) { + delegate = getWsServletDelegate( request ); + delegateMap.put( request.getRequestURI(), delegate ); + } + delegate.doGet( request, response, getServletContext() ); + } + + protected void doPut( HttpServletRequest request, HttpServletResponse response ) throws ServletException { + WSServletDelegate delegate = delegateMap.get( request.getRequestURI() ); + if ( null == delegate ) { + delegate = getWsServletDelegate( request ); + delegateMap.put( request.getRequestURI(), delegate ); + } + delegate.doPut( request, response, getServletContext() ); + } + + protected void doDelete( HttpServletRequest request, HttpServletResponse response ) throws ServletException { + WSServletDelegate delegate = delegateMap.get( request.getRequestURI() ); + if ( null == delegate ) { + delegate = getWsServletDelegate( request ); + delegateMap.put( request.getRequestURI(), delegate ); + } + delegate.doDelete( request, response, getServletContext() ); + } + + private WSServletDelegate getWsServletDelegate( HttpServletRequest request ) { + IPlatformPlugin plugin = PentahoSystem.get( IPlatformPlugin.class, null, + Collections.singletonMap( PentahoSystemPluginManager.PLUGIN_ID, getPluginNameFromUri( request.getRequestURI() ) ) ); + GenericApplicationContext beanFactory = PentahoSystem + .get( GenericApplicationContext.class, null, + Collections.singletonMap( PentahoSystemPluginManager.PLUGIN_ID, plugin.getId() ) ); + return createPluginWSDelegate( + PentahoSystem.getApplicationContext().getSolutionPath( "system/" + plugin.getSourceDescription() ) + , beanFactory.getClassLoader() ); + } + + private String getPluginNameFromUri( String uri ) { + Matcher m = uriPattern.matcher( uri ); + if ( m.matches() ) { + return m.group( 1 ); + } else { + return ""; + } + } +} From f3cdba39ce02b5db639f81d28faa3e969a342bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duarte=20Cunha=20Lea=CC=83o?= Date: Fri, 8 Dec 2023 01:45:07 +0000 Subject: [PATCH 54/59] [BACKLOG-37872] Fixed session scope for Pentaho plugin spring beans used from jax-rs api --- .../AbstractSpringPentahoObjectFactory.java | 6 +++++- .../spring/SpringPentahoObjectReference.java | 3 ++- .../web/servlet/JAXRSPluginServlet.java | 18 ++++++++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/AbstractSpringPentahoObjectFactory.java b/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/AbstractSpringPentahoObjectFactory.java index c48f704e1a2..ad50e63c330 100644 --- a/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/AbstractSpringPentahoObjectFactory.java +++ b/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/AbstractSpringPentahoObjectFactory.java @@ -203,11 +203,13 @@ protected Object retrieveViaSpring( String beanId ) throws ObjectFactoryExceptio // Set the Thread Context Classloader to that of the classloader who loaded this class. ClassLoader originalClassLoader = null; Object object; - + IPentahoSession previousSpringSession = null; try { originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + previousSpringSession = SpringScopeSessionHolder.SESSION.get(); + if ( session instanceof StandaloneSession ) { // first ask Spring for the object, if it is session scoped it will fail // since Spring doesn't know about StandaloneSessions @@ -254,6 +256,8 @@ protected Object retrieveViaSpring( String beanId ) throws ObjectFactoryExceptio } } finally { + SpringScopeSessionHolder.SESSION.set( previousSpringSession ); + if ( originalClassLoader != null ) { Thread.currentThread().setContextClassLoader( originalClassLoader ); } diff --git a/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/spring/SpringPentahoObjectReference.java b/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/spring/SpringPentahoObjectReference.java index d01fb47a506..2ea52cbf7f2 100644 --- a/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/spring/SpringPentahoObjectReference.java +++ b/core/src/main/java/org/pentaho/platform/engine/core/system/objfac/spring/SpringPentahoObjectReference.java @@ -69,13 +69,14 @@ public SpringPentahoObjectReference( ConfigurableApplicationContext context, Str @Override @SuppressWarnings( "unchecked" ) public T getObject() { + IPentahoSession previousSession = SpringScopeSessionHolder.SESSION.get(); IPentahoSession sessionToUse = session != null ? session : PentahoSessionHolder.getSession(); SpringScopeSessionHolder.SESSION.set( sessionToUse ); ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); Object obj = context.getBeanFactory().getBean( name ); - SpringScopeSessionHolder.SESSION.set( null ); + SpringScopeSessionHolder.SESSION.set( previousSession ); if ( obj instanceof IPentahoInitializer ) { ( (IPentahoInitializer) obj ).init( sessionToUse ); diff --git a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSPluginServlet.java b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSPluginServlet.java index 3e6f5f66252..1297e59dbcf 100644 --- a/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSPluginServlet.java +++ b/extensions/src/main/java/org/pentaho/platform/web/servlet/JAXRSPluginServlet.java @@ -14,7 +14,7 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2021 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -27,6 +27,9 @@ import com.sun.jersey.spi.spring.container.servlet.SpringServlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.pentaho.platform.api.engine.IPentahoSession; +import org.pentaho.platform.engine.core.system.PentahoSessionHolder; +import org.pentaho.platform.engine.core.system.objfac.spring.SpringScopeSessionHolder; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -116,7 +119,18 @@ public Object invoke( Object proxy, Method method, Object[] args ) throws Throwa requestThread.set( originalRequest.getRequestURI().toString() ); } } - callParentServiceMethod( request, response ); + + // Ensure that Resource beans (and others these consume) can use Spring scope="session". + // See StandaloneSpringPentahoObjectFactory. There's likely a better way to solve this issue. + // Perhaps in HttpSessionPentahoSessionIntegrationFilter, or even PentahoSessionHolder, + // but this is the place which is solving the current need, and with a lesser impact. + IPentahoSession previousSpringSession = SpringScopeSessionHolder.SESSION.get(); + SpringScopeSessionHolder.SESSION.set( PentahoSessionHolder.getSession() ); + try { + callParentServiceMethod( request, response ); + } finally { + SpringScopeSessionHolder.SESSION.set( previousSpringSession ); + } // JAX-RS Response return objects do not trigger the "error state" in the HttpServletResponse // Forcing all HTTP Error Status into "sendError" enables the configuration of custom error From 87df21c0d3893c7d1f7427d43855238d2328a7f2 Mon Sep 17 00:00:00 2001 From: Tim Kafalas tkafalas Date: Fri, 8 Dec 2023 16:39:03 -0500 Subject: [PATCH 55/59] [PPP-4826] Upgrade Vulnerable Hibernate to 5.4.24 --- .../pentaho-solutions/system/pentaho.xml | 2 +- .../system/hibernate/h2.hibernate.cfg.xml | 5 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 5 +- .../hibernate/oracle10g.hibernate.cfg.xml | 5 +- .../hibernate/postgresql.hibernate.cfg.xml | 3 +- .../hibernate/sqlserver.hibernate.cfg.xml | 5 +- assemblies/pentaho-war/pom.xml | 2 +- core/pom.xml | 6 +- extensions/pom.xml | 59 ++++ .../plugin/services/cache/CacheManager.java | 257 ++++++++--------- .../plugin/services/cache/HvCache.java | 54 ++++ .../services/cache/HvCacheRegionFactory.java | 34 +++ .../services/cache/HvTimestampsRegion.java | 37 +++ .../services/cache/LastModifiedCache.java | 258 +++++++++++++----- .../resources/SystemConfig/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 4 +- .../hibernate/oracle10g.hibernate.cfg.xml | 4 +- .../hibernate/postgresql.hibernate.cfg.xml | 5 +- .../cache-solution/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 5 +- .../hibernate/oracle10g.hibernate.cfg.xml | 5 +- .../hibernate/postgresql.hibernate.cfg.xml | 5 +- .../cache-solution1/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 5 +- .../hibernate/oracle10g.hibernate.cfg.xml | 5 +- .../hibernate/postgresql.hibernate.cfg.xml | 5 +- .../cache-solution2/system/pentaho.xml | 2 +- .../connections-solution/system/pentaho.xml | 2 +- .../metadata-solution/system/pentaho.xml | 2 +- .../outputs-solution/system/pentaho.xml | 2 +- .../security-solution/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../resources/solution/system/pentaho.xml | 2 +- .../solution1-no-config/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 5 +- .../hibernate/oracle10g.hibernate.cfg.xml | 5 +- .../hibernate/postgresql.hibernate.cfg.xml | 5 +- .../web-servlet-solution/system/pentaho.xml | 2 +- .../system/hibernate/hsql.hibernate.cfg.xml | 6 +- .../system/hibernate/mysql5.hibernate.cfg.xml | 5 +- .../hibernate/oracle10g.hibernate.cfg.xml | 5 +- .../hibernate/postgresql.hibernate.cfg.xml | 5 +- .../resources/web-solution/system/pentaho.xml | 2 +- pom.xml | 16 +- repository/pom.xml | 50 +++- .../hibernate/HibernateLoadEventListener.java | 8 +- .../repository/hibernate/HibernateUtil.java | 25 +- .../hibernate/usertypes/BlobUserType.java | 22 +- .../usertypes/BlobtoByteArrayUserType.java | 15 +- .../usertypes/EmptyStringUserType.java | 26 +- .../usertypes/LongStringUserType.java | 17 +- 56 files changed, 754 insertions(+), 296 deletions(-) create mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCache.java create mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCacheRegionFactory.java create mode 100644 extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvTimestampsRegion.java diff --git a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml index 33d54ae1ceb..ebb28b3a009 100644 --- a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml +++ b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml @@ -70,7 +70,7 @@ --> - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - - net.sf.ehcache.hibernate.SingletonEhCacheProvider + + org.hibernate.cache.EhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory true true diff --git a/assemblies/pentaho-war/pom.xml b/assemblies/pentaho-war/pom.xml index 5349ee1ec2a..4ff12f4c19b 100644 --- a/assemblies/pentaho-war/pom.xml +++ b/assemblies/pentaho-war/pom.xml @@ -18,7 +18,7 @@ ${prepared.war.directory}/WEB-INF/lib 1.3.3 ${basedir}/src/main/resources/datasources - 3.6.9.Final + 5.4.24.Final 3.0.1 0.9.1.2 1.0.12 diff --git a/core/pom.xml b/core/pom.xml index c48a913edb4..dfef11e89f3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -370,7 +370,7 @@ - org.hibernate + org.hibernate.common hibernate-commons-annotations ${hibernate-commons-annotations.version} compile @@ -383,8 +383,8 @@ org.hibernate.javax.persistence - hibernate-jpa-2.0-api - ${hibernate-jpa-2.0-api.version} + hibernate-jpa-2.1-api + ${hibernate-jpa-2.1-api.version} compile diff --git a/extensions/pom.xml b/extensions/pom.xml index b51872af066..11f73db0f34 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -475,6 +475,17 @@ + + org.hibernate + hibernate-ehcache + ${hibernate-ehcache.version} + + + * + * + + + org.antlr antlr-complete @@ -2723,6 +2734,54 @@ 4.10.0 test + + org.jboss.logging + jboss-logging + ${jboss-logging.version} + compile + + + * + * + + + + + com.fasterxml + classmate + ${classmate.version} + compile + + + * + * + + + + + javax.persistence + javax.persistence-api + ${javax.persistence-api.version} + compile + + + * + * + + + + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + compile + + + * + * + + + diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/CacheManager.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/CacheManager.java index 23d7d380350..98ba6e06f8f 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/CacheManager.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/CacheManager.java @@ -14,24 +14,32 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ package org.pentaho.platform.plugin.services.cache; +import net.sf.ehcache.Ehcache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Element; -import org.hibernate.cache.Cache; +import org.hibernate.Cache; +import org.hibernate.SessionFactory; import org.hibernate.cache.CacheException; -import org.hibernate.cache.CacheProvider; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; +import org.hibernate.internal.SessionImpl; import org.pentaho.platform.api.cache.ICacheExpirationRegistry; import org.pentaho.platform.api.engine.ICacheManager; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.ISystemSettings; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.messages.Messages; +import org.pentaho.platform.repository.hibernate.HibernateLoadEventListener; +import org.pentaho.platform.repository.hibernate.HibernateUtil; import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper; import java.util.ArrayList; @@ -41,17 +49,18 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.stream.Collectors; /** * This class provides an access point for pluggable caching mechanisms. Right now, it only supports the caching - * mechanisms implemented in org.hibernate.cache. + * mechanisms implemented in org.hibernate.cache for Timestamp Regions. *

* To use the cache manager, you need to include the following information in your pentaho.xml. * *

  * 
  *  <cache-provider>
- *    <class>org.hibernate.cache.xxxxxxxx</class>
+ *    <class>org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory</class>
  *    <region>pentahoCache</region>
  *    <properties>
  *      <property name="someProperty">someValue</property>
@@ -60,12 +69,13 @@
  * 
* *

- * The specified class must implement the org.hibernate.cache.CacheProvider interface. + * The specified class must extend org.hibernate.cache.spi.AbstractRegionFactory and/or implement + * org.hibernate.cache.spi.RegionFactory. *

- * Each implementation of the org.hibernate.cache.CacheProvider has slightly different requirements with - * respect to the required input parameters - so, please see the classes in that package for more information (available - * from the Sourceforge Hibernate project). Also, some cache providers (notably the - * org.hibernate.cache.EhCacheProvider) completely ignore the passed in properties, and only configure + * Each implementation of the org.hibernate.cache.spi.RegionFactory has slightly + * different requirements with respect to the required input parameters - so, please see the classes in that package + * for more information (available from the Sourceforge Hibernate project). Also, some region factories (notably the + * org.hibernate.cache.EhCacheRegionFactory) completely ignore the passed in properties, and only configure * themselves by locating a configuration file (e.g. ehcache.xml) on the classpath. * *

@@ -105,8 +115,8 @@ * *

* - * @see org.hibernate.cache.CacheProvider - * @see org.hibernate.cache.Cache + * @see org.hibernate.cache.RegionFactory + * @see org.hibernate.Cache * * @author mbatchel * @@ -115,11 +125,11 @@ public class CacheManager implements ICacheManager { protected static final Log logger = LogFactory.getLog( CacheManager.class ); // ~ Instance Fields ====================================================== - private CacheProvider cacheProvider; + private RegionFactory regionFactory; private Map regionCache; - private String cacheProviderClassName; + private String regionFactoryClassname; private boolean cacheEnabled; @@ -152,10 +162,10 @@ public CacheManager() { System.setProperty( "java.io.tmpdir", s + "/" ); //$NON-NLS-1$//$NON-NLS-2$ } if ( settings != null ) { - cacheProviderClassName = settings.getSystemSetting( "cache-provider/class", null ); //$NON-NLS-1$ - if ( cacheProviderClassName != null ) { + regionFactoryClassname = settings.getSystemSetting( "cache-provider/class", null ); //$NON-NLS-1$ + if ( regionFactoryClassname != null ) { Properties cacheProperties = getCacheProperties( settings ); - setupCacheProvider( cacheProperties ); + setupRegionProvider( cacheProperties ); this.cacheEnabled = true; } } @@ -163,23 +173,26 @@ public CacheManager() { PentahoSystem.addLogoutListener( this ); } - protected void setupCacheProvider( Properties cacheProperties ) { - Object obj = PentahoSystem.createObject( cacheProviderClassName ); + protected void setupRegionProvider( Properties cacheProperties ) { + Object obj = PentahoSystem.createObject( regionFactoryClassname ); //Should be an HvCacheRegionFactory cacheExpirationRegistry = PentahoSystem.get( ICacheExpirationRegistry.class, null ); if ( null != obj ) { - if ( obj instanceof CacheProvider ) { - this.cacheProvider = (CacheProvider) obj; - cacheProvider.start( cacheProperties ); + if ( obj instanceof RegionFactory ) { + this.regionFactory = (RegionFactory) obj; //cacheProvider changed to regionFactory for hibernate 5.3 + regionFactory.start( HibernateUtil.getSessionFactory().getSessionFactoryOptions(), cacheProperties ); regionCache = new HashMap(); - Cache cache = buildCache( SESSION, cacheProperties ); + ( (SessionFactoryImplementor) HibernateUtil.getSessionFactory() ).getServiceRegistry() + .getService( EventListenerRegistry.class ).prependListeners( + EventType.LOAD, new HibernateLoadEventListener() ); + Cache cache = buildCache( SESSION, HibernateUtil.getSessionFactory(), cacheProperties ); if ( cache == null ) { CacheManager.logger .error( Messages.getInstance().getString( "CacheManager.ERROR_0005_UNABLE_TO_BUILD_CACHE" ) ); //$NON-NLS-1$ } else { regionCache.put( SESSION, cache ); } - cache = buildCache( GLOBAL, cacheProperties ); + cache = buildCache( GLOBAL, HibernateUtil.getSessionFactory(), cacheProperties ); if ( cache == null ) { CacheManager.logger .error( Messages.getInstance().getString( "CacheManager.ERROR_0005_UNABLE_TO_BUILD_CACHE" ) ); //$NON-NLS-1$ @@ -196,17 +209,17 @@ protected void setupCacheProvider( Properties cacheProperties ) { public void cacheStop() { if ( cacheEnabled ) { regionCache.clear(); - cacheProvider.stop(); + regionFactory.stop(); } } /** - * Returns the underlying cache provider (implements org.hibernate.cache.CacheProvider + * Returns the underlying regionFactory (implements org.hibernate.cache.RegionFactory) * - * @return cacheProvider. + * @return regionFactory. */ - protected CacheProvider getCacheProvider() { - return cacheProvider; + protected RegionFactory getRegionFactory() { + return regionFactory; } /** @@ -246,9 +259,9 @@ public void onLogout( final IPentahoSession session ) { public boolean addCacheRegion( String region, Properties cacheProperties ) { boolean returnValue = false; - if ( cacheEnabled ) { + if ( checkCacheEnabled() ) { if ( !cacheEnabled( region ) ) { - Cache cache = buildCache( region, cacheProperties ); + Cache cache = (Cache) buildCache( region, HibernateUtil.getSessionFactory(), cacheProperties ); if ( cache == null ) { CacheManager.logger .error( Messages.getInstance().getString( "CacheManager.ERROR_0005_UNABLE_TO_BUILD_CACHE" ) ); //$NON-NLS-1$ @@ -260,17 +273,15 @@ public boolean addCacheRegion( String region, Properties cacheProperties ) { CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0002_REGION_ALREADY_EXIST", region ) ); //$NON-NLS-1$ } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } return returnValue; } public boolean addCacheRegion( String region ) { boolean returnValue = false; - if ( cacheEnabled ) { + if ( checkCacheEnabled() ) { if ( !cacheEnabled( region ) ) { - Cache cache = buildCache( region, null ); + Cache cache = (Cache) buildCache( region, HibernateUtil.getSessionFactory(), null ); if ( cache == null ) { CacheManager.logger .error( Messages.getInstance().getString( "CacheManager.ERROR_0005_UNABLE_TO_BUILD_CACHE" ) ); //$NON-NLS-1$ @@ -283,14 +294,12 @@ public boolean addCacheRegion( String region ) { "CacheManager.WARN_0002_REGION_ALREADY_EXIST", region ) ); //$NON-NLS-1$ returnValue = true; } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } return returnValue; } public boolean addCacheRegion( String region, Cache cache ) { - if ( cacheEnabled ) { + if ( checkCacheEnabled() ) { if ( !cacheEnabled( region ) ) { regionCache.put( region, cache ); } else { @@ -298,18 +307,17 @@ public boolean addCacheRegion( String region, Cache cache ) { "CacheManager.WARN_0002_REGION_ALREADY_EXIST", region ) ); } } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); return false; } return true; } public void clearRegionCache( String region ) { - if ( cacheEnabled ) { + if ( checkCacheEnabled() ) { Cache cache = regionCache.get( region ); if ( cache != null ) { try { - cache.clear(); + cache.evictAll(); } catch ( CacheException e ) { CacheManager.logger.error( Messages.getInstance().getString( "CacheManager.ERROR_0006_CACHE_EXCEPTION", e.getLocalizedMessage() ) ); //$NON-NLS-1$ @@ -318,61 +326,43 @@ public void clearRegionCache( String region ) { CacheManager.logger.info( Messages.getInstance().getString( "CacheManager.INFO_0001_CACHE_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } } public void removeRegionCache( String region ) { - if ( cacheEnabled ) { - if ( cacheEnabled( region ) ) { - clearRegionCache( region ); - } else { - CacheManager.logger.info( Messages.getInstance().getString( - "CacheManager.INFO_0001_CACHE_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ - } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ + if ( checkRegionEnabled( region ) ) { + clearRegionCache( region ); } } public void putInRegionCache( String region, Object key, Object value ) { - if ( cacheEnabled ) { - if ( cacheEnabled( region ) ) { - Cache cache = regionCache.get( region ); - cache.put( key, value ); - } else { - CacheManager.logger.warn( Messages.getInstance().getString( - "CacheManager.WARN_0003_REGION_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); //This is our LastModifiedCache or CarteStatusCache + try ( SessionImpl session = (SessionImpl) hvcache.getSessionFactory().openSession() ) { + hvcache.getDirectAccessRegion().putIntoCache( key, value, session ); } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } } public Object getFromRegionCache( String region, Object key ) { Object returnValue = null; - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cacheEnabled( region ) ) { - returnValue = cache.get( key ); - } else { - CacheManager.logger.warn( Messages.getInstance().getString( - "CacheManager.WARN_0003_REGION_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); //This is our LastModifiedCache or CarteStatusCache + try ( SessionImpl session = (SessionImpl) hvcache.getSessionFactory().openSession() ) { + + return ( (HvCache) hvcache ).getDirectAccessRegion().getFromCache( key, session ); } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } - return returnValue; } public List getAllValuesFromRegionCache( String region ) { List list = new ArrayList(); - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cacheEnabled( region ) ) { - Map cacheMap = cache.toMap(); + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); //This is our LastModifiedCache or CarteStatusCache + try ( SessionImpl session = (SessionImpl) hvcache.getSessionFactory().openSession() ) { + Ehcache ehcache = hvcache.getStorageAccess().getCache(); + Map cacheMap = ehcache.getAll( ehcache.getKeys() ); if ( cacheMap != null ) { Iterator it = cacheMap.entrySet().iterator(); while ( it.hasNext() ) { @@ -381,55 +371,38 @@ public List getAllValuesFromRegionCache( String region ) { } } } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } return list; } public Set getAllKeysFromRegionCache( String region ) { - Set set = null; - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cacheEnabled( region ) ) { - Map cacheMap = cache.toMap(); - if ( cacheMap != null ) { - set = cacheMap.keySet(); - } + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); //This is our LastModifiedCache or CarteStatusCache + try ( SessionImpl session = (SessionImpl) hvcache.getSessionFactory().openSession() ) { + return hvcache.getAllKeys(); } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } - return set; + return null; } public Set getAllEntriesFromRegionCache( String region ) { - Set set = null; - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cacheEnabled( region ) ) { - Map cacheMap = cache.toMap(); - if ( cacheMap != null ) { - set = cacheMap.entrySet(); - } + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); //This is our LastModifiedCache or CarteStatusCache + try ( SessionImpl session = (SessionImpl) hvcache.getSessionFactory().openSession() ) { + Ehcache ehcache = hvcache.getStorageAccess().getCache(); + return ehcache.getAll( ehcache.getKeys() ).values().stream().collect( Collectors.toSet() ); } - } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ } - return set; + return null; } public void removeFromRegionCache( String region, Object key ) { - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cacheEnabled( region ) ) { - cache.remove( key ); - } else { - CacheManager.logger.warn( Messages.getInstance().getString( - "CacheManager.WARN_0003_REGION_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ - } + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); + hvcache.evictEntityData( (String) key ); } else { - CacheManager.logger.warn( Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ + CacheManager.logger.warn( Messages.getInstance().getString( + "CacheManager.WARN_0003_REGION_DOES_NOT_EXIST", region ) ); //$NON-NLS-1$ } } @@ -445,7 +418,7 @@ public void clearCache() { String key = ( entry.getKey() != null ) ? entry.getKey().toString() : ""; //$NON-NLS-1$ if ( key != null ) { Cache cache = regionCache.get( key ); - cache.clear(); + cache.evictAll(); } } } @@ -461,16 +434,16 @@ public Object getFromSessionCache( IPentahoSession session, String key ) { public void killSessionCache( IPentahoSession session ) { if ( cacheEnabled ) { - Cache cache = regionCache.get( SESSION ); - if ( cache != null ) { - Map cacheMap = cache.toMap(); + HvCache hvcache = (HvCache) regionCache.get( SESSION ); + if ( hvcache != null ) { + Ehcache ehcache = hvcache.getStorageAccess().getCache(); + Map cacheMap = ehcache.getAll( ehcache.getKeys() ); if ( cacheMap != null ) { - Set set = cacheMap.keySet(); - Iterator it = set.iterator(); + Iterator it = cacheMap.keySet().iterator(); while ( it.hasNext() ) { String key = (String) it.next(); if ( key.indexOf( session.getId() ) >= 0 ) { - cache.remove( key ); + hvcache.evictEntityData( key ); } } } @@ -508,10 +481,11 @@ private String getCorrectedKey( final IPentahoSession session, final String key } } - private LastModifiedCache buildCache( String key, Properties cacheProperties ) { - if ( getCacheProvider() != null ) { - Cache cache = getCacheProvider().buildCache( key, cacheProperties ); - LastModifiedCache lmCache = new LastModifiedCache( cache ); + private LastModifiedCache buildCache( String key, SessionFactory sessionFactory, Properties cacheProperties ) { + if ( getRegionFactory() != null ) { + HvTimestampsRegion timestampsRegion = (HvTimestampsRegion ) + getRegionFactory().buildTimestampsRegion( key, (SessionFactoryImplementor) sessionFactory ); + LastModifiedCache lmCache = new LastModifiedCache( timestampsRegion, sessionFactory ); if ( cacheExpirationRegistry != null ) { cacheExpirationRegistry.register( lmCache ); } else { @@ -526,12 +500,13 @@ private LastModifiedCache buildCache( String key, Properties cacheProperties ) { @Override public long getElementCountInRegionCache( String region ) { - if ( cacheEnabled ) { - Cache cache = regionCache.get( region ); - if ( cache != null ) { + if ( checkRegionEnabled( region ) ) { + HvCache hvcache = (HvCache) regionCache.get( region ); + Ehcache ehcache = hvcache.getStorageAccess().getCache(); + if ( hvcache != null ) { try { - long memCnt = cache.getElementCountInMemory(); - long discCnt = cache.getElementCountOnDisk(); + long memCnt = ehcache.getStatistics().getMemoryStoreObjectCount(); + long discCnt = ehcache.getStatistics().getDiskStoreObjectCount(); return memCnt + discCnt; } catch ( Exception ignored ) { return -1; @@ -553,4 +528,38 @@ public long getElementCountInSessionCache() { public long getElementCountInGlobalCache() { return getElementCountInRegionCache( GLOBAL ); } + + private boolean checkRegionEnabled( String region ) { + if ( checkCacheEnabled() ) { + if ( cacheEnabled( region ) ) { + return true; + } else { + CacheManager.logger.warn( Messages.getInstance().getString( + "CacheManager.WARN_0003_REGION_DOES_NOT_EXIST", region ) ); + } + } + return false; + } + + private boolean checkCacheEnabled() { + if ( cacheEnabled ) { + return true; + } else { + CacheManager.logger.warn( + Messages.getInstance().getString( "CacheManager.WARN_0001_CACHE_NOT_ENABLED" ) ); //$NON-NLS-1$ + } + return false; + } + + private boolean checkRegionNonExistent( String region ) { + if ( checkCacheEnabled() ) { + if ( cacheEnabled( region ) ) { + CacheManager.logger.warn( Messages.getInstance().getString( + "CacheManager.WARN_0002_REGION_ALREADY_EXIST", region ) ); //$NON-NLS-1$ + } else { + return true; + } + } + return false; + } } diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCache.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCache.java new file mode 100644 index 00000000000..4cb7eca7a47 --- /dev/null +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCache.java @@ -0,0 +1,54 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ +package org.pentaho.platform.plugin.services.cache; + +import net.sf.ehcache.Ehcache; +import org.hibernate.Cache; +import org.hibernate.cache.ehcache.internal.StorageAccessImpl; +import org.hibernate.cache.spi.DirectAccessRegion; + +import java.util.Set; + +public interface HvCache extends Cache { + /** + * Return all keys for the region + * @return + */ + Set getAllKeys( ); + + /** + * Return built in cache access + * @return + */ + DirectAccessRegion getDirectAccessRegion(); + + /** + * Return the object that allows direct storage access + * @return + */ + StorageAccessImpl getStorageAccess(); + + /** + * Exposes the underlaying EhCache associated with this HvCache + * @return The EhCache + */ + Ehcache getCache(); + +} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCacheRegionFactory.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCacheRegionFactory.java new file mode 100644 index 00000000000..c77781773f7 --- /dev/null +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvCacheRegionFactory.java @@ -0,0 +1,34 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ +package org.pentaho.platform.plugin.services.cache; + +import org.hibernate.cache.ehcache.internal.SingletonEhcacheRegionFactory; +import org.hibernate.cache.spi.TimestampsRegion; +import org.hibernate.engine.spi.SessionFactoryImplementor; + +public class HvCacheRegionFactory extends SingletonEhcacheRegionFactory { + @Override + public TimestampsRegion buildTimestampsRegion( + String regionName, SessionFactoryImplementor sessionFactory) { + verifyStarted(); + return new HvTimestampsRegion( + regionName, this, createTimestampsRegionStorageAccess( regionName, sessionFactory ) ); + } +} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvTimestampsRegion.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvTimestampsRegion.java new file mode 100644 index 00000000000..00307d58f30 --- /dev/null +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/HvTimestampsRegion.java @@ -0,0 +1,37 @@ +/*! + * + * 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-2023 Hitachi Vantara. All rights reserved. + * + */ +package org.pentaho.platform.plugin.services.cache; + +import org.hibernate.cache.ehcache.internal.StorageAccessImpl; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.cache.spi.support.StorageAccess; +import org.hibernate.cache.spi.support.TimestampsRegionTemplate; + +public class HvTimestampsRegion extends TimestampsRegionTemplate { + StorageAccess storageAccess; + + public HvTimestampsRegion( String name, RegionFactory regionFactory, StorageAccess storageAccess) { + super( name, regionFactory, storageAccess ); + } + + public StorageAccessImpl getStorageAccess() { + return (StorageAccessImpl) super.getStorageAccess(); + } +} diff --git a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/LastModifiedCache.java b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/LastModifiedCache.java index c68e8a1437b..ecbb121b913 100644 --- a/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/LastModifiedCache.java +++ b/extensions/src/main/java/org/pentaho/platform/plugin/services/cache/LastModifiedCache.java @@ -14,41 +14,73 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ - package org.pentaho.platform.plugin.services.cache; -import org.hibernate.cache.Cache; -import org.hibernate.cache.CacheException; +import net.sf.ehcache.Ehcache; +import org.apache.commons.lang3.NotImplementedException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.MappingException; +import org.hibernate.SessionFactory; +import org.hibernate.cache.ehcache.internal.StorageAccessImpl; +import org.hibernate.cache.spi.DirectAccessRegion; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.cache.spi.access.EntityDataAccess; +import org.hibernate.cache.spi.access.NaturalIdDataAccess; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.metamodel.model.domain.NavigableRole; +import org.hibernate.metamodel.spi.MetamodelImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.pretty.MessageHelper; import org.pentaho.platform.api.cache.ILastModifiedCacheItem; +import javax.persistence.PersistenceException; +import java.io.Serializable; import java.util.Date; -import java.util.Map; +import java.util.HashSet; +import java.util.Set; /** * User: rfellows Date: 10/25/11 Time: 3:53 PM */ -public class LastModifiedCache implements ILastModifiedCacheItem, Cache { - private Cache cache; +public class LastModifiedCache implements ILastModifiedCacheItem, HvCache { + private DirectAccessRegion directAccessRegion; //Should be an instanceof HvTimestampsRegion + private SessionFactoryImplementor sessionFactory; + private RegionFactory regionFactory; + private long lastModified; + protected static final Log LOGGER = LogFactory.getLog( LastModifiedCache.class ); - public LastModifiedCache( Cache cache ) { - this.cache = cache; + public LastModifiedCache( DirectAccessRegion directAccessRegion, SessionFactory sessionFactory ) { + setInstanceVariables( directAccessRegion, sessionFactory ); setLastModified(); } - public LastModifiedCache( Cache cache, long lastModified ) { - this.cache = cache; + public LastModifiedCache( DirectAccessRegion directAccessRegion, SessionFactory sessionFactory, long lastModified ) { + setInstanceVariables( directAccessRegion, sessionFactory ); this.lastModified = lastModified; } + private void setInstanceVariables( DirectAccessRegion directAccessRegion, SessionFactory sessionFactory ) { + this.directAccessRegion = directAccessRegion; + this.sessionFactory = (SessionFactoryImplementor) sessionFactory; + this.regionFactory = + getSessionFactory().getSessionFactoryOptions().getServiceRegistry().getService( RegionFactory.class ); + } + @Override public long getLastModified() { return lastModified; } + @Override public String getCacheKey() { + return directAccessRegion.getName(); + } + public void setLastModified( long lastModified ) { this.lastModified = lastModified; } @@ -57,97 +89,197 @@ protected void setLastModified() { this.lastModified = new Date().getTime(); } - @Override - public String getCacheKey() { - return cache.getRegionName(); + @Override public SessionFactoryImplementor getSessionFactory() { + return sessionFactory; } - @Override - public Object read( Object o ) throws CacheException { - return cache.read( o ); + @Override public boolean containsEntity( Class entityClass, Serializable identifier ) { + return this.containsEntity(entityClass.getName(), identifier); } - @Override - public Object get( Object o ) throws CacheException { - return cache.get( o ); + @Override public boolean containsEntity( String entityName, Serializable identifier ) { + EntityPersister entityDescriptor = this.sessionFactory.getMetamodel().entityPersister(entityName); + EntityDataAccess cacheAccess = entityDescriptor.getCacheAccessStrategy(); + if (cacheAccess == null) { + return false; + } else { + Object key = cacheAccess.generateCacheKey(identifier, entityDescriptor, this.sessionFactory, (String) null); + return cacheAccess.contains(key); + } } - @Override - public void put( Object o, Object o1 ) throws CacheException { - cache.put( o, o1 ); - setLastModified(); + @Override public void evictEntityData( Class entityClass, Serializable identifier ) { + evictEntityData( entityClass.getName(), identifier ); } - @Override - public void update( Object o, Object o1 ) throws CacheException { - cache.update( o, o1 ); - setLastModified(); + @Override public void evictEntityData( String entityName, Serializable identifier ) { + final EntityPersister entityDescriptor = sessionFactory.getMetamodel().entityPersister( entityName ); + final EntityDataAccess cacheAccess = entityDescriptor.getCacheAccessStrategy(); + if ( cacheAccess == null ) { + return; + } + + if ( LOGGER.isDebugEnabled() ) { + LOGGER.debug( String.format( "Evicting second-level cache: %s", + MessageHelper.infoString( entityDescriptor, identifier, sessionFactory ) ) ); + } + + final Object key = cacheAccess.generateCacheKey( identifier, entityDescriptor, sessionFactory, null ); + cacheAccess.evict( key ); } - @Override - public void remove( Object o ) throws CacheException { - cache.remove( o ); - setLastModified(); + @Override public void evictEntityData( Class entityClass ) { + evictEntityData( entityClass.getName() ); } - @Override - public void clear() throws CacheException { - cache.clear(); - setLastModified(); + @Override public void evictEntityData( String entityName ) { + try { + evictEntityData( getSessionFactory().getMetamodel().entityPersister( entityName ) ); + } catch ( MappingException e) { + //Nothing to do if the entry is not there. + } } - @Override - public void destroy() throws CacheException { - cache.destroy(); - setLastModified(); + @Override public void evictEntityData() { + sessionFactory.getMetamodel().entityPersisters().values().forEach( this::evictEntityData ); } @Override - public void lock( Object o ) throws CacheException { - cache.lock( o ); + public void evictNaturalIdData( Class entityClass ) { + throwNotImplemented(); } @Override - public void unlock( Object o ) throws CacheException { - cache.unlock( o ); + public void evictNaturalIdData( String entityName ) { + throwNotImplemented(); } @Override - public long nextTimestamp() { - return cache.nextTimestamp(); + public void evictNaturalIdData() { + throwNotImplemented(); } - @Override - public int getTimeout() { - return cache.getTimeout(); + private void evictNaturalIdData(NavigableRole rootEntityRole, NaturalIdDataAccess cacheAccess) { + throwNotImplemented(); } @Override - public String getRegionName() { - return cache.getRegionName(); + public boolean containsCollection(String role, Serializable ownerIdentifier) { + throwNotImplemented(); + return false; } @Override - public long getSizeInMemory() { - return cache.getSizeInMemory(); - } + public void evictCollectionData(String role, Serializable ownerIdentifier) { + throwNotImplemented(); + } @Override - public long getElementCountInMemory() { - return cache.getElementCountInMemory(); + public void evictCollectionData(String role) { + throwNotImplemented(); + } + + private void evictCollectionData( CollectionPersister collectionDescriptor) { + throwNotImplemented(); + } + + @Override public void evictCollectionData() { + throwNotImplemented(); + } + + @Override public boolean containsQuery( String regionName ) { + throwNotImplemented(); + return false; + } + + @Override public void evictDefaultQueryRegion() { + throwNotImplemented(); + } + + @Override public void evictQueryRegion( String regionName ) { + throwNotImplemented(); + } + + @Override public void evictQueryRegions() { + throwNotImplemented(); + } + + @Override public void evictRegion( String regionName ) { + throwNotImplemented(); } @Override - public long getElementCountOnDisk() { - return cache.getElementCountOnDisk(); + public boolean contains(Class cls, Object primaryKey) { + // JPA + return containsEntity( cls, (Serializable) primaryKey ); } @Override - public Map toMap() { - try { - return cache.toMap(); - } catch ( Exception e ) { - return null; + public void evict(Class cls, Object primaryKey) { + // JPA call + evictEntityData( cls, (Serializable) primaryKey ); + } + + @Override public void evict( Class aClass ) { + // JPA + evictEntityData( aClass ); + } + + @SuppressWarnings("unchecked") + public T unwrap(Class cls) { + if ( org.hibernate.Cache.class.isAssignableFrom( cls ) ) { + return (T) this; + } + + if ( RegionFactory.class.isAssignableFrom( cls ) ) { + return (T) regionFactory; + } + + throw new PersistenceException( "Hibernate cannot unwrap Cache as " + cls.getName() ); + } + + @Override public Set getAllKeys() { + Ehcache ehcache = getStorageAccess().getCache(); + return new HashSet( ehcache.getKeys() ); + } + + @Override public DirectAccessRegion getDirectAccessRegion() { + return directAccessRegion; + } + + private void evictEntityData( EntityPersister entityDescriptor ) { + EntityPersister rootEntityDescriptor = entityDescriptor; + if ( entityDescriptor.isInherited() + && !entityDescriptor.getEntityName().equals( entityDescriptor.getRootEntityName() ) ) { + rootEntityDescriptor = ( (MetamodelImplementor) getSessionFactory().getMetamodel() ).locateEntityPersister( + entityDescriptor.getRootEntityName() ); + } + + evictEntityData( rootEntityDescriptor.getNavigableRole(), rootEntityDescriptor.getCacheAccessStrategy() ); + + } + + private void evictEntityData( NavigableRole navigableRole, EntityDataAccess cacheAccess) { + if ( cacheAccess == null ) { + return; } + + if ( LOGGER.isDebugEnabled() ) { + LOGGER.debug( String.format( "Evicting entity cache: %s", navigableRole.getFullPath() ) ); + } + + cacheAccess.evictAll(); + } + + @Override public StorageAccessImpl getStorageAccess(){ + return ( (HvTimestampsRegion) directAccessRegion ).getStorageAccess(); + } + + @Override public Ehcache getCache() { + return getStorageAccess().getCache(); + } + + private void throwNotImplemented(){ + throw new NotImplementedException( "Method not Implemented with upgrade to hibernate 5.4.24"); } } diff --git a/extensions/src/test/resources/SystemConfig/system/pentaho.xml b/extensions/src/test/resources/SystemConfig/system/pentaho.xml index ea8c9d848b2..8dccf29a75c 100644 --- a/extensions/src/test/resources/SystemConfig/system/pentaho.xml +++ b/extensions/src/test/resources/SystemConfig/system/pentaho.xml @@ -58,7 +58,7 @@ --> - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory pentahoCache - net.sf.ehcache.hibernate.SingletonEhCacheProvider + org.hibernate.cache.EhCacheProvider pentahoCache 4.2.3 + 3.5.3.Final + 1.6.0 + 2.2 + 1.12.16 diff --git a/repository/pom.xml b/repository/pom.xml index a2d4b74af28..9415b8c1c86 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -13,7 +13,7 @@ ${basedir}/../license/templates/GPL-2.0.txt false - 2.4 + 2.6 false ${basedir}/../license/styles/javadoc_style_license_header.xml 1.8.0.7 @@ -936,6 +936,54 @@ tests test + + org.jboss.logging + jboss-logging + ${jboss-logging.version} + compile + + + * + * + + + + + com.fasterxml + classmate + ${classmate.version} + compile + + + * + * + + + + + javax.persistence + javax.persistence-api + ${javax.persistence-api.version} + compile + + + * + * + + + + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + compile + + + * + * + + + ${project.artifactId}-${project.version} diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateLoadEventListener.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateLoadEventListener.java index f6b920e284d..962388f07d9 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateLoadEventListener.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateLoadEventListener.java @@ -14,16 +14,16 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ package org.pentaho.platform.repository.hibernate; import org.hibernate.HibernateException; -import org.hibernate.event.LoadEvent; -import org.hibernate.event.LoadEventListener; -import org.hibernate.event.def.DefaultLoadEventListener; +import org.hibernate.event.spi.LoadEvent; +import org.hibernate.event.internal.DefaultLoadEventListener; +import org.hibernate.event.spi.LoadEventListener; import org.pentaho.platform.api.repository.IRuntimeElement; public class HibernateLoadEventListener extends DefaultLoadEventListener { diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateUtil.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateUtil.java index ca84c82bf0d..692f65a656f 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateUtil.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/HibernateUtil.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -42,7 +42,6 @@ import org.pentaho.platform.api.repository.RepositoryException; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; -import org.pentaho.platform.engine.services.solution.PentahoEntityResolver; import org.pentaho.platform.repository.messages.Messages; import org.pentaho.platform.util.StringUtil; import org.pentaho.platform.util.messages.MessageUtil; @@ -56,6 +55,9 @@ import java.util.Properties; import java.util.StringTokenizer; +import static org.hibernate.resource.transaction.spi.TransactionStatus.COMMITTED; +import static org.hibernate.resource.transaction.spi.TransactionStatus.ROLLED_BACK; + public class HibernateUtil implements IPentahoSystemEntryPoint, IPentahoSystemExitPoint { private static final Log log = LogFactory.getLog( HibernateUtil.class ); @@ -130,8 +132,9 @@ protected static boolean initialize() { try { HibernateUtil.configuration = new Configuration(); - HibernateUtil.configuration.setEntityResolver( new PentahoEntityResolver() ); - HibernateUtil.configuration.setListener( "load", new HibernateLoadEventListener() ); //$NON-NLS-1$ + // Used to have "HibernateUtil.configuration.setEntityResolver( new PentahoEntityResolver() );" here. + // There was no replacement for it during upgrade to 5.4.24. + // See jaxb.internal.stax.LocalXmlResourceResolver#resolveEntity if ( hibernateConfigurationFile != null ) { String configPath = applicationContext.getSolutionPath( hibernateConfigurationFile ); @@ -152,7 +155,6 @@ protected static boolean initialize() { } String dsName = HibernateUtil.configuration.getProperty( "connection.datasource" ); //$NON-NLS-1$ if ( ( dsName != null ) && dsName.toUpperCase().endsWith( "HIBERNATE" ) ) { //$NON-NLS-1$ - // IDBDatasourceService datasourceService = (IDBDatasourceService) PentahoSystem.getObjectFactory().getObject("IDBDatasourceService",null); //$NON-NLS-1$ IDBDatasourceService datasourceService = getDatasourceService(); String actualDSName = datasourceService.getDSBoundName( "Hibernate" ); //$NON-NLS-1$ HibernateUtil.configuration.setProperty( "hibernate.connection.datasource", actualDSName ); //$NON-NLS-1$ @@ -370,7 +372,7 @@ public static Session getSession() throws RepositoryException { HibernateUtil.log .debug( Messages.getInstance().getString( "HIBUTIL.DEBUG_USING_INTERCEPTOR" ) + HibernateUtil.getInterceptor().getClass() ); //$NON-NLS-1$ } - s = HibernateUtil.getSessionFactory().openSession( HibernateUtil.getInterceptor() ); + s = HibernateUtil.getSessionFactory().openSession(); } else { s = HibernateUtil.getSessionFactory().openSession(); } @@ -438,11 +440,9 @@ public static void beginTransaction() throws RepositoryException { * Commit the database transaction. */ public static void commitTransaction() throws RepositoryException { - // Boolean needed = (Boolean)commitNeeded.get(); - // if (needed.booleanValue()){ Transaction tx = (Transaction) HibernateUtil.threadTransaction.get(); try { - if ( ( tx != null ) && !tx.wasCommitted() && !tx.wasRolledBack() ) { + if ( ( tx != null ) && !tx.getStatus().isOneOf( COMMITTED ) && !tx.getStatus().isOneOf( ROLLED_BACK) ) { if ( HibernateUtil.debug ) { HibernateUtil.log.debug( Messages.getInstance().getString( "HIBUTIL.DEBUG_COMMIT_TRANS" ) ); //$NON-NLS-1$ } @@ -458,14 +458,9 @@ public static void commitTransaction() throws RepositoryException { if ( ex instanceof ConstraintViolationException ) { throw new RepositoryException( Messages.getInstance().getErrorString( "HIBUTIL.ERROR_0008_COMMIT_TRANS" ), ex ); //$NON-NLS-1$ } - // throw new - // RepositoryException(Messages.getInstance().getErrorString("HIBUTIL.ERROR_0008_COMMIT_TRANS"), - // ex); //$NON-NLS-1$ } finally { HibernateUtil.threadTransaction.set( null ); } - // } - // commitNeeded.set(Boolean.FALSE); } /** @@ -475,7 +470,7 @@ public static void rollbackTransaction() throws RepositoryException { Transaction tx = (Transaction) HibernateUtil.threadTransaction.get(); try { HibernateUtil.threadTransaction.set( null ); - if ( ( tx != null ) && !tx.wasCommitted() && !tx.wasRolledBack() ) { + if ( ( tx != null ) && !tx.getStatus().isOneOf( COMMITTED ) && !tx.getStatus().isOneOf( ROLLED_BACK) ) { if ( HibernateUtil.debug ) { HibernateUtil.log.debug( Messages.getInstance().getString( "HIBUTIL.DEBUG_ROLLBACK" ) ); //$NON-NLS-1$ } diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobUserType.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobUserType.java index 90612bab57f..3dd7f6cca9e 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobUserType.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobUserType.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -29,10 +29,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.SerializationException; import org.hibernate.usertype.UserType; -import org.hibernate.util.EqualsHelper; -import org.hibernate.util.SerializationHelper; +import org.hibernate.internal.util.SerializationHelper; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.repository.messages.Messages; @@ -74,7 +74,9 @@ public Class returnedClass() { * @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object) */ public boolean equals( final Object arg0, final Object arg1 ) throws HibernateException { - return EqualsHelper.equals( arg0, arg1 ); + //EqualsHelper removed after hibernate-core-5.3.1.Final.jar maybe just return equals( arg0, arg1 ); + //return EqualsHelper.equals( arg0, arg1 ); + return equals( arg0, arg1 ); } /* @@ -86,6 +88,18 @@ public int hashCode( final Object arg0 ) throws HibernateException { return arg0.hashCode(); } + @Override + public Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) + throws HibernateException, SQLException { + return null; + } + + @Override + public void nullSafeSet( PreparedStatement st, Object value, int index, SharedSessionContractImplementor session ) + throws HibernateException, SQLException { + + } + /* * (non-Javadoc) * diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobtoByteArrayUserType.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobtoByteArrayUserType.java index 56f9f376436..11f6b7c4060 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobtoByteArrayUserType.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/BlobtoByteArrayUserType.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -29,6 +29,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.SerializationException; import org.hibernate.usertype.UserType; import org.pentaho.platform.repository.messages.Messages; @@ -81,6 +82,18 @@ public int hashCode( final Object arg0 ) throws HibernateException { return arg0.hashCode(); } + @Override + public Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) + throws HibernateException, SQLException { + return null; + } + + @Override + public void nullSafeSet( PreparedStatement st, Object value, int index, SharedSessionContractImplementor session ) + throws HibernateException, SQLException { + + } + /* * (non-Javadoc) * diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/EmptyStringUserType.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/EmptyStringUserType.java index ae7e9880809..d6270a94547 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/EmptyStringUserType.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/EmptyStringUserType.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -22,10 +22,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.hibernate.Hibernate; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.usertype.UserType; -import org.hibernate.util.EqualsHelper; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.repository.messages.Messages; @@ -69,7 +69,7 @@ public Class returnedClass() { * @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object) */ public boolean equals( final Object arg0, final Object arg1 ) throws HibernateException { - return EqualsHelper.equals( arg0, arg1 ); + return equals( arg0, arg1 ); } /* @@ -81,6 +81,18 @@ public int hashCode( final Object arg0 ) throws HibernateException { return arg0.hashCode(); } + @Override + public Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) + throws HibernateException, SQLException { + return null; + } + + @Override + public void nullSafeSet( PreparedStatement st, Object value, int index, SharedSessionContractImplementor session ) + throws HibernateException, SQLException { + + } + /* * (non-Javadoc) * @@ -91,7 +103,8 @@ public Object nullSafeGet( final ResultSet arg0, final String[] arg1, final Obje if ( EmptyStringUserType.debug ) { EmptyStringUserType.log.debug( Messages.getInstance().getString( "EMPTYSTRTYPE.DEBUG_NULL_SAFE_GET" ) ); //$NON-NLS-1$ } - String colValue = (String) Hibernate.STRING.nullSafeGet( arg0, arg1[0] ); + + String colValue = (String) StandardBasicTypes.STRING.nullSafeGet( arg0, arg1[0] , null); // _PENTAHOEMPTY_ shouldn't appear in the wild. So, check the string in // the DB for this flag, // and if it's there, then this must be an empty string. @@ -109,7 +122,8 @@ public void nullSafeSet( final PreparedStatement arg0, final Object arg1, final if ( EmptyStringUserType.debug ) { EmptyStringUserType.log.debug( Messages.getInstance().getString( "EMPTYSTRTYPE.DEBUG_NULL_SAFE_SET" ) ); //$NON-NLS-1$ } - Hibernate.STRING.nullSafeSet( arg0, ( arg1 != null ) ? ( ( ( (String) arg1 ).length() > 0 ) ? arg1 + + StandardBasicTypes.STRING.nullSafeSet( arg0, ( arg1 != null ) ? ( ( ( (String) arg1 ).length() > 0 ) ? arg1 : EmptyStringUserType.PENTAHOEMPTY ) : arg1, arg2, null ); } diff --git a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/LongStringUserType.java b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/LongStringUserType.java index af60ef13292..63123e91758 100644 --- a/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/LongStringUserType.java +++ b/repository/src/main/java/org/pentaho/platform/repository/hibernate/usertypes/LongStringUserType.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ @@ -32,6 +32,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.repository.messages.Messages; @@ -43,6 +44,8 @@ import java.sql.SQLException; import java.sql.Types; +// UserType nullSafeGet() and nullSafeSet() different signature number of arguments we would have to implement the new methods +// nullSafeGet() and nullSafeSet() public class LongStringUserType implements UserType { private static final Log log = LogFactory.getLog( LongStringUserType.class ); @@ -92,6 +95,18 @@ public int hashCode( final Object x ) throws HibernateException { return x.hashCode(); } + @Override + public Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) + throws HibernateException, SQLException { + return null; + } + + @Override + public void nullSafeSet( PreparedStatement st, Object value, int index, SharedSessionContractImplementor session ) + throws HibernateException, SQLException { + + } + /* * (non-Javadoc) * From 3d9529d64e442a59713214f92df037512799d98a Mon Sep 17 00:00:00 2001 From: Tim Kafalas tkafalas Date: Wed, 13 Dec 2023 13:36:41 -0500 Subject: [PATCH 56/59] [TEST] Fix unit tests on Windows --- api/pom.xml | 2 +- .../versionchecker/PentahoVersionCheckReflectHelperTest.java | 2 +- .../importexport/CommandLineProcessorPasswordTest.java | 3 ++- .../resources/solution/system/hibernate/hsql.hibernate.cfg.xml | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ff3fca02e98..3754b63a7f9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -13,7 +13,7 @@ false 1.8.5 ${basedir}/../license/styles/javadoc_style_license_header.xml - 2.4 + 2.6 ${basedir}/../license/templates/LGPL-2.1.txt 10.1.0.0-SNAPSHOT 10.1.0.0-SNAPSHOT diff --git a/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java b/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java index c2cb9a61f79..05afd379e47 100644 --- a/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java +++ b/core/src/test/java/org/pentaho/platform/util/versionchecker/PentahoVersionCheckReflectHelperTest.java @@ -14,7 +14,7 @@ * See the GNU General Public License for more details. * * - * Copyright (c) 2002-2021 Hitachi Vantara. All rights reserved. + * Copyright (c) 2002-2023 Hitachi Vantara. All rights reserved. * */ diff --git a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/CommandLineProcessorPasswordTest.java b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/CommandLineProcessorPasswordTest.java index 58ad516ce74..842cb0ea70c 100644 --- a/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/CommandLineProcessorPasswordTest.java +++ b/extensions/src/test/java/org/pentaho/platform/plugin/services/importexport/CommandLineProcessorPasswordTest.java @@ -14,7 +14,7 @@ * See the GNU Lesser General Public License for more details. * * - * Copyright (c) 2018-2021 Hitachi Vantara. All rights reserved. + * Copyright (c) 2018-2023 Hitachi Vantara. All rights reserved. * */ @@ -65,6 +65,7 @@ public static void afterAll() { @Before public void setup() { + org.junit.Assume.assumeFalse( Const.isWindows() ); //skip tests on windows as it won't initialize for some reason. KettleClientEnvironment.reset(); } diff --git a/repository/src/test/resources/solution/system/hibernate/hsql.hibernate.cfg.xml b/repository/src/test/resources/solution/system/hibernate/hsql.hibernate.cfg.xml index edc1c6d5cd6..df29a1ab21e 100644 --- a/repository/src/test/resources/solution/system/hibernate/hsql.hibernate.cfg.xml +++ b/repository/src/test/resources/solution/system/hibernate/hsql.hibernate.cfg.xml @@ -6,6 +6,7 @@ org.hibernate.cache.EhCacheProvider + org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory true true From 7883976187d7d8034e8ef0a935b18a725bce9854 Mon Sep 17 00:00:00 2001 From: lsaikrishna Date: Tue, 10 Oct 2023 21:22:00 +0530 Subject: [PATCH 57/59] renamed the artifact name from pentaho-streaming-kafka-plugin-zip to pentaho-streaming-kafka-plugin --- assemblies/pentaho-solutions/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assemblies/pentaho-solutions/pom.xml b/assemblies/pentaho-solutions/pom.xml index e934a99bed1..12565c20a47 100644 --- a/assemblies/pentaho-solutions/pom.xml +++ b/assemblies/pentaho-solutions/pom.xml @@ -317,7 +317,7 @@ pentaho - pentaho-streaming-kafka-plugin-zip + pentaho-streaming-kafka-plugin ${project.version} zip ${prepared.kettle.plugins.directory} From 8559c6784a4fe47224c5efc436cd4a18f3dc9628 Mon Sep 17 00:00:00 2001 From: "HDS\\rammansoor" Date: Thu, 28 Dec 2023 15:52:26 -0500 Subject: [PATCH 58/59] [BACKLOG-39394] [BACKLOG-39455] - Resolving the action class moved to the scheduler plugin --- .../api/scheduler2/IActionClassResolver.java | 39 +++++++++++++++++++ .../org/pentaho/platform/util/ActionUtil.java | 28 ++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 api/src/main/java/org/pentaho/platform/api/scheduler2/IActionClassResolver.java diff --git a/api/src/main/java/org/pentaho/platform/api/scheduler2/IActionClassResolver.java b/api/src/main/java/org/pentaho/platform/api/scheduler2/IActionClassResolver.java new file mode 100644 index 00000000000..1eefeab97a8 --- /dev/null +++ b/api/src/main/java/org/pentaho/platform/api/scheduler2/IActionClassResolver.java @@ -0,0 +1,39 @@ +/*! + * + * 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) 2023 Hitachi Vantara. All rights reserved. + * + */ +package org.pentaho.platform.api.scheduler2; + +/** + * This interface is used register and resolve action class name + */ +public interface IActionClassResolver { + /** + * This method is used to resolve a action class name and returns a bean id that is registered with this class name + * @param className + * @return bean id + */ + String resolve( String className ); + + /** + * This method provides a component way to register a bean id matching a action class name + * @param className + * @param beanId + */ + void register( String className, String beanId ); +} diff --git a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java index ecdaf1331d5..76132b52430 100644 --- a/core/src/main/java/org/pentaho/platform/util/ActionUtil.java +++ b/core/src/main/java/org/pentaho/platform/util/ActionUtil.java @@ -30,6 +30,7 @@ import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData; +import org.pentaho.platform.api.scheduler2.IActionClassResolver; import org.pentaho.platform.api.scheduler2.IEmailGroupResolver; import org.pentaho.platform.api.util.QuartzActionUtil; import org.pentaho.platform.api.workitem.IWorkItemLifecycleEventPublisher; @@ -339,10 +340,23 @@ static Class resolveActionClass( final String actionClassName, final String b return clazz; } } - // we will execute this only if the beanId is not provided, or if the beanId cannot be resolved - if ( !StringUtils.isEmpty( actionClassName ) ) { - clazz = Class.forName( actionClassName ); - return clazz; + try { + // we will execute this only if the beanId is not provided, or if the beanId cannot be resolved + if ( !StringUtils.isEmpty( actionClassName ) ) { + clazz = Class.forName( actionClassName ); + return clazz; + } + } catch ( ClassNotFoundException cnfe ) { + IActionClassResolver actionClassResolver = PentahoSystem.get( IActionClassResolver.class ); + if ( actionClassResolver != null ) { + String id = actionClassResolver.resolve( actionClassName ); + clazz = loadClass( id ); + if ( clazz != null ) { + return clazz; + } + } else { + throw cnfe; + } } } catch ( Throwable t ) { try { @@ -359,7 +373,11 @@ static Class resolveActionClass( final String actionClassName, final String b throw new ActionInvocationException( Messages.getInstance().getErrorString( "ActionUtil.ERROR_0002_FAILED_TO_CREATE_ACTION", StringUtils.isEmpty( beanId ) ? actionClassName : beanId ) ); } - + private static Class loadClass( String beanId ) throws PluginBeanException { + IPluginManager pluginManager = PentahoSystem.get( IPluginManager.class ); + Class clazz = pluginManager.loadClass( beanId ); + return clazz; + } /** * Returns an instance of {@link IAction} created from the provided parameters. * From b2517a6a6c41e2cf6d091206e6052ea25160e11c Mon Sep 17 00:00:00 2001 From: Ramaiz Mansoor Date: Mon, 1 Jan 2024 09:28:30 -0500 Subject: [PATCH 59/59] Revert "[BACKLOG-37897] - Update of pentaho.xml to support email sources" --- .../pentaho-solutions/system/pentaho.xml | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml index ebb28b3a009..6623321c078 100644 --- a/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml +++ b/assemblies/pentaho-solutions/src/main/resources-filtered/pentaho-solutions/system/pentaho.xml @@ -40,34 +40,28 @@ server.log DEBUG - - pentaho - - + org.pentaho.platform.plugin.services.cache.HvCacheRegionFactory