<commit_before>package util;

import controllers.Application;
import org.apache.commons.mail.EmailException;

import models.ResultFile;
import models.Workflow;
import models.WorkflowResult;
import models.WorkflowRun;
import org.kurator.akka.WorkflowRunner;
import org.kurator.akka.data.WorkflowProduct;
import play.Logger;

import java.io.*;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by lowery on 5/10/16.
 */
public class AsyncWorkflowRunnable implements Runnable {
    private WorkflowRunner runner;
    private WorkflowRun run;
    private ByteArrayOutputStream errStream;
    private ByteArrayOutputStream outStream;

    public synchronized void init(Workflow workflow, WorkflowRunner runner, ByteArrayOutputStream errStream, ByteArrayOutputStream outStream) {
        this.errStream = errStream;
        this.outStream = outStream;
        this.runner = runner;

        run = new WorkflowRun();
        run.user = Application.getCurrentUser();
        run.workflow = workflow;
        run.startTime = new Date();
        run.save();
    }

    public WorkflowRun getWorkflowRun() {
        return run;
    }

    public void run() {
        WorkflowResult result = new WorkflowResult();

        try {
            for (WorkflowProduct product : runner.getWorkflowProducts()) {
                String fileName = String.valueOf(product.value);
                File file = new File(fileName);

                if (file.exists()) {
                    ResultFile resultFile = new ResultFile();
                    resultFile.fileName = String.valueOf(product.value);
                    resultFile.label = product.label;

                    result.resultFiles.add(resultFile);
                } else {
                    Logger.error("artifact specified does not exist: " + fileName);
                }
            }

            File archive = File.createTempFile("artifacts_", ".zip");

            result.archivePath = archive.getAbsolutePath();

            result.errorText = new String(errStream.toByteArray());
            result.outputText = new String(outStream.toByteArray());
            result.save();

            run.result = result;
            run.endTime = new Date();
            run.save();

            createArchive(archive, run);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            ResultNotificationMailer mailer = new ResultNotificationMailer();
            mailer.sendNotification(run.user, run);
        
        } catch (EmailException e) { 
            // TODO: Handle exceptions related to sending the email
            System.out.println("Error sending notification email message: " + e.getMessage());
        }
    }

    private void createArchive(File archive, WorkflowRun run) {
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(archive));
            List<ResultFile> resultFiles = run.result.resultFiles;

            for (ResultFile resultFile : resultFiles) {
                File file = new File(resultFile.fileName);
                writeFile(file, out);
            }

            File readmeFile = createReadmeFile();

            File outputFile = File.createTempFile("output_log_", ".txt");
            File errorFile = File.createTempFile("error_log_", ".txt");

            // TODO: yaml file should be workflow yaml and not web app version
            //File yamlFile = new File(run.workflow.yamlFile);<commit_msg>Fixing bug that causes a workflow to be marked as done before the archive compression completes<commit_after>package util;

import controllers.Application;
import org.apache.commons.mail.EmailException;

import models.ResultFile;
import models.Workflow;
import models.WorkflowResult;
import models.WorkflowRun;
import org.kurator.akka.WorkflowRunner;
import org.kurator.akka.data.WorkflowProduct;
import play.Logger;

import java.io.*;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by lowery on 5/10/16.
 */
public class AsyncWorkflowRunnable implements Runnable {
    private WorkflowRunner runner;
    private WorkflowRun run;
    private ByteArrayOutputStream errStream;
    private ByteArrayOutputStream outStream;

    public synchronized void init(Workflow workflow, WorkflowRunner runner, ByteArrayOutputStream errStream, ByteArrayOutputStream outStream) {
        this.errStream = errStream;
        this.outStream = outStream;
        this.runner = runner;

        run = new WorkflowRun();
        run.user = Application.getCurrentUser();
        run.workflow = workflow;
        run.startTime = new Date();
        run.save();
    }

    public WorkflowRun getWorkflowRun() {
        return run;
    }

    public void run() {
        WorkflowResult result = new WorkflowResult();

        try {
            for (WorkflowProduct product : runner.getWorkflowProducts()) {
                String fileName = String.valueOf(product.value);
                File file = new File(fileName);

                if (file.exists()) {
                    ResultFile resultFile = new ResultFile();
                    resultFile.fileName = String.valueOf(product.value);
                    resultFile.label = product.label;

                    result.resultFiles.add(resultFile);
                } else {
                    Logger.error("artifact specified does not exist: " + fileName);
                }
            }

            File archive = File.createTempFile("artifacts_", ".zip");

            result.archivePath = archive.getAbsolutePath();

            result.errorText = new String(errStream.toByteArray());
            result.outputText = new String(outStream.toByteArray());
            result.save();

            createArchive(archive, run);

            run.result = result;
            run.endTime = new Date();
            run.save();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            ResultNotificationMailer mailer = new ResultNotificationMailer();
            mailer.sendNotification(run.user, run);
        
        } catch (EmailException e) { 
            // TODO: Handle exceptions related to sending the email
            System.out.println("Error sending notification email message: " + e.getMessage());
        }
    }

    private void createArchive(File archive, WorkflowRun run) {
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(archive));
            List<ResultFile> resultFiles = run.result.resultFiles;

            for (ResultFile resultFile : resultFiles) {
                File file = new File(resultFile.fileName);
                writeFile(file, out);
            }

            File readmeFile = createReadmeFile();

            File outputFile = File.createTempFile("output_log_", ".txt");
            File errorFile = File.createTempFile("error_log_", ".txt");

            // TODO: yaml file should be workflow yaml and not web app version
            //File yamlFile = new File(run.workflow.yamlFile);
{'fraction_non_alphanumeric': 0.09205020920502092, 'fraction_numerical': 0.001394700139470014, 'mean_word_length': 2.241862567811935, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3849917', 'n_tokens_mistral': 1849, 'n_tokens_neox': 1754, 'n_words': 460}