Skip to content

Instantly share code, notes, and snippets.

@trentonstrong
Created January 23, 2013 23:13
Show Gist options
  • Save trentonstrong/4615570 to your computer and use it in GitHub Desktop.
Save trentonstrong/4615570 to your computer and use it in GitHub Desktop.
asdfasfd
package com.okcupidlabs.neo4j.server.plugins;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.MediaType;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.kernel.impl.transaction.xaframework.ForceMode;
import org.neo4j.server.rest.domain.PropertySettingStrategy;
import org.neo4j.server.rest.repr.BadInputException;
import org.neo4j.server.rest.repr.InputFormat;
import org.neo4j.server.rest.repr.NodeRepresentation;
import org.neo4j.server.rest.repr.OutputFormat;
import org.neo4j.server.rest.web.DatabaseActions;
import org.neo4j.server.rest.web.NodeNotFoundException;
import sun.jvm.hotspot.tools.FinalizerInfo;
//An extension to the Neo4j Server for atomically creating or updating nodes/edges if they already exist.
@Path("/test")
public class AtomicCreateUpdate {
private final UriInfo uriInfo;
private final InputFormat input;
private final OutputFormat output;
private final DatabaseActions actions;
private final GraphDatabaseService service;
public AtomicCreateUpdate(@Context UriInfo uriInfo, @Context InputFormat input,
@Context OutputFormat output, @Context DatabaseActions actions,
@Context GraphDatabaseService service)
{
this.uriInfo = uriInfo;
this.input = input;
this.output = output;
this.actions = actions;
this.service = service;
}
// Creates or patches a node given a unique index key and value for the node.
@POST
@Path("/upsert_node/{index_name}/{index_key}/{index_value}")
public Response upsertNode(
@HeaderParam("Transaction") ForceMode force,
@PathParam("index_name") String indexName,
@PathParam("index_key") String indexKey,
@PathParam("index_value") String indexValue,
String body)
{
if (!this.service.index().existsForNodes(indexName)) {
throw new IllegalArgumentException("Index with index_name: " + indexKey + " does not exist.");
}
IndexHits<Node> hits = service.index().forNodes(indexName).get(indexKey, indexValue);
// invariant for a unique index: we should never have multiple hits
// this allows us to be promiscuous with the hits iterator down below ;)
boolean indexUniqueInvariant = hits.size() <= 1;
assert indexUniqueInvariant : hits.size();
boolean nodeFound = hits.size() == 1;
if (nodeFound) {
Node upsertedNode = hits.next();
try {
actions.forceMode(force).setAllNodeProperties(upsertedNode.getId(), input.readMap(body));
} catch (BadInputException e) {
return output.badRequest(e);
} catch (ArrayStoreException e) {
return badJsonFormat(body);
} catch (NodeNotFoundException e) {
return output.notFound(e);
}
return output.ok(new NodeRepresentation(upsertedNode));
} else {
try {
return output.created(actions.forceMode(force).createNode(input.readMap(body)));
}
catch (ArrayStoreException e) {
return badJsonFormat(body);
} catch (BadInputException e) {
return output.badRequest(e);
} catch ( ClassCastException e) {
return output.badRequest(e);
}
}
}
private Response badJsonFormat(String body) {
return Response.status( 400 )
.type( MediaType.TEXT_PLAIN )
.entity( "Invalid JSON array in POST body: " + body )
.build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment