package edu.washington.escience.myria.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
/**
* Util methods for handling of Json API stuff.
* */
public final class JsonAPIUtils {
/**
* Util class allows no instance.
* */
private JsonAPIUtils() {}
/**
* @param masterHostname master hostname
* @param apiPort rest api port
* @param queryFile query file
* @return a HTTPURLConnection instance of retrieving responses.
* @throws IOException if IO errors
* */
public static HttpURLConnection submitQuery(
final String masterHostname, final int apiPort, final File queryFile) throws IOException {
return submitQuery(masterHostname, apiPort, FileUtils.readFileToString(queryFile));
}
/**
* @param masterHostname master hostname
* @param apiPort rest api port
* @param queryString query string
* @return a HTTPURLConnection instance of retrieving responses.
* @throws IOException if IO errors
* */
public static HttpURLConnection submitQuery(
final String masterHostname, final int apiPort, final String queryString) throws IOException {
String type = "application/json";
URL u = new URL("http://" + masterHostname + ":" + apiPort + "/query");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", type);
byte[] e = queryString.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(e.length));
OutputStream os = conn.getOutputStream();
os.write(e);
os.close();
conn.connect();
conn.getResponseCode();
return conn;
}
/**
* Construct a URL for get/put of a dataset.
*
* @param host master hostname
* @param port master port
* @param user user parameter of the dataset
* @param program program parameter of the dataset
* @param relation relation parameter of the dataset
* @param format the format of the relation ("json", "csv", "tsv")
* @return a URL for the dataset
* @throws IOException if an error occurs
*/
private static URL getDatasetUrl(
final String host,
final int port,
final String user,
final String program,
final String relation,
final String format)
throws IOException {
return new URL(
String.format(
"http://%s:%d/dataset/user-%s/program-%s/relation-%s/data?format=%s",
host,
port,
user,
program,
relation,
format));
}
/**
* Download a dataset.
*
* @param host master hostname
* @param port master port
* @param user user parameter of the dataset
* @param program program parameter of the dataset
* @param relation relation parameter of the dataset
* @param format the format of the relation ("json", "csv", "tsv")
*
* @return dataset encoded in the requested format
* @throws IOException if an error occurs
*/
public static String download(
final String host,
final int port,
final String user,
final String program,
final String relation,
final String format)
throws IOException {
URL url = getDatasetUrl(host, port, user, program, relation, format);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Failed to download result:" + conn.getResponseCode());
}
try {
InputStream is = conn.getInputStream();
return IOUtils.toString(is, "UTF-8");
} finally {
conn.disconnect();
}
}
/**
* Replace the contents of a dataset.
*
* @param host master hostname
* @param port master port
* @param user user parameter of the dataset
* @param program program parameter of the dataset
* @param relation relation parameter of the dataset
* @param dataset the dataset to upload
* @param format the format of the relation ("json", "csv", "tsv")
*
* @throws IOException if an error occurs
*/
public static void replace(
final String host,
final int port,
final String user,
final String program,
final String relation,
final String dataset,
final String format)
throws IOException {
URL url = getDatasetUrl(host, port, user, program, relation, format);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestMethod("PUT");
byte[] payload = dataset.getBytes("UTF-8");
conn.setFixedLengthStreamingMode(payload.length);
try {
OutputStream out = conn.getOutputStream();
out.write(payload);
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Failed upload: " + conn.getResponseCode());
}
} finally {
conn.disconnect();
}
}
/**
* @param masterHostname master hostname
* @param apiPort rest api port
* @param queryFile query file
* @return a HTTPURLConnection instance of retrieving responses.
* @throws IOException if IO errors
* */
public static HttpURLConnection ingestData(
final String masterHostname, final int apiPort, final File queryFile) throws IOException {
return ingestData(masterHostname, apiPort, FileUtils.readFileToString(queryFile));
}
/**
* @param masterHostname master hostname
* @param apiPort rest api port
* @param queryString query string
* @return a HTTPURLConnection instance of retrieving responses.
* @throws IOException if IO errors
* */
public static HttpURLConnection ingestData(
final String masterHostname, final int apiPort, final String queryString) throws IOException {
String type = "application/json";
URL u = new URL("http://" + masterHostname + ":" + apiPort + "/dataset");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", type);
byte[] e = queryString.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(e.length));
OutputStream os = conn.getOutputStream();
os.write(e);
os.close();
conn.connect();
conn.getResponseCode();
return conn;
}
/**
* @param masterHostname master hostname
* @param apiPort rest api port
* @param user user parameter of the dataset
* @param program program parameter of the dataset
* @param relation relation parameter of the dataset
* @return a HTTPURLConnection instance of retrieving responses.
* @throws IOException if IO errors
* */
public static HttpURLConnection deleteDataset(
final String masterHostname,
final int apiPort,
final String user,
final String program,
final String relation)
throws IOException {
String type = "application/json";
URL u =
new URL(
String.format(
"http://%s:%d/dataset/user-%s/program-%s/relation-%s/",
masterHostname,
apiPort,
user,
program,
relation));
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("DELETE");
conn.setRequestProperty("Content-Type", type);
conn.connect();
conn.getResponseCode();
conn.disconnect();
return conn;
}
}