SGF-553 - Use SDG's MappingPdxSerializer as the default PdxSerializer when PDX is configured with @EnablePdx.

This commit is contained in:
John Blum
2016-10-05 18:51:41 -07:00
parent e486765021
commit 6a5f2f7a36
6 changed files with 407 additions and 56 deletions

View File

@@ -37,7 +37,9 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
@@ -45,6 +47,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
@@ -52,6 +55,8 @@ import org.springframework.data.gemfire.config.support.CustomEditorBeanFactoryPo
import org.springframework.data.gemfire.config.support.DefinedIndexesApplicationListener;
import org.springframework.data.gemfire.config.support.DiskStoreDirectoryBeanPostProcessor;
import org.springframework.data.gemfire.config.support.PdxDiskStoreAwareBeanFactoryPostProcessor;
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
import org.springframework.data.gemfire.mapping.MappingPdxSerializer;
import org.springframework.data.gemfire.util.PropertiesBuilder;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -118,6 +123,9 @@ public abstract class AbstractCacheConfiguration implements BeanClassLoaderAware
private GatewayConflictResolver gatewayConflictResolver;
@Autowired(required = false)
private GemfireMappingContext mappingContext;
private List<JndiDataSource> jndiDataSources;
private List<TransactionListener> transactionListeners;
@@ -306,20 +314,16 @@ public abstract class AbstractCacheConfiguration implements BeanClassLoaderAware
* @see <a href="http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/data_serialization/gemfire_pdx_serialization.html">GemFire PDX Serialization</a>
*/
protected void configurePdx(AnnotationMetadata importMetadata) {
if (importMetadata.hasAnnotation(EnablePdx.class.getName())) {
Map<String, Object> enablePdxAttributes = importMetadata.getAnnotationAttributes(EnablePdx.class.getName());
String enablePdxTypeName = EnablePdx.class.getName();
String pdxSerializerBeanName = (String) enablePdxAttributes.get("serializerBeanName");
if (importMetadata.hasAnnotation(enablePdxTypeName)) {
Map<String, Object> enablePdxAttributes = importMetadata.getAnnotationAttributes(enablePdxTypeName);
if (beanFactory().containsBean(pdxSerializerBeanName)) {
PdxSerializer pdxSerializer = beanFactory().getBean(pdxSerializerBeanName, PdxSerializer.class);
setPdxDiskStoreName((String) enablePdxAttributes.get("diskStoreName"));
setPdxIgnoreUnreadFields(Boolean.TRUE.equals(enablePdxAttributes.get("ignoreUnreadFields")));
setPdxPersistent(Boolean.TRUE.equals(enablePdxAttributes.get("persistent")));
setPdxReadSerialized(Boolean.TRUE.equals(enablePdxAttributes.get("readSerialized")));
setPdxSerializer(pdxSerializer);
}
setPdxDiskStoreName((String) enablePdxAttributes.get("diskStoreName"));
setPdxIgnoreUnreadFields(Boolean.TRUE.equals(enablePdxAttributes.get("ignoreUnreadFields")));
setPdxPersistent(Boolean.TRUE.equals(enablePdxAttributes.get("persistent")));
setPdxReadSerialized(Boolean.TRUE.equals(enablePdxAttributes.get("readSerialized")));
setPdxSerializer(resolvePdxSerializer((String) enablePdxAttributes.get("serializerBeanName")));
}
}
@@ -333,6 +337,27 @@ public abstract class AbstractCacheConfiguration implements BeanClassLoaderAware
protected void configureOther(AnnotationMetadata importMetadata) {
}
/* (non-Javadoc) */
protected PdxSerializer resolvePdxSerializer(String pdxSerializerBeanName) {
BeanFactory beanFactory = beanFactory();
PdxSerializer pdxSerializer = pdxSerializer();
return (beanFactory.containsBean(pdxSerializerBeanName)
? beanFactory.getBean(pdxSerializerBeanName, PdxSerializer.class)
: (pdxSerializer != null ? pdxSerializer : newPdxSerializer()));
}
/* (non-Javadoc) */
@SuppressWarnings("unchecked")
protected <T extends PdxSerializer> T newPdxSerializer() {
BeanFactory beanFactory = beanFactory();
ConversionService conversionService = (beanFactory instanceof ConfigurableBeanFactory
? ((ConfigurableBeanFactory) beanFactory).getConversionService() : null);
return (T) MappingPdxSerializer.create(this.mappingContext, conversionService);
}
/* (non-Javadoc) */
protected void registerCustomEditorBeanFactoryPostProcessor(AnnotationMetadata importMetadata) {
if (CUSTOM_EDITORS_REGISTERED.compareAndSet(false, true)) {
@@ -484,6 +509,25 @@ public abstract class AbstractCacheConfiguration implements BeanClassLoaderAware
return (annotationType.equals(getAnnotationType()) && importMetadata.hasAnnotation(getAnnotationTypeName()));
}
/**
* Determines whether this is a GemFire {@link com.gemstone.gemfire.cache.server.CacheServer} or
* {@link com.gemstone.gemfire.cache.Cache peer cache} application, which is indicated by the presence
* of either the {@link CacheServerApplication} annotation or the {@link PeerCacheApplication} annotation
* on a Spring application {@link org.springframework.context.annotation.Configuration @Configuration} class.
*
* @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
* from the annotations used to configure the Spring application.
* @return a boolean value indicating whether this is a GemFire cache server or peer cache application.
* @see org.springframework.core.type.AnnotationMetadata
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
* @see #isCacheServerApplication(AnnotationMetadata)
* @see #isPeerCacheApplication(AnnotationMetadata)
*/
protected boolean isCacheServerOrPeerCacheApplication(AnnotationMetadata importMetadata) {
return (isCacheServerApplication(importMetadata) || isPeerCacheApplication(importMetadata));
}
/**
* Determine whether this Spring application is a {@link com.gemstone.gemfire.cache.server.CacheServer},
* {@link com.gemstone.gemfire.cache.client.ClientCache} or a {@link com.gemstone.gemfire.cache.Cache} application.
@@ -654,6 +698,15 @@ public abstract class AbstractCacheConfiguration implements BeanClassLoaderAware
return defaultIfNull(this.logLevel, DEFAULT_LOG_LEVEL);
}
/* (non-Javadoc) */
void setMappingContext(GemfireMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
protected GemfireMappingContext mappingContext() {
return this.mappingContext;
}
void setMcastPort(Integer mcastPort) {
this.mcastPort = mcastPort;
setLocators(DEFAULT_LOCATORS);

View File

@@ -82,12 +82,13 @@ public class PeerCacheConfiguration extends AbstractCacheConfiguration {
* @param importMetadata {@link AnnotationMetadata} containing peer cache meta-data used to configure
* the GemFire peer {@link com.gemstone.gemfire.cache.Cache}.
* @see org.springframework.core.type.AnnotationMetadata
* @see #isCacheServerOrPeerCacheApplication(AnnotationMetadata)
*/
@Override
protected void configureCache(AnnotationMetadata importMetadata) {
super.configureCache(importMetadata);
if (isPeerCacheApplication(importMetadata) || isCacheServerApplication(importMetadata)) {
if (isCacheServerOrPeerCacheApplication(importMetadata)) {
Map<String, Object> peerCacheApplicationAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());

View File

@@ -40,6 +40,7 @@ import org.springframework.util.StringUtils;
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration
* @since 1.9.0
*/
@SuppressWarnings("unused")
@@ -102,11 +103,13 @@ public abstract class EmbeddedServiceConfigurationSupport implements ImportBeanD
* {@inheritDoc}
*/
@Override
public final void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
public final void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
if (isAnnotationPresent(importingClassMetadata)) {
Map<String, Object> annotationAttributes = getAnnotationAttributes(importingClassMetadata);
registerBeanDefinitions(importingClassMetadata, annotationAttributes, registry);
setGemFireProperties(registry, annotationAttributes);
setGemFireProperties(importingClassMetadata, annotationAttributes, registry);
}
}
@@ -117,7 +120,9 @@ public abstract class EmbeddedServiceConfigurationSupport implements ImportBeanD
}
/* (non-Javadoc) */
protected void setGemFireProperties(BeanDefinitionRegistry registry, Map<String, Object> annotationAttributes) {
protected void setGemFireProperties(AnnotationMetadata importingClassMetadata,
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
Properties gemfireProperties = toGemFireProperties(annotationAttributes);
if (hasProperties(gemfireProperties)) {

View File

@@ -18,6 +18,10 @@ package org.springframework.data.gemfire.mapping;
import java.util.Collections;
import java.util.Map;
import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializer;
import com.gemstone.gemfire.pdx.PdxWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
@@ -36,14 +40,10 @@ import org.springframework.data.mapping.model.PersistentEntityParameterValueProv
import org.springframework.data.mapping.model.SpELContext;
import org.springframework.util.Assert;
import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializer;
import com.gemstone.gemfire.pdx.PdxWriter;
/**
* GemFire {@link PdxSerializer} implementation that uses a Spring Data GemFire {@link GemfireMappingContext}
* to read and write entities.
*
*
* @author Oliver Gierke
* @author David Turanski
* @author John Blum
@@ -74,8 +74,34 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
private SpELContext context;
/**
* Creates a new {@link MappingPdxSerializer} using the default
* {@link GemfireMappingContext} and {@link DefaultConversionService}.
* Factory method to construct a new instance of the {@link MappingPdxSerializer} initialized with the given
* {@link GemfireMappingContext} and Spring {@link ConversionService}. If either the {@link GemfireMappingContext}
* or Spring {@link ConversionService} are {@literal null}, then this factory method will construct default
* instances of each.
*
* @param mappingContext {@link GemfireMappingContext} used by this {@link PdxSerializer} to handle mappings
* between application domain object types and PDX Serialization meta-data/data.
* @param conversionService Spring's {@link ConversionService} used to convert PDX deserialized data to application
* object property types.
* @return an initialized instance of the {@link MappingPdxSerializer}.
* @see org.springframework.core.convert.ConversionService
* @see org.springframework.data.gemfire.mapping.MappingPdxSerializer
*/
public static MappingPdxSerializer create(GemfireMappingContext mappingContext,
ConversionService conversionService) {
mappingContext = (mappingContext != null ? mappingContext : new GemfireMappingContext());
conversionService = (conversionService != null ? conversionService : new DefaultConversionService());
return new MappingPdxSerializer(mappingContext, conversionService);
}
/**
* Creates a new {@link MappingPdxSerializer} using the default {@link GemfireMappingContext}
* and {@link DefaultConversionService}.
*
* @see org.springframework.core.convert.support.DefaultConversionService
* @see org.springframework.data.gemfire.mapping.GemfireMappingContext
*/
public MappingPdxSerializer() {
this(new GemfireMappingContext(), new DefaultConversionService());
@@ -100,11 +126,8 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
this.context = new SpELContext(PdxReaderPropertyAccessor.INSTANCE);
}
/*
* (non-Javadoc)
*
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(
* org.springframework.context.ApplicationContext)
/**
* {@inheritDoc}
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
@@ -151,11 +174,8 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
return mappingContext;
}
/*
* (non-Javadoc)
*
* @see com.gemstone.gemfire.pdx.PdxSerializer#fromData(java.lang.Class,
* com.gemstone.gemfire.pdx.PdxReader)
/**
* {@inheritDoc}
*/
@Override
public Object fromData(final Class<?> type, final PdxReader reader) {
@@ -205,11 +225,8 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
return accessor.getBean();
}
/*
* (non-Javadoc)
*
* @see com.gemstone.gemfire.pdx.PdxSerializer#toData(java.lang.Object,
* com.gemstone.gemfire.pdx.PdxWriter)
/**
* {@inheritDoc}
*/
@Override
public boolean toData(final Object value, final PdxWriter writer) {
@@ -240,7 +257,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
}
else {
writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType());
}
}
}
catch (Exception e) {
throw new MappingException(String.format(
@@ -298,5 +315,4 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
protected GemfirePersistentEntity<?> getPersistentEntity(Class<?> entityType) {
return getMappingContext().getPersistentEntity(entityType);
}
}

View File

@@ -0,0 +1,236 @@
/*
* Copyright 2016 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.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.HashMap;
import java.util.Map;
import com.gemstone.gemfire.pdx.PdxSerializer;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
import org.springframework.data.gemfire.mapping.MappingPdxSerializer;
import org.springframework.util.MethodInvoker;
/**
* Unit tests for {@link AbstractCacheConfiguration}.
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.runners.MockitoJUnitRunner
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration
* @since 1.9.0
*/
@RunWith(MockitoJUnitRunner.class)
public class AbstractCacheConfigurationUnitTests {
@Mock
private BeanFactory mockBeanFactory;
private TestCacheConfiguration cacheConfiguration;
@Before
public void setup() {
cacheConfiguration = new TestCacheConfiguration();
}
@SuppressWarnings("unchecked")
protected <T> T invokeMethod(Object obj, String methodName) throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(obj);
methodInvoker.setTargetMethod(methodName);
methodInvoker.prepare();
return (T) methodInvoker.invoke();
}
@Test
public void configurePdxWhenEnablePdxIsConfigured() {
AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class);
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
Map<String, Object> annotationAttributes = new HashMap<String, Object>(5);
annotationAttributes.put("diskStoreName", "BlockDiskStore");
annotationAttributes.put("ignoreUnreadFields", Boolean.FALSE);
annotationAttributes.put("persistent", Boolean.TRUE);
annotationAttributes.put("readSerialized", Boolean.TRUE);
annotationAttributes.put("serializerBeanName", "MockPdxSerializer");
when(mockAnnotationMetadata.hasAnnotation(eq(EnablePdx.class.getName()))).thenReturn(true);
when(mockAnnotationMetadata.getAnnotationAttributes(eq(EnablePdx.class.getName())))
.thenReturn(annotationAttributes);
when(mockBeanFactory.containsBean(eq("MockPdxSerializer"))).thenReturn(true);
when(mockBeanFactory.getBean(eq("MockPdxSerializer"), eq(PdxSerializer.class))).thenReturn(mockPdxSerializer);
cacheConfiguration.setBeanFactory(mockBeanFactory);
cacheConfiguration.configurePdx(mockAnnotationMetadata);
assertThat(cacheConfiguration.pdxDiskStoreName()).isEqualTo("BlockDiskStore");
assertThat(cacheConfiguration.pdxIgnoreUnreadFields()).isFalse();
assertThat(cacheConfiguration.pdxPersistent()).isTrue();
assertThat(cacheConfiguration.pdxReadSerialized()).isTrue();
assertThat(cacheConfiguration.pdxSerializer()).isEqualTo(mockPdxSerializer);
verify(mockAnnotationMetadata, times(1)).hasAnnotation(eq(EnablePdx.class.getName()));
verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnablePdx.class.getName()));
verify(mockBeanFactory, times(1)).containsBean(eq("MockPdxSerializer"));
verify(mockBeanFactory, times(1)).getBean(eq("MockPdxSerializer"), eq(PdxSerializer.class));
}
@Test
public void configurePdxWhenEnablePdxIsNotConfigured() {
AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class);
when(mockAnnotationMetadata.hasAnnotation(anyString())).thenReturn(false);
cacheConfiguration.configurePdx(mockAnnotationMetadata);
assertThat(cacheConfiguration.pdxDiskStoreName()).isNull();
assertThat(cacheConfiguration.pdxIgnoreUnreadFields()).isNull();
assertThat(cacheConfiguration.pdxPersistent()).isNull();
assertThat(cacheConfiguration.pdxReadSerialized()).isNull();
assertThat(cacheConfiguration.pdxSerializer()).isNull();
verify(mockAnnotationMetadata, times(1)).hasAnnotation(eq(EnablePdx.class.getName()));
verifyNoMoreInteractions(mockAnnotationMetadata);
}
@Test
public void resolvePdxSerializerUsesPdxSerializerBean() {
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(true);
when(mockBeanFactory.getBean(anyString(), eq(PdxSerializer.class))).thenReturn(mockPdxSerializer);
cacheConfiguration.setBeanFactory(mockBeanFactory);
PdxSerializer actualPdxSerializer = cacheConfiguration.resolvePdxSerializer("MockPdxSerializer");
assertThat(actualPdxSerializer).isEqualTo(mockPdxSerializer);
verify(mockBeanFactory, times(1)).containsBean(eq("MockPdxSerializer"));
verify(mockBeanFactory, times(1)).getBean(eq("MockPdxSerializer"), eq(PdxSerializer.class));
}
@Test
public void resolvePdxSerializerUsesConfiguredPdxSerializer() {
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(false);
cacheConfiguration.setBeanFactory(mockBeanFactory);
cacheConfiguration.setPdxSerializer(mockPdxSerializer);
PdxSerializer actualPdxSerializer = cacheConfiguration.resolvePdxSerializer("TestPdxSerializer");
assertThat(actualPdxSerializer).isEqualTo(mockPdxSerializer);
verify(mockBeanFactory, times(1)).containsBean(eq("TestPdxSerializer"));
verify(mockBeanFactory, never()).getBean(anyString(), eq(PdxSerializer.class));
verifyZeroInteractions(mockPdxSerializer);
}
@Test
public void resolvePdxSerializerCallsNewMappingPdxSerializer() {
AbstractCacheConfiguration cacheConfigurationSpy = spy(this.cacheConfiguration);
MappingPdxSerializer mockPdxSerializer = mock(MappingPdxSerializer.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(false);
doReturn(mockPdxSerializer).when(cacheConfigurationSpy).newPdxSerializer();
cacheConfigurationSpy.setBeanFactory(mockBeanFactory);
PdxSerializer actualPdxSerializer = cacheConfigurationSpy.resolvePdxSerializer("TestPdxSerializer");
assertThat(actualPdxSerializer).isEqualTo(mockPdxSerializer);
verify(mockBeanFactory, times(1)).containsBean(eq("TestPdxSerializer"));
verify(mockBeanFactory, never()).getBean(anyString(), eq(PdxSerializer.class));
verify(cacheConfigurationSpy, times(1)).newPdxSerializer();
}
@Test
public void newPdxSerializerUsesConfiguredConversionServiceAndMappingContext() throws Exception {
ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class);
ConversionService mockConversionService = mock(ConversionService.class);
GemfireMappingContext mockMappingContext = mock(GemfireMappingContext.class);
when(mockBeanFactory.getConversionService()).thenReturn(mockConversionService);
cacheConfiguration.setBeanFactory(mockBeanFactory);
cacheConfiguration.setMappingContext(mockMappingContext);
MappingPdxSerializer pdxSerializer = cacheConfiguration.newPdxSerializer();
assertThat(pdxSerializer).isNotNull();
assertThat(invokeMethod(pdxSerializer, "getConversionService")).isEqualTo(mockConversionService);
assertThat(invokeMethod(pdxSerializer, "getMappingContext")).isEqualTo(mockMappingContext);
verify(mockBeanFactory, times(1)).getConversionService();
verifyZeroInteractions(mockConversionService);
verifyZeroInteractions(mockMappingContext);
}
@Test
public void newPdxSerializerDefaultsConversionServiceAndMappingContextWhenNotConfigured() throws Exception {
cacheConfiguration.setBeanFactory(mockBeanFactory);
MappingPdxSerializer pdxSerializer = cacheConfiguration.newPdxSerializer();
assertThat(pdxSerializer).isNotNull();
assertThat(invokeMethod(pdxSerializer, "getConversionService")).isInstanceOf(ConversionService.class);
assertThat(invokeMethod(pdxSerializer, "getMappingContext")).isInstanceOf(GemfireMappingContext.class);
}
protected static class TestCacheConfiguration extends AbstractCacheConfiguration {
@Override
protected Class getAnnotationType() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
protected <T extends CacheFactoryBean> T newCacheFactoryBean() {
throw new UnsupportedOperationException("Not Implemented");
}
}
}

View File

@@ -15,15 +15,13 @@
*/
package org.springframework.data.gemfire.mapping;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.isA;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -31,6 +29,10 @@ import static org.mockito.Mockito.when;
import java.util.Collections;
import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializer;
import com.gemstone.gemfire.pdx.PdxWriter;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -46,13 +48,9 @@ import org.springframework.data.gemfire.repository.sample.Person;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.ParameterValueProvider;
import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializer;
import com.gemstone.gemfire.pdx.PdxWriter;
/**
* Unit tests for {@link MappingPdxSerializer}.
*
*
* @author Oliver Gierke
* @author John Blum
* @see org.junit.Rule
@@ -101,6 +99,49 @@ public class MappingPdxSerializerUnitTests {
Address.class, mockAddressSerializer));
}
@Test
public void createFullyInitialized() {
ConversionService mockConversionService = mock(ConversionService.class);
GemfireMappingContext mockMappingContext = mock(GemfireMappingContext.class);
MappingPdxSerializer pdxSerializer = MappingPdxSerializer.create(mockMappingContext, mockConversionService);
assertThat(pdxSerializer).isNotNull();
assertThat(pdxSerializer.getConversionService()).isEqualTo(mockConversionService);
assertThat(pdxSerializer.getMappingContext()).isEqualTo(mockMappingContext);
}
@Test
public void createWithNullConversionService() {
GemfireMappingContext mockMappingContext = mock(GemfireMappingContext.class);
MappingPdxSerializer pdxSerializer = MappingPdxSerializer.create(mockMappingContext, null);
assertThat(pdxSerializer).isNotNull();
assertThat(pdxSerializer.getConversionService()).isInstanceOf(ConversionService.class);
assertThat(pdxSerializer.getMappingContext()).isEqualTo(mockMappingContext);
}
@Test
public void createWithNullMappingContext() {
ConversionService mockConversionService = mock(ConversionService.class);
MappingPdxSerializer pdxSerializer = MappingPdxSerializer.create(null, mockConversionService);
assertThat(pdxSerializer).isNotNull();
assertThat(pdxSerializer.getConversionService()).isEqualTo(mockConversionService);
assertThat(pdxSerializer.getMappingContext()).isInstanceOf(GemfireMappingContext.class);
}
@Test
public void createWithNullConversionServiceAndNullMappingContext() {
MappingPdxSerializer pdxSerializer = MappingPdxSerializer.create(null, null);
assertThat(pdxSerializer).isNotNull();
assertThat(pdxSerializer.getConversionService()).isInstanceOf(ConversionService.class);
assertThat(pdxSerializer.getMappingContext()).isInstanceOf(GemfireMappingContext.class);
}
@Test
@SuppressWarnings("unchecked")
public void usesRegisteredInstantiator() {
@@ -142,14 +183,14 @@ public class MappingPdxSerializerUnitTests {
Object obj = serializer.fromData(Person.class, mockReader);
assertThat(obj, is(instanceOf(Person.class)));
assertThat(obj).isInstanceOf(Person.class);
Person jonDoe = (Person) obj;
assertThat(jonDoe.getAddress(), is(equalTo(expectedAddress)));
assertThat(jonDoe.getId(), is(equalTo(1l)));
assertThat(jonDoe.getFirstname(), is(equalTo("Jon")));
assertThat(jonDoe.getLastname(), is(equalTo("Doe")));
assertThat(jonDoe.getAddress()).isEqualTo(expectedAddress);
assertThat(jonDoe.getId()).isEqualTo(1l);
assertThat(jonDoe.getFirstname()).isEqualTo("Jon");
assertThat(jonDoe.getLastname()).isEqualTo("Doe");
verify(mockInstantiator, times(1)).createInstance(any(GemfirePersistentEntity.class), any(ParameterValueProvider.class));
verify(mockReader, times(1)).readField(eq("id"));
@@ -193,7 +234,7 @@ public class MappingPdxSerializerUnitTests {
serializer.setCustomSerializers(Collections.<Class<?>, PdxSerializer>singletonMap(
Address.class, mockAddressSerializer));
assertThat(serializer.toData(jonDoe, mockWriter), is(true));
assertThat(serializer.toData(jonDoe, mockWriter)).isTrue();
verify(mockAddressSerializer, times(1)).toData(eq(address), eq(mockWriter));
verify(mockWriter, times(1)).writeField(eq("id"), eq(1l), eq(Long.class));
@@ -231,5 +272,4 @@ public class MappingPdxSerializerUnitTests {
verify(mockWriter, never()).markIdentityField(anyString());
}
}
}