Package com.serotonin.m2m2.reports.web

Source Code of com.serotonin.m2m2.reports.web.ReportWorkItem

/*
    Copyright (C) 2014 Infinite Automation Systems Inc. All rights reserved.
    @author Matthew Lohbihler
*/
package com.serotonin.m2m2.reports.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.mail.internet.AddressException;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;

import com.serotonin.InvalidArgumentException;
import com.serotonin.io.StreamUtils;
import com.serotonin.m2m2.Common;
import com.serotonin.m2m2.db.dao.DataPointDao;
import com.serotonin.m2m2.db.dao.MailingListDao;
import com.serotonin.m2m2.db.dao.UserDao;
import com.serotonin.m2m2.i18n.TranslatableMessage;
import com.serotonin.m2m2.i18n.Translations;
import com.serotonin.m2m2.reports.ReportDao;
import com.serotonin.m2m2.reports.vo.ReportInstance;
import com.serotonin.m2m2.reports.vo.ReportPointVO;
import com.serotonin.m2m2.reports.vo.ReportVO;
import com.serotonin.m2m2.reports.web.ReportChartCreator.PointStatistics;
import com.serotonin.m2m2.rt.maint.work.EmailWorkItem;
import com.serotonin.m2m2.rt.maint.work.WorkItem;
import com.serotonin.m2m2.util.chart.ImageChartUtils;
import com.serotonin.m2m2.vo.DataPointVO;
import com.serotonin.m2m2.vo.User;
import com.serotonin.m2m2.vo.permission.Permissions;
import com.serotonin.util.ColorUtils;
import com.serotonin.web.mail.EmailAttachment;
import com.serotonin.web.mail.EmailContent;
import com.serotonin.web.mail.EmailInline;

/**
* This is a report work item that runs a report. It is added to the work queue by the ReportJob class.
*
* @author Matthew Lohbihler
*/
public class ReportWorkItem implements WorkItem {
    static final Log LOG = LogFactory.getLog(ReportWorkItem.class);

    //    private static UsageExpiryChecker USAGE_EXPIRY_CHECKER;

    @Override
    public int getPriority() {
        return WorkItem.PRIORITY_LOW;
    }

    public static void queueReport(ReportVO report) {
        LOG.debug("Queuing report with id " + report.getId());

        // Verify that the user is not disabled.
        User user = new UserDao().getUser(report.getUserId());
        if (user.isDisabled())
            return;

        // User is ok. Continue...
        ReportWorkItem item = new ReportWorkItem();

        // Create the database record in process.
        item.reportConfig = report;
        ReportInstance reportInstance = new ReportInstance(report);

        item.user = user;
        item.reportDao = new ReportDao();
        item.reportDao.saveReportInstance(reportInstance);

        // Start the report work item out of process.
        item.reportInstance = reportInstance;
        Common.backgroundProcessing.addWorkItem(item);

        LOG.debug("Queued report with id " + report.getId() + ", instance id " + reportInstance.getId());
    }

    ReportVO reportConfig;
    private User user;
    private ReportDao reportDao;
    private ReportInstance reportInstance;
    List<File> filesToDelete = new ArrayList<File>();

    @Override
    public void execute() {
        //        if (USAGE_EXPIRY_CHECKER == null)
        //            USAGE_EXPIRY_CHECKER = new UsageExpiryChecker("reports", 25, null);

        LOG.debug("Running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId());

        reportInstance.setRunStartTime(System.currentTimeMillis());
        reportDao.saveReportInstance(reportInstance);
        Translations translations = Common.getTranslations();

        // Create a list of DataPointVOs to which the user has permission.
        DataPointDao dataPointDao = new DataPointDao();
        List<ReportDao.PointInfo> points = new ArrayList<ReportDao.PointInfo>(reportConfig.getPoints().size());
        for (ReportPointVO reportPoint : reportConfig.getPoints()) {
            DataPointVO point = dataPointDao.getDataPoint(reportPoint.getPointId());
            if (point != null && Permissions.hasDataPointReadPermission(user, point)) {
                String colour = null;
                try {
                    if (!StringUtils.isBlank(reportPoint.getColour()))
                        colour = ColorUtils.toHexString(reportPoint.getColour()).substring(1);
                }
                catch (InvalidArgumentException e) {
                    // Should never happen since the colour would have been validated on save, so just let it go
                    // as null.
                }
                points.add(new ReportDao.PointInfo(point, colour, reportPoint.getWeight(), reportPoint
                        .isConsolidatedChart(), reportPoint.getPlotType()));
            }
        }

        int recordCount = 0;
        try {
            //            if (USAGE_EXPIRY_CHECKER.isExpired(true))
            //                recordCount = -2;
            //            else if (!points.isEmpty())
            //                recordCount = reportDao.runReport(reportInstance, points);
            if (!points.isEmpty()){
                if(Common.databaseProxy.getNoSQLProxy() == null)
                  recordCount = reportDao.runReportSQL(reportInstance, points);
                else
                  recordCount = reportDao.runReportNoSQL(reportInstance, points);
            }
        }
        catch (RuntimeException e) {
            recordCount = -1;
            throw e;
        }
        catch (Throwable e) {
            recordCount = -1;
            throw new RuntimeException("Report instance failed", e);
        }
        finally {
            reportInstance.setRunEndTime(System.currentTimeMillis());
            reportInstance.setRecordCount(recordCount);
            reportDao.saveReportInstance(reportInstance);
        }

        if (reportConfig.isEmail()) {
            String inlinePrefix = "R" + System.currentTimeMillis() + "-" + reportInstance.getId() + "-";

            // TODO should we create different instances of the email based upon language and timezone?

            // We are creating an email from the result. Create the content.
            final ReportChartCreator creator = new ReportChartCreator(translations, TimeZone.getDefault());
            creator.createContent(reportInstance, reportDao, inlinePrefix, reportConfig.isIncludeData());

            // Create the to list
            Set<String> addresses = new MailingListDao().getRecipientAddresses(reportConfig.getRecipients(),
                    new DateTime(reportInstance.getReportStartTime()));
            String[] toAddrs = addresses.toArray(new String[0]);

            // Create the email content object.
            EmailContent emailContent = new EmailContent(null, creator.getHtml(), Common.UTF8);

            // Add the consolidated chart
            if (creator.getImageData() != null)
                emailContent
                        .addInline(new EmailInline.ByteArrayInline(inlinePrefix + ReportChartCreator.IMAGE_CONTENT_ID,
                                creator.getImageData(), ImageChartUtils.getContentType()));

            // Add the point charts
            for (PointStatistics pointStatistics : creator.getPointStatistics()) {
                if (pointStatistics.getImageData() != null)
                    emailContent.addInline(new EmailInline.ByteArrayInline(inlinePrefix
                            + pointStatistics.getChartName(), pointStatistics.getImageData(), ImageChartUtils
                            .getContentType()));
            }

            // Add optional images used by the template.
            for (String s : creator.getInlineImageList())
                addImage(emailContent, s);

            // Check if we need to attach the data.
            if (reportConfig.isIncludeData()) {
                addFileAttachment(emailContent, reportInstance.getName() + ".csv", creator.getExportFile());
                addFileAttachment(emailContent, reportInstance.getName() + "Events.csv", creator.getEventFile());
                addFileAttachment(emailContent, reportInstance.getName() + "Comments.csv", creator.getCommentFile());
            }

            Runnable[] postEmail = null;
            if (reportConfig.isIncludeData()) {
                // See that the temp file(s) gets deleted after the email is sent.
                Runnable deleteTempFile = new Runnable() {
                    @Override
                    public void run() {
                        for (File file : filesToDelete) {
                            if (!file.delete())
                                LOG.warn("Temp file " + file.getPath() + " not deleted");
                        }
                    }
                };
                postEmail = new Runnable[] { deleteTempFile };
            }

            try {
                TranslatableMessage lm = new TranslatableMessage("ftl.scheduledReport", reportConfig.getName());
                String subject = creator.getSubject();
                if (subject == null)
                    subject = lm.translate(translations);
                EmailWorkItem.queueEmail(toAddrs, subject, emailContent, postEmail);
            }
            catch (AddressException e) {
                LOG.error(e);
            }
           
            if(reportConfig.isSchedule()){
              // Delete the report instance.
              reportDao.deleteReportInstance(reportInstance.getId(), user.getId());
            }
        }

        LOG.debug("Finished running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId());
    }

    private void addImage(EmailContent emailContent, String imagePath) {
        emailContent.addInline(new EmailInline.FileInline(imagePath, Common.getWebPath(imagePath)));
    }

    private void addFileAttachment(EmailContent emailContent, String name, File file) {
        if (file != null) {
            if (reportConfig.isZipData()) {
                try {
                    File zipFile = File.createTempFile("tempZIP", ".zip");
                    ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
                    zipOut.putNextEntry(new ZipEntry(name));

                    FileInputStream in = new FileInputStream(file);
                    StreamUtils.transfer(in, zipOut);
                    in.close();

                    zipOut.closeEntry();
                    zipOut.close();

                    emailContent.addAttachment(new EmailAttachment.FileAttachment(name + ".zip", zipFile));

                    filesToDelete.add(zipFile);
                }
                catch (IOException e) {
                    LOG.error("Failed to create zip file", e);
                }
            }
            else
                emailContent.addAttachment(new EmailAttachment.FileAttachment(name, file));

            filesToDelete.add(file);
        }
    }
}
TOP

Related Classes of com.serotonin.m2m2.reports.web.ReportWorkItem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.