added tests for server plugin support

added tests for multiple index addition of an entity
This commit is contained in:
Michael Hunger
2011-04-14 12:09:19 +02:00
parent 281f6316a4
commit aaef3b62aa
8 changed files with 230 additions and 14 deletions

View File

@@ -26,16 +26,15 @@ import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
public class RestTestBase {
protected RestGraphDatabase graphDb;
private static final String HOSTNAME = "localhost";
private static final int PORT = 7473;
private static LocalTestServer neoServer = new LocalTestServer(HOSTNAME,PORT).withPropertiesFile("test-db.properties");
private static final String SERVER_ROOT_URI = "http://" + HOSTNAME + ":" + PORT + "/db/data/";
public static final int PORT = 7473;
protected static LocalTestServer neoServer = new LocalTestServer(HOSTNAME,PORT).withPropertiesFile("test-db.properties");
public static final String SERVER_ROOT_URI = "http://" + HOSTNAME + ":" + PORT + "/db/data/";
@BeforeClass
public static void startDb() throws Exception {
@@ -44,7 +43,7 @@ public class RestTestBase {
}
@Before
public void setUp() throws URISyntaxException {
public void setUp() throws Exception {
cleanDb();
graphDb = new RestGraphDatabase(new URI(SERVER_ROOT_URI));
}

View File

@@ -0,0 +1,74 @@
/**
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.graph.neo4j.rest.support;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.data.graph.neo4j.Person;
import org.springframework.data.graph.neo4j.server.ProvidedClassPathXmlApplicationContext;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.springframework.data.graph.neo4j.Person.persistedPerson;
/**
* @author mh
* @since 14.04.11
*/
public class ServerPluginTest extends RestTestBase {
private Person person;
@BeforeClass
public static void init() {
new ProvidedClassPathXmlApplicationContext(neoServer.getGraphDatabase(), "Plugin-context.xml");
}
@Override
public void setUp() throws Exception {
super.setUp();
person = persistedPerson("Michael", 35);
}
@Test
public void testGetFriends() throws IOException {
final ClientResponse response = createRequest("ext/TestServerPlugin/graphdb/person").post(ClientResponse.class, "{\"name\":\"" + person.getName() + "\"}");
assertEquals(200,response.getStatus());
final String result = response.getEntity(String.class);
final Map data = (Map) new ObjectMapper().readValue(result, Object.class);
assertEquals(person.getName(),((Map)data.get("data")).get("Person.name"));
}
private ClientResponse post(String uriSuffix, String params) {
return createRequest(uriSuffix).post(ClientResponse.class, params);
}
private static WebResource.Builder createRequest(String uriSuffix) {
return Client.create().
resource(SERVER_ROOT_URI + uriSuffix).
type(MediaType.APPLICATION_JSON).
accept(MediaType.APPLICATION_JSON);
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.graph.neo4j.rest.support;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.server.plugins.*;
import org.springframework.context.ApplicationContext;
import org.springframework.data.graph.neo4j.Friendship;
import org.springframework.data.graph.neo4j.Person;
import org.springframework.data.graph.neo4j.PersonRepository;
import org.springframework.data.graph.neo4j.server.ProvidedClassPathXmlApplicationContext;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
/**
* @author mh
* @since 14.04.11
*/
@Description("A test plugin for spring data graph usage")
public class TestServerPlugin extends ServerPlugin {
private ApplicationContext ctx;
private PersonRepository personRepository;
private GraphDatabaseContext graphDatabaseContext;
public TestServerPlugin() {
System.out.println("Initializing ServerPlugin");
}
@Name( "person")
@PluginTarget(GraphDatabaseService.class)
public Node person(@Source GraphDatabaseService graphDb, @Parameter(name="name") String name) {
context(graphDb);
final Person result = personRepository.findByPropertyValue(Person.NAME_INDEX, "Person.name",name);
return result!=null ? result.getPersistentState() : null;
}
private synchronized ApplicationContext context(GraphDatabaseService graphDb) {
if (ctx==null) {
ctx = new ProvidedClassPathXmlApplicationContext(graphDb, "Plugin-context.xml");
personRepository = ctx.getBean(PersonRepository.class);
graphDatabaseContext = ctx.getBean(GraphDatabaseContext.class);
}
return ctx;
}
@Name( "get_all_friends" )
@Description("gets all friends of the given node")
@PluginTarget(Node.class)
public Iterable<Node> allFriendsOf(@Source Node target) {
context(target.getGraphDatabase());
final Person person = graphDatabaseContext.createEntityFromState(target, Person.class);
return new IterableWrapper<Node, Friendship>(person.getFriendships()) {
@Override
protected Node underlyingObjectToObject(Friendship friendship) {
return friendship.getPerson2().getPersistentState();
}
};
}
}

View File

@@ -0,0 +1 @@
org.springframework.data.graph.neo4j.rest.support.TestServerPlugin

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:datagraph="http://www.springframework.org/schema/data/graph"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/data/graph http://www.springframework.org/schema/data/graph/datagraph-1.0.xsd">
<datagraph:config graphDatabaseService="graphDatabaseService"/>
<datagraph:repositories base-package="org.springframework.data.graph.neo4j"/>
</beans>

View File

@@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFactory;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.index.Index;
import org.neo4j.index.lucene.ValueContext;
import org.springframework.data.graph.annotation.NodeEntity;
import org.springframework.data.graph.core.GraphBacked;
import org.springframework.data.graph.neo4j.annotation.Indexed;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
@@ -61,7 +60,7 @@ public class IndexingPropertyFieldAccessorListenerFactory<S extends PropertyCont
Class<T> graphBacked = (Class<T>) field.getDeclaringClass();
Index<? extends PropertyContainer> index = getIndex(field,graphBacked);
String indexKey = getIndexKey(field);
return (FieldAccessListener<T, ?>) new IndexingPropertyFieldAccessorListener(field, index, indexKey);
return (FieldAccessListener<T, ?>) new IndexingPropertyFieldAccessorListener(index, indexKey);
}
private String getIndexKey(Field field) {
@@ -101,7 +100,7 @@ public class IndexingPropertyFieldAccessorListenerFactory<S extends PropertyCont
protected final String indexKey;
private final Index<T> index;
public IndexingPropertyFieldAccessorListener(final Field field, final Index<T> index, final String indexKey) {
public IndexingPropertyFieldAccessorListener(final Index<T> index, final String indexKey) {
this.index = index;
this.indexKey = indexKey;
}
@@ -110,8 +109,13 @@ public class IndexingPropertyFieldAccessorListenerFactory<S extends PropertyCont
public void valueChanged(GraphBacked<T> graphBacked, Object oldVal, Object newVal) {
if (newVal instanceof Number) newVal = ValueContext.numeric((Number) newVal);
if (newVal==null) index.remove(graphBacked.getPersistentState(), indexKey, null);
else index.add(graphBacked.getPersistentState(), indexKey, newVal);
}
final T state = graphBacked.getPersistentState();
//index.remove(state, indexKey);
if (newVal == null) {
index.remove(state, indexKey);
} else {
index.add(state, indexKey, newVal);
}
}
}
}

View File

@@ -28,7 +28,7 @@ public class ProvidedClassPathXmlApplicationContext extends ClassPathXmlApplicat
private final GraphDatabaseService database;
public ProvidedClassPathXmlApplicationContext(GraphDatabaseService database, final String[] locations)
public ProvidedClassPathXmlApplicationContext(GraphDatabaseService database, final String... locations)
throws org.springframework.beans.BeansException {
super();
setConfigLocations(locations);

View File

@@ -45,6 +45,7 @@ import java.util.Collection;
import java.util.HashSet;
import static org.junit.Assert.*;
import static org.springframework.data.graph.neo4j.Person.NAME_INDEX;
import static org.springframework.data.graph.neo4j.Person.persistedPerson;
@RunWith(SpringJUnit4ClassRunner.class)
@@ -95,7 +96,7 @@ public class IndexTest {
Person me = persistedPerson(NAME_VALUE, 35);
Person spouse = persistedPerson(NAME_VALUE3, 36);
me.setSpouse(spouse);
final Person foundMe = this.personRepository.findByPropertyValue(Person.NAME_INDEX, "Person.name", NAME_VALUE);
final Person foundMe = this.personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE);
assertEquals(spouse, foundMe.getSpouse());
}
@@ -241,7 +242,7 @@ public class IndexTest {
@Transactional
public void testFindAllPersonByIndexOnAnnotatedField() {
Person person = persistedPerson(NAME_VALUE, 35);
final Person found = personRepository.findByPropertyValue(Person.NAME_INDEX, "Person.name", NAME_VALUE);
final Person found = personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE);
assertEquals(person, found);
}
@@ -288,6 +289,46 @@ public class IndexTest {
Assert.assertEquals("indexed node found", node, nodeIndex.get(NAME, NAME_VALUE).next());
}
@Test
@Transactional
public void testNodeCanbBeIndexedTwice() {
final Person p = persistedPerson(NAME_VALUE2, 30);
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE2));
p.setName(NAME_VALUE);
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE));
p.setName(NAME_VALUE2);
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE2));
}
@Test
public void testNodeCanbBeIndexedTwiceInDifferentTransactions() {
Transaction tx = null;
final Person p;
try {
tx = graphDatabaseContext.beginTx();
p = persistedPerson(NAME_VALUE2, 30);
tx.success();
} finally {
tx.finish();
}
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE2));
try {
tx = graphDatabaseContext.beginTx();
p.setName(NAME_VALUE);
tx.success();
} finally {
tx.finish();
}
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE));
try {
tx = graphDatabaseContext.beginTx();
p.setName(NAME_VALUE2);
tx.success();
} finally {
tx.finish();
}
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "Person.name", NAME_VALUE2));
}
@Test
@Transactional
public void testRelationshipIsIndexed() {