From 01df5ddb5fa8891a66bd807e6efb37e5404cb70d Mon Sep 17 00:00:00 2001 From: John Blum Date: Fri, 16 Feb 2018 18:11:19 -0800 Subject: [PATCH] DATAGEODE-84 - Fix CI test failures caused by changes in Spring Data Commons CDI Repository support allowing unlimited implementation classes. --- .../cdi/GemfireRepositoryExtension.java | 22 +++- .../cdi/GemfireRepositoryBeanTest.java | 120 +++++++++++------- 2 files changed, 86 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryExtension.java b/src/main/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryExtension.java index 9dc364d4..822f8cd0 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryExtension.java +++ b/src/main/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryExtension.java @@ -50,10 +50,9 @@ public class GemfireRepositoryExtension extends CdiRepositoryExtensionSupport { protected final Logger logger = LoggerFactory.getLogger(getClass()); - final Map, Bean> mappingContexts = - new HashMap, Bean>(); + final Map, Bean> mappingContexts = new HashMap<>(); - final Set> regionBeans = new HashSet>(); + final Set> regionBeans = new HashSet<>(); /* (non-Javadoc) */ public GemfireRepositoryExtension() { @@ -71,22 +70,29 @@ public class GemfireRepositoryExtension extends CdiRepositoryExtensionSupport { */ @SuppressWarnings("unchecked") void processBean(@Observes ProcessBean processBean) { + Bean bean = processBean.getBean(); for (Type type : bean.getTypes()) { - Type resolvedType = (type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type); + + Type resolvedType = type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type; if (resolvedType instanceof Class) { + Class classType = (Class) resolvedType; if (Region.class.isAssignableFrom(classType)) { + logger.debug("Found Region bean with name {}", bean.getName()); - regionBeans.add((Bean) bean); + + this.regionBeans.add((Bean) bean); } else if (GemfireMappingContext.class.isAssignableFrom(classType)) { + logger.debug("Discovered {} bean with types {} having qualifiers {}", GemfireMappingContext.class.getName(), bean.getTypes(), bean.getQualifiers()); - mappingContexts.put(bean.getQualifiers(), (Bean) bean); + + this.mappingContexts.put(bean.getQualifiers(), (Bean) bean); } } } @@ -104,8 +110,11 @@ public class GemfireRepositoryExtension extends CdiRepositoryExtensionSupport { * @see javax.enterprise.event.Observes */ void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { + for (Map.Entry, Set> entry : getRepositoryTypes()) { + Class repositoryType = entry.getKey(); + Set qualifiers = entry.getValue(); // Create the bean representing the Repository. @@ -130,5 +139,4 @@ public class GemfireRepositoryExtension extends CdiRepositoryExtensionSupport { return new GemfireRepositoryBean(beanManager, repositoryType, qualifiers, getCustomImplementationDetector(), gemfireMappingContextBean, regionBeans); } - } diff --git a/src/test/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryBeanTest.java index 228e0b32..5424fa3e 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/repository/cdi/GemfireRepositoryBeanTest.java @@ -30,12 +30,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.springframework.data.gemfire.util.ArrayUtils.asArray; -import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.AbstractMap; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -56,12 +55,17 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.data.gemfire.GemfireAccessor; import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.mapping.GemfireMappingContext; import org.springframework.data.gemfire.repository.GemfireRepository; import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory; import org.springframework.data.gemfire.repository.support.SimpleGemfireRepository; +import org.springframework.data.gemfire.util.CollectionUtils; +import org.springframework.data.repository.config.CustomRepositoryImplementationDetector; /** * The GemfireRepositoryBeanTest class is a test suite of test cases testing the contract and functionality @@ -88,47 +92,48 @@ public class GemfireRepositoryBeanTest { @Mock private BeanManager mockBeanManager; - protected T[] asArray(T... array) { - return array; + private CustomRepositoryImplementationDetector newCustomRepositoryImplementationDetector() { + + MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class); + + return new CustomRepositoryImplementationDetector(mockMetadataReaderFactory, + new StandardEnvironment(), new DefaultResourceLoader()); } - protected Set asSet(T... array) { - return new HashSet(Arrays.asList(array)); - } - - protected Set asSet(Iterable collection) { - Set set = new HashSet(); - - for (T element : collection) { - set.add(element); - } - - return set; + private Set toSet(Iterable collection) { + return CollectionUtils.addAll(new HashSet<>(), collection); } @Test public void getDependencyInstanceGetsReference() { + Bean mockRegionBean = mock(Bean.class); + CreationalContext mockCreationalContext = mock(CreationalContext.class); + Region mockRegion = mock(Region.class); when(mockBeanManager.createCreationalContext(eq(mockRegionBean))).thenReturn(mockCreationalContext); when(mockBeanManager.getReference(eq(mockRegionBean), eq(Region.class), eq(mockCreationalContext))) .thenReturn(mockRegion); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, null); + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), null, null); assertThat(repositoryBean.getDependencyInstance(mockRegionBean, Region.class), is(equalTo(mockRegion))); verify(mockBeanManager, times(1)).createCreationalContext(eq(mockRegionBean)); - verify(mockBeanManager, times(1)).getReference(eq(mockRegionBean), eq(Region.class), eq(mockCreationalContext)); + verify(mockBeanManager, times(1)) + .getReference(eq(mockRegionBean), eq(Region.class), eq(mockCreationalContext)); } @Test public void resolveGemfireMappingContextUsesDefault() { - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, null); + + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), null, null); assertThat(repositoryBean.resolveGemfireMappingContext(), is(equalTo(GemfireRepositoryBean.DEFAULT_GEMFIRE_MAPPING_CONTEXT))); @@ -136,17 +141,20 @@ public class GemfireRepositoryBeanTest { @Test public void resolveGemfireMappingContextUsesQualifiedMappingContext() { + Bean mockMappingContextBean = mock(Bean.class); + CreationalContext mockCreationalContext = mock(CreationalContext.class); + GemfireMappingContext expectedGemfireMappingContext = new GemfireMappingContext(); when(mockBeanManager.createCreationalContext(eq(mockMappingContextBean))).thenReturn(mockCreationalContext); when(mockBeanManager.getReference(eq(mockMappingContextBean), eq(GemfireMappingContext.class), eq(mockCreationalContext))).thenReturn(expectedGemfireMappingContext); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, - mockMappingContextBean, null); + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), mockMappingContextBean, null); GemfireMappingContext actualGemfireMappingContext = repositoryBean.resolveGemfireMappingContext(); @@ -159,6 +167,7 @@ public class GemfireRepositoryBeanTest { @Test public void resolveGemfireRegions() { + Region mockRegionOne = mock(Region.class); Region mockRegionTwo = mock(Region.class); @@ -167,21 +176,22 @@ public class GemfireRepositoryBeanTest { Bean mockRegionBeanOne = mock(Bean.class); Bean mockRegionBeanTwo = mock(Bean.class); - when(mockRegionBeanOne.getTypes()).thenReturn(asSet((Type) Region.class)); - when(mockRegionBeanTwo.getTypes()).thenReturn(asSet((Type) Region.class)); + when(mockRegionBeanOne.getTypes()).thenReturn(CollectionUtils.asSet((Type) Region.class)); + when(mockRegionBeanTwo.getTypes()).thenReturn(CollectionUtils.asSet((Type) Region.class)); when(mockBeanManager.createCreationalContext(any(Bean.class))).thenReturn(mockCreationalContext); when(mockBeanManager.getReference(eq(mockRegionBeanOne), eq(Region.class), eq(mockCreationalContext))) .thenReturn(mockRegionOne); when(mockBeanManager.getReference(eq(mockRegionBeanTwo), eq(Region.class), eq(mockCreationalContext))) .thenReturn(mockRegionTwo); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean(mockBeanManager, - PersonRepository.class, Collections.emptySet(), null, null, asSet(mockRegionBeanOne, mockRegionBeanTwo)); + GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean(this.mockBeanManager, PersonRepository.class, + Collections.emptySet(), newCustomRepositoryImplementationDetector(), null, + CollectionUtils.asSet(mockRegionBeanOne, mockRegionBeanTwo)); Iterable regions = repositoryBean.resolveGemfireRegions(); assertThat(regions, is(notNullValue())); - assertThat(asSet(regions).containsAll(asSet(mockRegionOne, mockRegionTwo)), is(true)); + assertThat(toSet(regions).containsAll(CollectionUtils.asSet(mockRegionOne, mockRegionTwo)), is(true)); verify(mockRegionBeanOne, times(1)).getTypes(); verify(mockRegionBeanTwo, times(1)).getTypes(); @@ -195,15 +205,17 @@ public class GemfireRepositoryBeanTest { @Test public void resolveTypeFindsTargetComponentType() { + Bean mockBean = mock(Bean.class); - when(mockBean.getTypes()).thenReturn( - asSet((Type) Object.class, Map.class, ConcurrentMap.class, Region.class)); + when(mockBean.getTypes()) + .thenReturn(CollectionUtils.asSet((Type) Object.class, Map.class, ConcurrentMap.class, Region.class)); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, null); + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), null, null); - assertThat(repositoryBean.resolveType(mockBean, Region.class), is(equalTo((Type) Region.class))); + assertThat(repositoryBean.resolveType(mockBean, Region.class), is(equalTo(Region.class))); assertThat(repositoryBean.resolveType(mockBean, Map.class), isIn(asArray((Type) Map.class, ConcurrentMap.class, Region.class))); @@ -212,21 +224,25 @@ public class GemfireRepositoryBeanTest { @Test public void resolveTypeWithParameterizedType() { + Bean mockBean = mock(Bean.class); + Map parameterizedTypeMap = Collections.emptyMap(); + ParameterizedType mockParameterizedType = mock(ParameterizedType.class); assertThat(parameterizedTypeMap.getClass(), is(instanceOf(Type.class))); assertThat(parameterizedTypeMap.getClass().getGenericSuperclass(), is(instanceOf(ParameterizedType.class))); assertThat(parameterizedTypeMap.getClass().getTypeParameters().length, is(equalTo(2))); - when(mockBean.getTypes()).thenReturn(asSet((Type) mockParameterizedType)); + when(mockBean.getTypes()).thenReturn(CollectionUtils.asSet((Type) mockParameterizedType)); when(mockParameterizedType.getRawType()).thenReturn(parameterizedTypeMap.getClass()); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, null); + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), null, null); - assertThat(repositoryBean.resolveType(mockBean, Map.class), is(equalTo((Type) mockParameterizedType))); + assertThat(repositoryBean.resolveType(mockBean, Map.class), is(equalTo(mockParameterizedType))); verify(mockBean, times(1)).getTypes(); verify(mockParameterizedType, times(1)).getRawType(); @@ -234,12 +250,14 @@ public class GemfireRepositoryBeanTest { @Test public void resolveTypeWithUnresolvableType() { + Bean mockBean = mock(Bean.class); - when(mockBean.getTypes()).thenReturn(asSet((Type) Map.class, Object.class)); + when(mockBean.getTypes()).thenReturn(CollectionUtils.asSet((Type) Map.class, Object.class)); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, null); + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean<>(this.mockBeanManager, PersonRepository.class, Collections.emptySet(), + newCustomRepositoryImplementationDetector(), null, null); try { expectedException.expect(IllegalStateException.class); @@ -258,6 +276,7 @@ public class GemfireRepositoryBeanTest { @Test // IntegrationTest public void createGemfireRepositoryInstanceSuccessfully() throws Exception { + Bean mockRegionBean = mock(Bean.class); CreationalContext> mockCreationalContext = mock(CreationalContext.class); @@ -269,19 +288,22 @@ public class GemfireRepositoryBeanTest { when(mockRegion.getName()).thenReturn("Person"); when(mockRegion.getAttributes()).thenReturn(mockRegionAttributes); when(mockRegionAttributes.getKeyConstraint()).thenReturn(Long.class); - when(mockRegionBean.getTypes()).thenReturn(asSet((Type) Region.class)); + when(mockRegionBean.getTypes()).thenReturn(CollectionUtils.asSet((Type) Region.class)); when(mockBeanManager.createCreationalContext(any(Bean.class))).thenReturn(mockCreationalContext); when(mockBeanManager.getReference(eq(mockRegionBean), eq(Region.class), eq(mockCreationalContext))) .thenReturn(mockRegion); final AtomicBoolean repositoryProxyPostProcessed = new AtomicBoolean(false); - GemfireRepositoryBean repositoryBean = new GemfireRepositoryBean( - mockBeanManager, PersonRepository.class, Collections.emptySet(), null, null, - asSet(mockRegionBean)) + GemfireRepositoryBean repositoryBean = + new GemfireRepositoryBean(this.mockBeanManager, PersonRepository.class, + Collections.emptySet(), newCustomRepositoryImplementationDetector(), null, + CollectionUtils.asSet(mockRegionBean)) { + @Override GemfireRepositoryFactory newGemfireRepositoryFactory() { + GemfireRepositoryFactory gemfireRepositoryFactory = super.newGemfireRepositoryFactory(); gemfireRepositoryFactory.addRepositoryProxyPostProcessor((factory, repositoryInformation) -> { @@ -303,10 +325,11 @@ public class GemfireRepositoryBeanTest { repositoryProxyPostProcessed.set(true); } - catch (Exception e) { - throw new RuntimeException(e); + catch (Exception cause) { + throw new RuntimeException(cause); } }); + return gemfireRepositoryFactory; } }; @@ -334,7 +357,6 @@ public class GemfireRepositoryBeanTest { class Person {} - interface PersonRepository extends GemfireRepository { - } + interface PersonRepository extends GemfireRepository { } }