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:
John Blum
2015-08-28 00:33:13 -07:00
parent 447d55efbe
commit 3a360a37b4
11 changed files with 925 additions and 155 deletions

View File

@@ -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));
}
}

View File

@@ -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));
}

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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);