/** * QATasks.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.qa; 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.workflow.exceptions.TaskExecutionFailedException; import it.eurix.archtools.workflow.plugin.WfPlugin; import it.eurix.archtools.workflow.plugin.WfPlugin.WfService; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.http.HttpEntity; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import eu.prestoprime.datamanagement.P4DataManager; @WfPlugin(name = "QAPlugin") public class QATasks { private static final Logger logger = LoggerFactory.getLogger(QATasks.class); @WfService(name = "qa_upload", version = "0.8.0") public void upload(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // retrieve dynamic params String dipID = dParamsString.get("id"); // retrieve static params String baseUNC = sParams.get("baseUNC"); try { // get AIP DIP dip = P4DataManager.getInstance().getDIPByID(dipID); // get MQ file String videoFile = null; String[] MQformats = sParams.get("MQformats").split(","); logger.debug("Checking for MQ formats: " + MQformats.toString()); for (String format : MQformats) { List<String> videoFileList = dip.getAVMaterial(format, "FILE"); if (videoFileList.size() > 0) { videoFile = videoFileList.get(0); break; } } if (videoFile == null) { throw new TaskExecutionFailedException("Unable to find supported MQ format..."); } // compute mediaURI File file = new File(videoFile); if (!file.isFile()) throw new TaskExecutionFailedException("File retrieved from AIP is not a file..."); String fileName = file.getName(); String mediaURI = baseUNC + "\\" + dipID + "\\videos\\" + fileName; // send mediaURI to following task // (eu.prestoprime.plugin.qaplugin.ExecuteQATask) dParamsString.put("mediaURI", mediaURI); logger.info("mediaURI = " + mediaURI); } catch (DataException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AIP with ID: " + dipID); } catch (IPException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to retrieve AV material location..."); } } public static enum PROFILES { DefaultProfile }; public static enum STATUS { idle, queued, processing, paused, cancelled, failed, finished }; @WfService(name = "qa_execute", version = "0.8.0") public void execute(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // retrieve static parameters String host = sParams.get("host"); // retrieve dynamic parameters String mediaURI = dParamsString.get("mediaURI"); PROFILES analysisProfileName = PROFILES.DefaultProfile; File resultFile; try { resultFile = File.createTempFile("qa-result", ".tmp"); } catch (IOException e) { e.printStackTrace(); throw new TaskExecutionFailedException("Unable to create temp file"); } String path, line, params, id; DefaultHttpClient client; HttpUriRequest request; HttpEntity entity; BufferedReader reader; // interact with QA service main: do { try { path = host + "/service/numberOfFreeSlots"; request = new HttpGet(path); client = new DefaultHttpClient(); entity = client.execute(request).getEntity(); reader = new BufferedReader(new InputStreamReader(entity.getContent())); if ((line = reader.readLine()) != null) { if (Integer.parseInt(line) > 0) { logger.debug("Free slot found, requesting... - L1"); path = host + "/job"; request = new HttpPost(path); params = "mediaUri=" + mediaURI; params += "\nanalisysProfileName=" + analysisProfileName.toString(); ((HttpPost) request).setEntity(new StringEntity(params)); entity = client.execute(request).getEntity(); reader = new BufferedReader(new InputStreamReader(entity.getContent())); if ((line = reader.readLine()) != null) { if (!line.startsWith("error")) { id = line; logger.debug("Requested, ID: " + id + " - L2"); path = host + "/job/" + id + "/"; HttpPut put = new HttpPut(path); StringEntity entity2 = new StringEntity("control: start"); put.setEntity(entity2); entity = client.execute(put).getEntity(); reader = new BufferedReader(new InputStreamReader(entity.getContent())); if ((line = reader.readLine()) != null) { if (line.equals("success")) { do { path = host + "/job/" + id + "/status"; request = new HttpGet(path); entity = client.execute(request).getEntity(); reader = new BufferedReader(new InputStreamReader(entity.getContent())); if ((line = reader.readLine()) != null) { line = line.toLowerCase(); switch (STATUS.valueOf(line)) { case cancelled: logger.debug("Cancelled - L3"); throw new TaskExecutionFailedException("Request unexpectly cancelled..."); case failed: throw new TaskExecutionFailedException("Processing failed..."); case finished: logger.debug("Finished!! Downloading results - L4"); // download mpeg7 result path = host + "/job/" + id + "/result/mpeg7"; request = new HttpGet(path); entity = client.execute(request).getEntity(); InputStream is = entity.getContent(); OutputStream os = new FileOutputStream(resultFile); byte[] buf = new byte[1024]; int len; while ((len = is.read(buf)) > 0) os.write(buf, 0, len); os.close(); is.close(); logger.debug("Saved result, deleting from QA server..."); path = host + "/job/" + id + "/"; request = new HttpDelete(path); entity = client.execute(request).getEntity(); reader = new BufferedReader(new InputStreamReader(entity.getContent())); if ((line = reader.readLine()) != null) { if (line.equals("success")) { break main; } } default: logger.debug("Not finished yet, waiting... - L4"); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } continue; } } } while (true); } else { logger.debug("Error in the PUT method - L3"); } } } else { logger.debug(line + " - L2"); } } } else { logger.debug("No free slot, waiting... - L1"); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } continue; } } } catch (Exception e) { e.printStackTrace(); } break; } while (true); // send file to following task dParamsFile.put("resultFile", resultFile); logger.debug("ResultFile: " + resultFile.getAbsolutePath()); } @WfService(name = "qa_update_auto", version = "0.8.0") public void autoUpdate(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // retrieve dynamic parameters String id = dParamsString.get("id"); File resultFile = dParamsFile.get("resultFile"); // update AIP AIP aip = null; try { // parse resultFile DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Node node = dbf.newDocumentBuilder().parse(resultFile); // get AIP aip = P4DataManager.getInstance().getAIPByID(id); // update AIP aip.updateSection(node, "qa_auto"); logger.debug("Updated QA section..."); } catch (Exception e) { throw new TaskExecutionFailedException("Unable to update AIP...\n" + e.getMessage()); } finally { // release AIP P4DataManager.getInstance().releaseIP(aip); } } @WfService(name = "qa_update_manual", version = "0.8.0") public void manualUpdate(Map<String, String> sParams, Map<String, String> dParamsString, Map<String, File> dParamsFile) throws TaskExecutionFailedException { // retrieve dynamic parameters String id = dParamsString.get("id"); File resultFile = dParamsFile.get("resultFile"); // update AIP AIP aip = null; try { // parse resultFile DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Node node = dbf.newDocumentBuilder().parse(resultFile); // get AIP aip = P4DataManager.getInstance().getAIPByID(id); // update AIP aip.updateSection(node, "qa_manual"); logger.debug("Updated QA section..."); } catch (Exception e) { throw new TaskExecutionFailedException("Unable to update AIP...\n" + e.getMessage()); } finally { // release AIP P4DataManager.getInstance().releaseIP(aip); } } }