| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You 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.apache.geode.internal.cache.snapshot; |
| |
| import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION; |
| import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; |
| import static org.apache.geode.distributed.ConfigurationProperties.USE_CLUSTER_CONFIGURATION; |
| import static org.junit.Assert.assertEquals; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Properties; |
| import java.util.TreeMap; |
| |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.Cache; |
| import org.apache.geode.cache.CacheFactory; |
| import org.apache.geode.cache.DataPolicy; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.RegionFactory; |
| import org.apache.geode.cache.Scope; |
| import org.apache.geode.cache.client.ClientCache; |
| import org.apache.geode.cache.client.ClientCacheFactory; |
| import org.apache.geode.cache.client.ClientRegionShortcut; |
| import org.apache.geode.cache.snapshot.SnapshotIterator; |
| import org.apache.geode.cache.snapshot.SnapshotOptions.SnapshotFormat; |
| import org.apache.geode.cache.snapshot.SnapshotReader; |
| import org.apache.geode.distributed.LocatorLauncher; |
| import org.apache.geode.distributed.ServerLauncher; |
| import org.apache.geode.internal.AvailablePortHelper; |
| import org.apache.geode.test.dunit.DistributedTestUtils; |
| import org.apache.geode.test.dunit.Host; |
| import org.apache.geode.test.dunit.NetworkUtils; |
| import org.apache.geode.test.dunit.VM; |
| import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; |
| import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder; |
| |
| |
| public class GFSnapshotDUnitTest extends JUnit4DistributedTestCase { |
| |
| private VM locator; |
| private VM server; |
| private VM client; |
| private Host host; |
| |
| @Rule |
| public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder(); |
| |
| @Before |
| public void before() { |
| host = Host.getHost(0); |
| locator = host.getVM(0); |
| server = host.getVM(1); |
| client = host.getVM(2); |
| } |
| |
| @Test |
| public void testDataExportAndIterate() throws IOException, ClassNotFoundException { |
| int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); |
| String serverHostName = NetworkUtils.getServerHostName(host); |
| |
| Properties properties = configureCommonProperties(new Properties()); |
| |
| locator.invoke("Start Locator", |
| () -> configureAndStartLocator(locatorPort, serverHostName, properties)); |
| server.invoke("Start Server", |
| () -> configureAndStartServer(locatorPort, serverHostName, properties)); |
| client.invoke("Start client", () -> { |
| createAndStartClient(locatorPort, serverHostName); |
| return null; |
| }); |
| client.invoke("Populate data", () -> populateDataOnClient()); |
| String snapshotFilePath = server.invoke("Export data snapshot", () -> createSnapshot()); |
| client.invoke("Iterate over snapshot", () -> { |
| ClientCache clientCache = ClientCacheFactory.getAnyInstance(); |
| clientCache.close(); |
| createAndStartClient(locatorPort, serverHostName); |
| iterateOverSnapshot(snapshotFilePath); |
| }); |
| } |
| |
| private void createAndStartClient(final int locatorPort, final String serverHostName) { |
| ClientCacheFactory clientCacheFactory = new ClientCacheFactory(); |
| clientCacheFactory.set("log-level", "config").addPoolLocator(serverHostName, locatorPort); |
| ClientCache clientCache = clientCacheFactory.create(); |
| clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("TestRegion"); |
| } |
| |
| private Object populateDataOnClient() { |
| ClientCache clientCache = ClientCacheFactory.getAnyInstance(); |
| Region testRegion = clientCache.getRegion("TestRegion"); |
| for (int i = 0; i < 100; i++) { |
| testRegion.put(i, new TestObject(i, "owner_" + i)); |
| } |
| return null; |
| } |
| |
| private String createSnapshot() throws IOException { |
| final String memberName = getUniqueName() + "-server"; |
| File file = temporaryFolder.newFolder(memberName + "-snapshot"); |
| Cache cache = CacheFactory.getAnyInstance(); |
| cache.getSnapshotService().save(file, SnapshotFormat.GEMFIRE); |
| return file.getAbsolutePath(); |
| } |
| |
| private void iterateOverSnapshot(final String snapshotFilePath) |
| throws IOException, ClassNotFoundException { |
| |
| File mySnapshot = new File(snapshotFilePath + "/snapshot-TestRegion.gfd"); |
| SnapshotIterator<Integer, TestObject> snapshotIterator = SnapshotReader.read(mySnapshot); |
| |
| Map<Integer, TestObject> result = new TreeMap<>(); |
| |
| try { |
| while (snapshotIterator.hasNext()) { |
| Entry<Integer, TestObject> entry = snapshotIterator.next(); |
| int key = entry.getKey(); |
| TestObject value = entry.getValue(); |
| result.put(key, value); |
| } |
| } finally { |
| snapshotIterator.close(); |
| } |
| assertEquals(100, result.size()); |
| int count = 0; |
| for (Entry<Integer, TestObject> entry : result.entrySet()) { |
| assertEquals(count, (int) entry.getKey()); |
| assertEquals(new TestObject(count, "owner_" + count), entry.getValue()); |
| count++; |
| } |
| } |
| |
| private Properties configureCommonProperties(final Properties properties) { |
| properties.setProperty(MCAST_PORT, "0"); |
| properties.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); |
| properties.setProperty(USE_CLUSTER_CONFIGURATION, "false"); |
| return properties; |
| } |
| |
| private void configureAndStartLocator(final int locatorPort, final String serverHostName, |
| final Properties properties) throws IOException { |
| DistributedTestUtils.deleteLocatorStateFile(locatorPort); |
| |
| final String memberName = getUniqueName() + "-locator"; |
| final File workingDirectory = temporaryFolder.newFolder(memberName); |
| |
| LocatorLauncher.Builder builder = new LocatorLauncher.Builder(); |
| |
| for (String propertyName : properties.stringPropertyNames()) { |
| builder.set(propertyName, properties.getProperty(propertyName)); |
| } |
| LocatorLauncher locatorLauncher = builder.setBindAddress(serverHostName) |
| .setHostnameForClients(serverHostName).setMemberName(memberName).setPort(locatorPort) |
| .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); |
| locatorLauncher.start(); |
| |
| } |
| |
| private void configureAndStartServer(final int locatorPort, final String serverHostName, |
| final Properties properties) throws IOException { |
| final String memberName = getUniqueName() + "-server"; |
| final File workingDirectory = temporaryFolder.newFolder(memberName); |
| final File pdxDirectory = temporaryFolder.newFolder(memberName + "-pdx"); |
| final File diskStoreDirectory = temporaryFolder.newFolder(memberName + "-disk"); |
| |
| |
| ServerLauncher.Builder builder = new ServerLauncher.Builder(); |
| |
| for (String propertyName : properties.stringPropertyNames()) { |
| builder.set(propertyName, properties.getProperty(propertyName)); |
| } |
| |
| ServerLauncher serverLauncher = |
| builder.set("locators", serverHostName + "[" + locatorPort + "]").setMemberName(memberName) |
| .set("log-level", "config").setHostNameForClients(serverHostName) |
| .setServerBindAddress(serverHostName).setServerPort(0) |
| .setWorkingDirectory(workingDirectory.getCanonicalPath()).setPdxDiskStore("pdxDS") |
| .setPdxPersistent(true).build(); |
| serverLauncher.start(); |
| |
| Cache cache = CacheFactory.getAnyInstance(); |
| |
| cache.createDiskStoreFactory().setDiskDirsAndSizes(new File[] {pdxDirectory}, new int[] {16000}) |
| .create("pdxDS"); |
| |
| cache.createDiskStoreFactory() |
| .setDiskDirsAndSizes(new File[] {diskStoreDirectory}, new int[] {16000}) |
| .create("diskStore"); |
| |
| RegionFactory<Object, Object> regionFactory = cache.createRegionFactory(); |
| regionFactory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE).setScope(Scope.DISTRIBUTED_ACK) |
| .setDiskStoreName("diskStore").create("TestRegion"); |
| } |
| |
| |
| } |