org.vertexium.tools.GraphRestore Maven / Gradle / Ivy
The newest version!
package org.vertexium.tools;
import com.beust.jcommander.Parameter;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONArray;
import org.json.JSONObject;
import org.vertexium.*;
import org.vertexium.property.StreamingPropertyValue;
import org.vertexium.util.JavaSerializableUtils;
import java.io.*;
public class GraphRestore extends GraphToolBase {
@Parameter(names = {"--in", "-i"}, description = "Input filename")
private String inputFileName = null;
public static void main(String[] args) throws Exception {
GraphRestore graphRestore = new GraphRestore();
graphRestore.run(args);
}
protected void run(String[] args) throws Exception {
super.run(args);
InputStream in = createInputStream();
try {
restore(getGraph(), in, getAuthorizations());
} finally {
in.close();
}
}
private InputStream createInputStream() throws FileNotFoundException {
if (inputFileName == null) {
return System.in;
}
return new FileInputStream(inputFileName);
}
public void restore(Graph graph, InputStream in, Authorizations authorizations) throws IOException {
String line;
char lastType = 'V';
Element element = null;
// We can't use a BufferedReader here because when we need to read the streaming property values we need raw bytes not converted bytes
while ((line = readLine(in)) != null) {
try {
char type = line.charAt(0);
JSONObject json = new JSONObject(line.substring(1));
switch (type) {
case 'V':
element = restoreVertex(graph, json, authorizations);
break;
case 'E':
// flush when we make the transition to edges so that we have vertices to lookup and link to.
if (type != lastType) {
graph.flush();
}
element = restoreEdge(graph, json, authorizations);
break;
case 'D':
restoreStreamingPropertyValue(in, graph, json, element, authorizations);
break;
default:
throw new RuntimeException("Unexpected line: " + line);
}
lastType = type;
} catch (Exception ex) {
throw new IOException("Invalid line: " + line, ex);
}
}
}
private String readLine(InputStream in) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while (true) {
int b = in.read();
if (b < 0) {
if (buffer.size() == 0) {
return null;
}
break;
}
if (b == '\n') {
break;
}
buffer.write(b);
}
return new String(buffer.toByteArray());
}
private Vertex restoreVertex(Graph graph, JSONObject json, Authorizations authorizations) {
Visibility visibility = jsonToVisibility(json);
String vertexId = json.getString("id");
VertexBuilder v = graph.prepareVertex(vertexId, visibility);
jsonToProperties(json, v);
return v.save(authorizations);
}
private Edge restoreEdge(Graph graph, JSONObject json, Authorizations authorizations) {
Visibility visibility = jsonToVisibility(json);
String edgeId = json.getString("id");
String outVertexId = json.getString("outVertexId");
String inVertexId = json.getString("inVertexId");
String label = json.getString("label");
Vertex outVertex = graph.getVertex(outVertexId, authorizations);
Vertex inVertex = graph.getVertex(inVertexId, authorizations);
EdgeBuilder e = graph.prepareEdge(edgeId, outVertex, inVertex, label, visibility);
jsonToProperties(json, e);
return e.save(authorizations);
}
protected Visibility jsonToVisibility(JSONObject jsonObject) {
return new Visibility(jsonObject.getString("visibility"));
}
protected void jsonToProperties(JSONObject jsonObject, ElementBuilder e) {
JSONArray propertiesJson = jsonObject.getJSONArray("properties");
for (int i = 0; i < propertiesJson.length(); i++) {
JSONObject propertyJson = propertiesJson.getJSONObject(i);
jsonToProperty(propertyJson, e);
}
}
private void jsonToProperty(JSONObject propertyJson, ElementBuilder e) {
String key = propertyJson.getString("key");
String name = propertyJson.getString("name");
Object value = jsonStringToObject(propertyJson.getString("value"));
Metadata metadata = jsonToPropertyMetadata(propertyJson.optJSONObject("metadata"));
Visibility visibility = new Visibility(propertyJson.getString("visibility"));
e.addPropertyValue(key, name, value, metadata, visibility);
}
private void restoreStreamingPropertyValue(InputStream in, Graph graph, JSONObject propertyJson, Element element, Authorizations authorizations) throws ClassNotFoundException, IOException {
String key = propertyJson.getString("key");
String name = propertyJson.getString("name");
Metadata metadata = jsonToPropertyMetadata(propertyJson.optJSONObject("metadata"));
Visibility visibility = new Visibility(propertyJson.getString("visibility"));
Class valueType = Class.forName(propertyJson.getString("valueType"));
InputStream spvin = new StreamingPropertyValueInputStream(in);
StreamingPropertyValue value = StreamingPropertyValue.create(spvin, valueType);
value.searchIndex(propertyJson.optBoolean("searchIndex", false));
value.store(propertyJson.optBoolean("store", true));
element.addPropertyValue(key, name, value, metadata, visibility, authorizations);
}
private Metadata jsonToPropertyMetadata(JSONObject metadataJson) {
Metadata metadata = new Metadata();
if (metadataJson == null) {
return metadata;
}
for (Object key : metadataJson.keySet()) {
String keyString = (String) key;
JSONObject metadataItemJson = metadataJson.getJSONObject(keyString);
Object val = jsonStringToObject(metadataItemJson.getString("value"));
Visibility visibility = new Visibility(metadataItemJson.getString("visibility"));
metadata.add(keyString, val, visibility);
}
return metadata;
}
private Object jsonStringToObject(String str) {
if (str.startsWith(GraphBackup.BASE64_PREFIX)) {
str = str.substring(GraphBackup.BASE64_PREFIX.length());
return JavaSerializableUtils.bytesToObject(Base64.decodeBase64(str));
} else {
return str;
}
}
private class StreamingPropertyValueInputStream extends InputStream {
private final InputStream in;
private int segmentLength;
private boolean done;
public StreamingPropertyValueInputStream(InputStream in) throws IOException {
this.in = in;
readSegmentLengthLine();
}
private void readSegmentLengthLine() throws IOException {
String line = readLine(this.in);
this.segmentLength = Integer.parseInt(line);
if (this.segmentLength == 0) {
this.done = true;
}
}
@Override
public int read() throws IOException {
if (this.done) {
return -1;
}
if (this.segmentLength == 0) {
this.in.read(); // throw away new line character
readSegmentLengthLine();
if (this.done) {
return -1;
}
}
int ret = this.in.read();
this.segmentLength--;
return ret;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy