package com.thinkaurelius.faunus.formats.rexster;
import com.thinkaurelius.faunus.formats.rexster.util.HttpHelper;
import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.conf.Configuration;
import org.codehaus.jettison.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class RexsterConfiguration {
public static final int VERTEX_TRUE_COUNT = -1;
public static final String FAUNUS_GRAPH_INPUT_REXSTER_HOSTNAME = "faunus.graph.input.rexster.hostname";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_PORT = "faunus.graph.input.rexster.port";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_SSL = "faunus.graph.input.rexster.ssl";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_GRAPH = "faunus.graph.input.rexster.graph";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_V_ESTIMATE = "faunus.graph.input.rexster.v-estimate";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_USERNAME = "faunus.graph.input.rexster.username";
public static final String FAUNUS_GRAPH_INPUT_REXSTER_PASSWORD = "faunus.graph.input.rexster.password";
private Configuration conf;
private static long trueVertexCount = Long.MIN_VALUE;
public RexsterConfiguration(final Configuration job) {
this.conf = job;
}
public Configuration getConf() {
return conf;
}
public boolean getSsl() {
return this.conf.getBoolean(FAUNUS_GRAPH_INPUT_REXSTER_SSL, false);
}
public String getRestAddress() {
return this.conf.get(FAUNUS_GRAPH_INPUT_REXSTER_HOSTNAME);
}
public int getRestPort() {
return this.conf.getInt(FAUNUS_GRAPH_INPUT_REXSTER_PORT, 8182);
}
public String getGraph() {
return this.conf.get(FAUNUS_GRAPH_INPUT_REXSTER_GRAPH);
}
public String getAuthenticationHeaderValue() {
return "Basic " + Base64.encodeBase64URLSafeString(
(this.conf.get(FAUNUS_GRAPH_INPUT_REXSTER_USERNAME, "") + ":" + this.conf.get(FAUNUS_GRAPH_INPUT_REXSTER_USERNAME, ""))
.getBytes());
}
public synchronized long getEstimatedVertexCount() {
long vertexCount = this.conf.getInt(FAUNUS_GRAPH_INPUT_REXSTER_V_ESTIMATE, 10000);
// getting the true count means doing a g.V over in rexster. this method is synchronized so that
// g.V.count() is not called more than once for the job.
if (vertexCount == VERTEX_TRUE_COUNT) {
if (trueVertexCount == Long.MIN_VALUE) {
trueVertexCount = getTrueVertexCount();
}
vertexCount = trueVertexCount;
}
return vertexCount;
}
public String getHttpProtocol() {
return this.getSsl() ? "https" : "http";
}
public String getRestEndpoint() {
return String.format("%s://%s:%s/graphs/%s/%s/%s",
this.getHttpProtocol(), this.getRestAddress(),
this.getRestPort(), this.getGraph(), FaunusRexsterInputFormatExtension.EXTENSION_NAMESPACE,
FaunusRexsterInputFormatExtension.EXTENSION_NAME);
}
public String getRestStreamEndpoint() {
return String.format("%s/%s",
this.getRestEndpoint(), FaunusRexsterInputFormatExtension.EXTENSION_METHOD_STREAM);
}
public String getRestCountEndpoint() {
return String.format("%s/%s",
this.getRestEndpoint(), FaunusRexsterInputFormatExtension.EXTENSION_METHOD_COUNT);
}
private long getTrueVertexCount() {
try {
final HttpURLConnection connection = HttpHelper.createConnection(
this.getRestCountEndpoint(), this.getAuthenticationHeaderValue());
final JSONObject json = new JSONObject(convertStreamToString(connection.getInputStream()));
return json.optLong(FaunusRexsterInputFormatExtension.EXTENSION_METHOD_COUNT);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
private static String convertStreamToString(final InputStream is) throws Exception {
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
return sb.toString();
}
}