Skip to content

Commit 5318782

Browse files
committed
Fix bug to handle cache data import into client LOCAL Regions when no PDX type registry exists.
Resolves gh-91.
1 parent 98ee687 commit 5318782

File tree

4 files changed

+183
-3
lines changed

4 files changed

+183
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13+
* or implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
package org.springframework.geode.boot.autoconfigure.data;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
23+
import org.apache.geode.cache.client.ClientRegionShortcut;
24+
25+
import org.springframework.beans.factory.annotation.Autowired;
26+
import org.springframework.boot.autoconfigure.SpringBootApplication;
27+
import org.springframework.boot.test.context.SpringBootTest;
28+
import org.springframework.context.annotation.Profile;
29+
import org.springframework.data.gemfire.GemfireTemplate;
30+
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
31+
import org.springframework.geode.boot.autoconfigure.DataImportExportAutoConfiguration;
32+
import org.springframework.test.context.ActiveProfiles;
33+
import org.springframework.test.context.junit4.SpringRunner;
34+
35+
import example.app.golf.model.Golfer;
36+
37+
/**
38+
* Integration Tests for {@link DataImportExportAutoConfiguration}.
39+
*
40+
* @author John Blum
41+
* @see org.junit.Test
42+
* @see org.springframework.boot.autoconfigure.SpringBootApplication
43+
* @see org.springframework.boot.test.context.SpringBootTest
44+
* @see org.springframework.context.annotation.Profile
45+
* @see org.springframework.data.gemfire.GemfireTemplate
46+
* @see org.springframework.geode.boot.autoconfigure.DataImportExportAutoConfiguration
47+
* @see org.springframework.test.context.ActiveProfiles
48+
* @see org.springframework.test.context.junit4.SpringRunner
49+
* @since 1.3.0
50+
*/
51+
@ActiveProfiles("IMPORT-LOCAL")
52+
@RunWith(SpringRunner.class)
53+
@SpringBootTest(
54+
classes = LocalClientCacheDataImportAutoConfigurationIntegrationTests.TestGeodeClientConfiguration.class,
55+
properties = "spring.boot.data.gemfire.cache.data.import.active-profiles=IMPORT-LOCAL"
56+
)
57+
public class LocalClientCacheDataImportAutoConfigurationIntegrationTests {
58+
59+
@Autowired
60+
@SuppressWarnings("unused")
61+
private GemfireTemplate golfersTemplate;
62+
63+
@Test
64+
public void golfersWereLoaded() {
65+
66+
assertThat(this.golfersTemplate).isNotNull();
67+
assertThat(this.golfersTemplate.getRegion()).isNotNull();
68+
assertThat(this.golfersTemplate.getRegion().getName()).isEqualTo("Golfers");
69+
assertThat(this.golfersTemplate.getRegion()).hasSize(1);
70+
71+
Object value = this.golfersTemplate.get(1L);
72+
73+
assertThat(value).isInstanceOf(Golfer.class);
74+
75+
Golfer golfer = (Golfer) value;
76+
77+
assertThat(golfer).isNotNull();
78+
assertThat(golfer.getId()).isEqualTo(1L);
79+
assertThat(golfer.getName()).isEqualTo("John Blum");
80+
assertThat(golfer.getHandicap()).isEqualTo(9);
81+
}
82+
83+
@Profile("IMPORT-LOCAL")
84+
@SpringBootApplication
85+
@EnableEntityDefinedRegions(basePackageClasses = Golfer.class, clientRegionShortcut = ClientRegionShortcut.LOCAL)
86+
static class TestGeodeClientConfiguration { }
87+
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"@type" : "example.app.golf.model.Golfer",
3+
"id" : 1,
4+
"name" : "John Blum",
5+
"handicap" : 9
6+
}

spring-geode/src/main/java/org/springframework/geode/data/json/converter/support/JSONFormatterJsonToPdxConverter.java

+55-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
package org.springframework.geode.data.json.converter.support;
1717

1818
import org.apache.geode.pdx.JSONFormatter;
19+
import org.apache.geode.pdx.JSONFormatterException;
1920
import org.apache.geode.pdx.PdxInstance;
2021

22+
import org.springframework.geode.data.json.converter.JsonToObjectConverter;
2123
import org.springframework.geode.data.json.converter.JsonToPdxConverter;
24+
import org.springframework.geode.pdx.ObjectPdxInstanceAdapter;
2225
import org.springframework.geode.pdx.PdxInstanceWrapper;
2326
import org.springframework.lang.NonNull;
2427

@@ -34,21 +37,69 @@
3437
*/
3538
public class JSONFormatterJsonToPdxConverter implements JsonToPdxConverter {
3639

40+
private JsonToObjectConverter converter = newJsonToObjectConverter();
41+
42+
// TODO configure via an SPIs
43+
private JsonToObjectConverter newJsonToObjectConverter() {
44+
return new JacksonJsonToObjectConverter();
45+
}
46+
47+
/**
48+
* Returns a reference to the configured {@link JsonToObjectConverter} used to convert from {@link String JSON}
49+
* to an {@link Object}.
50+
*
51+
* @return a reference to the configured {@link JsonToObjectConverter}; never {@literal null}.
52+
* @see org.springframework.geode.data.json.converter.JsonToObjectConverter
53+
*/
54+
protected @NonNull JsonToObjectConverter getJsonToObjectConverter() {
55+
return this.converter;
56+
}
57+
3758
/**
3859
* @inheritDoc
3960
*/
4061
@Override
4162
public final @NonNull PdxInstance convert(@NonNull String json) {
42-
return convertJsonToPdx(json);
63+
64+
try {
65+
return convertJsonToPdx(json);
66+
}
67+
catch (JSONFormatterException cause) {
68+
return convertJsonToObjectToPdx(json);
69+
}
70+
}
71+
72+
/**
73+
* Adapts the given {@link Object} as a {@link PdxInstance}.
74+
*
75+
* @param target {@link Object} to adapt as PDX; must not be {@literal null}.
76+
* @return a {@link PdxInstance} representing the given {@link Object}.
77+
* @see org.springframework.geode.pdx.ObjectPdxInstanceAdapter#from(Object)
78+
* @see org.apache.geode.pdx.PdxInstance
79+
*/
80+
protected @NonNull PdxInstance adapt(@NonNull Object target) {
81+
return ObjectPdxInstanceAdapter.from(target);
82+
}
83+
84+
/**
85+
* Converts the given {@link String JSON} into a {@link Object} and then adapts the {@link Object}
86+
* as a {@link PdxInstance}.
87+
*
88+
* @param json {@link String JSON} to convert into an {@link Object} into PDX.
89+
* @return a {@link PdxInstance} converted from the given {@link String JSON}.
90+
* @see org.apache.geode.pdx.PdxInstance
91+
* @see #getJsonToObjectConverter()
92+
* @see #adapt(Object)
93+
*/
94+
protected @NonNull PdxInstance convertJsonToObjectToPdx(@NonNull String json) {
95+
return adapt(getJsonToObjectConverter().convert(json));
4396
}
4497

4598
/**
4699
* Converts the given {@link String JSON} to {@link PdxInstance PDX}.
47100
*
48101
* @param json {@link String} containing JSON to convert to PDX; must not be {@literal null}.
49102
* @return JSON for the given {@link PdxInstance PDX}.
50-
* @see org.springframework.geode.pdx.PdxInstanceWrapper#from(PdxInstance)
51-
* @see org.apache.geode.pdx.JSONFormatter#fromJSON(String)
52103
* @see org.apache.geode.pdx.PdxInstance
53104
* @see #jsonFormatterFromJson(String)
54105
* @see #wrap(PdxInstance)
@@ -74,6 +125,7 @@ public class JSONFormatterJsonToPdxConverter implements JsonToPdxConverter {
74125
*
75126
* @param pdxInstance {@link PdxInstance} to wrap.
76127
* @return a new instance of {@link PdxInstanceWrapper} wrapping the given {@link PdxInstance}.
128+
* @see org.springframework.geode.pdx.PdxInstanceWrapper#from(PdxInstance)
77129
* @see org.springframework.geode.pdx.PdxInstanceWrapper
78130
* @see org.apache.geode.pdx.PdxInstance
79131
*/

spring-geode/src/test/java/org/springframework/geode/data/json/converter/support/JSONFormatterJsonToPdxConverterUnitTests.java

+34
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,33 @@
1818
import static org.assertj.core.api.Assertions.assertThat;
1919
import static org.mockito.ArgumentMatchers.eq;
2020
import static org.mockito.Mockito.doReturn;
21+
import static org.mockito.Mockito.doThrow;
2122
import static org.mockito.Mockito.mock;
2223
import static org.mockito.Mockito.spy;
2324
import static org.mockito.Mockito.times;
2425
import static org.mockito.Mockito.verify;
2526

2627
import org.junit.Test;
2728

29+
import org.apache.geode.pdx.JSONFormatterException;
2830
import org.apache.geode.pdx.PdxInstance;
2931

32+
import org.springframework.geode.data.json.converter.JsonToObjectConverter;
33+
import org.springframework.geode.pdx.ObjectPdxInstanceAdapter;
3034
import org.springframework.geode.pdx.PdxInstanceWrapper;
3135

36+
import example.app.crm.model.Customer;
37+
3238
/**
3339
* Unit Tests for {@link JSONFormatterJsonToPdxConverter}.
3440
*
3541
* @author John Blum
3642
* @see org.junit.Test
3743
* @see org.mockito.Mockito
3844
* @see org.apache.geode.pdx.PdxInstance
45+
* @see org.springframework.geode.data.json.converter.JsonToObjectConverter
3946
* @see org.springframework.geode.data.json.converter.support.JSONFormatterJsonToPdxConverter
47+
* @see org.springframework.geode.pdx.ObjectPdxInstanceAdapter
4048
* @see org.springframework.geode.pdx.PdxInstanceWrapper
4149
* @since 1.3.0
4250
*/
@@ -62,4 +70,30 @@ public void convertCallsConvertJsonToPdx() {
6270
verify(converter, times(1)).jsonFormatterFromJson(eq(json));
6371
verify(converter, times(1)).wrap(eq(mockPdxInstance));
6472
}
73+
74+
@Test
75+
public void convertCallsConvertJsonToObjectToPdx() {
76+
77+
String json = "{ \"name\": \"Jon Doe\" }";
78+
79+
JsonToObjectConverter mockJsonToObjectConverter = mock(JsonToObjectConverter.class);
80+
81+
Customer jonDoe = Customer.newCustomer(1L, "Jon Doe");
82+
83+
JSONFormatterJsonToPdxConverter converter = spy(new JSONFormatterJsonToPdxConverter());
84+
85+
doThrow(new JSONFormatterException("TEST")).when(converter).convertJsonToPdx(eq(json));
86+
doReturn(mockJsonToObjectConverter).when(converter).getJsonToObjectConverter();
87+
doReturn(jonDoe).when(mockJsonToObjectConverter).convert(eq(json));
88+
89+
PdxInstance pdx = converter.convert(json);
90+
91+
assertThat(pdx).isInstanceOf(ObjectPdxInstanceAdapter.class);
92+
assertThat(pdx.getObject()).isSameAs(jonDoe);
93+
94+
verify(converter, times(1)).convertJsonToPdx(eq(json));
95+
verify(converter, times(1)).convertJsonToObjectToPdx(eq(json));
96+
verify(converter, times(1)).getJsonToObjectConverter();
97+
verify(mockJsonToObjectConverter, times(1)).convert(eq(json));
98+
}
6599
}

0 commit comments

Comments
 (0)