package com.tinkerpop.rexster;
import com.sun.jersey.api.client.ClientResponse;
import junit.framework.Assert;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONTokener;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class EdgeResourceIntegrationTest extends AbstractGraphResourceIntegrationTest {
public EdgeResourceIntegrationTest() throws Exception {
super();
}
@Test
public void getEdgeDoesNotExistStatusNotFound() {
for (GraphTestHolder testGraph : this.testGraphs) {
if (testGraph.getFeatures().supportsEdgeRetrieval) {
ClientResponse graphResponse = doGraphGet(testGraph, "edges/123doesnotexist");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.NOT_FOUND, graphResponse.getClientResponseStatus());
}
}
}
@Test
public void getEdgeFoundStatusOk() {
for (GraphTestHolder testGraph : this.testGraphs) {
if (testGraph.getFeatures().supportsEdgeRetrieval) {
String id = testGraph.getEdgeIdSet().values().iterator().next();
ClientResponse graphResponse = doGraphGet(testGraph, "edges/" + encode(id));
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
JSONObject edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
JSONObject results = edgeJson.optJSONObject(Tokens.RESULTS);
Assert.assertEquals(id, results.optString(Tokens._ID));
}
}
}
@Test
public void getEdgesAllFoundStatusOk() {
for (GraphTestHolder testGraph : this.testGraphs) {
if (testGraph.getFeatures().supportsEdgeIteration) {
ClientResponse graphResponse = doGraphGet(testGraph, "edges");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
JSONObject edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
Assert.assertEquals(6, edgeJson.optJSONArray(Tokens.RESULTS).length());
}
}
}
@Test
public void getEdgesPagingStatusOk() {
for (GraphTestHolder testGraph : this.testGraphs) {
if (testGraph.getFeatures().supportsEdgeIteration) {
ArrayList<String> uniqueIds = new ArrayList<String>();
// get the first two elements
ClientResponse graphResponse = doGraphGet(testGraph, "edges", "rexster.offset.start=0&rexster.offset.end=2");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
JSONObject edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
JSONArray results = edgeJson.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(2, results.length());
uniqueIds.add(results.optJSONObject(0).optString(Tokens._ID));
Assert.assertFalse(uniqueIds.contains(results.optJSONObject(1).optString(Tokens._ID)));
uniqueIds.add(results.optJSONObject(1).optString(Tokens._ID));
// get the next two elements
graphResponse = doGraphGet(testGraph, "edges", "rexster.offset.start=2&rexster.offset.end=4");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
results = edgeJson.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(2, results.length());
Assert.assertFalse(uniqueIds.contains(results.optJSONObject(1).optString(Tokens._ID)));
uniqueIds.add(results.optJSONObject(0).optString(Tokens._ID));
Assert.assertFalse(uniqueIds.contains(results.optJSONObject(1).optString(Tokens._ID)));
uniqueIds.add(results.optJSONObject(1).optString(Tokens._ID));
// get the final two elements
graphResponse = doGraphGet(testGraph, "edges", "rexster.offset.start=4&rexster.offset.end=6");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
results = edgeJson.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(2, results.length());
Assert.assertFalse(uniqueIds.contains(results.optJSONObject(1).optString(Tokens._ID)));
uniqueIds.add(results.optJSONObject(0).optString(Tokens._ID));
Assert.assertFalse(uniqueIds.contains(results.optJSONObject(1).optString(Tokens._ID)));
uniqueIds.add(results.optJSONObject(1).optString(Tokens._ID));
// get the final two elements without specifying the end parameter
graphResponse = doGraphGet(testGraph, "edges", "rexster.offset.start=4");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
results = edgeJson.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(2, results.length());
Assert.assertEquals(uniqueIds.get(4), results.optJSONObject(0).optString(Tokens._ID));
Assert.assertEquals(uniqueIds.get(5), results.optJSONObject(1).optString(Tokens._ID));
// get the first two elements without specifying the start parameter
graphResponse = doGraphGet(testGraph, "edges", "rexster.offset.end=2");
Assert.assertNotNull(graphResponse);
Assert.assertEquals(ClientResponse.Status.OK, graphResponse.getClientResponseStatus());
edgeJson = graphResponse.getEntity(JSONObject.class);
Assert.assertNotNull(edgeJson);
results = edgeJson.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(2, results.length());
Assert.assertEquals(uniqueIds.get(0), results.optJSONObject(0).optString(Tokens._ID));
Assert.assertEquals(uniqueIds.get(1), results.optJSONObject(1).optString(Tokens._ID));
}
}
}
@Test
public void postEdgeEdgeExistingWithNoEdgePropertiesStatusConflict() {
for (GraphTestHolder testGraph : this.testGraphs) {
// POST edge does a getEdge to determine if the edge was already posted with that ID
// and to allow new properties to be POSTed to the edge
if (testGraph.getFeatures().supportsEdgeRetrieval) {
String id = testGraph.getEdgeIdSet().values().iterator().next();
ClientResponse response = this.doGraphPost(testGraph, "edges/" + encode(id));
Assert.assertNotNull(response);
Assert.assertEquals(ClientResponse.Status.CONFLICT, response.getClientResponseStatus());
}
}
}
@Test
public void postEdgeNewEdgeVerticesDoNotExistStatusConflict() {
for (GraphTestHolder testGraph : this.testGraphs) {
// POST edge does a getEdge to determine if the edge was already posted with that ID
// and to allow new properties to be POSTed to the edge
if (testGraph.getFeatures().supportsEdgeRetrieval) {
String id = testGraph.getEdgeIdSet().values().iterator().next();
ClientResponse response = this.doGraphPost(testGraph, "edges/" + encode(id), "_outV=102notreal&_inV=123notreal");
Assert.assertNotNull(response);
Assert.assertEquals(ClientResponse.Status.CONFLICT, response.getClientResponseStatus());
}
}
}
@Test
public void postEdgeSimpleStatusOk() throws JSONException {
for (GraphTestHolder testGraph : this.testGraphs) {
Iterator<String> itty = testGraph.getVertexIdSet().values().iterator();
String vertexIdIn = itty.next();
String vertexIdOut = itty.next();
// post as URI
String edgeProperty = "propertya=(i,123)&propertyb=(d,321.5)&propertyc=test";
ClientResponse response = this.doGraphPost(testGraph, "edges", "_outV=" + encode(vertexIdOut) + "&_inV=" + encode(vertexIdIn) + "&_label=uriPost&" + edgeProperty);
assertPostedEdge(vertexIdIn, vertexIdOut, response, true);
// post as JSON
Map<String, Object> jsonEdgeData = new HashMap<String, Object>();
jsonEdgeData.put(Tokens._OUT_V, vertexIdOut);
jsonEdgeData.put(Tokens._IN_V, vertexIdIn);
jsonEdgeData.put(Tokens._LABEL, "jsonPost");
jsonEdgeData.put("propertya", 123);
jsonEdgeData.put("propertyb", 321.5);
jsonEdgeData.put("propertyc", "test");
JSONObject jsonEdgeToPost = new JSONObject(jsonEdgeData);
response = this.doGraphPostOfJson(testGraph, "edges", jsonEdgeToPost);
assertPostedEdge(vertexIdIn, vertexIdOut, response, true);
}
}
@Test
public void postEdgeComplexStatusOk() throws JSONException {
for (GraphTestHolder testGraph : this.testGraphs) {
if (testGraph.getFeatures().supportsMapProperty){
Iterator<String> itty = testGraph.getVertexIdSet().values().iterator();
String vertexIdIn = itty.next();
String vertexIdOut = itty.next();
// post as URI
String complexValue = "(map,(propertya=(i,123),propertyb=(d,321.5),propertyc=(list,(x,y,z)),propertyd=(map,(x=xyz))))";
String complexKeyValueUri = "&complex=" + complexValue;
ClientResponse response = this.doGraphPost(testGraph, "edges", "_outV=" + encode(vertexIdOut) + "&_inV=" + encode(vertexIdIn) + "&_label=uriPost" + complexKeyValueUri);
assertPostedEdge(vertexIdIn, vertexIdOut, response, false);
// post as JSON
String complexKeyValueJson = "{\"propertya\":123,\"propertyb\":321.5,\"propertyc\":[\"x\",\"y\",\"z\"],\"propertyd\":{\"x\":\"xyz\"}}";
JSONTokener tokener = new JSONTokener(complexKeyValueJson);
JSONObject complexJsonObject = new JSONObject(tokener);
Map<String, Object> jsonEdgeData = new HashMap<String, Object>();
jsonEdgeData.put(Tokens._OUT_V, vertexIdOut);
jsonEdgeData.put(Tokens._IN_V, vertexIdIn);
jsonEdgeData.put(Tokens._LABEL, "jsonPost");
jsonEdgeData.put("complex", complexJsonObject);
JSONObject jsonEdgeToPost = new JSONObject(jsonEdgeData);
response = this.doGraphPostOfJson(testGraph, "edges", jsonEdgeToPost);
assertPostedEdge(vertexIdIn, vertexIdOut, response, false);
}
}
}
@Test
public void putEdgeStatusNotFound() {
for (GraphTestHolder testGraph : this.testGraphs) {
// A PUT has to get the edge before it can update it
if (testGraph.getFeatures().supportsEdgeRetrieval) {
String keyValueThatWillNeverUpdate = "&k1=v1";
ClientResponse response = this.doGraphPut(testGraph, "edges/1000notreal", keyValueThatWillNeverUpdate);
Assert.assertEquals(ClientResponse.Status.NOT_FOUND, response.getClientResponseStatus());
}
}
}
@Test
public void putEdgeSimpleStatusOk() throws JSONException {
for (GraphTestHolder testGraph : this.testGraphs) {
// A PUT has to get the edge before it can update it
if (testGraph.getFeatures().supportsEdgeRetrieval) {
Iterator<String> itty = testGraph.getEdgeIdSet().values().iterator();
String firstEdgeId = itty.next();
String secondEdgeId = itty.next();
// put as URI
String edgeProperty = "propertya=(i,123)&propertyb=(d,321.5)&propertyc=test";
ClientResponse response = this.doGraphPut(testGraph, "edges/" + encode(firstEdgeId), edgeProperty);
assertPuttedEdge(firstEdgeId, response, true);
// put as JSON
Map<String, Object> jsonEdgeData = new HashMap<String, Object>();
jsonEdgeData.put("propertya", 123);
jsonEdgeData.put("propertyb", 321.5);
jsonEdgeData.put("propertyc", "test");
JSONObject jsonEdgeToPut = new JSONObject(jsonEdgeData);
response = this.doGraphPutOfJson(testGraph, "edges/" + encode(secondEdgeId), jsonEdgeToPut);
assertPuttedEdge(secondEdgeId, response, true);
}
}
}
@Test
public void putEdgeComplexStatusOk() throws JSONException {
for (GraphTestHolder testGraph : this.testGraphs) {
// A PUT has to get the edge before it can update it
if (testGraph.getFeatures().supportsEdgeRetrieval && testGraph.getFeatures().supportsMapProperty) {
Iterator<String> itty = testGraph.getEdgeIdSet().values().iterator();
String firstEdgeId = itty.next();
String secondEdgeId = itty.next();
// put as URI
String complexValue = "(map,(propertya=(i,123),propertyb=(d,321.5),propertyc=(list,(x,y,z)),propertyd=(map,(x=xyz))))";
String complexKeyValueUri = "complex=" + complexValue;
ClientResponse response = this.doGraphPut(testGraph, "edges/" + encode(firstEdgeId), complexKeyValueUri);
assertPuttedEdge(firstEdgeId, response, false);
// put as JSON
String complexKeyValueJson = "{\"propertya\":123,\"propertyb\":321.5,\"propertyc\":[\"x\",\"y\",\"z\"],\"propertyd\":{\"x\":\"xyz\"}}";
JSONTokener tokener = new JSONTokener(complexKeyValueJson);
JSONObject complexJsonObject = new JSONObject(tokener);
Map<String, Object> jsonEdgeData = new HashMap<String, Object>();
jsonEdgeData.put("complex", complexJsonObject);
JSONObject jsonEdgeToPost = new JSONObject(jsonEdgeData);
response = this.doGraphPutOfJson(testGraph, "edges/" + encode(secondEdgeId), jsonEdgeToPost);
assertPuttedEdge(secondEdgeId, response, false);
}
}
}
@Test
public void deleteEdgeStatusNotFound() {
for (GraphTestHolder testGraph : this.testGraphs) {
// A DELETE has to get the edge before it can remove it
if (testGraph.getFeatures().supportsEdgeRetrieval) {
ClientResponse response = this.doGraphDelete(testGraph, "edges/1000notreal");
Assert.assertEquals(ClientResponse.Status.NOT_FOUND, response.getClientResponseStatus());
}
}
}
@Test
public void deleteEdgeStatusOk() {
for (GraphTestHolder testGraph : this.testGraphs) {
// maybe make a test that doesn't do property deletes first so that this test doesn't
// need edge retrieval
if (testGraph.getFeatures().supportsEdgeRetrieval) {
Iterator<String> itty = testGraph.getEdgeIdSet().values().iterator();
String edgeToDelete = itty.next();
ClientResponse responseGetEdge = this.doGraphGet(testGraph, "edges/" + encode(edgeToDelete));
Assert.assertEquals(ClientResponse.Status.OK, responseGetEdge.getClientResponseStatus());
JSONObject edgeJson = responseGetEdge.getEntity(JSONObject.class);
List<String> keysToRemove = new ArrayList<String>();
Iterator<String> propertyItty = edgeJson.optJSONObject(Tokens.RESULTS).keys();
String keysToDeleteQueryString = "";
while (propertyItty.hasNext()) {
String key = propertyItty.next();
if (!key.startsWith(Tokens.UNDERSCORE)) {
keysToRemove.add(key);
keysToDeleteQueryString = keysToDeleteQueryString + "&" + key;
}
}
// delete the properties first
ClientResponse responsePropertyDelete = this.doGraphDelete(testGraph, "edges/" + encode(edgeToDelete), keysToDeleteQueryString);
Assert.assertEquals(ClientResponse.Status.OK, responsePropertyDelete.getClientResponseStatus());
responseGetEdge = this.doGraphGet(testGraph, "edges/" + encode(edgeToDelete));
Assert.assertEquals(ClientResponse.Status.OK, responseGetEdge.getClientResponseStatus());
edgeJson = responseGetEdge.getEntity(JSONObject.class).optJSONObject(Tokens.RESULTS);
for (String key : keysToRemove) {
Assert.assertFalse(edgeJson.has(key));
}
// delete the edge itself
responsePropertyDelete = this.doGraphDelete(testGraph, "edges/" + encode(edgeToDelete));
Assert.assertEquals(ClientResponse.Status.OK, responsePropertyDelete.getClientResponseStatus());
responseGetEdge = this.doGraphGet(testGraph, "edges/" + encode(edgeToDelete));
Assert.assertEquals(ClientResponse.Status.NOT_FOUND, responseGetEdge.getClientResponseStatus());
}
}
}
private void assertPostedEdge(String vertexIdIn, String vertexIdOut, ClientResponse response, boolean simpleProperties) {
Assert.assertNotNull(response);
Assert.assertEquals(ClientResponse.Status.OK, response.getClientResponseStatus());
JSONObject createdEdgeJson = response.getEntity(JSONObject.class).optJSONObject(Tokens.RESULTS);
Assert.assertEquals(vertexIdIn, createdEdgeJson.optString(Tokens._IN_V));
Assert.assertEquals(vertexIdOut, createdEdgeJson.optString(Tokens._OUT_V));
if (simpleProperties) {
assertPostedEdgeSimpleProperties(createdEdgeJson);
} else {
assertPostedEdgeComplexProperties(createdEdgeJson);
}
}
private void assertPuttedEdge(String edgeId, ClientResponse response, boolean simpleProperties) {
Assert.assertNotNull(response);
Assert.assertEquals(ClientResponse.Status.OK, response.getClientResponseStatus());
JSONObject createdEdgeJson = response.getEntity(JSONObject.class).optJSONObject(Tokens.RESULTS);
Assert.assertEquals(edgeId, createdEdgeJson.optString(Tokens._ID));
if (simpleProperties) {
assertPostedEdgeSimpleProperties(createdEdgeJson);
} else {
assertPostedEdgeComplexProperties(createdEdgeJson);
}
int countProperties = 0;
Iterator<String> itty = createdEdgeJson.keys();
while (itty.hasNext()) {
String key = itty.next();
if (!key.startsWith(Tokens.UNDERSCORE)) {
countProperties++;
}
}
if (simpleProperties) {
Assert.assertEquals(3, countProperties);
} else {
Assert.assertEquals(1, countProperties);
}
}
private void assertPostedEdgeComplexProperties(JSONObject createdEdgeJson) {
JSONObject mapRootProperty = createdEdgeJson.optJSONObject("complex");
Assert.assertEquals(123, mapRootProperty.optInt("propertya"));
Assert.assertEquals(321.5, mapRootProperty.optDouble("propertyb"));
JSONArray listInMapProperty = mapRootProperty.optJSONArray("propertyc");
Assert.assertEquals(3, listInMapProperty.length());
JSONObject mapInMapProperty = mapRootProperty.optJSONObject("propertyd");
Assert.assertEquals("xyz", mapInMapProperty.optString("x"));
}
private void assertPostedEdgeSimpleProperties(JSONObject createdEdgeJson) {
Assert.assertEquals(123, createdEdgeJson.optInt("propertya"));
Assert.assertEquals(321.5, createdEdgeJson.optDouble("propertyb"));
Assert.assertEquals("test", createdEdgeJson.optString("propertyc"));
}
}