/**
* MServeClient.java
* Author: Francesco Rosso (rosso@eurix.it)
* Contributors: Francesco Gallo (gallo@eurix.it)
*
* This file is part of PrestoPRIME Preservation Platform (P4).
*
* Copyright (C) 2009-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.mserve.client;
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.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MServeClient {
private static final Logger logger = LoggerFactory.getLogger(MServeClient.class);
public enum MServeTask {
d10mxfchecksum("prestoprime.tasks.d10mxfchecksum"), extractkeyframes("prestoprime.tasks.extractkeyframes"), ffmbc("prestoprime.tasks.ffmbc"), ffmpeg2theora("prestoprime.tasks.ffmpeg2theora"), ffprobe("prestoprime.tasks.ffprobe"), mxftechmdextractor("prestoprime.tasks.mxftechmdextractor");
private String name;
private MServeTask(String name) {
this.name = name;
}
public String getName() {
return name;
}
};
private String host;
private String serviceID;
public MServeClient(String host, String serviceID) {
this.host = host;
this.serviceID = serviceID;
}
/**
* Uploads a file on MServe and returns its fileID
*
* @param file
* @return
* @throws MServeException
*/
public String uploadFile(File file) throws MServeException {
try {
URL url = new URL(host + "/auths/" + serviceID + "/mfiles/");
logger.debug("MServe URL: " + url.toString());
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = new HttpPost(url.toString());
request.setHeader("Accept", "application/json");
MultipartEntity part = new MultipartEntity();
part.addPart("file", new FileBody(file));
((HttpPost) request).setEntity(part);
HttpEntity stream = client.execute(request).getEntity();
InputStream istream = stream.getContent();
BufferedReader buf = new BufferedReader(new InputStreamReader(istream));
String line;
StringBuffer sb = new StringBuffer();
while (null != ((line = buf.readLine()))) {
sb.append(line.trim());
}
buf.close();
istream.close();
logger.debug(sb.toString());
JSONObject response = new JSONObject(sb.toString());
return response.getString("id");
} catch (MalformedURLException e) {
throw new MServeException("Bad REST interface...");
} catch (IOException e) {
throw new MServeException("Unable to make IO...");
} catch (JSONException e) {
throw new MServeException("Bad JSON response...");
}
}
/**
* Runs a specific task on MServe, wait until it completes or fails and
* returns the output.
*
* @param fileID
* @param task
* @param params
* @return
* @throws MServeException
*/
public File runMServeTask(String fileID, MServeTask task, Map<String, String> params) throws MServeException {
String jobID = this.createJob(fileID, task, params);
String joboutputID;
while ((joboutputID = this.pollJob(jobID)) == null) {
try {
System.out.println("waiting...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("joboutputID: " + joboutputID);
File outputFile = this.getJobFile(joboutputID);
return outputFile;
}
private String createJob(String fileID, MServeTask task, Map<String, String> params) throws MServeException {
try {
URL url = new URL(host + "/mfiles/" + fileID + "/jobs/");
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = new HttpPost(url.toString());
request.setHeader("Accept", "application/json");
List<NameValuePair> parameters = new ArrayList<>();
parameters.add(new BasicNameValuePair("jobtype", task.getName()));
if (params != null)
for (Entry<String, String> param : params.entrySet())
parameters.add(new BasicNameValuePair(param.getKey(), param.getValue()));
UrlEncodedFormEntity part = new UrlEncodedFormEntity(parameters);
((HttpPost) request).setEntity(part);
HttpEntity stream = client.execute(request).getEntity();
InputStream istream = stream.getContent();
BufferedReader buf = new BufferedReader(new InputStreamReader(istream));
String output = "";
String line;
while (null != ((line = buf.readLine()))) {
output += line.trim();
}
buf.close();
istream.close();
JSONObject response = new JSONObject(output);
System.out.println(response);
return response.getString("id");
} catch (MalformedURLException e) {
throw new MServeException("Bad REST interface...");
} catch (IOException e) {
throw new MServeException("Unable to make IO...");
} catch (JSONException e) {
throw new MServeException("Bad JSON response...");
}
}
private String pollJob(String jobID) throws MServeException {
try {
URL url = new URL(host + "/jobs/" + jobID);
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = new HttpGet(url.toString());
request.setHeader("Accept", "application/json");
HttpEntity stream = client.execute(request).getEntity();
InputStream istream = stream.getContent();
BufferedReader buf = new BufferedReader(new InputStreamReader(istream));
String output = "";
String line;
while (null != ((line = buf.readLine()))) {
output += line.trim();
}
buf.close();
istream.close();
JSONObject response = new JSONObject(output);
if (response.getJSONObject("tasks").getBoolean("failed"))
throw new MServeException("Job failed...");
if (!(response.getJSONObject("tasks").getBoolean("successful")))
return null;
return response.getJSONArray("joboutput_set").getJSONObject(0).getString("id");
} catch (MalformedURLException e) {
throw new MServeException("Bad REST interface...");
} catch (IOException e) {
throw new MServeException("Unable to make IO...");
} catch (JSONException e) {
throw new MServeException("Bad JSON response...");
}
}
private File getJobFile(String joboutputID) {
try {
URL url = new URL(host + "/joboutputs/" + joboutputID + "/file");
File outputFile = File.createTempFile("mserve-", ".out");
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(outputFile);
IOUtils.copy(is, os);
return outputFile;
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}