Refactor JsonCacheDataImporterExporter to extend ResourceCapableCacheDataImporterExporter.
Change doImportInto(:Region) logic to make use of the ImportResourceResolver and ResourceReader on import. Change doExportFrom(:Region) logic to make use of the ExportResourceResolver and ResourceWriter on export. Resolves gh-92.
This commit is contained in:
@@ -15,29 +15,21 @@
|
||||
*/
|
||||
package org.springframework.geode.data.json;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.pdx.PdxInstance;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.data.gemfire.util.ArrayUtils;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.geode.data.AbstractCacheDataImporterExporter;
|
||||
import org.springframework.geode.data.CacheDataExporter;
|
||||
import org.springframework.geode.data.CacheDataImporter;
|
||||
import org.springframework.geode.data.json.converter.AbstractObjectArrayToJsonConverter;
|
||||
import org.springframework.geode.data.json.converter.JsonToPdxArrayConverter;
|
||||
import org.springframework.geode.data.json.converter.support.JacksonJsonToPdxConverter;
|
||||
import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter;
|
||||
import org.springframework.geode.pdx.ObjectPdxInstanceAdapter;
|
||||
import org.springframework.geode.pdx.PdxInstanceWrapper;
|
||||
import org.springframework.geode.util.CacheUtils;
|
||||
@@ -45,44 +37,65 @@ import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* The {@link JsonCacheDataImporterExporter} class is a {@link CacheDataImporter} and {@link CacheDataExporter}
|
||||
* implementation that can export/import JSON data to/from a {@link Resource} given a target {@link Region}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.io.File
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see org.springframework.core.io.ClassPathResource
|
||||
* @see org.springframework.core.io.Resource
|
||||
* @see org.springframework.core.io.ResourceLoader
|
||||
* @see org.springframework.geode.data.AbstractCacheDataImporterExporter
|
||||
* @see org.springframework.geode.data.CacheDataExporter
|
||||
* @see org.springframework.geode.data.CacheDataImporter
|
||||
* @see org.springframework.geode.data.json.converter.JsonToPdxArrayConverter
|
||||
* @see org.springframework.geode.data.json.converter.ObjectToJsonConverter
|
||||
* @see org.springframework.geode.data.json.converter.support.JSONFormatterPdxToJsonConverter
|
||||
* @see org.springframework.geode.data.json.converter.ObjectArrayToJsonConverter
|
||||
* @see org.springframework.geode.data.json.converter.support.JacksonJsonToPdxConverter
|
||||
* @see org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter
|
||||
* @see org.springframework.geode.pdx.ObjectPdxInstanceAdapter
|
||||
* @see org.springframework.geode.pdx.PdxInstanceWrapper
|
||||
* @see org.springframework.stereotype.Component
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Component
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class JsonCacheDataImporterExporter extends AbstractCacheDataImporterExporter {
|
||||
public class JsonCacheDataImporterExporter extends ResourceCapableCacheDataImporterExporter {
|
||||
|
||||
private static final boolean APPEND_TO_FILE = false;
|
||||
protected static final PdxInstance[] EMPTY_PDX_INSTANCE_ARRAY = {};
|
||||
|
||||
private static final int CONTENT_PREVIEW_LENGTH = 50;
|
||||
private static final int DEFAULT_BUFFER_SIZE = 32768;
|
||||
|
||||
private JsonToPdxArrayConverter jsonToPdxArrayConverter = newJsonToPdxArrayConverter();
|
||||
@Autowired(required = false)
|
||||
private JsonToPdxArrayConverter jsonToPdxArrayConverter;
|
||||
|
||||
private final RegionValuesToJsonConverter regionValuesToJsonConverter = new RegionValuesToJsonConverter();
|
||||
|
||||
// TODO configure via an SPI or DI
|
||||
/**
|
||||
* Determines whether the given array is empty or not. An array is not empty if the array reference
|
||||
* is not {@literal null} and contains at least 1 element.
|
||||
*
|
||||
* @param <T> {@link Class type} of the array elements.
|
||||
* @param array {@link Object} array to evaluate.
|
||||
* @return a boolean value indicating whether the array is empty or not.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> boolean isNotEmpty(T... array) {
|
||||
return array != null && array.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the JSON to PDX (array) converter.
|
||||
*
|
||||
* @see #newJsonToPdxArrayConverter()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
super.afterPropertiesSet();
|
||||
|
||||
this.jsonToPdxArrayConverter = this.jsonToPdxArrayConverter != null
|
||||
? this.jsonToPdxArrayConverter
|
||||
: newJsonToPdxArrayConverter();
|
||||
}
|
||||
|
||||
private @NonNull JsonToPdxArrayConverter newJsonToPdxArrayConverter() {
|
||||
return new JacksonJsonToPdxConverter();
|
||||
}
|
||||
@@ -105,150 +118,52 @@ public class JsonCacheDataImporterExporter extends AbstractCacheDataImporterExpo
|
||||
|
||||
Assert.notNull(region, "Region must not be null");
|
||||
|
||||
String json = toJson(region);
|
||||
getExportResourceResolver()
|
||||
.resolve(region)
|
||||
.ifPresent(resource -> {
|
||||
|
||||
getLogger().debug("Saving JSON [{}] from Region [{}]", json, region.getName());
|
||||
String json = toJson(region);
|
||||
|
||||
getResource(region, getResourceLocation())
|
||||
.ifPresent(resource -> save(json, resource));
|
||||
getLogger().debug("Saving JSON [{}] from Region [{}]", json, region.getName());
|
||||
|
||||
getResourceWriter().write(resource, json.getBytes());
|
||||
});
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given {@link String content} (e.g. JSON) to the specified {@link Resource}.
|
||||
*
|
||||
* @param content {@link String} containing the content to save.
|
||||
* @param resource {@link Resource} to save the {@link String content} to; must not be {@literal null}.
|
||||
* @throws IllegalArgumentException if {@link Resource} is {@literal null}.
|
||||
* @see org.springframework.core.io.Resource
|
||||
*/
|
||||
protected void save(@Nullable String content, @NonNull Resource resource) {
|
||||
|
||||
Assert.notNull(resource, "Resource must not be null");
|
||||
|
||||
if (StringUtils.hasText(content)) {
|
||||
try (Writer writer = newWriter(resource)) {
|
||||
writer.write(content, 0, content.length());
|
||||
writer.flush();
|
||||
}
|
||||
catch (IOException cause) {
|
||||
|
||||
String message = String.format("Failed to save content '%s' to Resource [%s]",
|
||||
formatContentForPreview(content), resource.getDescription());
|
||||
|
||||
throw new DataAccessResourceFailureException(message, cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull Writer newWriter(@NonNull Resource resource) throws IOException {
|
||||
return new BufferedWriter(new FileWriter(resource.getFile(), APPEND_TO_FILE));
|
||||
}
|
||||
|
||||
@Nullable String formatContentForPreview(@Nullable String content) {
|
||||
|
||||
if (StringUtils.hasText(content)) {
|
||||
|
||||
int length = Math.min(content.length(), CONTENT_PREVIEW_LENGTH);
|
||||
|
||||
content = content.substring(0, length).concat(length < content.length() ? "..." : "");
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@NonNull @Override @SuppressWarnings("unchecked")
|
||||
@NonNull @Override
|
||||
public Region doImportInto(@NonNull Region region) {
|
||||
|
||||
Assert.notNull(region, "Region must not be null");
|
||||
|
||||
getResource(region, CLASSPATH_RESOURCE_PREFIX)
|
||||
.filter(Resource::exists)
|
||||
.map(this::getContent)
|
||||
getImportResourceResolver()
|
||||
.resolve(region)
|
||||
.map(this.getResourceReader()::read)
|
||||
.map(this::toPdx)
|
||||
.map(Arrays::stream)
|
||||
.ifPresent(pdxInstances -> pdxInstances.forEach(pdxInstance ->
|
||||
region.put(resolveKey(pdxInstance), resolveValue(pdxInstance))));
|
||||
.ifPresent(pdxInstances -> regionPutPdx(region, pdxInstances));
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contents of the given {@link Resource} as an array of {@literal Byte#TYPE bytes}.
|
||||
* Puts all PDX data from the {@link PdxInstance} array into the target {@link Region} mapped to
|
||||
* the PDX {@link PdxInstance#isIdentityField(String) identifier} as the {@literal key}.
|
||||
*
|
||||
* @param resource {@link Resource} from which to load the content; must not be {@literal null}.
|
||||
* @return an array of {@link Byte#TYPE bytes} containing the contents of the given {@link Resource}.
|
||||
* @throws IllegalArgumentException if {@link Resource} is {@literal null}.
|
||||
* @throws DataAccessResourceFailureException if an {@link IOException} occurs while reading from
|
||||
* and loading the contents of the given {@link Resource}.
|
||||
* @see org.springframework.core.io.Resource
|
||||
*/
|
||||
protected @NonNull byte[] getContent(@NonNull Resource resource) {
|
||||
|
||||
Assert.notNull(resource, "Resource must not be null");
|
||||
|
||||
try (InputStream in = resource.getInputStream()){
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(in.available());
|
||||
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
|
||||
for (int bytesRead = in.read(buffer); bytesRead != -1; bytesRead = in.read(buffer)) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
return out.toByteArray();
|
||||
}
|
||||
catch (IOException cause) {
|
||||
throw new DataAccessResourceFailureException(String.format("Failed to read from Resource [%s]",
|
||||
resource.getDescription()), cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a computed JSON {@link Resource} containing JSON data to be loaded into the given {@link Region}.
|
||||
*
|
||||
* @param region target {@link Region} used to compute the JSON {@link Resource} to load.
|
||||
* @param resourcePrefix {@link String} containing a path prefix (e.g. {@literal classpath:} used to indicate
|
||||
* the location of the {@link Resource} to load.
|
||||
* @return an {@link Optional} JSON {@link Resource} containing JSON data to load into the given {@link Region}.
|
||||
* @see org.springframework.core.io.Resource
|
||||
* @param region target {@link Region} to store the PDX data; must not be {@literal null}
|
||||
* @param pdx {@link PdxInstance} array containing the PDX data to store in the target {@link Region}.
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see java.util.Optional
|
||||
* @see org.apache.geode.cache.Region#put(Object, Object)
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
*/
|
||||
protected Optional<Resource> getResource(@NonNull Region region, @Nullable String resourcePrefix) {
|
||||
@SuppressWarnings("unchecked")
|
||||
void regionPutPdx(@NonNull Region region, @Nullable PdxInstance[] pdx) {
|
||||
|
||||
Assert.notNull(region, "Region must not be null");
|
||||
|
||||
String regionName = region.getName().toLowerCase();
|
||||
String resourceName = String.format(RESOURCE_NAME_PATTERN, regionName);
|
||||
String resolvedResourcePrefix = StringUtils.hasText(resourcePrefix)
|
||||
? resourcePrefix
|
||||
: CLASSPATH_RESOURCE_PREFIX;
|
||||
|
||||
Resource resource = getApplicationContext()
|
||||
.map(it -> it.getResource(String.format("%1$s%2$s", resolvedResourcePrefix, resourceName)))
|
||||
.orElseGet((() -> new ClassPathResource(resourceName)));
|
||||
|
||||
return Optional.of(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link String file system path} specifying the location for where to export the {@link Resource}.
|
||||
*
|
||||
* @return a {@link String file system path} specifying the location for where to export the {@link Resource}.
|
||||
*/
|
||||
protected @NonNull String getResourceLocation() {
|
||||
return String.format("%1$s%2$s%2$s%3$s%4$s", FILESYSTEM_RESOURCE_PREFIX, RESOURCE_PATH_SEPARATOR,
|
||||
System.getProperty("user.dir"), File.separator);
|
||||
Arrays.stream(ArrayUtils.nullSafeArray(pdx, PdxInstance.class)).forEach(pdxInstance ->
|
||||
region.put(resolveKey(pdxInstance), resolveValue(pdxInstance)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,9 +234,19 @@ public class JsonCacheDataImporterExporter extends AbstractCacheDataImporterExpo
|
||||
* @see #getJsonToPdxArrayConverter()
|
||||
*/
|
||||
protected @NonNull PdxInstance[] toPdx(@NonNull byte[] json) {
|
||||
return getJsonToPdxArrayConverter().convert(json);
|
||||
|
||||
return isNotEmpty(json)
|
||||
? getJsonToPdxArrayConverter().convert(json)
|
||||
: EMPTY_PDX_INSTANCE_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all {@link Region#values() values} in the targeted {@link Region} into {@literal JSON}.
|
||||
*
|
||||
* The converter is capable of handling both {@link Object Objects} and PDX.
|
||||
*
|
||||
* @see org.springframework.geode.data.json.converter.AbstractObjectArrayToJsonConverter
|
||||
*/
|
||||
static class RegionValuesToJsonConverter extends AbstractObjectArrayToJsonConverter {
|
||||
|
||||
@NonNull <K, V> String convert(@NonNull Region<K, V> region) {
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
|
||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -58,17 +57,21 @@ import org.apache.geode.pdx.PdxInstanceFactory;
|
||||
import org.apache.geode.pdx.PdxSerializationException;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.gemfire.LocalRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.EnablePdx;
|
||||
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.tests.integration.SpringApplicationContextIntegrationTestsSupport;
|
||||
import org.springframework.geode.core.io.ResourceWriteException;
|
||||
import org.springframework.geode.core.io.ResourceWriter;
|
||||
import org.springframework.geode.core.util.ObjectUtils;
|
||||
import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ImportResourceResolver;
|
||||
import org.springframework.geode.pdx.PdxInstanceBuilder;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.mock.env.MockPropertySource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -78,11 +81,12 @@ import example.app.pos.model.Product;
|
||||
import example.app.pos.model.PurchaseOrder;
|
||||
|
||||
/**
|
||||
* Integration Test for {@link JsonCacheDataImporterExporter}.
|
||||
* Integration Tests for {@link JsonCacheDataImporterExporter}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see com.fasterxml.jackson.databind.ObjectMapper
|
||||
* @see com.fasterxml.jackson.databind.node.ObjectNode
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.RegionService
|
||||
@@ -90,65 +94,58 @@ import example.app.pos.model.PurchaseOrder;
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see org.apache.geode.pdx.PdxInstanceFactory
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.core.io.ClassPathResource
|
||||
* @see org.springframework.core.io.Resource
|
||||
* @see org.springframework.data.gemfire.LocalRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnablePdx
|
||||
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.data.gemfire.tests.integration.SpringApplicationContextIntegrationTestsSupport
|
||||
* @see org.springframework.geode.pdx.PdxInstanceBuilder
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTestsSupport {
|
||||
public class JsonCacheDataImporterExporterIntegrationTests extends SpringApplicationContextIntegrationTestsSupport {
|
||||
|
||||
private static final String EXPORT_ENABLED_PROPERTY = "spring.boot.data.gemfire.cache.data.export.enabled";
|
||||
private static final String EXPORT_RESOURCE_LOCATION_PROPERTY = "spring.boot.data.gemfire.cache.data.export.resource.location";
|
||||
private static final String IMPORT_ENABLED_PROPERTY = "spring.boot.data.gemfire.cache.data.import.enabled";
|
||||
private static final String IMPORT_RESOURCE_LOCATION_PROPERTY = "spring.boot.data.gemfire.cache.data.import.resource.location";
|
||||
|
||||
private static volatile Supplier<Resource> resourceSupplier;
|
||||
|
||||
private static volatile Supplier<StringWriter> writerSupplier;
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
private static volatile Supplier<Boolean> exportEnabledSupplier;
|
||||
private static volatile Supplier<Boolean> importEnabledSupplier;
|
||||
private static volatile Supplier<ImportResourceResolver> importResourceResolverSupplier;
|
||||
private static volatile Supplier<String> resourceLocationSupplier;
|
||||
private static volatile Supplier<StringWriter> resourceWriterSupplier;
|
||||
|
||||
@Before
|
||||
public void initializeSuppliers() {
|
||||
resourceSupplier = () -> null;
|
||||
writerSupplier = StringWriter::new;
|
||||
|
||||
exportEnabledSupplier = () -> false;
|
||||
importEnabledSupplier = () -> true;
|
||||
importResourceResolverSupplier = () -> null;
|
||||
resourceLocationSupplier = () -> "";
|
||||
resourceWriterSupplier = StringWriter::new;
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeApplicationContext() {
|
||||
@Override
|
||||
protected ConfigurableApplicationContext processBeforeRefresh(ConfigurableApplicationContext applicationContext) {
|
||||
|
||||
Optional.ofNullable(this.applicationContext)
|
||||
.ifPresent(ConfigurableApplicationContext::close);
|
||||
applicationContext = super.processBeforeRefresh(applicationContext);
|
||||
|
||||
this.applicationContext = null;
|
||||
}
|
||||
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
|
||||
|
||||
private ConfigurableApplicationContext newApplicationContext(Class<?>... componentClasses) {
|
||||
MockPropertySource mockPropertySource = new MockPropertySource(getClass().getName().concat(".MockPropertySource"))
|
||||
.withProperty(EXPORT_ENABLED_PROPERTY, exportEnabledSupplier.get())
|
||||
.withProperty(EXPORT_RESOURCE_LOCATION_PROPERTY, resourceLocationSupplier.get())
|
||||
.withProperty(IMPORT_ENABLED_PROPERTY, importEnabledSupplier.get())
|
||||
.withProperty(IMPORT_RESOURCE_LOCATION_PROPERTY, resourceLocationSupplier.get());
|
||||
|
||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
|
||||
applicationContext.register(componentClasses);
|
||||
applicationContext.registerShutdownHook();
|
||||
applicationContext.refresh();
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
propertySources.addFirst(mockPropertySource);
|
||||
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
private Class<?>[] withResource(String path) {
|
||||
|
||||
if (StringUtils.hasText(path)) {
|
||||
resourceSupplier = () -> new ClassPathResource(path);
|
||||
}
|
||||
|
||||
return new Class[] { TestGeodeConfiguration.class };
|
||||
}
|
||||
|
||||
private <K, V> Region<K, V> assertExampleRegion(Region<K, V> example) {
|
||||
|
||||
assertThat(example).isNotNull();
|
||||
@@ -168,7 +165,9 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
@Test
|
||||
public void exampleRegionContainsJonDoe() {
|
||||
|
||||
Region<?, ?> example = getExampleRegion(newApplicationContext(withResource("data-example-jondoe.json")));
|
||||
resourceLocationSupplier = () -> "classpath:data-#{#regionName}-jondoe.json";
|
||||
|
||||
Region<?, ?> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
assertThat(example).hasSize(1);
|
||||
|
||||
@@ -194,8 +193,9 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
@Test
|
||||
public void exampleRegionContainsDoeFamily() {
|
||||
|
||||
Region<?, ?> example =
|
||||
getExampleRegion(newApplicationContext(withResource("data-example-doefamily.json")));
|
||||
resourceLocationSupplier = () -> "classpath:data-#{#regionName}-doefamily.json";
|
||||
|
||||
Region<?, ?> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
assertThat(example).hasSize(9);
|
||||
|
||||
@@ -319,8 +319,9 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
@Test
|
||||
public void exampleRegionContainsComplexPurchaseOrderType() {
|
||||
|
||||
Region<?, ?> example =
|
||||
getExampleRegion(newApplicationContext(withResource("data-example-purchaseorder.json")));
|
||||
resourceLocationSupplier = () -> "classpath:data-#{#regionName}-purchaseorder.json";
|
||||
|
||||
Region<?, ?> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
assertThat(example).hasSize(1);
|
||||
|
||||
@@ -345,14 +346,14 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
public void exportFromExampleRegionToJson() {
|
||||
|
||||
try {
|
||||
System.setProperty(EXPORT_ENABLED_PROPERTY, Boolean.TRUE.toString());
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
writerSupplier = () -> writer;
|
||||
exportEnabledSupplier = () -> true;
|
||||
importEnabledSupplier = () -> false;
|
||||
resourceWriterSupplier = () -> writer;
|
||||
|
||||
Region<Long, Customer> example =
|
||||
getExampleRegion(newApplicationContext(withResource("data-example.json")));
|
||||
Region<Long, Customer> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).isEmpty();
|
||||
@@ -381,137 +382,125 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
@Test
|
||||
public void exportFromExampleRegionImportsIntoExampleRegion() throws IOException {
|
||||
|
||||
try {
|
||||
// EXPORT
|
||||
System.setProperty(EXPORT_ENABLED_PROPERTY, Boolean.TRUE.toString());
|
||||
// EXPORT
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
exportEnabledSupplier = () -> true;
|
||||
importEnabledSupplier = () -> false;
|
||||
resourceWriterSupplier = () -> writer;
|
||||
|
||||
writerSupplier = () -> writer;
|
||||
Region<Long, PurchaseOrder> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
Region<Long, PurchaseOrder> example =
|
||||
getExampleRegion(newApplicationContext(withResource("data-example.json")));
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).isEmpty();
|
||||
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).isEmpty();
|
||||
Product golfBalls = Product.newProduct("Titliest ProV1x Golf Balls")
|
||||
.havingPrice(BigDecimal.valueOf(34.99d))
|
||||
.in(Product.Category.SPECIALTY);
|
||||
|
||||
Product golfBalls = Product.newProduct("Titliest ProV1x Golf Balls")
|
||||
.havingPrice(BigDecimal.valueOf(34.99d))
|
||||
.in(Product.Category.SPECIALTY);
|
||||
LineItem lineItem = LineItem.newLineItem(golfBalls)
|
||||
.withQuantity(1);
|
||||
|
||||
LineItem lineItem = LineItem.newLineItem(golfBalls)
|
||||
.withQuantity(1);
|
||||
PurchaseOrder purchaseOrder = new PurchaseOrder()
|
||||
.identifiedAs(72L)
|
||||
.add(lineItem);
|
||||
|
||||
PurchaseOrder purchaseOrder = new PurchaseOrder()
|
||||
.identifiedAs(72L)
|
||||
.add(lineItem);
|
||||
assertThat(example.put(purchaseOrder.getId(), purchaseOrder)).isNull();
|
||||
assertThat(example).hasSize(1);
|
||||
assertPurchaseOrder(example.get(purchaseOrder.getId()), purchaseOrder.getId(),
|
||||
Collections.singletonList(lineItem), golfBalls.getPrice());
|
||||
|
||||
assertThat(example.put(purchaseOrder.getId(), purchaseOrder)).isNull();
|
||||
assertThat(example).hasSize(1);
|
||||
assertPurchaseOrder(example.get(purchaseOrder.getId()), purchaseOrder.getId(),
|
||||
Collections.singletonList(lineItem), golfBalls.getPrice());
|
||||
//log("JSON from JSONFormatter '%s'%n",
|
||||
// JSONFormatter.toJSON(serializeToPdx(example.getRegionService(), purchaseOrder)));
|
||||
|
||||
//log("JSON from JSONFormatter '%s'%n",
|
||||
// JSONFormatter.toJSON(serializeToPdx(example.getRegionService(), purchaseOrder)));
|
||||
closeApplicationContext();
|
||||
|
||||
closeApplicationContext();
|
||||
String json = writer.toString();
|
||||
|
||||
String json = writer.toString();
|
||||
assertThat(json).isNotEmpty();
|
||||
|
||||
assertThat(json).isNotEmpty();
|
||||
//log("JSON '%s'%n", json);
|
||||
//log("PurchaseOrder from JSON [%s]%n",
|
||||
// newObjectMapper().readValue(json.substring(1, json.length() - 1), PurchaseOrder.class));
|
||||
|
||||
//log("JSON '%s'%n", json);
|
||||
//log("PurchaseOrder from JSON [%s]%n",
|
||||
// newObjectMapper().readValue(json.substring(1, json.length() - 1), PurchaseOrder.class));
|
||||
// IMPORT
|
||||
Resource mockResource = mock(Resource.class, withSettings().lenient());
|
||||
|
||||
// IMPORT
|
||||
System.clearProperty(EXPORT_ENABLED_PROPERTY);
|
||||
doReturn("MOCK").when(mockResource).getDescription();
|
||||
doReturn(new ByteArrayInputStream(json.getBytes())).when(mockResource).getInputStream();
|
||||
|
||||
Resource mockResource = mock(Resource.class, withSettings().lenient());
|
||||
exportEnabledSupplier = () -> false;
|
||||
importEnabledSupplier = () -> true;
|
||||
importResourceResolverSupplier = () -> (ImportResourceResolver) region -> Optional.of(mockResource);
|
||||
|
||||
doReturn(true).when(mockResource).exists();
|
||||
doReturn("MOCK").when(mockResource).getDescription();
|
||||
doReturn(new ByteArrayInputStream(json.getBytes())).when(mockResource).getInputStream();
|
||||
example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class,
|
||||
TestImportResourceResolverGeodeConfiguration.class));
|
||||
|
||||
resourceSupplier = () -> mockResource;
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).hasSize(1);
|
||||
|
||||
example = getExampleRegion(newApplicationContext(withResource(null)));
|
||||
Object value = example.values().stream().findFirst().orElse(null);
|
||||
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).hasSize(1);
|
||||
assertThat(value).isInstanceOf(PdxInstance.class);
|
||||
|
||||
Object value = example.values().stream().findFirst().orElse(null);
|
||||
|
||||
assertThat(value).isInstanceOf(PdxInstance.class);
|
||||
|
||||
assertPurchaseOrder(ObjectUtils.asType(value, PurchaseOrder.class),
|
||||
purchaseOrder.getId(), Collections.singletonList(lineItem), golfBalls.getPrice());
|
||||
}
|
||||
finally {
|
||||
System.clearProperty(EXPORT_ENABLED_PROPERTY);
|
||||
}
|
||||
assertPurchaseOrder(ObjectUtils.asType(value, PurchaseOrder.class),
|
||||
purchaseOrder.getId(), Collections.singletonList(lineItem), golfBalls.getPrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportImportWithRegionContainingObjectsAndPdxInstances() throws IOException {
|
||||
|
||||
try {
|
||||
// EXPORT
|
||||
System.setProperty(EXPORT_ENABLED_PROPERTY, Boolean.TRUE.toString());
|
||||
// EXPORT
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
exportEnabledSupplier = () -> true;
|
||||
importEnabledSupplier = () -> false;
|
||||
resourceWriterSupplier = () -> writer;
|
||||
|
||||
writerSupplier = () -> writer;
|
||||
Region<Object, Object> example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class));
|
||||
|
||||
Region<Object, Object> example =
|
||||
getExampleRegion(newApplicationContext(withResource("data-example.json")));
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).isEmpty();
|
||||
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).isEmpty();
|
||||
Customer jonDoe = Customer.newCustomer(1L, "Jon Doe");
|
||||
Customer janeDoe = Customer.newCustomer(2L, "JaneDoe");
|
||||
|
||||
Customer jonDoe = Customer.newCustomer(1L, "Jon Doe");
|
||||
Customer janeDoe = Customer.newCustomer(2L, "JaneDoe");
|
||||
PdxInstance janeDoePdx = serializeToPdx(example.getRegionService(), janeDoe);
|
||||
|
||||
PdxInstance janeDoePdx = serializeToPdx(example.getRegionService(), janeDoe);
|
||||
assertThat(example.put(jonDoe.getId(), jonDoe)).isNull();
|
||||
assertThat(example.put(janeDoe.getId(), janeDoePdx)).isNull();
|
||||
assertThat(example).hasSize(2);
|
||||
assertThat(example.get(jonDoe.getId())).isEqualTo(jonDoe);
|
||||
assertThat(example.get(janeDoe.getId())).isInstanceOf(PdxInstance.class);
|
||||
|
||||
assertThat(example.put(jonDoe.getId(), jonDoe)).isNull();
|
||||
assertThat(example.put(janeDoe.getId(), janeDoePdx)).isNull();
|
||||
assertThat(example).hasSize(2);
|
||||
assertThat(example.get(jonDoe.getId())).isEqualTo(jonDoe);
|
||||
assertThat(example.get(janeDoe.getId())).isInstanceOf(PdxInstance.class);
|
||||
closeApplicationContext();
|
||||
|
||||
closeApplicationContext();
|
||||
String json = writer.toString();
|
||||
|
||||
String json = writer.toString();
|
||||
assertThat(json).isNotEmpty();
|
||||
|
||||
assertThat(json).isNotEmpty();
|
||||
// IMPORT
|
||||
Resource mockResource = mock(Resource.class, withSettings().lenient());
|
||||
|
||||
// IMPORT
|
||||
System.clearProperty(EXPORT_ENABLED_PROPERTY);
|
||||
doReturn("MOCK").when(mockResource).getDescription();
|
||||
doReturn(new ByteArrayInputStream(json.getBytes())).when(mockResource).getInputStream();
|
||||
|
||||
Resource mockResource = mock(Resource.class, withSettings().lenient());
|
||||
exportEnabledSupplier = () -> false;
|
||||
importEnabledSupplier = () -> true;
|
||||
importResourceResolverSupplier = () -> region -> Optional.of(mockResource);
|
||||
|
||||
doReturn(true).when(mockResource).exists();
|
||||
doReturn("MOCK").when(mockResource).getDescription();
|
||||
doReturn(new ByteArrayInputStream(json.getBytes())).when(mockResource).getInputStream();
|
||||
example = getExampleRegion(newApplicationContext(TestGeodeConfiguration.class,
|
||||
|
||||
resourceSupplier = () -> mockResource;
|
||||
TestImportResourceResolverGeodeConfiguration.class));
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).hasSize(2);
|
||||
|
||||
example = getExampleRegion(newApplicationContext(withResource(null)));
|
||||
for (Customer doe : Arrays.asList(jonDoe, janeDoe)) {
|
||||
|
||||
assertExampleRegion(example);
|
||||
assertThat(example).hasSize(2);
|
||||
Object value = example.get(doe.getId().byteValue());
|
||||
|
||||
for (Customer doe : Arrays.asList(jonDoe, janeDoe)) {
|
||||
|
||||
Object value = example.get(doe.getId().byteValue());
|
||||
|
||||
assertThat(value).isInstanceOf(PdxInstance.class);
|
||||
assertThat(((PdxInstance) value).getObject()).isEqualTo(doe);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
System.clearProperty(EXPORT_ENABLED_PROPERTY);
|
||||
assertThat(value).isInstanceOf(PdxInstance.class);
|
||||
assertThat(((PdxInstance) value).getObject()).isEqualTo(doe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,23 +666,40 @@ public class JsonCacheDataImporterExporterIntegrationTests extends IntegrationTe
|
||||
}
|
||||
|
||||
@Bean
|
||||
JsonCacheDataImporterExporter exampleRegionDataImporter() {
|
||||
JsonCacheDataImporterExporter exampleRegionDataImporterExporter() {
|
||||
return new JsonCacheDataImporterExporter();
|
||||
}
|
||||
|
||||
return new JsonCacheDataImporterExporter() {
|
||||
@Bean
|
||||
ResourceWriter stringWriterResourceWriter() {
|
||||
|
||||
@Override @SuppressWarnings("rawtypes")
|
||||
protected Optional<Resource> getResource(@NonNull Region region, String resourcePrefix) {
|
||||
return Optional.ofNullable(resourceSupplier.get());
|
||||
return (resource, data) -> {
|
||||
|
||||
String json = new String(data);
|
||||
|
||||
Writer writer = resourceWriterSupplier.get();
|
||||
|
||||
try {
|
||||
writer.write(json, 0, data.length);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
Writer newWriter(@NonNull Resource resource) {
|
||||
return writerSupplier.get();
|
||||
catch (IOException cause) {
|
||||
throw new ResourceWriteException(String.format("Failed to write data [%s] to Resource [%s]",
|
||||
json, resource.getDescription()), cause);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestImportResourceResolverGeodeConfiguration {
|
||||
|
||||
@Bean
|
||||
ImportResourceResolver testImportResourceResolver() {
|
||||
return importResourceResolverSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TimedType {
|
||||
|
||||
public static TimedType create() {
|
||||
|
||||
@@ -17,42 +17,34 @@ package org.springframework.geode.data.json;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
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.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.pdx.PdxInstance;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.data.gemfire.util.ArrayUtils;
|
||||
import org.springframework.geode.core.io.ResourceReader;
|
||||
import org.springframework.geode.core.io.ResourceWriter;
|
||||
import org.springframework.geode.data.json.converter.JsonToPdxArrayConverter;
|
||||
import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ExportResourceResolver;
|
||||
import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ImportResourceResolver;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
/**
|
||||
* Unit Tests for {@link JsonCacheDataImporterExporter}.
|
||||
@@ -63,19 +55,19 @@ import org.springframework.geode.data.json.converter.JsonToPdxArrayConverter;
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.pdx.PdxInstance
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
* @see org.springframework.core.io.ClassPathResource
|
||||
* @see org.springframework.core.io.Resource
|
||||
* @see org.springframework.geode.core.io.ResourceReader
|
||||
* @see org.springframework.geode.core.io.ResourceWriter
|
||||
* @see org.springframework.geode.data.json.JsonCacheDataImporterExporter
|
||||
* @see org.springframework.geode.data.json.converter.JsonToPdxArrayConverter
|
||||
* @see org.springframework.geode.data.json.converter.ObjectToJsonConverter
|
||||
* @see org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ExportResourceResolver
|
||||
* @see org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ImportResourceResolver
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class JsonCacheDataImporterExporterUnitTests {
|
||||
|
||||
@Spy
|
||||
private JsonCacheDataImporterExporter importer;
|
||||
private TestJsonCacheDataImporterExporter importerExporter;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -85,28 +77,56 @@ public class JsonCacheDataImporterExporterUnitTests {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
ResourceWriter mockResourceWriter = mock(ResourceWriter.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
ExportResourceResolver mockExportResourceResolver = mock(ExportResourceResolver.class);
|
||||
|
||||
doReturn("TestRegion").when(mockRegion).getName();
|
||||
doReturn(Optional.of(mockResource)).when(this.importer).getResource(eq(mockRegion), anyString());
|
||||
doReturn( "file:///path/to/data.json").when(importer).getResourceLocation();
|
||||
doNothing().when(this.importer).save(anyString(), any(Resource.class));
|
||||
doReturn(json).when(this.importer).toJson(any());
|
||||
doReturn(mockExportResourceResolver).when(this.importerExporter).getExportResourceResolver();
|
||||
doReturn(mockResourceWriter).when(this.importerExporter).getResourceWriter();
|
||||
doReturn(Optional.of(mockResource)).when(mockExportResourceResolver).resolve(eq(mockRegion));
|
||||
doReturn(json).when(this.importerExporter).toJson(eq(mockRegion));
|
||||
|
||||
assertThat(this.importer.doExportFrom(mockRegion)).isEqualTo(mockRegion);
|
||||
assertThat(this.importerExporter.doExportFrom(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importer, times(1)).toJson(eq(mockRegion));
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion),
|
||||
eq("file:///path/to/data.json"));
|
||||
verify(this.importer, times(1)).getResourceLocation();
|
||||
verify(this.importer, times(1)).save(eq(json), eq(mockResource));
|
||||
InOrder order = inOrder(this.importerExporter, mockRegion, mockExportResourceResolver, mockResourceWriter);
|
||||
|
||||
order.verify(this.importerExporter, times(1)).getExportResourceResolver();
|
||||
order.verify(mockExportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
order.verify(this.importerExporter, times(1)).toJson(eq(mockRegion));
|
||||
order.verify(mockRegion, times(1)).getName();
|
||||
order.verify(this.importerExporter, times(1)).getResourceWriter();
|
||||
order.verify(mockResourceWriter, times(1)).write(eq(mockResource), eq(json.getBytes()));
|
||||
verifyNoMoreInteractions(mockRegion, mockExportResourceResolver, mockResourceWriter);
|
||||
verifyNoInteractions(mockResource);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doExportFromWithNoResource() {
|
||||
|
||||
ExportResourceResolver mockExportResourceResolver = mock(ExportResourceResolver.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn(mockExportResourceResolver).when(this.importerExporter).getExportResourceResolver();
|
||||
doReturn(Optional.empty()).when(mockExportResourceResolver).resolve(eq(mockRegion));
|
||||
|
||||
assertThat(this.importerExporter.doExportFrom(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importerExporter, times(1)).getExportResourceResolver();
|
||||
verify(mockExportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
verifyNoMoreInteractions(mockExportResourceResolver, mockRegion);
|
||||
verifyNoInteractions(mockRegion);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void doExportFromNullRegion() {
|
||||
|
||||
try {
|
||||
this.importer.doExportFrom(null);
|
||||
this.importerExporter.doExportFrom(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
@@ -117,222 +137,151 @@ public class JsonCacheDataImporterExporterUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveJsonToResource() throws IOException {
|
||||
|
||||
String json = "[{ \"name\": \"Jon Doe\"}, { \"name\": \"Jane Doe\"}]";
|
||||
|
||||
StringWriter writer = new StringWriter(json.length());
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn(writer).when(this.importer).newWriter(eq(mockResource));
|
||||
|
||||
this.importer.save(json, mockResource);
|
||||
|
||||
assertThat(writer.toString()).isEqualTo(json);
|
||||
|
||||
verify(this.importer, times(1)).newWriter(eq(mockResource));
|
||||
verifyNoInteractions(mockResource);
|
||||
}
|
||||
|
||||
@Test(expected = DataAccessResourceFailureException.class)
|
||||
public void saveThrowsIoException() throws IOException {
|
||||
|
||||
Writer mockWriter = mock(Writer.class);
|
||||
|
||||
String json = "[{ \"name\": \"Jon Doe\"}, { \"name\": \"Jane Doe\"}"
|
||||
+ ", { \"name\": \"Pie Doe\"}, { \"name\": \"Sour Doe\"}]";
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn("/path/to/data.json").when(mockResource).getDescription();
|
||||
doReturn(mockWriter).when(this.importer).newWriter(eq(mockResource));
|
||||
doThrow(new IOException("TEST")).when(mockWriter).write(anyString(), anyInt(), anyInt());
|
||||
|
||||
try {
|
||||
this.importer.save(json, mockResource);
|
||||
}
|
||||
catch (DataAccessResourceFailureException expected) {
|
||||
|
||||
assertThat(expected)
|
||||
.hasMessageStartingWith("Failed to save content '%s' to Resource [/path/to/data.json]",
|
||||
this.importer.formatContentForPreview(json));
|
||||
assertThat(expected).hasCauseInstanceOf(IOException.class);
|
||||
assertThat(expected.getCause()).hasMessage("TEST");
|
||||
assertThat(expected.getCause()).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(this.importer, times(1)).newWriter(eq(mockResource));
|
||||
verify(mockWriter, times(1)).write(eq(json), eq(0), eq(json.length()));
|
||||
verify(mockWriter, never()).flush();
|
||||
verify(mockWriter, times(1)).close();
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void saveWithNoContent() {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
try {
|
||||
this.importer.save(" ", mockResource);
|
||||
}
|
||||
finally {
|
||||
verify(this.importer, times(1)).save(eq(" "), eq(mockResource));
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
verifyNoInteractions(mockResource);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void saveWithNullResource() {
|
||||
|
||||
try {
|
||||
this.importer.save("{}", null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Resource must not be null");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(this.importer, times(1)).save(eq("{}"), isNull());
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doImportIntoPutsPdxIntoRegionForJson() {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
ResourceReader mockResourceReader = mock(ResourceReader.class);
|
||||
|
||||
Region<Integer, PdxInstance> mockRegion = mock(Region.class);
|
||||
|
||||
PdxInstance mockPdxInstanceOne = mock(PdxInstance.class);
|
||||
PdxInstance mockPdxInstanceTwo = mock(PdxInstance.class);
|
||||
|
||||
ImportResourceResolver mockImportResourceResolver = mock(ImportResourceResolver.class);
|
||||
|
||||
byte[] json = "[{ \"name\": \"Jon Doe\"}, { \"name\": \"Jane Doe\" }]".getBytes();
|
||||
|
||||
doReturn(Optional.of(mockResource)).when(this.importer).getResource(eq(mockRegion),eq("classpath:"));
|
||||
doReturn(true).when(mockResource).exists();
|
||||
doReturn(json).when(this.importer).getContent(eq(mockResource));
|
||||
doReturn(ArrayUtils.asArray(mockPdxInstanceOne, mockPdxInstanceTwo)).when(this.importer).toPdx(eq(json));
|
||||
doReturn(1).when(this.importer).resolveKey(eq(mockPdxInstanceOne));
|
||||
doReturn(2).when(this.importer).resolveKey(eq(mockPdxInstanceTwo));
|
||||
doReturn(mockImportResourceResolver).when(this.importerExporter).getImportResourceResolver();
|
||||
doReturn(mockResourceReader).when(this.importerExporter).getResourceReader();
|
||||
doReturn(Optional.of(mockResource)).when(mockImportResourceResolver).resolve(eq(mockRegion));
|
||||
doReturn(json).when(mockResourceReader).read(eq(mockResource));
|
||||
doReturn(ArrayUtils.asArray(mockPdxInstanceOne, mockPdxInstanceTwo)).when(this.importerExporter).toPdx(eq(json));
|
||||
doReturn(1).when(this.importerExporter).resolveKey(eq(mockPdxInstanceOne));
|
||||
doReturn(2).when(this.importerExporter).resolveKey(eq(mockPdxInstanceTwo));
|
||||
|
||||
assertThat(this.importer.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
assertThat(this.importerExporter.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion), eq("classpath:"));
|
||||
verify(this.importer, times(1)).getContent(eq(mockResource));
|
||||
verify(this.importer, times(1)).toPdx(eq(json));
|
||||
verify(this.importer, times(1)).resolveKey(eq(mockPdxInstanceOne));
|
||||
verify(this.importer, times(1)).postProcess(eq(mockPdxInstanceOne));
|
||||
verify(this.importer, times(1)).resolveValue(eq(mockPdxInstanceOne));
|
||||
verify(this.importer, times(1)).resolveKey(eq(mockPdxInstanceTwo));
|
||||
verify(this.importer, times(1)).postProcess(eq(mockPdxInstanceTwo));
|
||||
verify(this.importer, times(1)).resolveValue(eq(mockPdxInstanceTwo));
|
||||
verify(mockResource, times(1)).exists();
|
||||
verify(mockRegion, times(1)).put(eq(1), eq(mockPdxInstanceOne));
|
||||
verify(mockRegion, times(1)).put(eq(2), eq(mockPdxInstanceTwo));
|
||||
InOrder order =
|
||||
inOrder(this.importerExporter, mockRegion, mockResource, mockResourceReader, mockImportResourceResolver);
|
||||
|
||||
order.verify(this.importerExporter, times(1)).getImportResourceResolver();
|
||||
order.verify(mockImportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
order.verify(this.importerExporter, times(1)).getResourceReader();
|
||||
order.verify(mockResourceReader, times(1)).read(eq(mockResource));
|
||||
order.verify(this.importerExporter, times(1)).toPdx(eq(json));
|
||||
order.verify(this.importerExporter, times(1)).resolveKey(eq(mockPdxInstanceOne));
|
||||
order.verify(this.importerExporter, times(1)).resolveValue(eq(mockPdxInstanceOne));
|
||||
order.verify(this.importerExporter, times(1)).postProcess(eq(mockPdxInstanceOne));
|
||||
order.verify(mockRegion, times(1)).put(eq(1), eq(mockPdxInstanceOne));
|
||||
order.verify(this.importerExporter, times(1)).resolveKey(eq(mockPdxInstanceTwo));
|
||||
order.verify(this.importerExporter, times(1)).resolveValue(eq(mockPdxInstanceTwo));
|
||||
order.verify(this.importerExporter, times(1)).postProcess(eq(mockPdxInstanceTwo));
|
||||
order.verify(mockRegion, times(1)).put(eq(2), eq(mockPdxInstanceTwo));
|
||||
|
||||
verifyNoMoreInteractions(mockRegion, mockImportResourceResolver, mockResourceReader);
|
||||
verifyNoInteractions(mockResource, mockPdxInstanceOne, mockPdxInstanceTwo);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doImportIntoWithNoResource() {
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn(Optional.empty()).when(this.importer).getResource(eq(mockRegion), eq("classpath:"));
|
||||
|
||||
assertThat(this.importer.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importer, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion), eq("classpath:"));
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
verifyNoInteractions(mockRegion);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doImportIntoWithNonExistingResource() {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
ImportResourceResolver mockImportResourceResolver = mock(ImportResourceResolver.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn(Optional.of(mockResource)).when(this.importer).getResource(eq(mockRegion), eq("classpath:"));
|
||||
doReturn(false).when(mockResource).exists();
|
||||
ResourceReader mockResourceReader = mock(ResourceReader.class);
|
||||
|
||||
assertThat(this.importer.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
doReturn(mockImportResourceResolver).when(this.importerExporter).getImportResourceResolver();
|
||||
doReturn(mockResourceReader).when(this.importerExporter).getResourceReader();
|
||||
doReturn(Optional.empty()).when(mockImportResourceResolver).resolve(eq(mockRegion));
|
||||
|
||||
verify(this.importer, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion), eq("classpath:"));
|
||||
verify(mockResource, times(1)).exists();
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
verifyNoMoreInteractions(mockResource);
|
||||
verifyNoInteractions(mockRegion);
|
||||
assertThat(this.importerExporter.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importerExporter, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importerExporter, times(1)).getImportResourceResolver();
|
||||
verify(this.importerExporter, times(1)).getResourceReader();
|
||||
verify(mockImportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
verifyNoMoreInteractions(this.importerExporter, mockImportResourceResolver);
|
||||
verifyNoInteractions(mockRegion, mockResourceReader);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doImportIntoWithResourceContainingNoContent() {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
byte[] json = {};
|
||||
|
||||
ImportResourceResolver mockImportResourceResolver = mock(ImportResourceResolver.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn(Optional.of(mockResource)).when(this.importer).getResource(eq(mockRegion), eq("classpath:"));
|
||||
doReturn(true).when(mockResource).exists();
|
||||
doReturn(null).when(this.importer).getContent(eq(mockResource));
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
assertThat(this.importer.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
ResourceReader mockResourceReader = mock(ResourceReader.class);
|
||||
|
||||
verify(this.importer, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion), eq("classpath:"));
|
||||
verify(this.importer, times(1)).getContent(eq(mockResource));
|
||||
verify(mockResource, times(1)).exists();
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
verifyNoMoreInteractions(mockResource);
|
||||
verifyNoInteractions(mockRegion);
|
||||
doReturn(mockImportResourceResolver).when(this.importerExporter).getImportResourceResolver();
|
||||
doReturn(mockResourceReader).when(this.importerExporter).getResourceReader();
|
||||
doReturn(JsonCacheDataImporterExporter.EMPTY_PDX_INSTANCE_ARRAY).when(this.importerExporter).toPdx(any());
|
||||
doReturn(Optional.of(mockResource)).when(mockImportResourceResolver).resolve(eq(mockRegion));
|
||||
doReturn(json).when(mockResourceReader).read(eq(mockResource));
|
||||
|
||||
assertThat(this.importerExporter.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importerExporter, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importerExporter, times(1)).getImportResourceResolver();
|
||||
verify(this.importerExporter, times(1)).getResourceReader();
|
||||
verify(this.importerExporter, times(1)).toPdx(eq(json));
|
||||
verify(this.importerExporter, times(1))
|
||||
.regionPutPdx(eq(mockRegion), eq(JsonCacheDataImporterExporter.EMPTY_PDX_INSTANCE_ARRAY));
|
||||
verify(mockImportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
verify(mockResourceReader, times(1)).read(eq(mockResource));
|
||||
verifyNoMoreInteractions(this.importerExporter, mockImportResourceResolver, mockResourceReader);
|
||||
verifyNoInteractions(mockRegion, mockResource);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doImportIntoWithNoPdxInstance() {
|
||||
public void doImportIntoWithNoPdx() {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
byte[] json = "[{ \"name\":\"Jon Doe\" }]".getBytes();
|
||||
|
||||
ImportResourceResolver mockImportResourceResolver = mock(ImportResourceResolver.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
byte[] json = "[]".getBytes();
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn(Optional.of(mockResource)).when(this.importer).getResource(eq(mockRegion), eq("classpath:"));
|
||||
doReturn(true).when(mockResource).exists();
|
||||
doReturn(json).when(this.importer).getContent(eq(mockResource));
|
||||
doReturn(new PdxInstance[0]).when(this.importer).toPdx(eq(json));
|
||||
ResourceReader mockResourceReader = mock(ResourceReader.class);
|
||||
|
||||
assertThat(this.importer.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
doReturn(mockImportResourceResolver).when(this.importerExporter).getImportResourceResolver();
|
||||
doReturn(mockResourceReader).when(this.importerExporter).getResourceReader();
|
||||
doReturn(JsonCacheDataImporterExporter.EMPTY_PDX_INSTANCE_ARRAY).when(this.importerExporter).toPdx(eq(json));
|
||||
doReturn(Optional.of(mockResource)).when(mockImportResourceResolver).resolve(eq(mockRegion));
|
||||
doReturn(json).when(mockResourceReader).read(eq(mockResource));
|
||||
|
||||
verify(this.importer, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importer, times(1)).getResource(eq(mockRegion), eq("classpath:"));
|
||||
verify(this.importer, times(1)).getContent(eq(mockResource));
|
||||
verify(this.importer, times(1)).toPdx(eq(json));
|
||||
verify(mockResource, times(1)).exists();
|
||||
verifyNoMoreInteractions(this.importer);
|
||||
verifyNoMoreInteractions(mockResource);
|
||||
verifyNoInteractions(mockRegion);
|
||||
assertThat(this.importerExporter.doImportInto(mockRegion)).isEqualTo(mockRegion);
|
||||
|
||||
verify(this.importerExporter, times(1)).doImportInto(eq(mockRegion));
|
||||
verify(this.importerExporter, times(1)).getImportResourceResolver();
|
||||
verify(this.importerExporter, times(1)).getResourceReader();
|
||||
verify(this.importerExporter, times(1)).toPdx(eq(json));
|
||||
verify(this.importerExporter, times(1)).regionPutPdx(eq(mockRegion),
|
||||
eq(JsonCacheDataImporterExporter.EMPTY_PDX_INSTANCE_ARRAY));
|
||||
verify(mockImportResourceResolver, times(1)).resolve(eq(mockRegion));
|
||||
verify(mockResourceReader, times(1)).read(eq(mockResource));
|
||||
verifyNoMoreInteractions(this.importerExporter, mockImportResourceResolver, mockResourceReader);
|
||||
verifyNoInteractions(mockRegion, mockResource);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void doImportIntoNullRegion() {
|
||||
|
||||
try {
|
||||
this.importer.doImportInto(null);
|
||||
this.importerExporter.doImportInto(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
@@ -343,144 +292,12 @@ public class JsonCacheDataImporterExporterUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContentFromResource() throws IOException {
|
||||
|
||||
byte[] json = "{ \"name\": \"Jon Doe\" }".getBytes();
|
||||
|
||||
ByteArrayInputStream in = spy(new ByteArrayInputStream(json));
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn(in).when(mockResource).getInputStream();
|
||||
|
||||
assertThat(this.importer.getContent(mockResource)).isEqualTo(json);
|
||||
|
||||
verify(mockResource, times(1)).getInputStream();
|
||||
verify(in, times(1)).close();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getContentFromNullResource() {
|
||||
|
||||
try {
|
||||
this.importer.getContent(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Resource must not be null");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = DataAccessResourceFailureException.class)
|
||||
public void getContentThrowsIoException() throws IOException {
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn("Test Resource").when(mockResource).getDescription();
|
||||
doThrow(new IOException("TEST")).when(mockResource).getInputStream();
|
||||
|
||||
try {
|
||||
this.importer.getContent(mockResource);
|
||||
}
|
||||
catch (DataAccessResourceFailureException expected) {
|
||||
|
||||
assertThat(expected).hasMessageStartingWith("Failed to read from Resource [Test Resource]");
|
||||
assertThat(expected).hasCauseInstanceOf(IOException.class);
|
||||
assertThat(expected.getCause()).hasMessage("TEST");
|
||||
assertThat(expected.getCause()).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceFromRegionAndResourcePrefix() {
|
||||
|
||||
ApplicationContext mockApplicationContext = mock(ApplicationContext.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
Resource mockResource = mock(Resource.class);
|
||||
|
||||
doReturn(mockResource).when(mockApplicationContext).getResource(anyString());
|
||||
doReturn("Example").when(mockRegion).getName();
|
||||
doReturn(Optional.of(mockApplicationContext)).when(this.importer).getApplicationContext();
|
||||
|
||||
assertThat(this.importer.getResource(mockRegion, "sftp://host/resources/").orElse(null))
|
||||
.isEqualTo(mockResource);
|
||||
|
||||
verify(mockApplicationContext, times(1))
|
||||
.getResource(eq("sftp://host/resources/data-example.json"));
|
||||
verify(mockRegion, times(1)).getName();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceWhenApplicationContextIsNotPresent() {
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn("TEST").when(mockRegion).getName();
|
||||
|
||||
Resource resource = this.importer.getResource(mockRegion, "file://").orElse(null);
|
||||
|
||||
assertThat(resource).isInstanceOf(ClassPathResource.class);
|
||||
assertThat(((ClassPathResource) resource).getPath()).isEqualTo("data-test.json");
|
||||
|
||||
verify(mockRegion, times(1)).getName();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceWhenApplicationContextReturnsNoResource() {
|
||||
|
||||
ApplicationContext mockApplicationContext = mock(ApplicationContext.class);
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
doReturn(null).when(mockApplicationContext).getResource(anyString());
|
||||
doReturn("MocK").when(mockRegion).getName();
|
||||
doReturn(Optional.ofNullable(mockApplicationContext)).when(this.importer).getApplicationContext();
|
||||
|
||||
Resource resource = this.importer.getResource(mockRegion, null).orElse(null);
|
||||
|
||||
assertThat(resource).isInstanceOf(ClassPathResource.class);
|
||||
assertThat(((ClassPathResource) resource).getPath()).isEqualTo("data-mock.json");
|
||||
|
||||
verify(mockApplicationContext, times(1))
|
||||
.getResource(eq("classpath:data-mock.json"));
|
||||
verify(mockRegion, times(1)).getName();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getResourceFromNullRegion() {
|
||||
|
||||
try {
|
||||
this.importer.getResource(null, "classpath:");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Region must not be null");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceLocationIsInWorkingDirectory() {
|
||||
assertThat(this.importer.getResourceLocation()).isEqualTo(String.format("file://%1$s%2$s",
|
||||
System.getProperty("user.dir"), File.separator));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toJsonFromEmptyRegion() {
|
||||
|
||||
Region<?, ?> mockRegion = mock(Region.class);
|
||||
|
||||
assertThat(this.importer.toJson(mockRegion)).isEqualTo("[]");
|
||||
assertThat(this.importerExporter.toJson(mockRegion)).isEqualTo("[]");
|
||||
|
||||
verify(mockRegion, times(1)).values();
|
||||
}
|
||||
@@ -489,7 +306,7 @@ public class JsonCacheDataImporterExporterUnitTests {
|
||||
public void toJsonFromNullRegion() {
|
||||
|
||||
try {
|
||||
this.importer.toJson(null);
|
||||
this.importerExporter.toJson(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
@@ -512,13 +329,36 @@ public class JsonCacheDataImporterExporterUnitTests {
|
||||
|
||||
PdxInstance[] pdxArray = ArrayUtils.asArray(mockPdxInstanceOne, mockPdxInstanceTwo);
|
||||
|
||||
doReturn(mockConverter).when(this.importer).getJsonToPdxArrayConverter();
|
||||
doReturn(mockConverter).when(this.importerExporter).getJsonToPdxArrayConverter();
|
||||
doReturn(pdxArray).when(mockConverter).convert(eq(json));
|
||||
|
||||
assertThat(this.importer.toPdx(json)).isEqualTo(pdxArray);
|
||||
assertThat(this.importerExporter.toPdx(json)).isEqualTo(pdxArray);
|
||||
|
||||
verify(this.importer, times(1)).getJsonToPdxArrayConverter();
|
||||
verify(this.importerExporter, times(1)).getJsonToPdxArrayConverter();
|
||||
verify(mockConverter, times(1)).convert(eq(json));
|
||||
verifyNoMoreInteractions(mockConverter);
|
||||
}
|
||||
|
||||
static class TestJsonCacheDataImporterExporter extends JsonCacheDataImporterExporter {
|
||||
|
||||
@Override
|
||||
protected @NonNull ExportResourceResolver getExportResourceResolver() {
|
||||
return super.getExportResourceResolver();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull ImportResourceResolver getImportResourceResolver() {
|
||||
return super.getImportResourceResolver();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull ResourceReader getResourceReader() {
|
||||
return super.getResourceReader();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull ResourceWriter getResourceWriter() {
|
||||
return super.getResourceWriter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -52,7 +51,7 @@ import org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.PropertiesBuilder;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.geode.core.io.ResourceWriter;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import example.app.crm.model.Customer;
|
||||
@@ -89,7 +88,6 @@ import example.app.crm.model.Customer;
|
||||
public class JsonClientCacheDataImporterExporterIntegrationTests extends ForkingClientServerIntegrationTestsSupport {
|
||||
|
||||
private static final AtomicBoolean applicationContextClosed = new AtomicBoolean(false);
|
||||
private static final AtomicBoolean exportFromCalled = new AtomicBoolean(false);
|
||||
|
||||
private static ConfigurableApplicationContext applicationContext = null;
|
||||
|
||||
@@ -101,7 +99,6 @@ public class JsonClientCacheDataImporterExporterIntegrationTests extends Forking
|
||||
public static void assetClientCacheDataExportWorksAsExpected() throws IOException {
|
||||
|
||||
assertThat(applicationContextClosed.get()).isTrue();
|
||||
assertThat(exportFromCalled.get()).isTrue();
|
||||
|
||||
String actualJson = trimJson(writer.toString());
|
||||
String expectedJson = trimJson(loadJson(CUSTOMERS_JSON_RESOURCE_PATH));
|
||||
@@ -212,14 +209,18 @@ public class JsonClientCacheDataImporterExporterIntegrationTests extends Forking
|
||||
|
||||
@Bean
|
||||
JsonCacheDataImporterExporter cacheDataImporterExporter() {
|
||||
return new JsonCacheDataImporterExporter();
|
||||
}
|
||||
|
||||
return new JsonCacheDataImporterExporter() {
|
||||
@Bean
|
||||
ResourceWriter testResourceWriter() {
|
||||
|
||||
@Override
|
||||
@NonNull Writer newWriter(@NonNull org.springframework.core.io.Resource resource) {
|
||||
exportFromCalled.set(true);
|
||||
return writer;
|
||||
}
|
||||
return (resource, data) -> {
|
||||
|
||||
String json = new String(data);
|
||||
|
||||
writer.write(json);
|
||||
writer.flush();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user