Fix bug to handle cache data import into client LOCAL Regions when no PDX type registry exists.
Resolves gh-91.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.geode.boot.autoconfigure.data;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
import org.springframework.geode.boot.autoconfigure.DataImportExportAutoConfiguration;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import example.app.golf.model.Golfer;
|
||||
|
||||
/**
|
||||
* Integration Tests for {@link DataImportExportAutoConfiguration}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.context.annotation.Profile
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.geode.boot.autoconfigure.DataImportExportAutoConfiguration
|
||||
* @see org.springframework.test.context.ActiveProfiles
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@ActiveProfiles("IMPORT-LOCAL")
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(
|
||||
classes = LocalClientCacheDataImportAutoConfigurationIntegrationTests.TestGeodeClientConfiguration.class,
|
||||
properties = "spring.boot.data.gemfire.cache.data.import.active-profiles=IMPORT-LOCAL"
|
||||
)
|
||||
public class LocalClientCacheDataImportAutoConfigurationIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unused")
|
||||
private GemfireTemplate golfersTemplate;
|
||||
|
||||
@Test
|
||||
public void golfersWereLoaded() {
|
||||
|
||||
assertThat(this.golfersTemplate).isNotNull();
|
||||
assertThat(this.golfersTemplate.getRegion()).isNotNull();
|
||||
assertThat(this.golfersTemplate.getRegion().getName()).isEqualTo("Golfers");
|
||||
assertThat(this.golfersTemplate.getRegion()).hasSize(1);
|
||||
|
||||
Object value = this.golfersTemplate.get(1L);
|
||||
|
||||
assertThat(value).isInstanceOf(Golfer.class);
|
||||
|
||||
Golfer golfer = (Golfer) value;
|
||||
|
||||
assertThat(golfer).isNotNull();
|
||||
assertThat(golfer.getId()).isEqualTo(1L);
|
||||
assertThat(golfer.getName()).isEqualTo("John Blum");
|
||||
assertThat(golfer.getHandicap()).isEqualTo(9);
|
||||
}
|
||||
|
||||
@Profile("IMPORT-LOCAL")
|
||||
@SpringBootApplication
|
||||
@EnableEntityDefinedRegions(basePackageClasses = Golfer.class, clientRegionShortcut = ClientRegionShortcut.LOCAL)
|
||||
static class TestGeodeClientConfiguration { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"@type" : "example.app.golf.model.Golfer",
|
||||
"id" : 1,
|
||||
"name" : "John Blum",
|
||||
"handicap" : 9
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
package org.springframework.geode.data.json.converter.support;
|
||||
|
||||
import org.apache.geode.pdx.JSONFormatter;
|
||||
import org.apache.geode.pdx.JSONFormatterException;
|
||||
import org.apache.geode.pdx.PdxInstance;
|
||||
|
||||
import org.springframework.geode.data.json.converter.JsonToObjectConverter;
|
||||
import org.springframework.geode.data.json.converter.JsonToPdxConverter;
|
||||
import org.springframework.geode.pdx.ObjectPdxInstanceAdapter;
|
||||
import org.springframework.geode.pdx.PdxInstanceWrapper;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
@@ -34,12 +37,62 @@ import org.springframework.lang.NonNull;
|
||||
*/
|
||||
public class JSONFormatterJsonToPdxConverter implements JsonToPdxConverter {
|
||||
|
||||
private JsonToObjectConverter converter = newJsonToObjectConverter();
|
||||
|
||||
// TODO configure via an SPIs
|
||||
private JsonToObjectConverter newJsonToObjectConverter() {
|
||||
return new JacksonJsonToObjectConverter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the configured {@link JsonToObjectConverter} used to convert from {@link String JSON}
|
||||
* to an {@link Object}.
|
||||
*
|
||||
* @return a reference to the configured {@link JsonToObjectConverter}; never {@literal null}.
|
||||
* @see org.springframework.geode.data.json.converter.JsonToObjectConverter
|
||||
*/
|
||||
protected @NonNull JsonToObjectConverter getJsonToObjectConverter() {
|
||||
return this.converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public final @NonNull PdxInstance convert(@NonNull String json) {
|
||||
return convertJsonToPdx(json);
|
||||
|
||||
try {
|
||||
return convertJsonToPdx(json);
|
||||
}
|
||||
catch (JSONFormatterException cause) {
|
||||
return convertJsonToObjectToPdx(json);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts the given {@link Object} as a {@link PdxInstance}.
|
||||
*
|
||||
* @param target {@link Object} to adapt as PDX; must not be {@literal null}.
|
||||
* @return a {@link PdxInstance} representing the given {@link Object}.
|
||||
* @see org.springframework.geode.pdx.ObjectPdxInstanceAdapter#from(Object)
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
*/
|
||||
protected @NonNull PdxInstance adapt(@NonNull Object target) {
|
||||
return ObjectPdxInstanceAdapter.from(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link String JSON} into a {@link Object} and then adapts the {@link Object}
|
||||
* as a {@link PdxInstance}.
|
||||
*
|
||||
* @param json {@link String JSON} to convert into an {@link Object} into PDX.
|
||||
* @return a {@link PdxInstance} converted from the given {@link String JSON}.
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see #getJsonToObjectConverter()
|
||||
* @see #adapt(Object)
|
||||
*/
|
||||
protected @NonNull PdxInstance convertJsonToObjectToPdx(@NonNull String json) {
|
||||
return adapt(getJsonToObjectConverter().convert(json));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,8 +100,6 @@ public class JSONFormatterJsonToPdxConverter implements JsonToPdxConverter {
|
||||
*
|
||||
* @param json {@link String} containing JSON to convert to PDX; must not be {@literal null}.
|
||||
* @return JSON for the given {@link PdxInstance PDX}.
|
||||
* @see org.springframework.geode.pdx.PdxInstanceWrapper#from(PdxInstance)
|
||||
* @see org.apache.geode.pdx.JSONFormatter#fromJSON(String)
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see #jsonFormatterFromJson(String)
|
||||
* @see #wrap(PdxInstance)
|
||||
@@ -74,6 +125,7 @@ public class JSONFormatterJsonToPdxConverter implements JsonToPdxConverter {
|
||||
*
|
||||
* @param pdxInstance {@link PdxInstance} to wrap.
|
||||
* @return a new instance of {@link PdxInstanceWrapper} wrapping the given {@link PdxInstance}.
|
||||
* @see org.springframework.geode.pdx.PdxInstanceWrapper#from(PdxInstance)
|
||||
* @see org.springframework.geode.pdx.PdxInstanceWrapper
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.geode.data.json.converter.support;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -25,10 +26,15 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.geode.pdx.JSONFormatterException;
|
||||
import org.apache.geode.pdx.PdxInstance;
|
||||
|
||||
import org.springframework.geode.data.json.converter.JsonToObjectConverter;
|
||||
import org.springframework.geode.pdx.ObjectPdxInstanceAdapter;
|
||||
import org.springframework.geode.pdx.PdxInstanceWrapper;
|
||||
|
||||
import example.app.crm.model.Customer;
|
||||
|
||||
/**
|
||||
* Unit Tests for {@link JSONFormatterJsonToPdxConverter}.
|
||||
*
|
||||
@@ -36,7 +42,9 @@ import org.springframework.geode.pdx.PdxInstanceWrapper;
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see org.springframework.geode.data.json.converter.JsonToObjectConverter
|
||||
* @see org.springframework.geode.data.json.converter.support.JSONFormatterJsonToPdxConverter
|
||||
* @see org.springframework.geode.pdx.ObjectPdxInstanceAdapter
|
||||
* @see org.springframework.geode.pdx.PdxInstanceWrapper
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@@ -62,4 +70,30 @@ public class JSONFormatterJsonToPdxConverterUnitTests {
|
||||
verify(converter, times(1)).jsonFormatterFromJson(eq(json));
|
||||
verify(converter, times(1)).wrap(eq(mockPdxInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertCallsConvertJsonToObjectToPdx() {
|
||||
|
||||
String json = "{ \"name\": \"Jon Doe\" }";
|
||||
|
||||
JsonToObjectConverter mockJsonToObjectConverter = mock(JsonToObjectConverter.class);
|
||||
|
||||
Customer jonDoe = Customer.newCustomer(1L, "Jon Doe");
|
||||
|
||||
JSONFormatterJsonToPdxConverter converter = spy(new JSONFormatterJsonToPdxConverter());
|
||||
|
||||
doThrow(new JSONFormatterException("TEST")).when(converter).convertJsonToPdx(eq(json));
|
||||
doReturn(mockJsonToObjectConverter).when(converter).getJsonToObjectConverter();
|
||||
doReturn(jonDoe).when(mockJsonToObjectConverter).convert(eq(json));
|
||||
|
||||
PdxInstance pdx = converter.convert(json);
|
||||
|
||||
assertThat(pdx).isInstanceOf(ObjectPdxInstanceAdapter.class);
|
||||
assertThat(pdx.getObject()).isSameAs(jonDoe);
|
||||
|
||||
verify(converter, times(1)).convertJsonToPdx(eq(json));
|
||||
verify(converter, times(1)).convertJsonToObjectToPdx(eq(json));
|
||||
verify(converter, times(1)).getJsonToObjectConverter();
|
||||
verify(mockJsonToObjectConverter, times(1)).convert(eq(json));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user