eu.prestoprime.plugin.p4.CopyTasks.java Source code

Java tutorial

Introduction

Here is the source code for eu.prestoprime.plugin.p4.CopyTasks.java

Source

/**
 * CopyTasks.java
 * Author: Francesco Rosso (rosso@eurix.it)
 * 
 * This file is part of PrestoPRIME Preservation Platform (P4).
 * 
 * Copyright (C) 2012 EURIX Srl, Torino, Italy
 *  
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * 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.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.prestoprime.plugin.p4;

import it.eurix.archtools.data.DataException;
import it.eurix.archtools.data.model.DIP;
import it.eurix.archtools.data.model.IPException;
import it.eurix.archtools.data.model.SIP;
import it.eurix.archtools.tool.ToolException;
import it.eurix.archtools.tool.ToolOutput;
import it.eurix.archtools.tool.impl.MessageDigestExtractor;
import it.eurix.archtools.workflow.exceptions.TaskExecutionFailedException;
import it.eurix.archtools.workflow.plugin.WfPlugin;
import it.eurix.archtools.workflow.plugin.WfPlugin.WfService;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import eu.prestoprime.conf.ConfigurationManager;
import eu.prestoprime.conf.P4PropertyManager.P4Property;
import eu.prestoprime.datamanagement.P4DataManager;

@WfPlugin(name = "P4Plugin")
public class CopyTasks {

    private static final Logger logger = LoggerFactory.getLogger(CopyTasks.class);

    @WfService(name = "configure_storage", version = "1.0.0")
    public void configureStorage(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        String sipID = dParamsString.get("sipID");
        if (sipID == null)
            sipID = dParamsString.get("aipID");

        String p4storeFolder = ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_STORAGE_VOLUME)
                + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_STORAGE_FOLDER)
                + File.separator + sipID;
        dParamsString.put("p4storeFolder", p4storeFolder);

        String videosFolder = p4storeFolder + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_VIDEOS_FOLDER);
        new File(videosFolder).mkdirs();
        dParamsString.put("videosFolder", videosFolder);

        String framesFolder = p4storeFolder + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_FRAMES_FOLDER);
        new File(framesFolder).mkdirs();
        dParamsString.put("framesFolder", framesFolder);

        String graphFolder = p4storeFolder + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_GRAPH_FOLDER);
        new File(graphFolder).mkdirs();
        dParamsString.put("graphFolder", graphFolder);
    }

    @WfService(name = "master_file_first_copy", version = "2.0.0")
    public void masterFileFirstCopy(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        // get sipID
        String sipID = dParamsString.get("sipID");

        SIP sip = null;
        try {
            // get sip
            sip = P4DataManager.getInstance().getSIPByID(sipID);

            String inputVideo = null;

            // get MQ file
            String[] formats = sParams.get("MQformats").split(",");
            for (String format : formats) {

                List<String> videoFileList = sip.getAVMaterial(format, "FILE");
                if (videoFileList.size() > 0) {
                    inputVideo = videoFileList.get(0);
                    String outputVideoName = inputVideo.substring(inputVideo.lastIndexOf(File.separator) + 1);
                    String outputVideo = dParamsString.get("videosFolder") + File.separator + outputVideoName;

                    File inputFile = new File(inputVideo);
                    File outputFile = new File(outputVideo);

                    if (!outputFile.exists()) {
                        outputFile.createNewFile();
                    }
                    FileChannel source = new FileInputStream(inputFile).getChannel();
                    FileChannel destination = new FileOutputStream(outputFile).getChannel();
                    destination.transferFrom(source, 0, source.size());

                    // MD5
                    MessageDigestExtractor mde = new MessageDigestExtractor();
                    ToolOutput<MessageDigestExtractor.AttributeType> output = mde.extract(outputVideo);
                    String md5sum = output.getAttribute(MessageDigestExtractor.AttributeType.MD5);

                    // update SIP
                    sip.addFile(format, "FILE", outputVideo, md5sum, new File(outputVideo).length());

                    break;
                }
            }
            if (inputVideo == null) {
                throw new TaskExecutionFailedException("Unable to find supported MQ format...");
            }
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to retrieve the SIP...");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to retrieve MQ file from SIP...");
        } catch (IOException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to copy MQ file...");
        } catch (ToolException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to compute MD5 for WebM video file...");
        } finally {
            P4DataManager.getInstance().releaseIP(sip);
        }
    }

    @WfService(name = "master_file_second_copy", version = "2.0.0")
    public void masterFileSecondCopy(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        // get sipID
        String sipID = dParamsString.get("sipID");

        SIP sip = null;
        try {
            // get sip
            sip = P4DataManager.getInstance().getSIPByID(sipID);

            String inputVideo = null;

            // get MQ file
            String[] formats = sParams.get("MQformats").split(",");
            for (String format : formats) {

                List<String> videoFileList = sip.getAVMaterial(format, "FILE");
                if (videoFileList.size() > 0) {
                    inputVideo = videoFileList.get(0);

                    String outputFolder = sParams.get("second.local.copy.folder") + File.separator + sipID;
                    new File(outputFolder).mkdirs();
                    String outputVideoName = inputVideo.substring(inputVideo.lastIndexOf(File.separator) + 1);
                    String outputVideo = outputFolder + File.separator + outputVideoName;

                    File inputFile = new File(inputVideo);
                    File outputFile = new File(outputVideo);

                    if (!outputFile.exists()) {
                        outputFile.createNewFile();
                    }
                    FileChannel source = new FileInputStream(inputFile).getChannel();
                    FileChannel destination = new FileOutputStream(outputFile).getChannel();
                    destination.transferFrom(source, 0, source.size());

                    // MD5
                    MessageDigestExtractor mde = new MessageDigestExtractor();
                    ToolOutput<MessageDigestExtractor.AttributeType> output = mde.extract(outputVideo);
                    String md5sum = output.getAttribute(MessageDigestExtractor.AttributeType.MD5);

                    // update SIP
                    sip.addFile(format, "FILE-BCK", outputVideo, md5sum, new File(outputVideo).length());

                    break;
                }
            }
            if (inputVideo == null) {
                throw new TaskExecutionFailedException("Unable to find supported MQ format...");
            }
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to retrieve the SIP...");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to retrieve MQ file from SIP...");
        } catch (IOException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to copy MQ file...");
        } catch (ToolException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to compute MD5 for WebM video file...");
        } finally {
            P4DataManager.getInstance().releaseIP(sip);
        }
    }

    @WfService(name = "find_local_master_file", version = "2.2.0")
    public void findLocalMasterFile(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        String sourceFilePath = dParamsString.get("source.file.path");
        if (sourceFilePath == null) {
            // not set yet, find local master quality FILE

            String dipID = dParamsString.get("dipID");

            DIP dip = null;
            try {
                dip = P4DataManager.getInstance().getDIPByID(dipID);

                String[] MQFormats = sParams.get("MQformats").split(",");
                for (String MQFormat : MQFormats) {
                    List<String> AVMaterialList = dip.getAVMaterial(MQFormat, "FILE");
                    if (AVMaterialList.size() > 0) {
                        String AVMaterial = AVMaterialList.get(0);
                        AVMaterial = AVMaterial.replace(
                                ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_PLACEHOLDER),
                                ConfigurationManager.getPropertyInstance()
                                        .getProperty(P4Property.P4_STORAGE_VOLUME));

                        logger.debug("Found local MQ file: " + AVMaterial + "...");
                        dParamsString.put("source.file.path", AVMaterial);
                        dParamsString.put("source.file.type", "FILE");
                        dParamsString.put("source.file.mimetype", MQFormat);

                        break;
                    }
                }
            } catch (DataException e) {
                e.printStackTrace();
            } catch (IPException e) {
                e.printStackTrace();
            }
        }
    }

    @WfService(name = "make_consumer_copy", version = "2.0.0")
    public void makeConsumerCopy(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamFile) throws TaskExecutionFailedException {

        if (!Boolean.parseBoolean(dParamsString.get("isCopied"))) {

            // retrieve static params
            String destVolume = sParams.get("dest.path.volume").trim();
            String destFolder = sParams.get("dest.path.folder").trim();

            // retrieve dynamic params
            String dipID = dParamsString.get("id");
            String mimetype = dParamsString.get("mimetype");

            String outputFolder = destVolume + File.separator + destFolder;

            try {
                DIP dip = P4DataManager.getInstance().getDIPByID(dipID);

                // get MQ file
                String videoFile = null;

                if (mimetype != null) {
                    List<String> videoFileList = dip.getAVMaterial(mimetype, "FILE");

                    if (videoFileList.size() > 0) {
                        videoFile = videoFileList.get(0);

                        File sourceFile = new File(videoFile);

                        if (!sourceFile.canRead() || !sourceFile.isFile())
                            throw new TaskExecutionFailedException("Unable to read source video file...");

                        File targetDir = new File(outputFolder);
                        targetDir.mkdirs();

                        if (!targetDir.canWrite())
                            throw new TaskExecutionFailedException("Unable to write to output dir " + outputFolder);

                        String targetFileName = dipID + videoFile.substring(videoFile.lastIndexOf("."));
                        File targetFile = new File(outputFolder, targetFileName);

                        FileInputStream in = new FileInputStream(sourceFile);
                        FileOutputStream out = new FileOutputStream(targetFile);

                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = in.read(buffer)) != -1)
                            out.write(buffer, 0, bytesRead);

                        in.close();
                        out.close();

                        dParamsString.put("isCopied", "true");
                        dParamsString.put("target.file.name", targetFileName);

                        logger.debug("Consumer copy available at: " + targetFile.getAbsolutePath());
                    }
                }
            } catch (DataException e) {
                e.printStackTrace();
                throw new TaskExecutionFailedException("Unable to retrieve DIP with id: " + dipID);
            } catch (IPException | FileNotFoundException e) {
                e.printStackTrace();
                throw new TaskExecutionFailedException("Unable to retrieve MQ file");
            } catch (IOException e) {
                e.printStackTrace();
                throw new TaskExecutionFailedException("Unable to create consumer copy");
            }
        }
    }

    @WfService(name = "check_consumer_copy", version = "2.0.5")
    public void checkConsumerCopy(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        if (Boolean.parseBoolean(dParamsString.get("isCopied"))) {
            String dipID = dParamsString.get("id");
            String mimeType = dParamsString.get("mimetype");

            String p4url = ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_URL);
            String targetFileName = dParamsString.get("target.file.name");
            String destVolume = sParams.get("dest.path.volume").trim();
            String destFolder = sParams.get("dest.path.folder").trim();
            String outputFolder = destVolume + File.separator + destFolder;

            try {
                DIP dip = P4DataManager.getInstance().getDIPByID(dipID);

                JSONObject json = new JSONObject();

                json.put("file", targetFileName);
                json.put("CIFS", "//" + new URL(p4url).getHost() + "/" + destFolder);
                json.put("URL", p4url + "/" + destFolder + "/" + targetFileName);

                String MD5 = dip.getChecksum(mimeType, "MD5");
                if (MD5 != null) {
                    File targetFile = new File(outputFolder, targetFileName);
                    MessageDigestExtractor mde = new MessageDigestExtractor();
                    ToolOutput<MessageDigestExtractor.AttributeType> output = mde
                            .extract(targetFile.getAbsolutePath());
                    String currentMD5 = output.getAttribute(MessageDigestExtractor.AttributeType.MD5);
                    if (!currentMD5.equals(MD5))
                        throw new TaskExecutionFailedException("MD5 doesn't correspond...");
                    else
                        json.put("MD5", MD5);
                }

                dParamsString.put("result", json.toString());
            } catch (JSONException e) {
                dParamsString.put("result", "Unable to print output file information...");
            } catch (DataException | IPException e) {
                throw new TaskExecutionFailedException("Unable to retrieve the DIP...");
            } catch (MalformedURLException e) {
                throw new TaskExecutionFailedException("Malformed URL...");
            } catch (ToolException e) {
                throw new TaskExecutionFailedException("Unable to extract the checksum...");
            }
        } else {
            throw new TaskExecutionFailedException("Unable to find any file with requested mimetype...");
        }
    }
}