@Test @Graph( nodes = { @NODE( name = "a", setNameProperty = true ), @NODE( name = "b", setNameProperty = true ), @NODE( name = "c", setNameProperty = true ), @NODE( name = "d", setNameProperty = true ), @NODE( name = "e", setNameProperty = true ), @NODE( name = "f", setNameProperty = true ) }, relationships = { @REL( start = "a", end = "b", type = "to", properties = { @PROP( key = "cost", value = "1.5", type = GraphDescription.PropType.DOUBLE ) } ),
@Override public Map<String, Node> create( GraphDatabaseService graphdb ) { Map<String, Node> result = new HashMap<>(); try ( Transaction tx = graphdb.beginTx() ) { graphdb.index().getRelationshipAutoIndexer().setEnabled( autoIndexRelationships ); for ( NODE def : nodes ) { Node node = init( graphdb.createNode(), def.setNameProperty() ? def.name() : null, def.properties(), graphdb.index().getNodeAutoIndexer(), autoIndexNodes ); for ( LABEL label : def.labels() ) { node.addLabel( label( label.value() ) ); } result.put( def.name(), node ); } for ( REL def : rels ) { init( result.get( def.start() ).createRelationshipTo( result.get( def.end() ), RelationshipType.withName( def.type() ) ), def.setNameProperty() ? def.name() : null, def.properties(), graphdb.index().getRelationshipAutoIndexer(), autoIndexRelationships ); } tx.success(); } return result; }
@Graph( nodes = { @NODE( name = "source", setNameProperty = true ), @NODE( name = "middle", setNameProperty = true ), @NODE( name = "sink", setNameProperty = true ) }, relationships = { @REL( start = "source", end = "middle", type = "CONNECTED", properties = { @PROP( key = "capacity", value = "1", type = PropType.INTEGER ) } ), @REL( start = "middle", end = "sink", type = "CONNECTED", properties = { @PROP( key = "capacity", value = "3", type = PropType.INTEGER ) } ),
@Test @Graph( nodes = { @NODE( name = "a", setNameProperty = true ), @NODE( name = "b", setNameProperty = true ), @NODE( name = "c", setNameProperty = true ), @NODE( name = "d", setNameProperty = true ), @NODE( name = "e", setNameProperty = true ), @NODE( name = "f", setNameProperty = true ) }, relationships = { @REL( start = "a", end = "b", type = "to", properties = { @PROP( key = "cost", value = "1.5", type = GraphDescription.PropType.DOUBLE ) } ),
@Test @Graph( nodes = { @NODE( name = "a", setNameProperty = true ), @NODE( name = "b", setNameProperty = true ), @NODE( name = "c", setNameProperty = true ), @NODE( name = "d", setNameProperty = true ), @NODE( name = "e", setNameProperty = true ), @NODE( name = "f", setNameProperty = true ) }, relationships = { @REL( start = "a", end = "b", type = "to", properties = { @PROP( key = "cost", value = "1", type = GraphDescription.PropType.INTEGER ) } ),
@Graph( value = { "I know you" }, nodes = { @NODE( name = "I", properties = { @PROP( key = "name", value = "me" ) } ) } ) private void verifyIKnowYou( String type, String myName ) { try ( Transaction ignored = graphdb.beginTx() ) { Map<String, Node> graph = data.get(); assertEquals( "Wrong graph size.", 2, graph.size() ); Node iNode = graph.get( "I" ); assertNotNull( "The node 'I' was not defined", iNode ); Node you = graph.get( "you" ); assertNotNull( "The node 'you' was not defined", you ); assertEquals( "'I' has wrong 'name'.", myName, iNode.getProperty( "name" ) ); assertEquals( "'you' has wrong 'name'.", "you", you.getProperty( "name" ) ); Iterator<Relationship> rels = iNode.getRelationships().iterator(); assertTrue( "'I' has too few relationships", rels.hasNext() ); Relationship rel = rels.next(); assertEquals( "'I' is not related to 'you'", you, rel.getOtherNode( iNode ) ); assertEquals( "Wrong relationship type.", type, rel.getType().name() ); assertFalse( "'I' has too many relationships", rels.hasNext() ); rels = you.getRelationships().iterator(); assertTrue( "'you' has too few relationships", rels.hasNext() ); rel = rels.next(); assertEquals( "'you' is not related to 'i'", iNode, rel.getOtherNode( you ) ); assertEquals( "Wrong relationship type.", type, rel.getType().name() ); assertFalse( "'you' has too many relationships", rels.hasNext() ); assertEquals( "wrong direction", iNode, rel.getStartNode() ); } }
/** * It is not allowed to remove entries manually from automatic indexes. */ @Test @Graph( nodes = {@NODE( name = "I", setNameProperty = true )}, autoIndexNodes = true ) public void autoindexed_items_cannot_be_removed_manually() { long id = data.get() .get( "I" ) .getId(); String indexName; try ( Transaction tx = graphdb().beginTx() ) { indexName = graphdb().index().getNodeAutoIndexer().getAutoIndex().getName(); tx.success(); } gen.get() .expectedStatus( 405 ) .delete( getDataUri() + "index/node/" + indexName + "/name/I/" + id ) .entity(); gen.get() .expectedStatus( 405 ) .delete( getDataUri() + "index/node/" + indexName + "/name/" + id ) .entity(); gen.get() .expectedStatus( 405 ) .delete( getDataUri() + "index/node/" + indexName + "/" + id ) .entity(); }
@Test @Documented( "Get nodes by label and property.\n" + "\n" + "You can retrieve all nodes with a given label and property by passing one property as a query parameter.\n" + "Notice that the property value is JSON-encoded and then URL-encoded.\n" + "\n" + "If there is an index available on the label/property combination you send, that index will be used. If no\n" + "index is available, all nodes with the given label will be filtered through to find matching nodes.\n" + "\n" + "Currently, it is not possible to search using multiple properties." ) @GraphDescription.Graph( nodes = {@NODE( name = "Donald Sutherland", labels = {@LABEL( "Person" )} ), @NODE( name = "Clint Eastwood", labels = {@LABEL( "Person" )}, properties = { @PROP( key = "name", value = "Clint Eastwood" )} ), @NODE( name = "Steven Spielberg", labels = {@LABEL( "Person" )}, properties = { @PROP( key = "name", value = "Steven Spielberg" )} )} ) public void get_nodes_with_label_and_property() throws JsonParseException, UnsupportedEncodingException { data.get(); String labelName = "Person"; String result = gen.get() .expectedStatus( 200 ) .get( getNodesWithLabelAndPropertyUri( labelName, "name", "Clint Eastwood" ) ) .entity(); List<?> parsed = (List<?>) readJson( result ); assertEquals( asSet( "Clint Eastwood" ), Iterables.asSet( map( getProperty( "name", String.class ), parsed ) ) ); }
@Test @Title( "Retrieve query metadata" ) @Documented( "By passing in an additional GET parameter when you execute Cypher queries, metadata about the " + "query will be returned, such as how many labels were added or removed by the query." ) @Graph( nodes = {@NODE( name = "I", setNameProperty = true, labels = {@LABEL( "Director" )} )} ) public void testQueryStatistics() throws JsonParseException { // Given String script = createScript( "MATCH (n {name: 'I'}) SET n:Actor REMOVE n:Director RETURN labels(n)" ); // When Map<String,Object> output = jsonToMap( doCypherRestCall( cypherUri() + "?includeStats=true", script, Status.OK ) ); // Then @SuppressWarnings( "unchecked" ) Map<String,Object> stats = (Map<String,Object>) output.get( "stats" ); assertThat( stats, isA( Map.class ) ); assertThat( stats.get( "contains_updates" ), is( true ) ); assertThat( stats.get( "labels_added" ), is( 1 ) ); assertThat( stats.get( "labels_removed" ), is( 1 ) ); assertThat( stats.get( "nodes_created" ), is( 0 ) ); assertThat( stats.get( "nodes_deleted" ), is( 0 ) ); assertThat( stats.get( "properties_set" ), is( 0 ) ); assertThat( stats.get( "relationships_created" ), is( 0 ) ); assertThat( stats.get( "relationship_deleted" ), is( 0 ) ); }
@Test @Documented( "List all labels.\n" + " \n" + "By default, the server will return labels in use only. If you also want to return labels not in use,\n" + "append the \"in_use=0\" query parameter." ) @GraphDescription.Graph( nodes = { @NODE( name = "Clint Eastwood", setNameProperty = true, labels = { @LABEL( "Person" ), @LABEL( "Actor" ), @LABEL( "Director" ) } ), @NODE( name = "Donald Sutherland", setNameProperty = true, labels = { @LABEL( "Person" ), @LABEL( "Actor" ) } ), @NODE( name = "Steven Spielberg", setNameProperty = true, labels = { @LABEL( "Person" ), @LABEL( "Director" ) } ) } ) public void list_all_labels() throws JsonParseException { data.get(); String uri = getLabelsUri(); String body = gen.get() .expectedStatus( 200 ) .get( uri ) .entity(); Set<?> parsed = Iterables.asSet((List<?>) readJson( body )); assertTrue( parsed.contains( "Person" ) ); assertTrue( parsed.contains( "Actor" ) ); assertTrue( parsed.contains( "Director" ) ); }
@Test @Graph( nodes = { @NODE( name = "I", properties = { @PROP( key = "name", value = "me" ), @PROP( key = "bool", value = "true", type = GraphDescription.PropType.BOOLEAN ) } ), @NODE( name = "you", setNameProperty = true ) }, relationships = { @REL( start = "I", end = "you", type = "knows", properties = { @PROP( key = "name", value = "relProp" ), @PROP( key = "valid", value = "true", type = GraphDescription.PropType.BOOLEAN ) } ) }, autoIndexRelationships = true ) public void canCreateMoreInvolvedGraphWithPropertiesAndAutoIndex() { data.get(); verifyIKnowYou( "knows", "me" ); try ( Transaction ignored = graphdb.beginTx() ) { assertEquals( true, data.get().get( "I" ).getProperty( "bool" ) ); assertFalse( "node autoindex enabled.", graphdb().index().getNodeAutoIndexer().isEnabled() ); try ( IndexHits<Relationship> relationships = graphdb().index() .getRelationshipAutoIndexer().getAutoIndex().get( "name", "relProp" ) ) { assertTrue( "can't look up rel.", relationships.hasNext() ); } assertTrue( "relationship autoindex enabled.", graphdb().index().getRelationshipAutoIndexer().isEnabled() ); } }
/** * It is not allowed to add items manually to automatic indexes. */ @Test @Graph( nodes = {@NODE( name = "I" ), @NODE( name = "you" )}, relationships = {@REL( start = "I", end = "you", type = "know", properties = {@PROP( key = "since", value = "today" )} )}, autoIndexRelationships = true ) public void items_can_not_be_added_manually_to_a_Relationship_AutoIndex() { data.get(); String indexName; try ( Transaction tx = graphdb().beginTx() ) { indexName = graphdb().index().getRelationshipAutoIndexer().getAutoIndex().getName(); tx.success(); } try ( Transaction tx = graphdb().beginTx() ) { ResourceIterable<Relationship> relationships = (ResourceIterable<Relationship>) data.get().get( "I" ).getRelationships(); try ( ResourceIterator<Relationship> resourceIterator = relationships.iterator() ) { gen.get().expectedStatus( 405 ) .payload( createJsonStringFor( getRelationshipUri( resourceIterator.next() ), "name", "I" ) ) .post( postRelationshipIndexUri( indexName ) ).entity(); } } }
@Test @Documented( "Get nodes by label and array property." ) @GraphDescription.Graph( nodes = {@NODE( name = "Donald Sutherland", labels = {@LABEL( "Person" )} ), @NODE( name = "Clint Eastwood", labels = {@LABEL( "Person" )}, properties = { @PROP( key = "names", value = "Clint,Eastwood", type = ARRAY, componentType = STRING )} ), @NODE( name = "Steven Spielberg", labels = {@LABEL( "Person" )}, properties = { @PROP( key = "names", value = "Steven,Spielberg", type = ARRAY, componentType = STRING )} )} ) public void get_nodes_with_label_and_array_property() throws JsonParseException, UnsupportedEncodingException { data.get(); String labelName = "Person"; String uri = getNodesWithLabelAndPropertyUri( labelName, "names", new String[] { "Clint", "Eastwood" } ); String result = gen.get() .expectedStatus( 200 ) .get( uri ) .entity(); List<?> parsed = (List<?>) readJson( result ); assertEquals( 1, parsed.size() ); //noinspection AssertEqualsBetweenInconvertibleTypes assertEquals( Iterables.asSet( asList( asList( "Clint", "Eastwood" ) ) ), Iterables.asSet( map( getProperty( "names", List.class ), parsed ) ) ); }
@Test @Title( "Profile a query" ) @Documented( "By passing in an extra parameter, you can ask the cypher executor to return a profile of the " + "query as it is executed. This can help in locating bottlenecks." ) @Graph( nodes = {@NODE( name = "I", setNameProperty = true ), @NODE( name = "you", setNameProperty = true ), @NODE( name = "him", setNameProperty = true, properties = { @PROP( key = "age", value = "25", type = GraphDescription.PropType.INTEGER )} )}, relationships = { @REL( start = "I", end = "him", type = "know", properties = {} ), @REL( start = "I", end = "you", type = "know", properties = {} )} ) public void testProfiling() throws Exception { String script = createScript( "MATCH (x)-[r]->(n) WHERE id(x) = %I% RETURN type(r), n.name, n.age" ); // WHEN String response = doCypherRestCall( cypherUri() + "?profile=true", script, Status.OK ); // THEN Map<String,Object> des = jsonToMap( response ); assertThat( des.get( "plan" ), instanceOf( Map.class ) ); @SuppressWarnings( "unchecked" ) Map<String,Object> plan = (Map<String,Object>) des.get( "plan" ); assertThat( plan.get( "name" ), instanceOf( String.class ) ); assertThat( plan.get( "children" ), instanceOf( Collection.class ) ); assertThat( plan.get( "rows" ), instanceOf( Number.class ) ); assertThat( plan.get( "dbHits" ), instanceOf( Number.class ) ); }
private static void createIfAbsent( Map<String, NODE> nodes, String name, String ... labels ) { if ( !nodes.containsKey( name ) ) { nodes.put( name, new DefaultNode( name, labels ) ); } else { NODE preexistingNode = nodes.get( name ); // Join with any new labels HashSet<String> joinedLabels = new HashSet<>( asList( labels ) ); for ( LABEL label : preexistingNode.labels() ) { joinedLabels.add( label.value() ); } String[] labelNameArray = joinedLabels.toArray(new String[joinedLabels.size()]); nodes.put( name, new NodeWithAddedLabels( preexistingNode, labelNameArray ) ); } }
/** * It is not allowed to add items manually to automatic indexes. */ @Test @Graph( nodes = {@NODE( name = "I", setNameProperty = true )}, autoIndexNodes = true ) public void items_can_not_be_added_manually_to_an_AutoIndex() { data.get(); String indexName; try ( Transaction tx = graphdb().beginTx() ) { indexName = graphdb().index().getNodeAutoIndexer().getAutoIndex().getName(); tx.success(); } gen.get() .expectedStatus( 405 ) .payload( createJsonStringFor( getNodeUri( data.get() .get( "I" ) ), "name", "I" ) ) .post( postNodeIndexUri( indexName ) ) .entity(); }
@Documented( "Set property on node.\n" + "\n" + "Setting different properties will retain the existing ones for this node.\n" + "Note that a single value are submitted not as a map but just as a value\n" + "(which is valid JSON) like in the example\n" + "below." ) @Graph( nodes = {@NODE( name = "jim", properties = {@PROP( key = "foo2", value = "bar2" )} )} ) @Test public void shouldReturn204WhenPropertyIsSet() throws Exception { Node jim = data.get().get( "jim" ); gen.get().payload( JsonHelper.createJsonFrom( "bar" ) ).expectedStatus( 204 ).put( getPropertyUri( jim, "foo" ).toString() ); assertThat( jim, inTx(graphdb(), hasProperty( "foo" ) ) ); assertThat( jim, inTx(graphdb(), hasProperty( "foo2" ) ) ); }
@Documented( "Listing labels for a node." ) @Test @GraphDescription.Graph( nodes = {@NODE( name = "Clint Eastwood", labels = {@LABEL( "Actor" ), @LABEL( "Director" )}, setNameProperty = true )} ) public void listing_node_labels() throws JsonParseException { Map<String, Node> nodes = data.get(); String nodeUri = getNodeUri( nodes.get( "Clint Eastwood" ) ); String body = gen.get() .expectedStatus( 200 ) .get( nodeUri + "/labels" ) .entity(); @SuppressWarnings( "unchecked" ) List<String> labels = (List<String>) readJson( body ); assertEquals( asSet( "Actor", "Director" ), Iterables.asSet( labels ) ); }