From 7a13850ef07e9fddb0e2311fb960d3733a88b85f Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 21 Jul 2020 22:29:52 -0700 Subject: [PATCH] Refactor ResourceCapableCacheDataImporterExporter import & export cache ResourceResolver base classes to be static. Change AbstractCacheResourceResolver class to be ApplicationContextAware and EnvironmentAware. Add getLogger() method to the AbstractCacheResourceResolver class. Add Resource description in Logger message logged by onMissingResource(..) on export. Annotate AbstractExportResourceResolver.onMisingResource(..) method signature with Spring Framework @NonNull and @Nullable annotations. Separate logic from afterPropertiesSet() initializing the ApplicationContext, Environment and ResourceLoader objects on aware import/export ResourceResolvers into init methods. Edit Javadoc. Resolves gh-92. --- ...ourceCapableCacheDataImporterExporter.java | 139 ++++++- ...bleCacheDataImporterExporterUnitTests.java | 391 +++++++++++------- 2 files changed, 373 insertions(+), 157 deletions(-) diff --git a/spring-geode/src/main/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporter.java b/spring-geode/src/main/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporter.java index db3846ca..b7d5bef9 100644 --- a/spring-geode/src/main/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporter.java +++ b/spring-geode/src/main/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporter.java @@ -28,10 +28,13 @@ import org.apache.geode.cache.Region; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.expression.BeanFactoryAccessor; import org.springframework.core.convert.ConversionService; +import org.springframework.core.env.Environment; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.expression.EvaluationContext; @@ -62,6 +65,9 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * An {@link AbstractCacheDataImporterExporter} extension and implementation capable of handling and managing import * and export {@link Resource Resources}. @@ -108,16 +114,52 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC private ResourceWriter resourceWriter; /** - * Initializes the Export & Import {@link ResourceResolver ResourceResolvers} as needed along with - * the reader and writer for the {@link Resource} used on import and export. + * Initializes the export and import {@link ResourceResolver ResourceResolvers} as needed along with + * the {@link ResourceReader reader} and {@link ResourceWriter writer} for the {@link Resource} + * used on import and export. */ @Override public void afterPropertiesSet() { - this.exportResourceResolver = initialize(this.exportResourceResolver, FileSystemExportResourceResolver::new); - this.importResourceResolver = initialize(this.importResourceResolver, ClassPathImportResourceResolver::new); - this.resourceReader = initialize(this.resourceReader, ByteArrayResourceReader::new); - this.resourceWriter = initialize(this.resourceWriter, FileResourceWriter::new); + setExportResourceResolver(initialize(getExportResourceResolver(), FileSystemExportResourceResolver::new)); + setImportResourceResolver(initialize(getImportResourceResolver(), ClassPathImportResourceResolver::new)); + setResourceReader(initialize(getResourceReader(), ByteArrayResourceReader::new)); + setResourceWriter(initialize(getResourceWriter(), FileResourceWriter::new)); + + initApplicationContext(); + initEnvironment(); + initResourceLoader(); + } + + private void initApplicationContext() { + + getApplicationContext().ifPresent(applicationContext -> { + + if (this.exportResourceResolver instanceof ApplicationContextAware) { + ((ApplicationContextAware) this.exportResourceResolver).setApplicationContext(applicationContext); + } + + if (this.importResourceResolver instanceof ApplicationContextAware) { + ((ApplicationContextAware) this.importResourceResolver).setApplicationContext(applicationContext); + } + }); + } + + private void initEnvironment() { + + getEnvironment().ifPresent(environment -> { + + if (this.exportResourceResolver instanceof EnvironmentAware) { + ((EnvironmentAware) this.exportResourceResolver).setEnvironment(environment); + } + + if (this.importResourceResolver instanceof EnvironmentAware) { + ((EnvironmentAware) this.importResourceResolver).setEnvironment(environment); + } + }); + } + + private void initResourceLoader() { getResourceLoader().ifPresent(resourceLoader -> { @@ -297,13 +339,21 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC * {@link ResourceResolver ResourceResolvers}, whether for import or export. * * @see org.springframework.geode.core.io.support.ResourceLoaderResourceResolver + * @see org.springframework.context.ApplicationContextAware + * @see org.springframework.context.EnvironmentAware * @see CacheResourceResolver */ - protected abstract class AbstractCacheResourceResolver extends ResourceLoaderResourceResolver - implements CacheResourceResolver { + protected static abstract class AbstractCacheResourceResolver extends ResourceLoaderResourceResolver + implements ApplicationContextAware, CacheResourceResolver, EnvironmentAware { + + private ApplicationContext applicationContext; + + private Environment environment; private final ExpressionParser expressionParser; + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final Map compiledExpressions; private final SimpleEvaluationContext.Builder evaluationContextBuilder; @@ -364,6 +414,50 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC return this.evaluationContextBuilder.build(); } + /** + * Configures a reference to the Spring {@link ApplicationContext}. + * + * @param applicationContext reference to the {@link ApplicationContext}. + * @see org.springframework.context.ApplicationContext + */ + @Override + public void setApplicationContext(@Nullable ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + /** + * Returns an {@link Optional} reference to a Spring {@link ApplicationContext}. + * + * @return an {@link Optional} reference to a Spring {@link ApplicationContext}. + * @see org.springframework.context.ApplicationContext + * @see java.util.Optional + */ + protected Optional getApplicationContext() { + return Optional.ofNullable(this.applicationContext); + } + + /** + * Configures a reference to the Spring {@link Environment}. + * + * @param environment reference to the {@link Environment}. + * @see org.springframework.core.env.Environment + */ + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + /** + * Returns an {@link Optional} reference to the Spring {@link Environment}. + * + * @return an {@link Optional} reference to the Spring {@link Environment}. + * @see org.springframework.core.env.Environment + * @see java.util.Optional + */ + protected Optional getEnvironment() { + return Optional.ofNullable(this.environment); + } + /** * Gets the configured {@link ExpressionParser} used to parse SpEL {@link String expressions}. * @@ -374,6 +468,16 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC return this.expressionParser; } + /** + * Return the configured {@link Logger} to log messages. + * + * @return the configured {@link Logger}. + * @see org.slf4j.Logger + */ + protected Logger getLogger() { + return this.logger; + } + /** * Gets the configured {@link ParserContext} used by the {@link ExpressionParser} to identify SpEL expressions. * @@ -517,12 +621,12 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC /** * Abstract base class extended by export {@link CacheResourceResolver} implementations, providing a template - * to resolve the {@link Resource} used on export. + * to resolve the {@link Resource} used for export. * * @see AbstractCacheResourceResolver * @see ExportResourceResolver */ - public abstract class AbstractExportResourceResolver extends AbstractCacheResourceResolver + public static abstract class AbstractExportResourceResolver extends AbstractCacheResourceResolver implements ExportResourceResolver { /** @@ -537,7 +641,9 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC Optional resource = resolve(resourceLocation); - if (!resource.filter(ResourceUtils::isWritable).isPresent()) { + boolean writable = resource.filter(ResourceUtils::isWritable).isPresent(); + + if (!writable) { getLogger().warn("WARNING! Resource [{}] for Region [{}] is not writable", resourceLocation, region.getFullPath()); } @@ -549,9 +655,10 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC * @inheritDoc */ @Override - protected @Nullable Resource onMissingResource(Resource resource, String location) { + protected @Nullable Resource onMissingResource(@Nullable Resource resource, @NonNull String location) { - getLogger().warn("WARNING! Resource at location [{}] does not exist; will try to create it", location); + getLogger().warn("WARNING! Resource [{}] at location [{}] does not exist; will try to create it on export", + ResourceUtils.nullSafeGetDescription(resource), location); return resource; } @@ -560,7 +667,7 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC /** * Resolves the {@link Resource} used for {@literal export} from the {@literal filesystem}. */ - public class FileSystemExportResourceResolver extends AbstractExportResourceResolver { + public static class FileSystemExportResourceResolver extends AbstractExportResourceResolver { @Override protected @NonNull String getResourcePath() { @@ -585,7 +692,7 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC * @see AbstractCacheResourceResolver * @see ImportResourceResolver */ - public abstract class AbstractImportResourceResolver extends AbstractCacheResourceResolver + public static abstract class AbstractImportResourceResolver extends AbstractCacheResourceResolver implements ImportResourceResolver { /** @@ -615,7 +722,7 @@ public abstract class ResourceCapableCacheDataImporterExporter extends AbstractC /** * Resolves the {@link Resource} to {@literal import} from the {@literal classpath}. */ - public class ClassPathImportResourceResolver extends AbstractImportResourceResolver { + public static class ClassPathImportResourceResolver extends AbstractImportResourceResolver { @Override protected @NonNull String getResourcePath() { diff --git a/spring-geode/src/test/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporterUnitTests.java b/spring-geode/src/test/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporterUnitTests.java index 09ee81e4..faee5db8 100644 --- a/spring-geode/src/test/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporterUnitTests.java +++ b/spring-geode/src/test/java/org/springframework/geode/data/support/ResourceCapableCacheDataImporterExporterUnitTests.java @@ -28,7 +28,6 @@ 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 static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException; import java.io.File; import java.util.Map; @@ -39,13 +38,14 @@ import org.junit.Test; import org.apache.geode.cache.Region; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.env.Environment; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.WritableResource; import org.springframework.data.gemfire.tests.support.MapBuilder; -import org.springframework.data.gemfire.tests.util.ReflectionUtils; import org.springframework.expression.ParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.geode.core.io.ResourceReader; @@ -61,8 +61,6 @@ import org.springframework.geode.data.support.ResourceCapableCacheDataImporterEx import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.FileSystemExportResourceResolver; import org.springframework.geode.data.support.ResourceCapableCacheDataImporterExporter.ImportResourceResolver; import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.ObjectUtils; import org.slf4j.Logger; @@ -85,20 +83,8 @@ import org.slf4j.Logger; */ public class ResourceCapableCacheDataImporterExporterUnitTests { - @SuppressWarnings("unchecked") - private T inject(@NonNull T target, @NonNull String fieldName, @Nullable Object value) { - - try { - return (T) ReflectionUtils.setField(target, fieldName, value); - } - catch (NoSuchFieldException cause) { - throw newRuntimeException(cause, "Failed to set field [%s] on object of type [%s] to value [%s]", - fieldName, ObjectUtils.nullSafeClassName(target), value); - } - } - @Test - public void afterPropertiesSetUsesImportExportReaderWriterResourceDefaults() { + public void afterPropertiesSetUsesDefaultImportExportResourceResolversAndDefaultResourceReaderWriter() { ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); @@ -112,13 +98,17 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { } @Test - public void afterPropertiesSetWithInjectedImportExportResourceResolversAndResourceReaderWriter() { + public void afterPropertiesSetUsesInjectedImportExportResourceResolversAndInjectedResourceReaderWriter() { - ResourceLoaderAwareExportResourceResolver mockExportResourceResolver = - mock(ResourceLoaderAwareExportResourceResolver.class); + ApplicationContext mockApplicationContext = mock(ApplicationContext.class); - ResourceLoaderAwareImportResourceResolver mockImportResourceResolver = - mock(ResourceLoaderAwareImportResourceResolver.class); + Environment mockEnvironment = mock(Environment.class); + + ApplicationContextEnvironmentAndResourceLoaderAwareExportResourceResolver mockExportResourceResolver = + mock(ApplicationContextEnvironmentAndResourceLoaderAwareExportResourceResolver.class); + + ApplicationContextEnvironmentAndResourceLoaderAwareImportResourceResolver mockImportResourceResolver = + mock(ApplicationContextEnvironmentAndResourceLoaderAwareImportResourceResolver.class); ResourceLoader mockResourceLoader = mock(ResourceLoader.class); @@ -128,12 +118,13 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); - inject(importerExporter, "exportResourceResolver", mockExportResourceResolver); - inject(importerExporter, "importResourceResolver", mockImportResourceResolver); - inject(importerExporter, "resourceReader", mockResourceReader); - inject(importerExporter, "resourceWriter", mockResourceWriter); - + importerExporter.setApplicationContext(mockApplicationContext); + importerExporter.setEnvironment(mockEnvironment); + importerExporter.setExportResourceResolver(mockExportResourceResolver); + importerExporter.setImportResourceResolver(mockImportResourceResolver); importerExporter.setResourceLoader(mockResourceLoader); + importerExporter.setResourceReader(mockResourceReader); + importerExporter.setResourceWriter(mockResourceWriter); importerExporter.afterPropertiesSet(); assertThat(importerExporter.getExportResourceResolver()).isEqualTo(mockExportResourceResolver); @@ -142,9 +133,90 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { assertThat(importerExporter.getResourceReader()).isEqualTo(mockResourceReader); assertThat(importerExporter.getResourceWriter()).isEqualTo(mockResourceWriter); + verify(mockExportResourceResolver, times(1)).setApplicationContext(eq(mockApplicationContext)); + verify(mockExportResourceResolver, times(1)).setEnvironment(eq(mockEnvironment)); verify(mockExportResourceResolver, times(1)).setResourceLoader(eq(mockResourceLoader)); + verify(mockImportResourceResolver, times(1)).setApplicationContext(eq(mockApplicationContext)); + verify(mockImportResourceResolver, times(1)).setEnvironment(eq(mockEnvironment)); verify(mockImportResourceResolver, times(1)).setResourceLoader(eq(mockResourceLoader)); - verifyNoInteractions(mockResourceLoader, mockResourceReader, mockResourceWriter); + verifyNoInteractions(mockApplicationContext, mockEnvironment, mockResourceLoader, + mockResourceReader, mockResourceWriter); + } + + @Test + public void afterPropertiesSetInitializesPartly() { + + ApplicationContext mockApplicationContext = mock(ApplicationContext.class); + + Environment mockEnvironment = mock(Environment.class); + + ApplicationContextAndResourceLoaderAwareImportResourceResolver mockImportResourceResolver = + mock(ApplicationContextAndResourceLoaderAwareImportResourceResolver.class); + + ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); + + importerExporter.setApplicationContext(mockApplicationContext); + importerExporter.setEnvironment(mockEnvironment); + importerExporter.setImportResourceResolver(mockImportResourceResolver); + + assertThat(importerExporter.getExportResourceResolver()).isNull(); + assertThat(importerExporter.getImportResourceResolver()).isSameAs(mockImportResourceResolver); + assertThat(importerExporter.getResourceLoader().orElse(null)).isNull(); + assertThat(importerExporter.getResourceReader()).isNull(); + assertThat(importerExporter.getResourceWriter()).isNull(); + + importerExporter.afterPropertiesSet(); + + assertThat(importerExporter.getExportResourceResolver()).isInstanceOf(FileSystemExportResourceResolver.class); + assertThat(importerExporter.getImportResourceResolver()).isSameAs(mockImportResourceResolver); + assertThat(importerExporter.getResourceLoader().orElse(null)).isNull(); + assertThat(importerExporter.getResourceReader()).isInstanceOf(ByteArrayResourceReader.class); + assertThat(importerExporter.getResourceWriter()).isInstanceOf(FileResourceWriter.class); + + verify(mockImportResourceResolver, times(1)).setApplicationContext(eq(mockApplicationContext)); + verify(mockImportResourceResolver, never()).setResourceLoader(any()); + verifyNoMoreInteractions(mockImportResourceResolver); + verifyNoInteractions(mockApplicationContext, mockEnvironment); + } + + @Test + public void setAndGetExportResourceResolver() { + + ExportResourceResolver mockExportResourceResolver = mock(ExportResourceResolver.class); + + ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); + + assertThat(importerExporter.getExportResourceResolver()).isNull(); + + importerExporter.setExportResourceResolver(mockExportResourceResolver); + + assertThat(importerExporter.getExportResourceResolver()).isSameAs(mockExportResourceResolver); + + importerExporter.setExportResourceResolver(null); + + assertThat(importerExporter.getExportResourceResolver()).isNull(); + + verifyNoInteractions(mockExportResourceResolver); + } + + @Test + public void setAndGetImportResourceResolver() { + + ImportResourceResolver mockImportResourceResolver = mock(ImportResourceResolver.class); + + ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); + + assertThat(importerExporter.getImportResourceResolver()).isNull(); + + importerExporter.setImportResourceResolver(mockImportResourceResolver); + + assertThat(importerExporter.getImportResourceResolver()).isSameAs(mockImportResourceResolver); + + importerExporter.setImportResourceResolver(null); + + assertThat(importerExporter.getImportResourceResolver()).isNull(); + + verifyNoInteractions(mockImportResourceResolver); } @Test @@ -158,20 +230,101 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { importerExporter.setResourceLoader(mockResourceLoader); - assertThat(importerExporter.getResourceLoader().orElse(null)).isEqualTo(mockResourceLoader); + assertThat(importerExporter.getResourceLoader().orElse(null)).isSameAs(mockResourceLoader); importerExporter.setResourceLoader(null); assertThat(importerExporter.getResourceLoader().orElse(null)).isNull(); + + verifyNoInteractions(mockResourceLoader); + } + + @Test + public void setAndGetResourceReader() { + + ResourceReader mockResourceReader = mock(ResourceReader.class); + + ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); + + assertThat(importerExporter.getResourceReader()).isNull(); + + importerExporter.setResourceReader(mockResourceReader); + + assertThat(importerExporter.getResourceReader()).isSameAs(mockResourceReader); + + importerExporter.setResourceReader(null); + + assertThat(importerExporter.getResourceReader()).isNull(); + + verifyNoInteractions(mockResourceReader); + } + + @Test + public void setAndGetResourceWriter() { + + ResourceWriter mockResourceWriter = mock(ResourceWriter.class); + + ResourceCapableCacheDataImporterExporter importerExporter = new TestResourceCapableCacheDataImporterExporter(); + + assertThat(importerExporter.getResourceWriter()).isNull(); + + importerExporter.setResourceWriter(mockResourceWriter); + + assertThat(importerExporter.getResourceWriter()).isSameAs(mockResourceWriter); + + importerExporter.setResourceWriter(null); + + assertThat(importerExporter.getResourceWriter()).isNull(); + + verifyNoInteractions(mockResourceWriter); } // Tests for CacheResourceResolver and friends (sub-types) + @Test + public void setAndGetApplicationContext() { + + ApplicationContext mockApplicationContext = mock(ApplicationContext.class); + + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); + + assertThat(resourceResolver.getApplicationContext().orElse(null)).isNull(); + + resourceResolver.setApplicationContext(mockApplicationContext); + + assertThat(resourceResolver.getApplicationContext().orElse(null)).isSameAs(mockApplicationContext); + + resourceResolver.setApplicationContext(null); + + assertThat(resourceResolver.getApplicationContext().orElse(null)).isNull(); + + verifyNoInteractions(mockApplicationContext); + } + + @Test + public void setAndGetEnvironment() { + + Environment mockEnvironment = mock(Environment.class); + + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); + + assertThat(resourceResolver.getEnvironment().orElse(null)).isNull(); + + resourceResolver.setEnvironment(mockEnvironment); + + assertThat(resourceResolver.getEnvironment().orElse(null)).isSameAs(mockEnvironment); + + resourceResolver.setEnvironment(null); + + assertThat(resourceResolver.getEnvironment().orElse(null)).isNull(); + + verifyNoInteractions(mockEnvironment); + } + @Test public void expressionParserIsASpelExpressionParser() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); assertThat(resourceResolver.getExpressionParser()).isInstanceOf(SpelExpressionParser.class); } @@ -179,8 +332,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void parserContextIsTemplateBased() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); assertThat(resourceResolver.getParserContext()).isEqualTo(ParserContext.TEMPLATE_EXPRESSION); } @@ -188,8 +340,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void isQualifiedWithExistingResource() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); Resource mockResource = mock(Resource.class); @@ -204,8 +355,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void isQualifiedWithNonExistingResource() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); Resource mockResource = mock(Resource.class); @@ -220,8 +370,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void isQualifiedWithNullResource() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); assertThat(resourceResolver.isQualified(null)).isFalse(); } @@ -231,8 +380,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { Region mockRegion = mock(Region.class); - AbstractCacheResourceResolver resourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver()); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); doReturn("/path/to/").when(resourceResolver).getResourcePath(); doReturn("resource.xml").when(resourceResolver).getResourceName(eq(mockRegion)); @@ -259,12 +407,9 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn(true).when(mockEnvironment).containsProperty(eq(testPropertyName)); doReturn(rawPropertyValue).when(mockEnvironment).getProperty(eq(testPropertyName)); - TestResourceCapableCacheDataImporterExporter importerExporter = - spy(new TestResourceCapableCacheDataImporterExporter()); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); - AbstractCacheResourceResolver resourceResolver = spy(importerExporter.new TestCacheResourceResolver()); - - doReturn(Optional.of(mockEnvironment)).when(importerExporter).getEnvironment(); + doReturn(Optional.of(mockEnvironment)).when(resourceResolver).getEnvironment(); doAnswer(invocation -> { @@ -281,7 +426,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { verify(mockEnvironment, times(1)).containsProperty(eq(testPropertyName)); verify(mockEnvironment, times(1)).getProperty(eq(testPropertyName)); verify(mockRegion, times(1)).getName(); - verify(importerExporter, times(1)).getEnvironment(); + verify(resourceResolver, times(1)).getEnvironment(); verify(resourceResolver, times(1)).evaluate(eq(rawPropertyValue), eq(mockRegion)); verifyNoMoreInteractions(mockEnvironment, mockRegion); } @@ -291,19 +436,16 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { Region mockRegion = mock(Region.class); - TestResourceCapableCacheDataImporterExporter importerExporter = - spy(new TestResourceCapableCacheDataImporterExporter()); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); - AbstractCacheResourceResolver resourceResolver = spy(importerExporter.new TestCacheResourceResolver()); - - doReturn(Optional.empty()).when(importerExporter).getEnvironment(); + doReturn(Optional.empty()).when(resourceResolver).getEnvironment(); doReturn("/path/to/resource.xml").when(resourceResolver) .getFullyQualifiedResourceLocation(eq(mockRegion)); assertThat(resourceResolver.getResourceLocation(mockRegion, "test.property.name")) .isEqualTo("/path/to/resource.xml"); - verify(importerExporter, times(1)).getEnvironment(); + verify(resourceResolver, times(1)).getEnvironment(); verify(resourceResolver, never()).evaluate(anyString(), any(Region.class)); verifyNoInteractions(mockRegion); } @@ -317,19 +459,16 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn(false).when(mockEnvironment).containsProperty(anyString()); - TestResourceCapableCacheDataImporterExporter importerExporter = - spy(new TestResourceCapableCacheDataImporterExporter()); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); - AbstractCacheResourceResolver resourceResolver = spy(importerExporter.new TestCacheResourceResolver()); - - doReturn(Optional.of(mockEnvironment)).when(importerExporter).getEnvironment(); + doReturn(Optional.of(mockEnvironment)).when(resourceResolver).getEnvironment(); doReturn("/path/to/resource.bin").when(resourceResolver) .getFullyQualifiedResourceLocation(eq(mockRegion)); assertThat(resourceResolver.getResourceLocation(mockRegion, "test.property.name")) .isEqualTo("/path/to/resource.bin"); - verify(importerExporter, times(1)).getEnvironment(); + verify(resourceResolver, times(1)).getEnvironment(); verify(resourceResolver, never()).evaluate(anyString(), any(Region.class)); verify(mockEnvironment, times(1)).containsProperty(eq("test.property.name")); verifyNoMoreInteractions(mockEnvironment); @@ -346,19 +485,16 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn(true).when(mockEnvironment).containsProperty(eq("test.property.name")); doReturn(null).when(mockEnvironment).getProperty(anyString()); - TestResourceCapableCacheDataImporterExporter importerExporter = - spy(new TestResourceCapableCacheDataImporterExporter()); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); - AbstractCacheResourceResolver resourceResolver = spy(importerExporter.new TestCacheResourceResolver()); - - doReturn(Optional.of(mockEnvironment)).when(importerExporter).getEnvironment(); + doReturn(Optional.of(mockEnvironment)).when(resourceResolver).getEnvironment(); doReturn("/path/to/resource.dat").when(resourceResolver) .getFullyQualifiedResourceLocation(eq(mockRegion)); assertThat(resourceResolver.getResourceLocation(mockRegion, "test.property.name")) .isEqualTo("/path/to/resource.dat"); - verify(importerExporter, times(1)).getEnvironment(); + verify(resourceResolver, times(1)).getEnvironment(); verify(resourceResolver, never()).evaluate(anyString(), any(Region.class)); verify(mockEnvironment, times(1)).containsProperty(eq("test.property.name")); verify(mockEnvironment, times(1)).getProperty(eq("test.property.name")); @@ -369,8 +505,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test(expected = IllegalArgumentException.class) public void getResourceLocationWithNullRegion() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); try { resourceResolver.getResourceLocation(null, "test.property.name"); @@ -389,8 +524,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { Region mockRegion = mock(Region.class); - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); try { resourceResolver.getResourceLocation(mockRegion, " "); @@ -414,8 +548,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn("Example").when(mockRegion).getName(); - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); assertThat(resourceResolver.getResourceName(mockRegion)) .isEqualTo(String.format(ResourceCapableCacheDataImporterExporter.RESOURCE_NAME_PATTERN, "example")); @@ -427,8 +560,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void getResourceNameFromString() { - AbstractCacheResourceResolver resourceResolver = - new TestResourceCapableCacheDataImporterExporter().new TestCacheResourceResolver(); + AbstractCacheResourceResolver resourceResolver = new TestCacheResourceResolver(); assertThat(resourceResolver.getResourceName("EXAMPLE")) .isEqualTo(String.format(ResourceCapableCacheDataImporterExporter.RESOURCE_NAME_PATTERN, "EXAMPLE")); @@ -459,13 +591,10 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { .when(mockEnvironment).getProperty(any()); doReturn("Example").when(mockRegion).getName(); - TestResourceCapableCacheDataImporterExporter importerExporter = - mock(TestResourceCapableCacheDataImporterExporter.class); + AbstractCacheResourceResolver resourceResolver = spy(new TestCacheResourceResolver()); - doReturn(Optional.ofNullable(mockApplicationContext)).when(importerExporter).getApplicationContext(); - doReturn(Optional.ofNullable(mockEnvironment)).when(importerExporter).getEnvironment(); - - AbstractCacheResourceResolver resourceResolver = importerExporter.new TestCacheResourceResolver(); + doReturn(Optional.ofNullable(mockApplicationContext)).when(resourceResolver).getApplicationContext(); + doReturn(Optional.ofNullable(mockEnvironment)).when(resourceResolver).getEnvironment(); String expression = "https://#{#env['user.name']}:#{#env['user.password']}@skullbox:#{port}/nurv/cache/#{utility.toUpperCase(#regionName)}/data/import"; String parsedExpression = String.format("https://%s:s3c3rt@skullbox:8181/nurv/cache/EXAMPLE/data/import", @@ -491,24 +620,21 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { Region mockRegion = mock(Region.class); - doReturn("/Example").when(mockRegion).getFullPath(); - ResourceLoader mockResourceLoader = mock(ResourceLoader.class); WritableResource mockResource = mock(WritableResource.class); + doReturn("/Example").when(mockRegion).getFullPath(); doReturn(mockResource).when(mockResourceLoader).getResource(eq("/path/to/resource.xml")); doReturn(false).when(mockResource).exists(); doReturn(false).when(mockResource).isWritable(); + doReturn("MOCK").when(mockResource).getDescription(); - TestResourceCapableCacheDataImporterExporter importerExporter = - spy(new TestResourceCapableCacheDataImporterExporter()); - - AbstractExportResourceResolver exportResourceResolver = spy(importerExporter.new TestExportResourceResolver()); + AbstractExportResourceResolver exportResourceResolver = spy(new TestExportResourceResolver()); exportResourceResolver.setResourceLoader(mockResourceLoader); - doReturn(mockLogger).when(importerExporter).getLogger(); + doReturn(mockLogger).when(exportResourceResolver).getLogger(); doReturn("/path/to/resource.xml") .when(exportResourceResolver).getResourceLocation(eq(mockRegion), @@ -518,7 +644,6 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { assertThat(exportResourceResolver.resolve(mockRegion)).isEqualTo(Optional.of(mockResource)); - verify(importerExporter, times(2)).getLogger(); verify(exportResourceResolver, times(1)).getResourceLocation(eq(mockRegion), eq(ResourceCapableCacheDataImporterExporter.CACHE_DATA_EXPORT_RESOURCE_LOCATION_PROPERTY_NAME)); verify(exportResourceResolver, times(1)).isQualified(eq(mockResource)); @@ -528,9 +653,10 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { verify(mockResourceLoader, times(1)).getResource(eq("/path/to/resource.xml")); verify(mockResource, times(1)).exists(); verify(mockResource, times(1)).isWritable(); + verify(mockResource, times(1)).getDescription(); verify(mockLogger, times(1)) - .warn(eq("WARNING! Resource at location [{}] does not exist; will try to create it"), - eq("/path/to/resource.xml")); + .warn(eq("WARNING! Resource [{}] at location [{}] does not exist; will try to create it on export"), + eq("MOCK"), eq("/path/to/resource.xml")); verify(mockLogger, times(1)) .warn(eq("WARNING! Resource [{}] for Region [{}] is not writable"), eq("/path/to/resource.xml"), eq("/Example")); @@ -541,8 +667,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test(expected = IllegalArgumentException.class) public void resolveExportResourceWithNullRegionThrowsIllegalArgumentException() { - AbstractExportResourceResolver exportResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestExportResourceResolver()); + AbstractExportResourceResolver exportResourceResolver = spy(new TestExportResourceResolver()); try { exportResourceResolver.resolve((Region) null); @@ -559,8 +684,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void fileSystemExportResourceResolverResolvesToFileSystemPath() { - AbstractExportResourceResolver exportResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new FileSystemExportResourceResolver()); + AbstractExportResourceResolver exportResourceResolver = spy(new FileSystemExportResourceResolver()); assertThat(exportResourceResolver.getResourcePath()) .isEqualTo(String.format("file://%1$s%2$s", System.getProperty("user.dir"), File.separator)); @@ -575,8 +699,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn(true).when(mockResource).isReadable(); - AbstractImportResourceResolver importResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestImportResourceResolver()); + AbstractImportResourceResolver importResourceResolver = spy(new TestImportResourceResolver()); doReturn("/path/to/resource.json") .when(importResourceResolver).getResourceLocation(eq(mockRegion), @@ -601,8 +724,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn("/Example").when(mockRegion).getFullPath(); - AbstractImportResourceResolver importResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestImportResourceResolver()); + AbstractImportResourceResolver importResourceResolver = spy(new TestImportResourceResolver()); doReturn("/path/to/resource.json") .when(importResourceResolver).getResourceLocation(eq(mockRegion), @@ -640,8 +762,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { doReturn(false).when(mockResource).isReadable(); - AbstractImportResourceResolver importResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestImportResourceResolver()); + AbstractImportResourceResolver importResourceResolver = spy(new TestImportResourceResolver()); doReturn("/path/to/resource.json") .when(importResourceResolver).getResourceLocation(eq(mockRegion), @@ -672,8 +793,7 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test(expected = IllegalArgumentException.class) public void resolveImportResourceWithNullRegionThrowsIllegalArgumentException() { - AbstractImportResourceResolver importResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new TestImportResourceResolver()); + AbstractImportResourceResolver importResourceResolver = new TestImportResourceResolver(); try { importResourceResolver.resolve((Region) null); @@ -690,35 +810,24 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { @Test public void classPathImportResourceResolverResolvesToClassPath() { - AbstractImportResourceResolver importResourceResolver = - spy(new TestResourceCapableCacheDataImporterExporter().new ClassPathImportResourceResolver()); + AbstractImportResourceResolver importResourceResolver = spy(new ClassPathImportResourceResolver()); assertThat(importResourceResolver.getResourcePath()) .isEqualTo(ResourcePrefix.CLASSPATH_URL_PREFIX.toUrlPrefix()); } - interface ResourceLoaderAwareExportResourceResolver extends ResourceLoaderAware, ExportResourceResolver { } + interface ApplicationContextAndResourceLoaderAwareImportResourceResolver + extends ApplicationContextAware, ImportResourceResolver, ResourceLoaderAware {} - interface ResourceLoaderAwareImportResourceResolver extends ResourceLoaderAware, ImportResourceResolver { } + interface ApplicationContextEnvironmentAndResourceLoaderAwareExportResourceResolver + extends ApplicationContextAware, EnvironmentAware, ResourceLoaderAware, ExportResourceResolver { } + + interface ApplicationContextEnvironmentAndResourceLoaderAwareImportResourceResolver + extends ApplicationContextAware, EnvironmentAware, ResourceLoaderAware, ImportResourceResolver { } @SuppressWarnings("rawtypes") static class TestResourceCapableCacheDataImporterExporter extends ResourceCapableCacheDataImporterExporter { - @Override - protected Optional getApplicationContext() { - return super.getApplicationContext(); - } - - @Override - protected Optional getEnvironment() { - return super.getEnvironment(); - } - - @Override - protected Logger getLogger() { - return super.getLogger(); - } - @Override protected @NonNull Region doExportFrom(@NonNull Region region) { return region; @@ -728,34 +837,34 @@ public class ResourceCapableCacheDataImporterExporterUnitTests { protected @NonNull Region doImportInto(@NonNull Region region) { return region; } + } - class TestCacheResourceResolver extends AbstractCacheResourceResolver { + static class TestCacheResourceResolver extends AbstractCacheResourceResolver { - @Override - public Optional resolve(@NonNull Region region) { - return Optional.empty(); - } - - @NonNull @Override - protected String getResourcePath() { - return null; - } + @Override + public Optional resolve(@NonNull Region region) { + return Optional.empty(); } - class TestExportResourceResolver extends AbstractExportResourceResolver { - - @NonNull @Override - protected String getResourcePath() { - return null; - } + @NonNull @Override + protected String getResourcePath() { + return null; } + } - class TestImportResourceResolver extends AbstractImportResourceResolver { + static class TestExportResourceResolver extends AbstractExportResourceResolver { - @NonNull @Override - protected String getResourcePath() { - return null; - } + @NonNull @Override + protected String getResourcePath() { + return null; + } + } + + static class TestImportResourceResolver extends AbstractImportResourceResolver { + + @NonNull @Override + protected String getResourcePath() { + return null; } }