SGF-408 - Provide support in the SDG XML namespace to load a pre-defined data set using GemFire Snapshot Service for development and testing purposes.
Refactored the SnapshotServiceFactoryBean with the addition of a new property (suppressInitImport) to suppress importing on initialization. Refactored the SnapshotServiceFactoryBean SnapshotServiceAdapter interface's doImport(..) and doExport(..) method signatures to varargs. Added the ComposableSnapshotFilter class implemeting the SnapshotFilter interface and Composition Design Pattern for composing multiple SnapshotFilters into one using logical operators. Cleaned up and added addition unit tests. Completed all integration testing including testing with export and import snapshot application event driven GemFire Cache Region snapshots.
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.gemstone.gemfire.cache.snapshot.SnapshotFilter;
|
||||
|
||||
/**
|
||||
* The ComposableSnapshotFilter class is a GemFire SnapshotFilter implementation of the Composition design pattern
|
||||
* allowing 2 or more SnapshotFilters to be combined by logical AND and OR operators acting as a single SnapshotFilter.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ComposableSnapshotFilter<K, V> implements SnapshotFilter<K, V> {
|
||||
|
||||
/**
|
||||
* Operator is an enumeration of logical operators (AND, OR) used to compose SnapshotFilters
|
||||
* into a boolean expression.
|
||||
*/
|
||||
protected enum Operator {
|
||||
AND,
|
||||
OR;
|
||||
|
||||
public boolean isAnd() {
|
||||
return (this == AND);
|
||||
}
|
||||
|
||||
public boolean isOr() {
|
||||
return (this == OR);
|
||||
}
|
||||
|
||||
public boolean operate(boolean leftOperand, boolean rightOperand) {
|
||||
return (isAnd() ? (leftOperand && rightOperand) : (leftOperand || rightOperand));
|
||||
}
|
||||
}
|
||||
|
||||
private final Operator operator;
|
||||
|
||||
private final SnapshotFilter<K, V> leftOperand;
|
||||
private final SnapshotFilter<K, V> rightOperand;
|
||||
|
||||
/**
|
||||
* Constructs an instance of ComposableSnapshotFilter initialized with a logical operator combining the resulting
|
||||
* boolean expressions from the evaluation of the operands.
|
||||
*
|
||||
* @param leftOperand the left operand in the boolean-based expression.
|
||||
* @param operator the right operand in the boolean-based expression.
|
||||
* @param rightOperand the operator used to combine the resulting boolean expressions
|
||||
* from the evaluation of the operands.
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
*/
|
||||
private ComposableSnapshotFilter(SnapshotFilter<K, V> leftOperand, Operator operator, SnapshotFilter<K, V> rightOperand) {
|
||||
this.leftOperand = leftOperand;
|
||||
this.operator = operator;
|
||||
this.rightOperand = rightOperand;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
static <K, V> SnapshotFilter<K, V>[] nullSafeArray(SnapshotFilter<K, V>... array) {
|
||||
return (array != null ? array : new SnapshotFilter[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes the array of SnapshotFilters into a logical boolean expression using the specified Operator.
|
||||
*
|
||||
* @param <K> the class type of the SnapshotFilter key.
|
||||
* @param <V> the class type of the SnapshotFilter value.
|
||||
* @param operator the logical operator used to compose the SnapshotFilters.
|
||||
* @param snapshotFilters the array of SnapshotFilters to compose into a logical boolean expression
|
||||
* using the Operator.
|
||||
* @return a SnapshotFilter implementation composed of the SnapshotFilters using the specified Operator.
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
*/
|
||||
protected static <K, V> SnapshotFilter<K, V> compose(Operator operator, SnapshotFilter<K, V>... snapshotFilters) {
|
||||
SnapshotFilter<K, V> composedSnapshotFilter = null;
|
||||
|
||||
for (SnapshotFilter<K, V> snapshotFilter : nullSafeArray(snapshotFilters)) {
|
||||
composedSnapshotFilter = (composedSnapshotFilter == null ? snapshotFilter
|
||||
: new ComposableSnapshotFilter<K, V>(snapshotFilter, operator, composedSnapshotFilter));
|
||||
}
|
||||
|
||||
return composedSnapshotFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes the array of SnapshotFilters into a logical boolean expression using the AND Operator.
|
||||
*
|
||||
* @param <K> the class type of the SnapshotFilter key.
|
||||
* @param <V> the class type of the SnapshotFilter value.
|
||||
* @param snapshotFilters the array of SnapshotFilters to compose into a logical boolean expression
|
||||
* using the AND Operator.
|
||||
* @return a SnapshotFilter implementation composed of the SnapshotFilters using the AND Operator.
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator#AND
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
*/
|
||||
public static <K, V> SnapshotFilter<K, V> and(SnapshotFilter<K, V>... snapshotFilters) {
|
||||
return compose(Operator.AND, snapshotFilters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes the array of SnapshotFilters into a logical boolean expression using the OR Operator.
|
||||
*
|
||||
* @param <K> the class type of the SnapshotFilter key.
|
||||
* @param <V> the class type of the SnapshotFilter value.
|
||||
* @param snapshotFilters the array of SnapshotFilters to compose into a logical boolean expression
|
||||
* using the OR Operator.
|
||||
* @return a SnapshotFilter implementation composed of the SnapshotFilters using the OR Operator.
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator#OR
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
*/
|
||||
public static <K, V> SnapshotFilter<K, V> or(SnapshotFilter<K, V>... snapshotFilters) {
|
||||
return compose(Operator.OR, snapshotFilters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the following Map Entry is accepted by this composed SnapshotFilter implementation.
|
||||
*
|
||||
* @param entry the Map.Entry to evaluate.
|
||||
* @return a boolean value indicating whether this composed SnapshotFilter accepts the Map Entry.
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter#accept(Map.Entry)
|
||||
* @see java.util.Map.Entry
|
||||
*/
|
||||
@Override
|
||||
public boolean accept(final Map.Entry<K, V> entry) {
|
||||
return operator.operate(leftOperand.accept(entry), rightOperand.accept(entry));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static com.gemstone.gemfire.cache.snapshot.SnapshotOptions.SnapshotFormat;
|
||||
import static org.springframework.data.gemfire.SnapshotServiceFactoryBean.SnapshotServiceAdapter;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.DataInputStream;
|
||||
@@ -52,24 +53,27 @@ import com.gemstone.gemfire.cache.snapshot.SnapshotOptions;
|
||||
|
||||
/**
|
||||
* The SnapshotServiceFactoryBean class is a Spring FactoryBean used to configure and create an instance
|
||||
* of the appropriate GemFire Snapshot Service. A CacheSnapshotService is created if the Region is not specified,
|
||||
* otherwise a RegionSnapshotService is used based on the configured Region.
|
||||
* of an appropriate GemFire Snapshot Service to perform data import and exports. A CacheSnapshotService is created
|
||||
* if the Region is not specified, otherwise a RegionSnapshotService is used based on the configured Region.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see org.springframework.context.ApplicationListener
|
||||
* @see org.springframework.data.gemfire.SnapshotServiceFactoryBean.SnapshotServiceAdapter
|
||||
* @see com.gemstone.gemfire.cache.snapshot.CacheSnapshotService
|
||||
* @see com.gemstone.gemfire.cache.snapshot.RegionSnapshotService
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotServiceFactoryBean.SnapshotServiceAdapter<K, V>>,
|
||||
public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotServiceAdapter<K, V>>,
|
||||
InitializingBean, DisposableBean, ApplicationListener<SnapshotApplicationEvent<K, V>> {
|
||||
|
||||
protected static final SnapshotMetadata[] EMPTY_ARRAY = new SnapshotMetadata[0];
|
||||
|
||||
private Boolean suppressInitImport;
|
||||
|
||||
private Cache cache;
|
||||
|
||||
private Region<K, V> region;
|
||||
@@ -185,6 +189,27 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a boolean condition to indicate whether importing on initialization should be suppressed.
|
||||
*
|
||||
* @param suppressInitImport a Boolean value to indicate whether importing on initialization should be suppressed.
|
||||
* @see #isSuppressInitImport()
|
||||
*/
|
||||
public void setSuppressInitImport(Boolean suppressInitImport) {
|
||||
this.suppressInitImport = suppressInitImport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether importing on initialization should be suppressed.
|
||||
*
|
||||
* @return a boolean value indicating whether import on initialization should be suppressed.
|
||||
* @see #setSuppressInitImport(Boolean)
|
||||
* @see #afterPropertiesSet()
|
||||
*/
|
||||
protected boolean isSuppressInitImport() {
|
||||
return Boolean.TRUE.equals(suppressInitImport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reference to the GemFire Snapshot Service created by this FactoryBean.
|
||||
*
|
||||
@@ -233,7 +258,10 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
@SuppressWarnings("unchecked")
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
snapshotServiceAdapter = create();
|
||||
snapshotServiceAdapter.doImport(getImports());
|
||||
|
||||
if (!isSuppressInitImport()) {
|
||||
snapshotServiceAdapter.doImport(getImports());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,10 +361,7 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
* @see org.springframework.data.gemfire.SnapshotApplicationEvent
|
||||
*/
|
||||
protected boolean isMatch(SnapshotApplicationEvent event) {
|
||||
Region region = getRegion();
|
||||
|
||||
return ((event.isRegionSnapshotEvent() && event.matches(region))
|
||||
|| (event.isCacheSnapshotEvent() && region == null));
|
||||
return (event.isCacheSnapshotEvent() || event.matches(getRegion()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,9 +393,9 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
|
||||
SnapshotOptions<K, V> createOptions();
|
||||
|
||||
void doExport(SnapshotMetadata<K, V>[] configurations);
|
||||
void doExport(SnapshotMetadata<K, V>... configurations);
|
||||
|
||||
void doImport(SnapshotMetadata<K, V>[] configurations);
|
||||
void doImport(SnapshotMetadata<K, V>... configurations);
|
||||
|
||||
void load(File directory, SnapshotFormat format);
|
||||
|
||||
@@ -392,6 +417,8 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
*/
|
||||
protected static abstract class SnapshotServiceAdapterSupport<K, V> implements SnapshotServiceAdapter<K, V> {
|
||||
|
||||
protected static final File TEMPORARY_DIRECTORY = new File(System.getProperty("java.io.tmpdir"));
|
||||
|
||||
protected final Log log = createLog();
|
||||
|
||||
Log createLog() {
|
||||
@@ -408,14 +435,14 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doExport(SnapshotMetadata<K, V>[] configurations) {
|
||||
public void doExport(SnapshotMetadata<K, V>... configurations) {
|
||||
for (SnapshotMetadata<K, V> configuration : nullSafeArray(configurations)) {
|
||||
save(configuration.getLocation(), configuration.getFormat(), createOptions(configuration.getFilter()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doImport(SnapshotMetadata<K, V>[] configurations) {
|
||||
public void doImport(SnapshotMetadata<K, V>... configurations) {
|
||||
for (SnapshotMetadata<K, V> configuration : nullSafeArray(configurations)) {
|
||||
load(configuration.getFormat(), createOptions(configuration.getFilter()), handleLocation(configuration));
|
||||
}
|
||||
@@ -434,8 +461,7 @@ public class SnapshotServiceFactoryBean<K, V> implements FactoryBean<SnapshotSer
|
||||
protected File[] handleFileLocation(File file) {
|
||||
if (ArchiveFileFilter.INSTANCE.accept(file)) {
|
||||
try {
|
||||
File extractedArchiveDirectory = new File(System.getProperty("java.io.tmpdir"),
|
||||
file.getName().replaceAll("\\.", "-"));
|
||||
File extractedArchiveDirectory = new File(TEMPORARY_DIRECTORY, file.getName().replaceAll("\\.", "-"));
|
||||
|
||||
Assert.state(extractedArchiveDirectory.isDirectory() || extractedArchiveDirectory.mkdirs(),
|
||||
String.format("Failed create directory (%1$s) in which to extract archive (%2$s)",
|
||||
|
||||
@@ -49,7 +49,9 @@ import com.gemstone.gemfire.cache.ResumptionAction;
|
||||
abstract class ParsingUtils {
|
||||
|
||||
protected static final String CACHE_PROPERTY_NAME = "cache";
|
||||
protected static final String REGION_PROPERTY_NAME = "region";
|
||||
protected static final String CACHE_REF_ATTRIBUTE_NAME = "cache-ref";
|
||||
protected static final String REGION_REF_ATTRIBUTE_NAME = "region-ref";
|
||||
|
||||
static void setPropertyReference(Element element, BeanDefinitionBuilder builder, String attributeName,
|
||||
String propertyName) {
|
||||
@@ -431,6 +433,14 @@ abstract class ParsingUtils {
|
||||
return (StringUtils.hasText(cacheReference) ? cacheReference : GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
}
|
||||
|
||||
static void setRegionReference(Element element, BeanDefinitionBuilder builder) {
|
||||
builder.addPropertyReference(REGION_PROPERTY_NAME, resolveRegionReference(element));
|
||||
}
|
||||
|
||||
static String resolveRegionReference(Element element) {
|
||||
return element.getAttribute(REGION_REF_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
static void throwExceptionWhenGemFireFeatureUnavailable(GemfireFeature feature,
|
||||
String elementName, String attributeName, ParserContext parserContext) {
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ class SnapshotServiceParser extends AbstractSingleBeanDefinitionParser {
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
ParsingUtils.setCacheReference(element, builder);
|
||||
ParsingUtils.setPropertyReference(element, builder, "region-ref", "region");
|
||||
ParsingUtils.setRegionReference(element, builder);
|
||||
ParsingUtils.setPropertyValue(element, builder, "suppress-init-import");
|
||||
builder.addPropertyValue("exports", parseExports(element, parserContext));
|
||||
builder.addPropertyValue("imports", parseImports(element, parserContext));
|
||||
}
|
||||
|
||||
@@ -219,6 +219,7 @@ ID of the GemFire [Cache|Region] SnapshotService bean in the Spring context.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="suppress-init-import" type="xsd:string" default="false"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:complexType name="snapshotMetadataType">
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.isA;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.ComposableSnapshotFilter.Operator;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gemstone.gemfire.cache.snapshot.SnapshotFilter;
|
||||
|
||||
/**
|
||||
* The ComposableSnapshotFilterTest class is a test suite of test cases testing the contract and functionality
|
||||
* of the ComposableSnapshotFilter class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter
|
||||
* @see org.springframework.data.gemfire.ComposableSnapshotFilter.Operator
|
||||
* @see com.gemstone.gemfire.cache.snapshot.SnapshotFilter
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class ComposableSnapshotFilterTest {
|
||||
|
||||
private static final AtomicInteger ID_SEQUENCE = new AtomicInteger(0);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected SnapshotFilter mockSnapshotFilter(boolean accept) {
|
||||
SnapshotFilter mockSnapshotFilter = mock(SnapshotFilter.class, String.format(
|
||||
"MockSnapshotFilter-%1$d", ID_SEQUENCE.incrementAndGet()));
|
||||
|
||||
when(mockSnapshotFilter.accept(any(Map.Entry.class))).thenReturn(accept);
|
||||
|
||||
return mockSnapshotFilter;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void operatorIdentityIsSuccessful() {
|
||||
assertThat(Operator.AND.isAnd(), is(true));
|
||||
assertThat(Operator.AND.isOr(), is(false));
|
||||
assertThat(Operator.OR.isAnd(), is(false));
|
||||
assertThat(Operator.OR.isOr(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andOperatorOperationIsValid() {
|
||||
assertThat(Operator.AND.operate(true, true), is(true));
|
||||
assertThat(Operator.AND.operate(true, false), is(false));
|
||||
assertThat(Operator.AND.operate(false, true), is(false));
|
||||
assertThat(Operator.AND.operate(false, false), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orOperatorOperationIsValid() {
|
||||
assertThat(Operator.OR.operate(true, true), is(true));
|
||||
assertThat(Operator.OR.operate(true, false), is(true));
|
||||
assertThat(Operator.OR.operate(false, true), is(true));
|
||||
assertThat(Operator.OR.operate(false, false), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeArrayWithNonNullArray() {
|
||||
SnapshotFilter[] expectedArray = {};
|
||||
|
||||
assertThat(ComposableSnapshotFilter.nullSafeArray(expectedArray), is(sameInstance(expectedArray)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeArrayWithNullArray() {
|
||||
SnapshotFilter[] actualArray = ComposableSnapshotFilter.nullSafeArray((SnapshotFilter[]) null);
|
||||
|
||||
assertThat(actualArray, is(notNullValue()));
|
||||
assertThat(actualArray.length, is(equalTo(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void composeSingle() {
|
||||
SnapshotFilter mockSnapshotFilter = mockSnapshotFilter(false);
|
||||
SnapshotFilter composedFilter = ComposableSnapshotFilter.compose(Operator.AND, mockSnapshotFilter);
|
||||
|
||||
assertThat(composedFilter, is(sameInstance(mockSnapshotFilter)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void composeMultiple() throws Exception {
|
||||
SnapshotFilter mockSnapshotFilterOne = mockSnapshotFilter(false);
|
||||
SnapshotFilter mockSnapshotFilterTwo = mockSnapshotFilter(true);
|
||||
|
||||
SnapshotFilter composedFilter = ComposableSnapshotFilter.compose(Operator.AND, mockSnapshotFilterOne,
|
||||
mockSnapshotFilterTwo);
|
||||
|
||||
assertThat(composedFilter, is(not(sameInstance(mockSnapshotFilterOne))));
|
||||
assertThat(composedFilter, is(not(sameInstance(mockSnapshotFilterTwo))));
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat((SnapshotFilter) TestUtils.readField("leftOperand", composedFilter),
|
||||
is(equalTo(mockSnapshotFilterTwo)));
|
||||
assertThat((Operator) TestUtils.readField("operator", composedFilter), is(equalTo(Operator.AND)));
|
||||
assertThat((SnapshotFilter) TestUtils.readField("rightOperand", composedFilter),
|
||||
is(equalTo(mockSnapshotFilterOne)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void composeAndThenAccept() {
|
||||
SnapshotFilter falseFilter = mockSnapshotFilter(false);
|
||||
SnapshotFilter trueFilter = mockSnapshotFilter(true);
|
||||
|
||||
SnapshotFilter composedFilter = ComposableSnapshotFilter.and(trueFilter, trueFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(true));
|
||||
|
||||
composedFilter = ComposableSnapshotFilter.and(falseFilter, trueFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(false));
|
||||
|
||||
composedFilter = ComposableSnapshotFilter.and(falseFilter, falseFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void composeOrThenAccept() {
|
||||
SnapshotFilter falseFilter = mockSnapshotFilter(false);
|
||||
SnapshotFilter trueFilter = mockSnapshotFilter(true);
|
||||
|
||||
SnapshotFilter composedFilter = ComposableSnapshotFilter.or(trueFilter, trueFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(true));
|
||||
|
||||
composedFilter = ComposableSnapshotFilter.or(falseFilter, trueFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(true));
|
||||
|
||||
composedFilter = ComposableSnapshotFilter.or(falseFilter, falseFilter);
|
||||
|
||||
assertThat((ComposableSnapshotFilter) composedFilter, isA(ComposableSnapshotFilter.class));
|
||||
assertThat(composedFilter.accept(null), is(false));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -147,14 +147,14 @@ public class SnapshotApplicationEventTest {
|
||||
SnapshotApplicationEvent event = new TestSnapshotApplicationEvent(this, "/Example");
|
||||
|
||||
assertThat(event.getRegionPath(), is(equalTo("/Example")));
|
||||
assertThat(event.matches("/Prototype"), is(false));
|
||||
assertThat(event.matches("/Sample"), is(false));
|
||||
assertThat(event.matches("/Xmpl"), is(false));
|
||||
assertThat(event.matches("/Ex"), is(false));
|
||||
assertThat(event.matches("/E.g."), is(false));
|
||||
assertThat(event.matches("Example"), is(false));
|
||||
assertThat(event.matches("/Sample"), is(false));
|
||||
assertThat(event.matches("/Prototype"), is(false));
|
||||
assertThat(event.matches("/example"), is(false));
|
||||
assertThat(event.matches("/Exam"), is(false));
|
||||
assertThat(event.matches("/Xmpl"), is(false));
|
||||
assertThat(event.matches("/Ex."), is(false));
|
||||
assertThat(event.matches("/E.g."), is(false));
|
||||
assertThat(event.matches("/"), is(false));
|
||||
assertThat(event.matches(" "), is(false));
|
||||
assertThat(event.matches(""), is(false));
|
||||
@@ -166,6 +166,7 @@ public class SnapshotApplicationEventTest {
|
||||
assertThat(new TestSnapshotApplicationEvent(this, "/Example").matches("/Example"), is(true));
|
||||
assertThat(new TestSnapshotApplicationEvent(this, "/").matches("/"), is(true));
|
||||
assertThat(new TestSnapshotApplicationEvent(this, " ").matches(" "), is(true));
|
||||
assertThat(new TestSnapshotApplicationEvent(this, "").matches(" "), is(true));
|
||||
assertThat(new TestSnapshotApplicationEvent(this, "").matches(""), is(true));
|
||||
assertThat(new TestSnapshotApplicationEvent(this, (String) null).matches((String) null), is(true));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.gemfire.test.support.FileSystemUtils;
|
||||
import org.springframework.data.gemfire.test.support.ThreadUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.snapshot.SnapshotFilter;
|
||||
import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils;
|
||||
|
||||
/**
|
||||
* The SnapshotApplicationEventTriggeredImportsExportsIntegrationTest class is a test suite of test cases testing
|
||||
* the effects of the SnapshotServiceFactoryBean using Spring ApplicationEvents to trigger imports and exports
|
||||
* of GemFire Cache Region data.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @see org.springframework.data.gemfire.ExportSnapshotApplicationEvent
|
||||
* @see org.springframework.data.gemfire.ImportSnapshotApplicationEvent
|
||||
* @see org.springframework.data.gemfire.SnapshotServiceFactoryBean
|
||||
* @see org.springframework.data.gemfire.repository.sample.Person
|
||||
* @see com.gemstone.gemfire.cache.Region
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@SuppressWarnings("unused")
|
||||
public class SnapshotApplicationEventTriggeredImportsExportsIntegrationTest {
|
||||
|
||||
protected static final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
|
||||
|
||||
protected static File snapshotsDirectory;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Resource(name = "Doe")
|
||||
private Region<Long, Person> doe;
|
||||
|
||||
@Resource(name = "EveryoneElse")
|
||||
private Region<Long, Person> everyoneElse;
|
||||
|
||||
@Resource(name = "Handy")
|
||||
private Region<Long, Person> handy;
|
||||
|
||||
@Resource(name = "People")
|
||||
private Region<Long, Person> people;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupBeforeClass() throws Exception {
|
||||
snapshotsDirectory = new File(new File(FileSystemUtils.WORKING_DIRECTORY, "gemfire"), "snapshots");
|
||||
|
||||
assertThat(snapshotsDirectory.isDirectory() || snapshotsDirectory.mkdirs(), is(true));
|
||||
|
||||
File peopleSnapshotFile = new File(snapshotsDirectory, "people.snapshot");
|
||||
File nonHandyNonDoeSnapshotFile = new File(snapshotsDirectory, "nonHandyNonDoePeople.snapshot");
|
||||
|
||||
assertThat(peopleSnapshotFile.isFile() || peopleSnapshotFile.createNewFile(), is(true));
|
||||
assertThat(nonHandyNonDoeSnapshotFile.isFile() || nonHandyNonDoeSnapshotFile.createNewFile(), is(true));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() {
|
||||
FileSystemUtils.deleteRecursive(snapshotsDirectory.getParentFile());
|
||||
snapshotsDirectory = null;
|
||||
}
|
||||
|
||||
protected void assertPeople(Region<Long, Person> targetRegion, Person... people) {
|
||||
assertThat(targetRegion.size(), is(equalTo(people.length)));
|
||||
|
||||
for (Person person : people) {
|
||||
assertPerson(person, targetRegion.get(person.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertPerson(Person expectedPerson, Person actualPerson) {
|
||||
assertThat(String.format("Expected (%1$s); but was (%2$s)", expectedPerson, actualPerson),
|
||||
actualPerson, is(notNullValue()));
|
||||
assertThat(actualPerson.getId(), is(equalTo(expectedPerson.getId())));
|
||||
assertThat(actualPerson.getFirstname(), is(equalTo(expectedPerson.getFirstname())));
|
||||
assertThat(actualPerson.getLastname(), is(equalTo(expectedPerson.getLastname())));
|
||||
}
|
||||
|
||||
protected Person createPerson(String firstName, String lastName) {
|
||||
return new Person(ID_SEQUENCE.incrementAndGet(), firstName, lastName);
|
||||
}
|
||||
|
||||
protected Person put(Region<Long, Person> targetRegion, Person person) {
|
||||
targetRegion.putIfAbsent(person.getId(), person);
|
||||
return person;
|
||||
}
|
||||
|
||||
protected void wait(final int seconds, final int expectedDoeSize, final int expectedEveryoneSize,
|
||||
final int expectedHandySize) {
|
||||
ThreadUtils.timedWait(TimeUnit.SECONDS.toMillis(seconds), 500, new ThreadUtils.WaitCondition() {
|
||||
@Override public boolean waiting() {
|
||||
return (doe.size() < expectedDoeSize && everyoneElse.size() < expectedEveryoneSize
|
||||
&& handy.size() < expectedHandySize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void exportsTriggeringImportsOnSnapshotApplicationEvents() {
|
||||
Person jonDoe = put(people, createPerson("Jon", "Doe"));
|
||||
Person janeDoe = put(people, createPerson("Jane", "Doe"));
|
||||
Person jackBlack = put(people, createPerson("Jack", "Black"));
|
||||
Person jackHandy = put(people, createPerson("Jack", "Handy"));
|
||||
Person joeDirt = put(people, createPerson("Joe", "Dirt"));
|
||||
|
||||
SnapshotApplicationEvent event = new ExportSnapshotApplicationEvent<Long, Person>(this, people.getFullPath());
|
||||
|
||||
eventPublisher.publishEvent(event);
|
||||
wait(5, 2, 2, 1);
|
||||
|
||||
assertPeople(doe, jonDoe, janeDoe);
|
||||
assertPeople(everyoneElse, jackBlack, joeDirt);
|
||||
assertPeople(handy, jackHandy);
|
||||
|
||||
Person cookieDoe = put(people, createPerson("Cookie", "Doe"));
|
||||
Person pieDoe = put(people, createPerson("Pie", "Doe"));
|
||||
Person sourDoe = put(people, createPerson("Sour", "Doe"));
|
||||
Person randyHandy = put(people, createPerson("Randy", "Handy"));
|
||||
Person sandyHandy = put(people, createPerson("Sandy", "Handy"));
|
||||
Person jackHill = put(people, createPerson("Jack", "Hill"));
|
||||
Person jillHill = put(people, createPerson("Jill", "Hill"));
|
||||
|
||||
eventPublisher.publishEvent(event);
|
||||
wait(10, 5, 4, 3);
|
||||
|
||||
assertPeople(doe, jonDoe, janeDoe, cookieDoe, pieDoe, sourDoe);
|
||||
assertPeople(everyoneElse, jackBlack, joeDirt, jackHill, jillHill);
|
||||
assertPeople(handy, jackHandy, randyHandy, sandyHandy);
|
||||
|
||||
Person bobDoe = put(people, createPerson("Bob", "Doe"));
|
||||
Person mandyHandy = put(people, createPerson("Mandy", "Handy"));
|
||||
Person imaPigg = put(people, createPerson("Ima", "Pigg"));
|
||||
Person benDover = put(people, createPerson("Ben", "Dover"));
|
||||
|
||||
eventPublisher.publishEvent(event);
|
||||
wait(15, 6, 6, 4);
|
||||
|
||||
assertPeople(doe, jonDoe, janeDoe, cookieDoe, pieDoe, sourDoe, bobDoe);
|
||||
assertPeople(everyoneElse, jackBlack, joeDirt, jackHill, jillHill, imaPigg, benDover);
|
||||
assertPeople(handy, jackHandy, randyHandy, sandyHandy, mandyHandy);
|
||||
}
|
||||
|
||||
protected static class LastNameSnapshotFilter implements SnapshotFilter<Long, Person> {
|
||||
|
||||
private final String lastName;
|
||||
|
||||
public LastNameSnapshotFilter(String lastName) {
|
||||
Assert.hasText(lastName, "'lastName' must be specified");
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
protected String getLastName() {
|
||||
Assert.state(StringUtils.hasText(lastName), "'lastName' was not properly initialized");
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Map.Entry<Long, Person> entry) {
|
||||
return accept(entry.getValue());
|
||||
}
|
||||
|
||||
public boolean accept(Person person) {
|
||||
return getLastName().equalsIgnoreCase(person.getLastname());
|
||||
}
|
||||
}
|
||||
|
||||
protected static class NotLastNameSnapshotFilter extends LastNameSnapshotFilter {
|
||||
|
||||
public NotLastNameSnapshotFilter(String lastName) {
|
||||
super(lastName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(final Map.Entry<Long, Person> entry) {
|
||||
return !super.accept(entry);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SnapshotImportsMonitor {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private static final Map<File, Long> snapshotFileLastModifiedMap = new ConcurrentHashMap<File, Long>(2);
|
||||
|
||||
@Scheduled(fixedDelay = 1000)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processSnapshots() {
|
||||
boolean triggerEvent = false;
|
||||
|
||||
for (File snapshotFile : nullSafeArray(snapshotsDirectory.listFiles(FileSystemUtils.FileOnlyFilter.INSTANCE))) {
|
||||
triggerEvent |= isUnprocessedSnapshotFile(snapshotFile);
|
||||
}
|
||||
|
||||
if (triggerEvent) {
|
||||
eventPublisher.publishEvent(new ImportSnapshotApplicationEvent<Long, Person>(this));
|
||||
}
|
||||
}
|
||||
|
||||
protected File[] nullSafeArray(File... files) {
|
||||
return (files != null ? files : new File[0]);
|
||||
}
|
||||
|
||||
protected boolean isUnprocessedSnapshotFile(File snapshotFile) {
|
||||
Long lastModified = snapshotFile.lastModified();
|
||||
Long previousLastModified = snapshotFileLastModifiedMap.get(snapshotFile);
|
||||
|
||||
previousLastModified = (previousLastModified != null ? previousLastModified : lastModified);
|
||||
|
||||
snapshotFileLastModifiedMap.put(snapshotFile, lastModified);
|
||||
|
||||
return !previousLastModified.equals(lastModified);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import static com.gemstone.gemfire.cache.snapshot.SnapshotOptions.SnapshotFormat
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.isA;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
@@ -87,6 +88,14 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
|
||||
private SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean();
|
||||
|
||||
protected static File mockFile(String filename) {
|
||||
File mockFile = mock(File.class, filename);
|
||||
when(mockFile.isFile()).thenReturn(true);
|
||||
when(mockFile.getAbsolutePath()).thenReturn(String.format("/path/to/%1$s", filename));
|
||||
when(mockFile.getName()).thenReturn(filename);
|
||||
return mockFile;
|
||||
}
|
||||
|
||||
protected <K, V> SnapshotMetadata<K, V> newSnapshotMetadata() {
|
||||
return newSnapshotMetadata(FileSystemUtils.WORKING_DIRECTORY);
|
||||
}
|
||||
@@ -114,9 +123,7 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setupBeforeClass() throws Exception {
|
||||
snapshotDat = File.createTempFile("snapshot", "dat");
|
||||
snapshotDat.deleteOnExit();
|
||||
assertThat(snapshotDat.isFile(), is(true));
|
||||
snapshotDat = mockFile("snapshot.dat");
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -248,6 +255,23 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
assertThat(factoryBean.getRegion(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetSuppressInitImportSuccessfully() {
|
||||
assertThat(factoryBean.isSuppressInitImport(), is(false));
|
||||
|
||||
factoryBean.setSuppressInitImport(true);
|
||||
|
||||
assertThat(factoryBean.isSuppressInitImport(), is(true));
|
||||
|
||||
factoryBean.setSuppressInitImport(false);
|
||||
|
||||
assertThat(factoryBean.isSuppressInitImport(), is(false));
|
||||
|
||||
factoryBean.setSuppressInitImport(null);
|
||||
|
||||
assertThat(factoryBean.isSuppressInitImport(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSingletonIsTrue() {
|
||||
assertThat(factoryBean.isSingleton(), is(true));
|
||||
@@ -255,6 +279,8 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetCreatesSnapshotServiceAdapterAndDoesImportWithConfiguredImports() throws Exception {
|
||||
SnapshotMetadata expectedSnapshotMetadata = newSnapshotMetadata();
|
||||
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class,
|
||||
"MockSnapshotServiceAdapter");
|
||||
|
||||
@@ -264,14 +290,30 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
}
|
||||
};
|
||||
|
||||
SnapshotMetadata expectedSnapshotMetadata = newSnapshotMetadata();
|
||||
|
||||
factoryBean.setImports(toArray(expectedSnapshotMetadata));
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(expectedSnapshotMetadata)));
|
||||
|
||||
verify(mockSnapshotService, times(1)).doImport(eq(toArray(expectedSnapshotMetadata)));
|
||||
verify(mockSnapshotService, times(1)).doImport(eq(expectedSnapshotMetadata));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetCreatesSnapshotServiceAdapterButSuppressesImportOnInit() throws Exception {
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class, "MockSnapshotServiceAdapter");
|
||||
|
||||
SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean() {
|
||||
@Override protected SnapshotServiceAdapter create() {
|
||||
return mockSnapshotService;
|
||||
}
|
||||
};
|
||||
|
||||
factoryBean.setSuppressInitImport(true);
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
assertThat(factoryBean.isSuppressInitImport(), is(true));
|
||||
|
||||
verify(mockSnapshotService, never()).doImport(any(SnapshotMetadata[].class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -328,6 +370,8 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void destroyPerformsExportWithConfiguredExports() throws Exception {
|
||||
SnapshotMetadata expectedSnapshotMetadata = newSnapshotMetadata();
|
||||
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class,
|
||||
"MockSnapshotServiceAdapter");
|
||||
|
||||
@@ -337,232 +381,263 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
}
|
||||
};
|
||||
|
||||
SnapshotMetadata expectedSnapshotMetadata = newSnapshotMetadata();
|
||||
|
||||
factoryBean.setExports(toArray(expectedSnapshotMetadata));
|
||||
factoryBean.destroy();
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(expectedSnapshotMetadata)));
|
||||
|
||||
verify(mockSnapshotService, times(1)).doExport(eq(toArray(expectedSnapshotMetadata)));
|
||||
verify(mockSnapshotService, times(1)).doExport(eq(expectedSnapshotMetadata));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenMatchUsingEventSnapshotMetadataPerformsExport() throws Exception {
|
||||
Region mockRegion = mock(Region.class, "MockRegion");
|
||||
|
||||
SnapshotOptions mockSnapshotOptions = mock(SnapshotOptions.class, "MockSnapshotOptions");
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ExportSnapshotApplicationEvent.class,
|
||||
"MockExportSnapshotApplicationEvent");
|
||||
|
||||
final RegionSnapshotService mockSnapshotService = mock(RegionSnapshotService.class, "MockRegionSnapshotService");
|
||||
SnapshotMetadata eventSnapshotMetadata = newSnapshotMetadata(snapshotDat);
|
||||
|
||||
when(mockRegion.getFullPath()).thenReturn("/Example");
|
||||
when(mockSnapshotService.createOptions()).thenReturn(mockSnapshotOptions);
|
||||
when(mockSnapshotOptions.setFilter(any(SnapshotFilter.class))).thenReturn(mockSnapshotOptions);
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class, "MockSnapshotServiceAdapter");
|
||||
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(false);
|
||||
when(mockSnapshotEvent.matches(eq(mockRegion))).thenReturn(true);
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(toArray(eventSnapshotMetadata));
|
||||
|
||||
SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean() {
|
||||
@Override public SnapshotServiceAdapter getObject() throws Exception {
|
||||
return new RegionSnapshotServiceAdapter(mockSnapshotService);
|
||||
return mockSnapshotService;
|
||||
}
|
||||
};
|
||||
|
||||
factoryBean.setExports(toArray(newSnapshotMetadata()));
|
||||
factoryBean.setRegion(mockRegion);
|
||||
|
||||
SnapshotMetadata eventSnapshotMetadata = newSnapshotMetadata(snapshotDat);
|
||||
|
||||
SnapshotApplicationEvent event = new ExportSnapshotApplicationEvent(this, "/Example", eventSnapshotMetadata);
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(not(sameInstance(eventSnapshotMetadata))));
|
||||
assertThat(factoryBean.getRegion(), is(sameInstance(mockRegion)));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(true));
|
||||
assertThat(event.getSnapshotMetadata()[0], is(sameInstance(eventSnapshotMetadata)));
|
||||
|
||||
factoryBean.onApplicationEvent(event);
|
||||
factoryBean.onApplicationEvent(mockSnapshotEvent);
|
||||
|
||||
verify(mockRegion, times(1)).getFullPath();
|
||||
verify(mockSnapshotOptions, times(1)).setFilter(isNull(SnapshotFilter.class));
|
||||
verify(mockSnapshotService, times(1)).createOptions();
|
||||
verify(mockSnapshotService, times(1)).save(eq(eventSnapshotMetadata.getLocation()),
|
||||
eq(eventSnapshotMetadata.getFormat()), eq(mockSnapshotOptions));
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, times(1)).matches(eq(mockRegion));
|
||||
verify(mockSnapshotEvent, times(1)).getSnapshotMetadata();
|
||||
verify(mockSnapshotService, times(1)).doExport(eq(eventSnapshotMetadata));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenMatchUsingFactorySnapshotMetadataPerformsImport() throws Exception {
|
||||
final CacheSnapshotService mockSnapshotService = mock(CacheSnapshotService.class, "MockCacheSnapshotService");
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ImportSnapshotApplicationEvent.class,
|
||||
"MockImportSnapshotApplicationEvent");
|
||||
|
||||
SnapshotOptions mockSnapshotOptions = mock(SnapshotOptions.class, "MockSnapshotOptions");
|
||||
SnapshotMetadata factorySnapshotMetadata = newSnapshotMetadata(snapshotDat);
|
||||
|
||||
when(mockSnapshotService.createOptions()).thenReturn(mockSnapshotOptions);
|
||||
when(mockSnapshotOptions.setFilter(any(SnapshotFilter.class))).thenReturn(mockSnapshotOptions);
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class, "MockSnapshotServiceAdapter");
|
||||
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(true);
|
||||
when(mockSnapshotEvent.matches(any(Region.class))).thenReturn(false);
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(null);
|
||||
|
||||
SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean() {
|
||||
@Override public SnapshotServiceAdapter getObject() throws Exception {
|
||||
return new CacheSnapshotServiceAdapter(mockSnapshotService);
|
||||
return mockSnapshotService;
|
||||
}
|
||||
};
|
||||
|
||||
SnapshotMetadata expectedSnapshotMetadata = newSnapshotMetadata(snapshotDat);
|
||||
factoryBean.setImports(toArray(factorySnapshotMetadata));
|
||||
|
||||
factoryBean.setImports(toArray(expectedSnapshotMetadata));
|
||||
|
||||
SnapshotApplicationEvent event = new ImportSnapshotApplicationEvent(this);
|
||||
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(expectedSnapshotMetadata)));
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(factorySnapshotMetadata)));
|
||||
assertThat(factoryBean.getRegion(), is(nullValue()));
|
||||
assertThat(event.isCacheSnapshotEvent(), is(true));
|
||||
assertThat(event.getSnapshotMetadata().length, is(equalTo(0)));
|
||||
|
||||
factoryBean.onApplicationEvent(event);
|
||||
factoryBean.onApplicationEvent(mockSnapshotEvent);
|
||||
|
||||
verify(mockSnapshotOptions, times(1)).setFilter(isNull(SnapshotFilter.class));
|
||||
verify(mockSnapshotService, times(1)).createOptions();
|
||||
verify(mockSnapshotService, times(1)).load(eq(new File[] { expectedSnapshotMetadata.getLocation() }),
|
||||
eq(expectedSnapshotMetadata.getFormat()), eq(mockSnapshotOptions));
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, never()).matches(any(Region.class));
|
||||
verify(mockSnapshotEvent, times(1)).getSnapshotMetadata();
|
||||
verify(mockSnapshotService, times(1)).doImport(eq(factorySnapshotMetadata));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenNoMatchDoesNotPerformExport() throws Exception {
|
||||
final CacheSnapshotService mockSnapshotService = mock(CacheSnapshotService.class, "MockCacheSnapshotService");
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ExportSnapshotApplicationEvent.class,
|
||||
"MockExportSnapshotApplicationEvent");
|
||||
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(false);
|
||||
when(mockSnapshotEvent.matches(any(Region.class))).thenReturn(false);
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(null);
|
||||
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class, "MockSnapshotServiceAdapter");
|
||||
|
||||
SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean() {
|
||||
@Override public SnapshotServiceAdapter getObject() throws Exception {
|
||||
return new CacheSnapshotServiceAdapter(mockSnapshotService);
|
||||
return mockSnapshotService;
|
||||
}
|
||||
};
|
||||
|
||||
factoryBean.setExports(toArray(newSnapshotMetadata()));
|
||||
|
||||
SnapshotApplicationEvent event = new ExportSnapshotApplicationEvent(this, "/Example");
|
||||
|
||||
assertThat(factoryBean.getExports().length, is(equalTo(1)));
|
||||
assertThat(factoryBean.getExports()[0], isA(SnapshotMetadata.class));
|
||||
assertThat(factoryBean.getRegion(), is(nullValue()));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(true));
|
||||
|
||||
factoryBean.onApplicationEvent(event);
|
||||
factoryBean.onApplicationEvent(mockSnapshotEvent);
|
||||
|
||||
verify(mockSnapshotService, never()).createOptions();
|
||||
verify(mockSnapshotService, never()).save(any(File.class), any(SnapshotFormat.class));
|
||||
verify(mockSnapshotService, never()).save(any(File.class), any(SnapshotFormat.class),
|
||||
any(SnapshotOptions.class));
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, times(1)).matches(isNull(Region.class));
|
||||
verify(mockSnapshotEvent, never()).getSnapshotMetadata();
|
||||
verify(mockSnapshotService, never()).doExport(any(SnapshotMetadata.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenNoMatchDoesNotPerformImport() throws Exception {
|
||||
Region mockRegion = mock(Region.class, "MockRegion");
|
||||
|
||||
when(mockRegion.getFullPath()).thenReturn("/Example");
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ImportSnapshotApplicationEvent.class,
|
||||
"MockImportSnapshotApplicationEvent");
|
||||
|
||||
final RegionSnapshotService mockSnapshotService = mock(RegionSnapshotService.class, "MockRegionSnapshotService");
|
||||
final SnapshotServiceAdapter mockSnapshotService = mock(SnapshotServiceAdapter.class, "MockSnapshotServiceAdapter");
|
||||
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(false);
|
||||
when(mockSnapshotEvent.matches(any(Region.class))).thenReturn(false);
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(null);
|
||||
|
||||
SnapshotServiceFactoryBean factoryBean = new SnapshotServiceFactoryBean() {
|
||||
@Override public SnapshotServiceAdapter getObject() throws Exception {
|
||||
return new RegionSnapshotServiceAdapter(mockSnapshotService);
|
||||
return mockSnapshotService;
|
||||
}
|
||||
};
|
||||
|
||||
factoryBean.setImports(toArray(newSnapshotMetadata()));
|
||||
factoryBean.setRegion(mockRegion);
|
||||
|
||||
SnapshotApplicationEvent event = new ImportSnapshotApplicationEvent(this, "/Test");
|
||||
|
||||
assertThat(factoryBean.getImports().length, is(equalTo(1)));
|
||||
assertThat(factoryBean.getImports()[0], isA(SnapshotMetadata.class));
|
||||
assertThat(factoryBean.getRegion(), is(equalTo(mockRegion)));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(true));
|
||||
|
||||
factoryBean.onApplicationEvent(event);
|
||||
factoryBean.onApplicationEvent(mockSnapshotEvent);
|
||||
|
||||
verify(mockRegion, times(1)).getFullPath();
|
||||
verify(mockSnapshotService, never()).createOptions();
|
||||
verify(mockSnapshotService, never()).load(any(File.class), any(SnapshotFormat.class));
|
||||
verify(mockSnapshotService, never()).load(any(File.class), any(SnapshotFormat.class),
|
||||
any(SnapshotOptions.class));
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, times(1)).matches(eq(mockRegion));
|
||||
verify(mockSnapshotEvent, never()).getSnapshotMetadata();
|
||||
verify(mockSnapshotService, never()).doImport(any(SnapshotMetadata.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveSnapshotMetadataFromEvent() {
|
||||
SnapshotMetadata eventSnapshotMetadata = newSnapshotMetadata(snapshotDat);
|
||||
SnapshotMetadata exportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata importSnapshotMetadata = newSnapshotMetadata(FileSystemUtils.USER_HOME);
|
||||
SnapshotMetadata factoryExportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata factoryImportSnapshotMetadata = newSnapshotMetadata(FileSystemUtils.USER_HOME);
|
||||
|
||||
factoryBean.setExports(toArray(exportSnapshotMetadata));
|
||||
factoryBean.setImports(toArray(importSnapshotMetadata));
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(SnapshotApplicationEvent.class,
|
||||
"MockSnapshotApplicationEvent");
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(exportSnapshotMetadata)));
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(importSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(new ExportSnapshotApplicationEvent(
|
||||
this, eventSnapshotMetadata))[0], is(equalTo(eventSnapshotMetadata)));
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(toArray(eventSnapshotMetadata));
|
||||
|
||||
factoryBean.setExports(toArray(factoryExportSnapshotMetadata));
|
||||
factoryBean.setImports(toArray(factoryImportSnapshotMetadata));
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(factoryExportSnapshotMetadata)));
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(factoryImportSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(mockSnapshotEvent)[0], is(equalTo(eventSnapshotMetadata)));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).getSnapshotMetadata();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveExportSnapshotMetadataFromFactory() {
|
||||
SnapshotMetadata exportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata factoryExportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata factoryImportSnapshotMetadata = newSnapshotMetadata(FileSystemUtils.USER_HOME);
|
||||
|
||||
factoryBean.setExports(toArray(exportSnapshotMetadata));
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ExportSnapshotApplicationEvent.class,
|
||||
"MockExportSnapshotApplicationEvent");
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(exportSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(new ExportSnapshotApplicationEvent(this))[0],
|
||||
is(equalTo(exportSnapshotMetadata)));
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(null);
|
||||
|
||||
factoryBean.setExports(toArray(factoryExportSnapshotMetadata));
|
||||
factoryBean.setImports(toArray(factoryImportSnapshotMetadata));
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(factoryExportSnapshotMetadata)));
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(factoryImportSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(mockSnapshotEvent)[0], is(equalTo(factoryExportSnapshotMetadata)));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).getSnapshotMetadata();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveImportSnapshotMetadataFromFactory() {
|
||||
SnapshotMetadata exportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata factoryExportSnapshotMetadata = newSnapshotMetadata();
|
||||
SnapshotMetadata factoryImportSnapshotMetadata = newSnapshotMetadata(FileSystemUtils.USER_HOME);
|
||||
|
||||
factoryBean.setImports(toArray(exportSnapshotMetadata));
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(ImportSnapshotApplicationEvent.class,
|
||||
"MockImportSnapshotApplicationEvent");
|
||||
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(exportSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(new ImportSnapshotApplicationEvent(this))[0],
|
||||
is(equalTo(exportSnapshotMetadata)));
|
||||
when(mockSnapshotEvent.getSnapshotMetadata()).thenReturn(toArray());
|
||||
|
||||
factoryBean.setExports(toArray(factoryExportSnapshotMetadata));
|
||||
factoryBean.setImports(toArray(factoryImportSnapshotMetadata));
|
||||
|
||||
assertThat(factoryBean.getExports()[0], is(equalTo(factoryExportSnapshotMetadata)));
|
||||
assertThat(factoryBean.getImports()[0], is(equalTo(factoryImportSnapshotMetadata)));
|
||||
assertThat(factoryBean.resolveSnapshotMetadata(mockSnapshotEvent)[0], is(equalTo(factoryImportSnapshotMetadata)));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).getSnapshotMetadata();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withCacheBasedSnapshotServiceOnCacheSnapshotEventIsMatch() {
|
||||
SnapshotApplicationEvent event = new ExportSnapshotApplicationEvent(this);
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(SnapshotApplicationEvent.class, "MockSnapshotApplicationEvent");
|
||||
|
||||
assertThat(event.isCacheSnapshotEvent(), is(true));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(false));
|
||||
assertThat(factoryBean.isMatch(event), is(true));
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(true);
|
||||
|
||||
assertThat(factoryBean.getRegion(), is(nullValue()));
|
||||
assertThat(factoryBean.isMatch(mockSnapshotEvent), is(true));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, never()).matches(any(Region.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withCacheBasedSnapshotServiceOnRegionSnapshotEventIsNotAMatch() {
|
||||
SnapshotApplicationEvent event = new ImportSnapshotApplicationEvent(this, "/Example");
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(SnapshotApplicationEvent.class, "MockSnapshotApplicationEvent");
|
||||
|
||||
assertThat(event.isCacheSnapshotEvent(), is(false));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(true));
|
||||
assertThat(factoryBean.isMatch(event), is(false));
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(false);
|
||||
when(mockSnapshotEvent.matches(any(Region.class))).thenReturn(false);
|
||||
|
||||
assertThat(factoryBean.getRegion(), is(nullValue()));
|
||||
assertThat(factoryBean.isMatch(mockSnapshotEvent), is(false));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, times(1)).matches(isNull(Region.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRegionBasedSnapshotServiceOnRegionSnapshotEventIsMatch() {
|
||||
SnapshotApplicationEvent event = new ExportSnapshotApplicationEvent(this, "/Example");
|
||||
public void withRegionBasedSnapshotServiceOnCacheSnapshotEventIsMatch() {
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(SnapshotApplicationEvent.class, "MockSnapshotApplicationEvent");
|
||||
|
||||
assertThat(event.isCacheSnapshotEvent(), is(false));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(true));
|
||||
|
||||
Region mockRegion = mock(Region.class, "MockRegion");
|
||||
|
||||
when(mockRegion.getFullPath()).thenReturn(event.getRegionPath());
|
||||
|
||||
factoryBean.setRegion(mockRegion);
|
||||
|
||||
assertThat(factoryBean.getRegion(), is(sameInstance(mockRegion)));
|
||||
assertThat(factoryBean.isMatch(event), is(true));
|
||||
|
||||
verify(mockRegion, times(1)).getFullPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRegionBasedSnapshotServiceOnCacheSnapshotEventIsNotAMatch() {
|
||||
SnapshotApplicationEvent event = new ImportSnapshotApplicationEvent(this);
|
||||
|
||||
assertThat(event.isCacheSnapshotEvent(), is(true));
|
||||
assertThat(event.isRegionSnapshotEvent(), is(false));
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(true);
|
||||
|
||||
factoryBean.setRegion(mock(Region.class, "MockRegion"));
|
||||
|
||||
assertThat(factoryBean.getRegion(), is(notNullValue()));
|
||||
assertThat(factoryBean.isMatch(event), is(false));
|
||||
assertThat(factoryBean.isMatch(mockSnapshotEvent), is(true));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, never()).matches(any(Region.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRegionBasedSnapshotServiceOnRegionSnapshotEventIsMatch() {
|
||||
Region mockRegion = mock(Region.class, "MockRegion");
|
||||
|
||||
SnapshotApplicationEvent mockSnapshotEvent = mock(SnapshotApplicationEvent.class, "MockSnapshotApplicationEvent");
|
||||
|
||||
when(mockSnapshotEvent.isCacheSnapshotEvent()).thenReturn(false);
|
||||
when(mockSnapshotEvent.matches(eq(mockRegion))).thenReturn(true);
|
||||
|
||||
factoryBean.setRegion(mockRegion);
|
||||
|
||||
assertThat(factoryBean.getRegion(), is(sameInstance(mockRegion)));
|
||||
assertThat(factoryBean.isMatch(mockSnapshotEvent), is(true));
|
||||
|
||||
verify(mockSnapshotEvent, times(1)).isCacheSnapshotEvent();
|
||||
verify(mockSnapshotEvent, times(1)).matches(eq(mockRegion));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -636,9 +711,7 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
when(mockSnapshotOptionsOne.setFilter(eq(mockSnapshotFilterOne))).thenReturn(mockSnapshotOptionsOne);
|
||||
when(mockSnapshotOptionsTwo.setFilter(eq(mockSnapshotFilterTwo))).thenReturn(mockSnapshotOptionsTwo);
|
||||
|
||||
File snapshotDatTwo = File.createTempFile("snapshot-2", "dat");
|
||||
|
||||
snapshotDatTwo.deleteOnExit();
|
||||
File snapshotDatTwo = mockFile("snapshot-2.dat");
|
||||
|
||||
SnapshotMetadata[] expectedImports = toArray(newSnapshotMetadata(snapshotDat, mockSnapshotFilterOne),
|
||||
newSnapshotMetadata(snapshotDatTwo, mockSnapshotFilterTwo));
|
||||
@@ -1099,14 +1172,14 @@ public class SnapshotServiceFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void createSnapshotMetadataWithFileNullFilterAndGemFireFormat() throws Exception {
|
||||
SnapshotMetadata metadata = new SnapshotMetadata(snapshotDat, null, SnapshotFormat.GEMFIRE);
|
||||
SnapshotMetadata snapshotMetadata = new SnapshotMetadata(snapshotDat, null, SnapshotFormat.GEMFIRE);
|
||||
|
||||
assertThat(metadata.getLocation(), is(equalTo(snapshotDat)));
|
||||
assertThat(metadata.isDirectory(), is(false));
|
||||
assertThat(metadata.isFile(), is(true));
|
||||
assertThat(metadata.getFilter(), is(nullValue()));
|
||||
assertThat(metadata.isFilterPresent(), is(false));
|
||||
assertThat(metadata.getFormat(), is(equalTo(SnapshotFormat.GEMFIRE)));
|
||||
assertThat(snapshotMetadata.getLocation(), is(equalTo(snapshotDat)));
|
||||
assertThat(snapshotMetadata.isDirectory(), is(false));
|
||||
assertThat(snapshotMetadata.isFile(), is(true));
|
||||
assertThat(snapshotMetadata.getFilter(), is(nullValue()));
|
||||
assertThat(snapshotMetadata.isFilterPresent(), is(false));
|
||||
assertThat(snapshotMetadata.getFormat(), is(equalTo(SnapshotFormat.GEMFIRE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -49,16 +49,18 @@ import com.gemstone.gemfire.cache.Region;
|
||||
* @see org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
* @see org.springframework.data.gemfire.SnapshotServiceFactoryBean
|
||||
* @see org.springframework.data.gemfire.repository.sample.Person
|
||||
* @see com.gemstone.gemfire.cache.Region
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SnapshotServiceImportExportIntegrationTest {
|
||||
|
||||
protected static final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
|
||||
private static final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
|
||||
|
||||
private static ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private static File importPeopleSnapshot;
|
||||
private static File snapshotsDirectory;
|
||||
|
||||
private static Region<Long, Person> people;
|
||||
|
||||
@@ -87,8 +89,10 @@ public class SnapshotServiceImportExportIntegrationTest {
|
||||
@BeforeClass
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void setupBeforeClass() throws Exception {
|
||||
File exportDirectory = new File("./gemfire/snapshots/export");
|
||||
File importDirectory = new File("./gemfire/snapshots/import");
|
||||
snapshotsDirectory = new File(new File(FileSystemUtils.WORKING_DIRECTORY, "gemfire"), "snapshots");
|
||||
|
||||
File exportDirectory = new File(snapshotsDirectory, "export");
|
||||
File importDirectory = new File(snapshotsDirectory, "import");
|
||||
|
||||
assertThat(exportDirectory.isDirectory() || exportDirectory.mkdirs(), is(true));
|
||||
assertThat(importDirectory.isDirectory() || importDirectory.mkdirs(), is(true));
|
||||
@@ -113,18 +117,17 @@ public class SnapshotServiceImportExportIntegrationTest {
|
||||
public static void tearDownAfterClass() {
|
||||
applicationContext.close();
|
||||
|
||||
File exportPeopleSnapshot = new File("gemfire/snapshots/export/people.snapshot");
|
||||
File exportPeopleSnapshot = new File(new File(snapshotsDirectory, "export"), "people.snapshot");
|
||||
|
||||
assertThat(exportPeopleSnapshot.isFile(), is(true));
|
||||
assertThat(exportPeopleSnapshot.length(), is(equalTo(importPeopleSnapshot.length())));
|
||||
|
||||
FileSystemUtils.deleteRecursive(new File(FileSystemUtils.WORKING_DIRECTORY, "gemfire"));
|
||||
FileSystemUtils.deleteRecursive(snapshotsDirectory.getParentFile());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
//setupPeople();
|
||||
|
||||
ThreadUtils.timedWait(TimeUnit.SECONDS.toMillis(5), 500, new ThreadUtils.WaitCondition() {
|
||||
@Override public boolean waiting() {
|
||||
return !(people.size() > 0);
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:c="http://www.springframework.org/schema/c"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">SnapshotApplicationEventTriggeredImportsExportsIntegrationTest</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<gfe:partitioned-region id="Doe" persistent="false"/>
|
||||
<gfe:partitioned-region id="EveryoneElse" persistent="false"/>
|
||||
<gfe:partitioned-region id="Handy" persistent="false"/>
|
||||
<gfe:partitioned-region id="People" persistent="false"/>
|
||||
|
||||
<bean id="nonHandyNonDoeSnapshotFilter" class="org.springframework.data.gemfire.ComposableSnapshotFilter" factory-method="and">
|
||||
<constructor-arg index="0">
|
||||
<list>
|
||||
<bean class="org.springframework.data.gemfire.SnapshotApplicationEventTriggeredImportsExportsIntegrationTest.NotLastNameSnapshotFilter" c:lastName="Doe"/>
|
||||
<bean class="org.springframework.data.gemfire.SnapshotApplicationEventTriggeredImportsExportsIntegrationTest.NotLastNameSnapshotFilter" c:lastName="Handy"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="org.springframework.data.gemfire.SnapshotApplicationEventTriggeredImportsExportsIntegrationTest.SnapshotImportsMonitor"/>
|
||||
|
||||
<task:scheduler id="snapshotImportsMonitorScheduler" pool-size="1"/>
|
||||
|
||||
<task:annotation-driven scheduler="snapshotImportsMonitorScheduler"/>
|
||||
|
||||
<gfe-data:snapshot-service id="peopleSnapshotService" region-ref="People">
|
||||
<gfe-data:export-snapshot location="gemfire/snapshots/people.snapshot"/>
|
||||
<gfe-data:export-snapshot location="gemfire/snapshots/nonHandyNonDoePeople.snapshot" filter-ref="nonHandyNonDoeSnapshotFilter"/>
|
||||
</gfe-data:snapshot-service>
|
||||
|
||||
<gfe-data:snapshot-service id="doeSnapshotService" region-ref="Doe" suppress-init-import="true">
|
||||
<gfe-data:import-snapshot location="gemfire/snapshots/people.snapshot">
|
||||
<bean class="org.springframework.data.gemfire.SnapshotApplicationEventTriggeredImportsExportsIntegrationTest.LastNameSnapshotFilter" c:lastName="Doe"/>
|
||||
</gfe-data:import-snapshot>
|
||||
</gfe-data:snapshot-service>
|
||||
|
||||
<gfe-data:snapshot-service id="everyoneElseSnapshotService" region-ref="EveryoneElse" suppress-init-import="true">
|
||||
<gfe-data:import-snapshot location="gemfire/snapshots/nonHandyNonDoePeople.snapshot"/>
|
||||
</gfe-data:snapshot-service>
|
||||
|
||||
<gfe-data:snapshot-service id="handySnapshotService" region-ref="Handy" suppress-init-import="true">
|
||||
<gfe-data:import-snapshot location="gemfire/snapshots/people.snapshot">
|
||||
<bean class="org.springframework.data.gemfire.SnapshotApplicationEventTriggeredImportsExportsIntegrationTest.LastNameSnapshotFilter" c:lastName="Handy"/>
|
||||
</gfe-data:import-snapshot>
|
||||
</gfe-data:snapshot-service>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user