From 8fb61ef348c02595ff5ba962845e6092ae3d929c Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 5 Mar 2014 13:01:16 -0800 Subject: [PATCH] Adding additional test cases to re-inforce my feedback comments, specifically testing the Region 'Key' type and Entity '@Id property' type mismatch and constraint check in the GemfireRepositoryFactory.getTemplate(..) method, lines 128 and 129. --- .../gemfire/repository/sample/Animal.java | 6 +- .../sample/AnimalRepositoryTest.java | 45 +++++++--- .../data/gemfire/repository/sample/Plant.java | 85 +++++++++++++++++++ .../repository/sample/PlantRepository.java | 39 +++++++++ .../sample/PlantRepositoryTest.java | 58 +++++++++++++ .../repository/sample/RabbitRepository.java | 42 +++++++++ .../sample/AnimalRepositoryTest-context.xml | 6 ++ .../sample/PlantRepositoryTest-context.xml | 30 +++++++ 8 files changed, 296 insertions(+), 15 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/repository/sample/Plant.java create mode 100644 src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepository.java create mode 100644 src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/repository/sample/RabbitRepository.java create mode 100644 src/test/resources/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest-context.xml diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/Animal.java b/src/test/java/org/springframework/data/gemfire/repository/sample/Animal.java index 12c3c085..232e1502 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/sample/Animal.java +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/Animal.java @@ -10,15 +10,15 @@ import org.springframework.util.ObjectUtils; public class Animal { @Id - private long id; + private Long id; private String name; - public long getId() { + public Long getId() { return id; } - public void setId(long id) { + public void setId(Long id) { this.id = id; } diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest.java b/src/test/java/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest.java index 8ec7bc1c..52f83fa4 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest.java +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest.java @@ -2,6 +2,7 @@ package org.springframework.data.gemfire.repository.sample; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; @@ -12,6 +13,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Stuart Williams * @author John Blum + * @link https://github.com/spring-projects/spring-data-gemfire/pull/55 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @@ -24,6 +26,9 @@ public class AnimalRepositoryTest { @Autowired private DogRepository dogRepo; + @Autowired + private RabbitRepository rabbitRepo; + protected static Animal createAnimal(final long id, final String name) { Animal animal = new Animal(); animal.setId(id); @@ -32,17 +37,17 @@ public class AnimalRepositoryTest { } @Test - public void testAnimals() { + public void testEntityStoredInMultipleRegions() { Animal felix = createAnimal(1, "Felix"); Animal leo = createAnimal(2, "Leo"); - Animal credo = createAnimal(3, "Credo"); + Animal cerberus = createAnimal(3, "Cerberus"); Animal fido = createAnimal(1, "Fido"); assertNotNull(catRepo.save(felix)); assertNotNull(catRepo.save(leo)); - assertNotNull(catRepo.save(credo)); + assertNotNull(catRepo.save(cerberus)); assertNotNull(dogRepo.save(fido)); - assertNotNull(dogRepo.save(credo)); + assertNotNull(dogRepo.save(cerberus)); assertEquals(3L, catRepo.count()); assertEquals(2L, dogRepo.count()); @@ -54,21 +59,37 @@ public class AnimalRepositoryTest { assertEquals(leo, foundLeo); - Animal foundCredoTheCat = catRepo.findByName("Credo"); + Animal foundCerberusTheCat = catRepo.findByName("Cerberus"); - assertEquals(credo, foundCredoTheCat); - assertEquals(foundCredoTheCat, catRepo.findBy("Credo")); - assertEquals(foundCredoTheCat, catRepo.findOne(3L)); + assertEquals(cerberus, foundCerberusTheCat); + assertEquals(foundCerberusTheCat, catRepo.findBy("Cerberus")); + assertEquals(foundCerberusTheCat, catRepo.findOne(3L)); Animal foundFido = dogRepo.findBy("Fido"); assertEquals(fido, foundFido); - Animal foundCredoTheDog = dogRepo.findByName("Credo"); + Animal foundCerberusTheDog = dogRepo.findByName("Cerberus"); - assertEquals(credo, foundCredoTheDog); - assertEquals(foundCredoTheDog, dogRepo.findBy("Credo")); - assertEquals(foundCredoTheDog, dogRepo.findOne(3L)); + assertEquals(cerberus, foundCerberusTheDog); + assertEquals(foundCerberusTheDog, dogRepo.findBy("Cerberus")); + assertEquals(foundCerberusTheDog, dogRepo.findOne(3L)); + } + + @Test(expected = ClassCastException.class) + public void testStoreAnimalHavingLongIdInRabbitsRegionWithStringKey() { + try { + rabbitRepo.save(createAnimal(123L, "Harry")); + } + // NOTE the ClassCastException thrown from GemFire is expected; this is not correct and the identifying type + // mismatch should have been caught by GemfireRepositoryFactory.getTemplate(..) method on line 129 + // (appropriately throwing an IllegalArgumentException) after satisfying the condition on line 128, + // if only the @Region annotation were set on the domain class/entity! + catch (ClassCastException unexpected) { + //unexpected.printStackTrace(System.err); + assertTrue(unexpected.getMessage().contains("key ( java.lang.Long ) does not satisfy keyConstraint ( java.lang.String )")); + throw unexpected; + } } } diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/Plant.java b/src/test/java/org/springframework/data/gemfire/repository/sample/Plant.java new file mode 100644 index 00000000..026d3aa3 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/Plant.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2013 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.gemfire.repository.sample; + +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.Region; +import org.springframework.util.ObjectUtils; + +/** + * The Plant class is a very simple ADT modeling a plant for SDG Repository testing purposes. + *

+ * @author John Blum + * @see org.springframework.data.annotation.Id + * @see org.springframework.data.gemfire.mapping.Region + * @since 1.4.0 + */ +@Region("Plants") +@SuppressWarnings("unused") +public class Plant { + + @Id + private String id; + + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof Animal)) { + return false; + } + + Animal that = (Animal) obj; + + return ObjectUtils.nullSafeEquals(this.getId(), that.getId()) + && ObjectUtils.nullSafeEquals(this.getName(), that.getName()); + } + + @Override + public int hashCode() { + int hashValue = 17; + hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId()); + hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getName()); + return hashValue; + } + + @Override + public String toString() { + return String.format("{ type = %1$s, id = %2$s, name = %3$s }", getClass().getSimpleName(), getId(), getName()); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepository.java b/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepository.java new file mode 100644 index 00000000..e11294b1 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepository.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2013 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.gemfire.repository.sample; + +import org.springframework.data.gemfire.repository.GemfireRepository; +import org.springframework.data.gemfire.repository.Query; + +/** + * The PlantRepository class is a Repository extension for accessing and storing Plants. + * Note, this Spring GemFire Repository extension incorrectly maps Plants to the Plants Region on purpose + *

+ * @author John Blum + * @see org.springframework.data.gemfire.repository.GemfireRepository + * @see org.springframework.data.gemfire.repository.Query + * @since 1.4.0 + */ +@SuppressWarnings("unused") +public interface PlantRepository extends GemfireRepository { + + Animal findByName(String name); + + @Query("SELECT * FROM /Placeholder x WHERE x.name = $1") + Animal findBy(String name); + +} diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest.java b/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest.java new file mode 100644 index 00000000..d4918c76 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2013 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.gemfire.repository.sample; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * The PlantRepositoryTest class is a test suite of test cases testing the functionality behind PR #55 involving + * persisting application domain object/entities to multiple Regions in GemFire's Cache. + *

+ * @author John Blum + * @see org.springframework.context.ApplicationContext + * @since 1.4.0 + * @link https://github.com/spring-projects/spring-data-gemfire/pull/55 + */ +public class PlantRepositoryTest { + + protected static final String APPLICATION_CONTEXT_CONFIG_LOCATION = + "/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest-context.xml"; + + @Test(expected = IllegalArgumentException.class) + public void testStorePlantHavingStringIdInPlantsRegionWithLongKey() { + try { + ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_CONFIG_LOCATION); + context.getBean(PlantRepository.class); + } + // NOTE technically, the IllegalArgumentException for incompatible Region 'Key' and Entity ID is thrown + // when the Spring container starts up and the Repository beans are created. + catch (BeanCreationException expected) { + //expected.printStackTrace(System.err); + assertTrue(expected.getCause() instanceof IllegalArgumentException); + assertEquals(String.format("The region referenced only supports keys of type %1$s but the entity to be stored has an id of type %2$s!", + Long.class, String.class), expected.getCause().getMessage()); + throw (IllegalArgumentException) expected.getCause(); + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/RabbitRepository.java b/src/test/java/org/springframework/data/gemfire/repository/sample/RabbitRepository.java new file mode 100644 index 00000000..c9b7c79a --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/RabbitRepository.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2013 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.gemfire.repository.sample; + +import org.springframework.data.gemfire.mapping.Region; +import org.springframework.data.gemfire.repository.GemfireRepository; +import org.springframework.data.gemfire.repository.Query; + +/** + * The RabbitRepository class is a Spring Data GemFire Repository extension for accessing and persistent Rabbits + * from/to an underlying data store (GemFire). + *

+ * @author John Blum + * @see org.springframework.data.gemfire.mapping.Region + * @see org.springframework.data.gemfire.repository.GemfireRepository + * @see org.springframework.data.gemfire.repository.Query + * @since 1.4.0 + */ +@Region("Rabbits") +@SuppressWarnings("unused") +public interface RabbitRepository extends GemfireRepository { + + Animal findByName(String name); + + @Query("SELECT * FROM /Placeholder x WHERE x.name = $1") + Animal findBy(String name); + +} diff --git a/src/test/resources/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest-context.xml index ac42ea6f..e39a8304 100644 --- a/src/test/resources/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/repository/sample/AnimalRepositoryTest-context.xml @@ -31,6 +31,12 @@ key-constraint="java.lang.Long" value-constraint="org.springframework.data.gemfire.repository.sample.Animal"/> + + diff --git a/src/test/resources/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest-context.xml new file mode 100644 index 00000000..dd250a30 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/repository/sample/PlantRepositoryTest-context.xml @@ -0,0 +1,30 @@ + + + + + springGemFirePlantRepositoryTest + config + 0 + + + + + + + + +