/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details. * * Copyright 2005-2008 Pentaho Corporation. All rights reserved. * */ package org.pentaho.platform.repository.subscription; import java.io.IOException; import java.io.OutputStream; import java.text.DateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IContentGenerator; import org.pentaho.platform.api.engine.IMessageFormatter; import org.pentaho.platform.api.engine.IOutputHandler; import org.pentaho.platform.api.engine.IParameterProvider; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPluginManager; import org.pentaho.platform.api.engine.IRuntimeContext; import org.pentaho.platform.api.engine.IUserDetailsRoleListService; import org.pentaho.platform.api.engine.SubscriptionSchedulerException; import org.pentaho.platform.api.repository.IContentItem; import org.pentaho.platform.api.repository.ISchedule; import org.pentaho.platform.api.repository.ISubscribeContent; import org.pentaho.platform.api.repository.ISubscription; import org.pentaho.platform.api.repository.ISubscriptionRepository; import org.pentaho.platform.api.repository.SubscriptionRepositoryCheckedException; import org.pentaho.platform.engine.core.output.SimpleOutputHandler; import org.pentaho.platform.engine.core.solution.ActionInfo; import org.pentaho.platform.engine.core.solution.PentahoSessionParameterProvider; import org.pentaho.platform.engine.core.solution.SimpleParameterProvider; import org.pentaho.platform.engine.core.system.PentahoBase; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.core.system.StandaloneSession; import org.pentaho.platform.engine.core.system.UserSession; import org.pentaho.platform.engine.services.BaseRequestHandler; import org.pentaho.platform.repository.content.CoreContentRepositoryOutputHandler; import org.pentaho.platform.repository.messages.Messages; import org.pentaho.platform.util.UUIDUtil; import org.pentaho.platform.util.messages.LocaleHelper; public class SubscriptionExecute extends PentahoBase { private static final boolean debug = PentahoSystem.debug; private static final long serialVersionUID = -6053183867424885168L; private static final Log logger = LogFactory.getLog(SubscriptionExecute.class); private String logId; @Override public Log getLogger() { return SubscriptionExecute.logger; } @Override public String getLogId() { return logId; } public IPentahoSession getEffectiveUserSession(final String userName) { IUserDetailsRoleListService userDetailsRoleListService = PentahoSystem.get(IUserDetailsRoleListService.class); if (userDetailsRoleListService != null) { return userDetailsRoleListService.getEffectiveUserSession(userName, null); } else { UserSession us = new UserSession(userName, null, null); us.setAuthenticated(userName); return us; } } public void execute(final String scheduleReference, boolean isFinalFiring) { PentahoSystem.systemEntryPoint(); try { String sessionId = "scheduler-" + UUIDUtil.getUUIDAsString(); //$NON-NLS-1$ StandaloneSession scheduleSession = new StandaloneSession(scheduleReference, sessionId); ISubscriptionRepository subscriptionRepository = PentahoSystem.get(ISubscriptionRepository.class, scheduleSession); ISchedule sched = subscriptionRepository.getScheduleByScheduleReference(scheduleReference); if (sched == null) { error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0001_UNABLE_TO_GET_SCHEDULE", scheduleReference)); //$NON-NLS-1$ return; } Date lastExeTm = sched.getLastTrigger(); sched.setLastTrigger(new Date()); List<ISubscription> subscriptionList = subscriptionRepository.getSubscriptionsForSchedule(scheduleReference); info("FIRE: " + scheduleReference); //$NON-NLS-1$ for (int i = 0; i < subscriptionList.size(); ++i) { Subscription sub = (Subscription) subscriptionList.get(i); if (PentahoSystem.trace) { trace("" + sub); //$NON-NLS-1$ } Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.putAll(sub.getParameters()); ISubscribeContent subContent = sub.getContent(); ActionInfo contentInfo = ActionInfo.parseActionString(subContent.getActionReference()); String jobName = sub.getUser() + " : " + sub.getTitle(); //$NON-NLS-1$ IPentahoSession userSession = getEffectiveUserSession(sub.getUser()); // set the session so that anything who needs to access it will have // a single safe place to get one. in particular, some content generators // will need a session. PentahoSessionHolder.setSession(userSession); paramMap.put("solution", contentInfo.getSolutionName()); //$NON-NLS-1$ paramMap.put("path", contentInfo.getPath()); //$NON-NLS-1$ paramMap.put("action", contentInfo.getActionName()); //$NON-NLS-1$ paramMap.put("SUB_SCHEDULED_EXECUTE", "true"); //$NON-NLS-1$ //$NON-NLS-2$ paramMap.put("SUB_EXECUTE_TIME", sched.getLastTrigger()); //$NON-NLS-1$ paramMap.put("SUB_PREV_EXECUTE_TIME", lastExeTm); //$NON-NLS-1$ if (sched.isCronSchedule()) { paramMap.put("SUB_SCHEDULE", sched.getCronString()); //$NON-NLS-1$ } else if (sched.isRepeatSchedule()) { if (null != sched.getRepeatCount()) { paramMap.put("SUB_SCHEDULE_REPEAT_COUNT", sched.getRepeatCount()); //$NON-NLS-1$ } paramMap.put("SUB_SCHEDULE_REPEAT_TIME", sched.getRepeatInterval()); //$NON-NLS-1$ } else { throw new IllegalStateException(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0005_INVALID_CRON_OR_REPEAT", sched.getId())); //$NON-NLS-1$ } DateFormat fmt = SubscriptionHelper.getDateTimeFormatter(); Date d = sched.getStartDate(); if (null != d) { paramMap.put("SUB_START_DATE", fmt.format(d)); //$NON-NLS-1$ } d = sched.getEndDate(); if (null != d) { paramMap.put("SUB_END_DATE", fmt.format(d)); //$NON-NLS-1$ } paramMap.put("SUB_SCHEDULE_NAME", sched.getTitle()); //$NON-NLS-1$ paramMap.put("SUB_SCHEDULE_REF", sched.getScheduleReference()); //$NON-NLS-1$ paramMap.put("SUB_SCHEDULE_DESC", sched.getDescription()); //$NON-NLS-1$ paramMap.put("SUB_NAME", sub.getTitle()); //$NON-NLS-1$ paramMap.put("SUB_ID", sub.getId()); //$NON-NLS-1$ paramMap.put("useContentRepository", Boolean.TRUE); //$NON-NLS-1$ paramMap.put("content-handler-pattern", PentahoSystem.getApplicationContext().getBaseUrl() + "GetContent?id={0}"); //$NON-NLS-1$ //$NON-NLS-2$ paramMap.put("SUB_DESTINATION", sub.getDestination()); execute(jobName, paramMap, userSession); } // end while loop if (isFinalFiring) { // done with this schedule, delete it from the Subscription Repository try { SubscriptionRepositoryHelper.deleteScheduleContentAndSubscription(subscriptionRepository, sched); } catch (SubscriptionRepositoryCheckedException e) { logger.error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0004_SCHEDULE_DELETE_FAILED", scheduleReference), e); //$NON-NLS-1$ } catch (SubscriptionSchedulerException e) { logger.error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0004_SCHEDULE_DELETE_FAILED", scheduleReference), e); //$NON-NLS-1$ } } } finally { PentahoSystem.systemExitPoint(); } } private void execute(final String jobName, final Map<String, Object> parametersMap, final IPentahoSession userSession) { try { LocaleHelper.setLocale(Locale.getDefault()); logId = "Pro Subscription:" + jobName; //$NON-NLS-1$ Date now = new Date(); SubscriptionExecute.logger.info(Messages.getInstance().getString("SubscriptionExecute.INFO_TRIGGER_TIME", jobName, //$NON-NLS-1$ DateFormat.getDateInstance().format(now), DateFormat.getTimeInstance().format(now))); String solutionName = (String) parametersMap.get("solution"); //$NON-NLS-1$ String actionPath = (String) parametersMap.get("path"); //$NON-NLS-1$ String actionName = (String) parametersMap.get("action"); //$NON-NLS-1$ String subscriptionDestination = (String) parametersMap.get("SUB_DESTINATION"); String instanceId = null; String processId = this.getClass().getName(); if (solutionName == null) { error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0001_SOLUTION_NAME_MISSING")); //$NON-NLS-1$ return; } if (actionPath == null) { error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0002_ACTION_PATH_MISSING")); //$NON-NLS-1$ return; } if (actionName == null) { error(Messages.getInstance().getErrorString("SubscriptionExecute.ERROR_0003_ACTION_NAME_MISSING")); //$NON-NLS-1$ return; } if (SubscriptionExecute.debug) { if (SubscriptionExecute.debug) { debug(Messages.getInstance().getString("SubscriptionExecute.DEBUG_EXECUTION_INFO", solutionName + "/" + actionPath + "/" + actionName)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } boolean ignoreSubscriptionOutput = "true".equalsIgnoreCase((String) parametersMap.get("SUB_IGNORE_OUTPUT")); //$NON-NLS-1$ //$NON-NLS-2$ String subscriptionId = (String) parametersMap.get("SUB_ID"); //$NON-NLS-1$ String subscriptionName = (String) parametersMap.get("SUB_NAME"); //$NON-NLS-1$ IOutputHandler outputHandler = null; if (ignoreSubscriptionOutput) { outputHandler = new SimpleOutputHandler((OutputStream) null, false); } else { String contentPath = SubscriptionHelper.getSubscriptionOutputLocation(solutionName, actionPath, actionName); outputHandler = new CoreContentRepositoryOutputHandler(contentPath, subscriptionId, solutionName, userSession); ((CoreContentRepositoryOutputHandler) outputHandler).setWriteMode(IContentItem.WRITEMODE_KEEPVERSIONS); } parametersMap.put("useContentRepository", Boolean.TRUE); //$NON-NLS-1$ String contentUrlPattern = PentahoSystem.getApplicationContext().getBaseUrl(); if (!contentUrlPattern.endsWith("/")) { //$NON-NLS-1$ contentUrlPattern += "/"; //$NON-NLS-1$ } contentUrlPattern += "GetContent?id={0}"; //$NON-NLS-1$ parametersMap.put("content-handler-pattern", contentUrlPattern); //$NON-NLS-1$ SimpleParameterProvider parameterProvider = new SimpleParameterProvider(parametersMap); IParameterProvider sessionParams = new PentahoSessionParameterProvider(userSession); int lastDot = actionName.lastIndexOf('.'); String type = actionName.substring(lastDot + 1); IPluginManager pluginManager = PentahoSystem.get(IPluginManager.class, userSession); IContentGenerator generator = pluginManager.getContentGeneratorForType(type, userSession); if (generator == null) { BaseRequestHandler requestHandler = new BaseRequestHandler(userSession, null, outputHandler, parameterProvider, null); requestHandler.setParameterProvider(IParameterProvider.SCOPE_SESSION, sessionParams); requestHandler.setInstanceId(instanceId); requestHandler.setProcessId(processId); requestHandler.setAction(actionPath, actionName); requestHandler.setSolutionName(solutionName); IRuntimeContext rt = null; try { rt = requestHandler.handleActionRequest(0, 0); if (!StringUtils.isEmpty(subscriptionDestination)) { emailContent(outputHandler, subscriptionName, solutionName, actionName, instanceId, subscriptionDestination); } else if (!ignoreSubscriptionOutput && !outputHandler.isResponseExpected()) { if ((rt != null) && (rt.getStatus() == IRuntimeContext.RUNTIME_STATUS_SUCCESS)) { StringBuffer buffer = new StringBuffer(); PentahoSystem.get(IMessageFormatter.class, userSession).formatSuccessMessage("text/html", rt, buffer, false); //$NON-NLS-1$ writeMessage(buffer.toString(), outputHandler, subscriptionName, solutionName, actionName, instanceId, userSession); } else { // we need an error message... StringBuffer buffer = new StringBuffer(); PentahoSystem.get(IMessageFormatter.class, userSession).formatFailureMessage("text/html", rt, buffer, requestHandler.getMessages()); //$NON-NLS-1$ writeMessage(buffer.toString(), outputHandler, subscriptionName, solutionName, actionName, instanceId, userSession); } } } finally { if (rt != null) { rt.dispose(); } } } else { generator.setOutputHandler(outputHandler); generator.setItemName(actionName); generator.setInstanceId(instanceId); generator.setSession(userSession); Map<String, IParameterProvider> parameterProviders = new HashMap<String, IParameterProvider>(); parameterProviders.put(IParameterProvider.SCOPE_REQUEST, parameterProvider); parameterProviders.put(IParameterProvider.SCOPE_SESSION, new PentahoSessionParameterProvider(userSession)); generator.setParameterProviders(parameterProviders); try { generator.createContent(); // we succeeded if (!StringUtils.isEmpty(subscriptionDestination)) { emailContent(outputHandler, subscriptionName, solutionName, actionName, instanceId, subscriptionDestination); } else if (!ignoreSubscriptionOutput && !outputHandler.isResponseExpected()) { String message = Messages.getInstance().getString("SubscriptionExecute.DEBUG_FINISHED_EXECUTION", jobName); //$NON-NLS-1$ writeMessage(message.toString(), outputHandler, subscriptionName, solutionName, actionName, instanceId, userSession); } } catch (Exception e) { e.printStackTrace(); // we need an error message... if (!ignoreSubscriptionOutput && !outputHandler.isResponseExpected()) { String message = Messages.getInstance().getString("PRO_SUBSCRIPTREP.EXCEPTION_WITH_SCHEDULE", jobName); //$NON-NLS-1$ writeMessage(message.toString(), outputHandler, subscriptionName, solutionName, actionName, instanceId, userSession); } } } if (SubscriptionExecute.debug) { SubscriptionExecute.logger.debug(Messages.getInstance().getString("SubscriptionExecute.DEBUG_FINISHED_EXECUTION", jobName)); //$NON-NLS-1$ } } catch (Throwable t) { SubscriptionExecute.logger.error("Error Executing Job", t); //$NON-NLS-1$ } } protected void writeMessage(String message, IOutputHandler outputHandler, String subscriptionName, String solutionName, String fileName, String instanceId, IPentahoSession userSession) { IContentItem outputContentItem = outputHandler.getOutputContentItem(IOutputHandler.RESPONSE, IOutputHandler.CONTENT, subscriptionName, null, solutionName, instanceId, "text/html"); //$NON-NLS-1$ outputContentItem.setMimeType("text/html"); //$NON-NLS-1$ try { OutputStream os = outputContentItem.getOutputStream(fileName); os.write(message.getBytes(LocaleHelper.getSystemEncoding())); outputContentItem.closeOutputStream(); } catch (IOException ex) { error(ex.getLocalizedMessage()); } } protected void emailContent(IOutputHandler outputHandler, String subscriptionName, String solutionName, String fileName, String instanceId, String destination) { IContentItem outputContentItem = outputHandler.getOutputContentItem(IOutputHandler.RESPONSE, IOutputHandler.CONTENT, subscriptionName, null, solutionName, instanceId, null); //$NON-NLS-1$ fileName = subscriptionName; String fileDate = DateFormat.getDateInstance(DateFormat.SHORT).format(outputContentItem.getFileDateTime()); if ("application/pdf".equals(outputContentItem.getMimeType())) { fileName += ".pdf"; } else if ("text/html".equals(outputContentItem.getMimeType())) { fileName += ".html"; } else if ("text/csv".equals(outputContentItem.getMimeType())) { fileName += ".csv"; } else if ("application/vnd.ms-excel".equals(outputContentItem.getMimeType())) { fileName += ".xls"; } SubscriptionEmailContent emailer = new SubscriptionEmailContent(outputContentItem.getDataSource(), fileName, subscriptionName, destination); if (!emailer.send()) { SubscriptionExecute.logger.error("Problem sending subscription email."); } } }