Skip to content

Instantly share code, notes, and snippets.

@jexp
Last active December 28, 2015 13:19
Show Gist options
  • Select an option

  • Save jexp/7506922 to your computer and use it in GitHub Desktop.

Select an option

Save jexp/7506922 to your computer and use it in GitHub Desktop.
Example for loading the first n-elements of a Activity Stream with an unmanaged Neo4j-Server-Extension
package org.neo4j.example.activity;
import org.codehaus.jackson.map.ObjectMapper;
import org.neo4j.graphdb.GraphDatabaseService;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.IOException;
import java.io.OutputStream;
@Path("/activities")
public class ActivityResource {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private final ActivityStream stream;
public ActivityResource(@Context GraphDatabaseService db, @Context UriInfo uriInfo) {
stream = new ActivityStream(db);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{userName}")
public Response getActivityStream(@PathParam("userName") final String userName,
@QueryParam("count") final Integer count) {
return Response.ok().entity(new StreamingOutput() {
public void write(OutputStream out) throws IOException, WebApplicationException {
OBJECT_MAPPER.writeValue(out, stream.loadStream(userName,count));
}
}).build();
}
}
MATCH (head:ActivityHead)-[:NEXT*]->(activity)-[:IN_FORUM]->
(forum:Forum)<-[:FOLLOWS]-(user:User {name: {name}}),
(activity)<-[:WROTE]-(author:User)
RETURN author.name, activity.message, forum.name
LIMIT 20
package org.neo4j.example.activity;
import org.neo4j.graphdb.*;
import org.neo4j.tooling.GlobalGraphOperations;
import java.util.*;
import static org.neo4j.example.activity.ActivityStream.Labels.*;
import static org.neo4j.example.activity.ActivityStream.Relationships.*;
import static org.neo4j.graphdb.Direction.*;
import static org.neo4j.helpers.collection.IteratorUtil.single;
public class ActivityStream {
public static final String NAME = "name";
public static final String MESSAGE = "message";
enum Labels implements Label {
User, Forum, Activity, ActivityHead
}
enum Relationships implements RelationshipType {
FOLLOWS,NEXT, WROTE, IN_FORUM
}
private final GraphDatabaseService gdb;
public ActivityStream(GraphDatabaseService gdb) {
this.gdb = gdb;
}
static class Activity {
public final String author;
public final String message;
public final String forum;
Activity(String author, String message, String forum) {
this.author = author;
this.message = message;
this.forum = forum;
}
public static Activity from(Node node, Node forum) {
Node author = node.getSingleRelationship(WROTE, INCOMING).getEndNode();
return new Activity((String)author.getProperty(NAME),
(String)node.getProperty(MESSAGE),
(String)forum.getProperty(NAME));
}
}
public List<Activity> loadStream(String name, int count) {
try (Transaction tx = gdb.beginTx()) {
Node user = single(gdb.findNodesByLabelAndProperty(User, NAME, name));
Set<Node> forums = loadForums(user);
List<Activity> activities = loadActivities(count, forums);
tx.success();
return activities;
}
}
private List<Activity> loadActivities(int count, Set<Node> forums) {
List<Activity> activities = new ArrayList<>(count);
Node activity = single(GlobalGraphOperations.at(gdb).getAllNodesWithLabel(ActivityHead));
while (activity != null && activities.size() < count) {
Node forum = activity.getSingleRelationship(IN_FORUM, OUTGOING).getEndNode();
if (forums.contains(forum)) {
activities.add(ActivityStream.Activity.from(activity,forum));
}
activity = activity.hasRelationship(NEXT, OUTGOING) ?
activity.getSingleRelationship(NEXT, OUTGOING).getEndNode() : null;
}
return activities;
}
private Set<Node> loadForums(Node user) {
Set<Node> forums=new HashSet<>();
for (Relationship follows : user.getRelationships(OUTGOING, FOLLOWS)) {
forums.add(follows.getEndNode());
}
return forums;
}
}
package org.neo4j.example.activity;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.neo4j.test.TestGraphDatabaseFactory;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.neo4j.example.activity.ActivityStream.Labels.Activity;
import static org.neo4j.example.activity.ActivityStream.Labels.Forum;
import static org.neo4j.example.activity.ActivityStream.Labels.User;
import static org.neo4j.example.activity.ActivityStream.MESSAGE;
import static org.neo4j.example.activity.ActivityStream.NAME;
import static org.neo4j.example.activity.ActivityStream.Relationships.*;
/**
* @author mh
* @since 17.11.13
*/
public class ActivityStreamTest {
public static final String GRAPH_REFACTORING = "Graph Refactoring";
public static final String GRAPH_USE_CASES = "Graph Use Cases";
public static final String CAP_VS_ACID = "CAP vs ACID";
public static final String PETER = "Peter";
public static final String GRAPHS = "Graphs";
public static final String IAN = "Ian";
public static final String MICHAEL = "Michael";
public static final String NO_SQL = "NoSQL";
private GraphDatabaseService db;
private ActivityStream activityStream;
private Transaction tx;
@Before
public void setUp() throws Exception {
db = new TestGraphDatabaseFactory().newImpermanentDatabase();
activityStream = new ActivityStream(db);
tx = db.beginTx();
}
@After
public void tearDown() throws Exception {
tx.close();
db.shutdown();
}
@Test
public void testLoadSingleItem() throws Exception {
createTestData();
List<ActivityStream.Activity> activities = activityStream.loadStream(MICHAEL, 1);
assertEquals(1,activities.size());
assertEquals(CAP_VS_ACID,activities.get(0).message);
}
@Test
public void testLoadFullStream() throws Exception {
createTestData();
List<ActivityStream.Activity> activities = activityStream.loadStream(MICHAEL, 10);
assertEquals(3,activities.size());
assertEquals(CAP_VS_ACID,activities.get(0).message);
assertEquals(GRAPH_USE_CASES,activities.get(1).message);
assertEquals(GRAPH_REFACTORING,activities.get(2).message);
}
@Test
public void testLoadItemsForSingleForum() throws Exception {
createTestData();
List<ActivityStream.Activity> activities = activityStream.loadStream(IAN, 5);
assertEquals(2,activities.size());
assertEquals(GRAPH_USE_CASES,activities.get(0).message);
assertEquals(PETER,activities.get(0).author);
assertEquals(GRAPHS,activities.get(0).forum);
assertEquals(GRAPH_REFACTORING,activities.get(1).message);
assertEquals(IAN,activities.get(1).author);
}
private void createTestData() {
Node michael = createUser(MICHAEL);
Node peter = createUser(PETER);
Node ian = createUser(IAN);
Node noSQL = createForum(NO_SQL,michael,peter);
Node graphs = createForum(GRAPHS,michael,ian,peter);
Node message1 = createMessage(GRAPH_REFACTORING, ian, graphs, null);
Node message2 = createMessage(GRAPH_USE_CASES, peter, graphs, message1);
Node message3 = createMessage(CAP_VS_ACID, peter, noSQL, message2);
message3.addLabel(ActivityStream.Labels.ActivityHead);
}
private Node createUser(String name) {
Node user = db.createNode(User);
user.setProperty(NAME, name);
return user;
}
private Node createForum(String name,Node...followers) {
Node forum = db.createNode(Forum);
forum.setProperty(NAME, name);
for (Node follower : followers) {
follower.createRelationshipTo(forum, FOLLOWS);
}
return forum;
}
private Node createMessage(String message, Node author,Node forum,Node previous) {
Node activity = db.createNode(Activity);
activity.setProperty(MESSAGE, message);
author.createRelationshipTo(activity, WROTE);
activity.createRelationshipTo(forum, IN_FORUM);
if (previous!=null) activity.createRelationshipTo(previous, NEXT);
return activity;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment