/** * IRODSTasks.java * Author: Francesco Gallo (gallo@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.irods; import it.eurix.archtools.data.DataException; import it.eurix.archtools.data.model.AIP; 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.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.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Map; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.irods.jargon.core.connection.IRODSAccount; import org.irods.jargon.core.exception.JargonException; import org.irods.jargon.core.packinstr.TransferOptions; import org.irods.jargon.core.pub.DataObjectAO; import org.irods.jargon.core.pub.DataTransferOperations; import org.irods.jargon.core.pub.IRODSAccessObjectFactory; import org.irods.jargon.core.pub.IRODSFileSystem; import org.irods.jargon.core.pub.domain.DataObject; import org.irods.jargon.core.pub.io.IRODSFile; import org.irods.jargon.core.pub.io.IRODSFileFactory; import org.irods.jargon.core.pub.io.IRODSFileInputStream; import org.irods.jargon.core.transfer.DefaultTransferControlBlock; import org.irods.jargon.core.transfer.TransferControlBlock; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.prestoprime.datamanagement.P4DataManager; @WfPlugin(name = "IRODSPlugin") public class IRODSTasks { private static final Logger logger = LoggerFactory.getLogger(IRODSTasks.class); @WfService(name = "irods_put", version = "2.0.0") public void put(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // get static parameters String host = sParams.get("irods.host"); int port = Integer.parseInt(sParams.get("irods.port")); String username = sParams.get("irods.username"); String password = sParams.get("irods.password"); String homeDir = sParams.get("irods.home.dir"); String zone = sParams.get("irods.zone"); String defaultResource = sParams.get("irods.default.resource"); // get dynamic parameters String sipID = dParamsString.get("sipID"); SIP sip = null; try { IRODSFileSystem irodsFileSystem = IRODSFileSystem.instance(); sip = P4DataManager.getInstance().getSIPByID(sipID); IRODSAccount account = IRODSAccount.instance(host, port, username, password, homeDir, zone, defaultResource); IRODSAccessObjectFactory accessObjectFactory = irodsFileSystem.getIRODSAccessObjectFactory(); IRODSFileFactory fileFactory = accessObjectFactory.getIRODSFileFactory(account); TransferOptions transferOptions = new TransferOptions(); transferOptions.setComputeAndVerifyChecksumAfterTransfer(true); TransferControlBlock transferControlBlock = DefaultTransferControlBlock.instance(); transferControlBlock.setTransferOptions(transferOptions); DataTransferOperations dataTransferOperations = irodsFileSystem.getIRODSAccessObjectFactory().getDataTransferOperations(account); List<String> formats = sip.getAVFormats(); for (String format : formats) { String localFilePath = sip.getAVMaterial(format, "FILE").get(0); File localFile = new File(localFilePath); IRODSFile irodsFile = fileFactory.instanceIRODSFile(sip.getId() + localFilePath.substring(localFilePath.lastIndexOf("."))); dataTransferOperations.putOperation(localFile, irodsFile, null, transferControlBlock); String irodsFilePath = irodsFile.getAbsolutePath(); DataObjectAO dataObjectAO = accessObjectFactory.getDataObjectAO(account); DataObject dataObject = dataObjectAO.findByAbsolutePath(irodsFilePath); logger.debug("Transferred IRODSFile " + irodsFilePath + " size: " + dataObject.getDataSize() + " MD5: " + dataObject.getChecksum()); sip.addFile(format, "IRODS", irodsFilePath, dataObject.getChecksum(), dataObject.getDataSize()); irodsFileSystem.close(); } } catch (JargonException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to connect with IRODS server or to create transfer object..."); } catch (DataException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve SIP..."); } catch (IPException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AV Material..."); } finally { P4DataManager.getInstance().releaseIP(sip); } } @WfService(name = "irods_get", version = "2.0.0") public void get(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // get static parameters String host = sParams.get("irods.host"); int port = Integer.parseInt(sParams.get("irods.port")); String username = sParams.get("irods.username"); String password = sParams.get("irods.password"); String homeDir = sParams.get("irods.home.dir"); String zone = sParams.get("irods.zone"); String defaultResource = sParams.get("irods.default.resource"); // get dynamic parameters String dipID = dParamsString.get("dipID"); String targetFolder = dParamsString.get("targetFolder"); IRODSFileSystem irodsFileSystem = null; try { DIP dip = P4DataManager.getInstance().getDIPByID(dipID); String irodsFilePath = dip.getAVMaterial("application/mxf", "IRODS").get(0); irodsFileSystem = IRODSFileSystem.instance(); IRODSAccount account = IRODSAccount.instance(host, port, username, password, homeDir, zone, defaultResource); IRODSFileFactory fileFactory = irodsFileSystem.getIRODSFileFactory(account); logger.debug("IRODS File Path: " + irodsFilePath); //IRODSFileInputStream sourceFileIS = fileFactory.instanceIRODSFileInputStream(irodsFilePath); File targetFile = new File(targetFolder, FilenameUtils.getName(irodsFilePath)); //IOUtils.copy(sourceFileIS, new FileOutputStream(targetFile)); //new stuff for parallel transfer using iRODS TransferOptions transferOptions = new TransferOptions(); transferOptions.setComputeAndVerifyChecksumAfterTransfer(true); TransferControlBlock transferControlBlock = DefaultTransferControlBlock.instance(); transferControlBlock.setTransferOptions(transferOptions); DataTransferOperations dataTransferOperations = irodsFileSystem.getIRODSAccessObjectFactory().getDataTransferOperations(account); IRODSFile irodsFile = fileFactory.instanceIRODSFile(irodsFilePath); dataTransferOperations.getOperation(irodsFile, targetFile, null, transferControlBlock); //end new stuff } catch (JargonException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to connect with IRODS..."); } catch (DataException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve SIP..."); } catch (IPException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AV Material..."); } /*catch (IOException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to execute file operation..."); } */finally { try { if (irodsFileSystem != null) irodsFileSystem.close(); } catch (JargonException e) { } } } @WfService(name = "irods_make_consumer_copy", version = "2.0.0") public void makeConsumerCopy(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { if (!Boolean.parseBoolean(dParamsString.get("isCopied"))) { // get static parameters String host = sParams.get("irods.host"); int port = Integer.parseInt(sParams.get("irods.port")); String username = sParams.get("irods.username"); String password = sParams.get("irods.password"); String homeDir = sParams.get("irods.home.dir"); String zone = sParams.get("irods.zone"); String defaultResource = sParams.get("irods.default.resource"); String destVolume = sParams.get("dest.path.volume").trim(); String destFolder = sParams.get("dest.path.folder").trim(); String outputFolder = destVolume + File.separator + destFolder; // get dynamic parameters String dipID = dParamsString.get("id"); String mimetype = dParamsString.get("mimetype"); IRODSFileSystem irodsFileSystem = null; DIP dip = null; try { dip = P4DataManager.getInstance().getDIPByID(dipID); // get MQ file String videoFile = null; if (mimetype != null) { List<String> videoFileList = dip.getAVMaterial(mimetype, "IRODS"); if (videoFileList.size() > 0) { videoFile = videoFileList.get(0); irodsFileSystem = IRODSFileSystem.instance(); IRODSAccount account = IRODSAccount.instance(host, port, username, password, homeDir, zone, defaultResource); IRODSFileFactory fileFactory = irodsFileSystem.getIRODSFileFactory(account); IRODSFileInputStream sourceFileIS = fileFactory.instanceIRODSFileInputStream(videoFile); String targetFileName = dipID + videoFile.substring(videoFile.lastIndexOf(".")); IOUtils.copy(sourceFileIS, new FileOutputStream(new File(outputFolder, targetFileName))); dParamsString.put("isCopied", "true"); dParamsString.put("target.file.name", targetFileName); } } } catch (JargonException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to connect with IRODS..."); } catch (DataException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve SIP..."); } catch (IPException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AV Material..."); } catch (IOException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to execute file operation..."); } finally { try { if (irodsFileSystem != null) irodsFileSystem.close(); } catch (JargonException e) { } } } } @WfService(name = "irods_fixity_restore", version = "2.0.0") public void fixityRestore(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // get static parameters String host = sParams.get("irods.host"); int port = Integer.parseInt(sParams.get("irods.port")); String username = sParams.get("irods.username"); String password = sParams.get("irods.password"); String homeDir = sParams.get("irods.home.dir"); String zone = sParams.get("irods.zone"); String defaultResource = sParams.get("irods.default.resource"); // get dynamic parameters String aipID = dParamsString.get("aipID"); String format = dParamsString.get("toBeRestored"); if (format != null) { IRODSFileSystem irodsFileSystem = null; AIP aip = null; try { aip = P4DataManager.getInstance().getAIPByID(aipID); List<String> videoFileList = aip.getAVMaterial(format, "FILE"); List<String> videoIRODSList = aip.getAVMaterial(format, "IRODS"); if (videoFileList.size() > 0 && videoIRODSList.size() > 0) { irodsFileSystem = IRODSFileSystem.instance(); IRODSAccount account = IRODSAccount.instance(host, port, username, password, homeDir, zone, defaultResource); IRODSFileFactory fileFactory = irodsFileSystem.getIRODSFileFactory(account); File illVideo = new File(videoFileList.get(0)); IRODSFileInputStream healthyVideo = fileFactory.instanceIRODSFileInputStream(videoIRODSList.get(0)); IOUtils.copy(healthyVideo, new FileOutputStream(illVideo)); JSONObject result = new JSONObject(); result.put("status", "restored"); result.put("from", videoIRODSList.get(0)); result.put("to", illVideo.getAbsolutePath()); result.put("MD5", aip.getChecksum(format, "MD5")); dParamsString.put("result", result.toString()); dParamsString.remove("toBeRestored"); } } catch (JargonException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to connect with IRODS..."); } catch (DataException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve SIP..."); } catch (IPException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AV Material..."); } catch (IOException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to execute file operation..."); } catch (JSONException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to create JSON response..."); } finally { P4DataManager.getInstance().releaseIP(aip); try { if (irodsFileSystem != null) irodsFileSystem.close(); } catch (JargonException e) { } } } } }