GEODE-3169: Decoupling of DiskStore and backups This closes #715 * move backup logic away from DiskStore and into BackupManager * refactor code into smaller methods * improve test code clarity
Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/3bb6a221 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/3bb6a221 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/3bb6a221 Branch: refs/heads/feature/GEODE-1279 Commit: 3bb6a2214d02fcb339ecba0d0645457d3926ab12 Parents: f38dff9 Author: Nick Reich <[email protected]> Authored: Tue Aug 8 11:30:17 2017 -0700 Committer: Anil <[email protected]> Committed: Fri Aug 18 09:52:24 2017 -0700 ---------------------------------------------------------------------- .../admin/internal/FinishBackupRequest.java | 2 +- .../admin/internal/PrepareBackupRequest.java | 4 +- .../geode/internal/cache/BackupManager.java | 603 +++++++++++++++++++ .../geode/internal/cache/DiskStoreBackup.java | 9 +- .../internal/cache/DiskStoreFactoryImpl.java | 1 - .../geode/internal/cache/DiskStoreImpl.java | 224 +------ .../geode/internal/cache/GemFireCacheImpl.java | 5 +- .../geode/internal/cache/InternalCache.java | 1 - .../org/apache/geode/internal/cache/Oplog.java | 1 + .../cache/PartitionedRegionDataStore.java | 1 - .../cache/persistence/BackupManager.java | 389 ------------ .../internal/cache/xmlcache/CacheCreation.java | 2 +- .../internal/beans/MemberMBeanBridge.java | 6 +- .../geode/internal/cache/BackupDUnitTest.java | 176 +++--- .../geode/internal/cache/BackupJUnitTest.java | 145 +++-- .../cache/IncrementalBackupDUnitTest.java | 3 +- .../BackupPrepareAndFinishMsgDUnitTest.java | 548 ++++------------- ...ionedBackupPrepareAndFinishMsgDUnitTest.java | 28 + ...icateBackupPrepareAndFinishMsgDUnitTest.java | 28 + .../beans/DistributedSystemBridgeJUnitTest.java | 8 +- 20 files changed, 935 insertions(+), 1249 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/admin/internal/FinishBackupRequest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/FinishBackupRequest.java b/geode-core/src/main/java/org/apache/geode/admin/internal/FinishBackupRequest.java index f01666d..88f67bd 100644 --- a/geode-core/src/main/java/org/apache/geode/admin/internal/FinishBackupRequest.java +++ b/geode-core/src/main/java/org/apache/geode/admin/internal/FinishBackupRequest.java @@ -99,7 +99,7 @@ public class FinishBackupRequest extends CliLegacyMessage { persistentIds = new HashSet<PersistentID>(); } else { try { - persistentIds = cache.getBackupManager().finishBackup(targetDir, baselineDir, abort); + persistentIds = cache.getBackupManager().doBackup(targetDir, baselineDir, abort); } catch (IOException e) { logger.error( LocalizedMessage.create(LocalizedStrings.CliLegacyMessage_ERROR, this.getClass()), e); http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/admin/internal/PrepareBackupRequest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/PrepareBackupRequest.java b/geode-core/src/main/java/org/apache/geode/admin/internal/PrepareBackupRequest.java index 0c096f9..ede70c1 100644 --- a/geode-core/src/main/java/org/apache/geode/admin/internal/PrepareBackupRequest.java +++ b/geode-core/src/main/java/org/apache/geode/admin/internal/PrepareBackupRequest.java @@ -37,7 +37,7 @@ import org.apache.geode.internal.admin.remote.AdminResponse; import org.apache.geode.internal.admin.remote.CliLegacyMessage; import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.internal.cache.InternalCache; -import org.apache.geode.internal.cache.persistence.BackupManager; +import org.apache.geode.internal.cache.BackupManager; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.logging.log4j.LocalizedMessage; @@ -87,7 +87,7 @@ public class PrepareBackupRequest extends CliLegacyMessage { } else { try { BackupManager manager = cache.startBackup(getSender()); - persistentIds = manager.prepareBackup(); + persistentIds = manager.prepareForBackup(); } catch (IOException e) { logger.error( LocalizedMessage.create(LocalizedStrings.CliLegacyMessage_ERROR, this.getClass()), e); http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/BackupManager.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/BackupManager.java b/geode-core/src/main/java/org/apache/geode/internal/cache/BackupManager.java new file mode 100644 index 0000000..b7e0e47 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/BackupManager.java @@ -0,0 +1,603 @@ +/* + * 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; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; + +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.Logger; + +import org.apache.geode.InternalGemFireError; +import org.apache.geode.cache.DiskStore; +import org.apache.geode.cache.persistence.PersistentID; +import org.apache.geode.distributed.DistributedSystem; +import org.apache.geode.distributed.internal.DM; +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.MembershipListener; +import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.internal.ClassPathLoader; +import org.apache.geode.internal.DeployedJar; +import org.apache.geode.internal.JarDeployer; +import org.apache.geode.internal.cache.persistence.BackupInspector; +import org.apache.geode.internal.cache.persistence.RestoreScript; +import org.apache.geode.internal.i18n.LocalizedStrings; +import org.apache.geode.internal.logging.LogService; + +/** + * This class manages the state an logic to backup a single cache. + */ +public class BackupManager implements MembershipListener { + private static final Logger logger = LogService.getLogger(BackupManager.class); + + static final String INCOMPLETE_BACKUP_FILE = "INCOMPLETE_BACKUP_FILE"; + + private static final String BACKUP_DIR_PREFIX = "dir"; + private static final String README_FILE = "README_FILE.txt"; + private static final String DATA_STORES_DIRECTORY = "diskstores"; + private static final String USER_FILES = "user"; + private static final String CONFIG_DIRECTORY = "config"; + + private final Map<DiskStoreImpl, DiskStoreBackup> backupByDiskStore = new HashMap<>(); + private final RestoreScript restoreScript = new RestoreScript(); + private final InternalDistributedMember sender; + private final InternalCache cache; + private final CountDownLatch allowDestroys = new CountDownLatch(1); + private volatile boolean isCancelled = false; + + public BackupManager(InternalDistributedMember sender, InternalCache gemFireCache) { + this.sender = sender; + this.cache = gemFireCache; + } + + public void validateRequestingAdmin() { + // We need to watch for pure admin guys that depart. this allMembershipListener set + // looks like it should receive those events. + Set allIds = getDistributionManager().addAllMembershipListenerAndGetAllIds(this); + if (!allIds.contains(sender)) { + cleanup(); + throw new IllegalStateException("The admin member requesting a backup has already departed"); + } + } + + public HashSet<PersistentID> prepareForBackup() { + HashSet<PersistentID> persistentIds = new HashSet<>(); + for (DiskStore store : cache.listDiskStoresIncludingRegionOwned()) { + DiskStoreImpl storeImpl = (DiskStoreImpl) store; + storeImpl.lockStoreBeforeBackup(); + if (storeImpl.hasPersistedData()) { + persistentIds.add(storeImpl.getPersistentID()); + storeImpl.getStats().startBackup(); + } + } + return persistentIds; + } + + public HashSet<PersistentID> doBackup(File targetDir, File baselineDir, boolean abort) + throws IOException { + try { + if (abort) { + return new HashSet<>(); + } + HashSet<PersistentID> persistentIds = new HashSet<>(); + File backupDir = getBackupDir(targetDir); + + // Make sure our baseline is okay for this member + baselineDir = checkBaseline(baselineDir); + + // Create an inspector for the baseline backup + BackupInspector inspector = + (baselineDir == null ? null : BackupInspector.createInspector(baselineDir)); + + File storesDir = new File(backupDir, DATA_STORES_DIRECTORY); + Collection<DiskStore> diskStores = cache.listDiskStoresIncludingRegionOwned(); + Map<DiskStoreImpl, DiskStoreBackup> backupByDiskStore = new HashMap<>(); + + boolean foundPersistentData = false; + for (DiskStore store : diskStores) { + DiskStoreImpl diskStore = (DiskStoreImpl) store; + if (diskStore.hasPersistedData()) { + if (!foundPersistentData) { + createBackupDir(backupDir); + foundPersistentData = true; + } + File diskStoreDir = new File(storesDir, getBackupDirName(diskStore)); + diskStoreDir.mkdir(); + DiskStoreBackup backup = startDiskStoreBackup(diskStore, diskStoreDir, inspector); + backupByDiskStore.put(diskStore, backup); + } + diskStore.releaseBackupLock(); + } + + allowDestroys.countDown(); + + for (Map.Entry<DiskStoreImpl, DiskStoreBackup> entry : backupByDiskStore.entrySet()) { + DiskStoreImpl diskStore = entry.getKey(); + completeBackup(diskStore, entry.getValue()); + diskStore.getStats().endBackup(); + persistentIds.add(diskStore.getPersistentID()); + } + + if (!backupByDiskStore.isEmpty()) { + completeRestoreScript(backupDir); + } + + return persistentIds; + + } finally { + cleanup(); + } + } + + public void abort() { + cleanup(); + } + + private DM getDistributionManager() { + return cache.getInternalDistributedSystem().getDistributionManager(); + } + + private void cleanup() { + isCancelled = true; + allowDestroys.countDown(); + releaseBackupLocks(); + getDistributionManager().removeAllMembershipListener(this); + cache.clearBackupManager(); + } + + private void releaseBackupLocks() { + for (DiskStore store : cache.listDiskStoresIncludingRegionOwned()) { + ((DiskStoreImpl) store).releaseBackupLock(); + } + } + + /** + * Returns the memberId directory for this member in the baseline. The memberId may have changed + * if this member has been restarted since the last backup. + * + * @param baselineParentDir parent directory of last backup. + * @return null if the baseline for this member could not be located. + */ + private File findBaselineForThisMember(File baselineParentDir) { + File baselineDir = null; + + /* + * Find the first matching DiskStoreId directory for this member. + */ + for (DiskStore diskStore : cache.listDiskStoresIncludingRegionOwned()) { + File[] matchingFiles = baselineParentDir + .listFiles((file, name) -> name.endsWith(getBackupDirName((DiskStoreImpl) diskStore))); + // We found it? Good. Set this member's baseline to the backed up disk store's member dir (two + // levels up). + if (null != matchingFiles && matchingFiles.length > 0) + baselineDir = matchingFiles[0].getParentFile().getParentFile(); + } + return baselineDir; + } + + /** + * Performs a sanity check on the baseline directory for incremental backups. If a baseline + * directory exists for the member and there is no INCOMPLETE_BACKUP_FILE file then return the + * data stores directory for this member. + * + * @param baselineParentDir a previous backup directory. This is used with the incremental backup + * option. May be null if the user specified a full backup. + * @return null if the backup is to be a full backup otherwise return the data store directory in + * the previous backup for this member (if incremental). + */ + private File checkBaseline(File baselineParentDir) throws IOException { + File baselineDir = null; + + if (null != baselineParentDir) { + // Start by looking for this memberId + baselineDir = getBackupDir(baselineParentDir); + + if (!baselineDir.exists()) { + // hmmm, did this member have a restart? + // Determine which member dir might be a match for us + baselineDir = findBaselineForThisMember(baselineParentDir); + } + + if (null != baselineDir) { + // check for existence of INCOMPLETE_BACKUP_FILE file + File incompleteBackup = new File(baselineDir, INCOMPLETE_BACKUP_FILE); + if (incompleteBackup.exists()) { + baselineDir = null; + } + } + } + + return baselineDir; + } + + private void completeRestoreScript(File backupDir) throws IOException { + backupConfigFiles(restoreScript, backupDir); + backupUserFiles(restoreScript, backupDir); + backupDeployedJars(restoreScript, backupDir); + restoreScript.generate(backupDir); + File incompleteFile = new File(backupDir, INCOMPLETE_BACKUP_FILE); + if (!incompleteFile.delete()) { + throw new IOException("Could not delete file " + INCOMPLETE_BACKUP_FILE); + } + } + + /** + * Copy the oplogs to the backup directory. This is the final step of the backup process. The + * oplogs we copy are defined in the startDiskStoreBackup method. + */ + private void completeBackup(DiskStoreImpl diskStore, DiskStoreBackup backup) throws IOException { + if (backup == null) { + return; + } + try { + // Wait for oplogs to be unpreblown before backing them up. + diskStore.waitForDelayedWrites(); + + // Backup all of the oplogs + for (Oplog oplog : backup.getPendingBackup()) { + if (isCancelled()) { + break; + } + // Copy theoplog to the destination directory + int index = oplog.getDirectoryHolder().getArrayIndex(); + File backupDir = getBackupDir(backup.getTargetDir(), index); + // TODO prpersist - We could probably optimize this to *move* the files + // that we know are supposed to be deleted. + oplog.copyTo(backupDir); + + // Allow the oplog to be deleted, and process any pending delete + backup.backupFinished(oplog); + } + } finally { + backup.cleanup(); + } + } + + /** + * Returns the dir name used to back up this DiskStore's directories under. The name is a + * concatenation of the disk store name and id. + */ + private String getBackupDirName(DiskStoreImpl diskStore) { + String name = diskStore.getName(); + + if (name == null) { + name = GemFireCacheImpl.getDefaultDiskStoreName(); + } + + return (name + "_" + diskStore.getDiskStoreID().toString()); + } + + /** + * Start the backup process. This is the second step of the backup process. In this method, we + * define the data we're backing up by copying the init file and rolling to the next file. After + * this method returns operations can proceed as normal, except that we don't remove oplogs. + */ + private DiskStoreBackup startDiskStoreBackup(DiskStoreImpl diskStore, File targetDir, + BackupInspector baselineInspector) throws IOException { + diskStore.getBackupLock().setBackupThread(); + DiskStoreBackup backup = null; + boolean done = false; + try { + for (;;) { + Oplog childOplog = diskStore.getPersistentOplogSet().getChild(); + if (childOplog == null) { + backup = new DiskStoreBackup(new Oplog[0], targetDir); + backupByDiskStore.put(diskStore, backup); + break; + } + + // Get an appropriate lock object for each set of oplogs. + Object childLock = childOplog.lock; + + // TODO - We really should move this lock into the disk store, but + // until then we need to do this magic to make sure we're actually + // locking the latest child for both types of oplogs + + // This ensures that all writing to disk is blocked while we are + // creating the snapshot + synchronized (childLock) { + if (diskStore.getPersistentOplogSet().getChild() != childOplog) { + continue; + } + + if (logger.isDebugEnabled()) { + logger.debug("snapshotting oplogs for disk store {}", diskStore.getName()); + } + + createDiskStoreBackupDirs(diskStore, targetDir); + + restoreScript.addExistenceTest(diskStore.getDiskInitFile().getIFFile()); + + // Contains all oplogs that will backed up + Oplog[] allOplogs = null; + + // Incremental backup so filter out oplogs that have already been + // backed up + if (null != baselineInspector) { + Map<File, File> baselineCopyMap = new HashMap<>(); + allOplogs = filterBaselineOplogs(diskStore, baselineInspector, baselineCopyMap); + restoreScript.addBaselineFiles(baselineCopyMap); + } else { + allOplogs = diskStore.getAllOplogsForBackup(); + } + + // mark all oplogs as being backed up. This will + // prevent the oplogs from being deleted + backup = new DiskStoreBackup(allOplogs, targetDir); + backupByDiskStore.put(diskStore, backup); + + // copy the init file + File firstDir = getBackupDir(targetDir, diskStore.getInforFileDirIndex()); + diskStore.getDiskInitFile().copyTo(firstDir); + diskStore.getPersistentOplogSet().forceRoll(null); + + if (logger.isDebugEnabled()) { + logger.debug("done snaphotting for disk store {}", diskStore.getName()); + } + break; + } + } + done = true; + } finally { + if (!done) { + if (backup != null) { + backupByDiskStore.remove(diskStore); + backup.cleanup(); + } + } + } + return backup; + } + + private void createDiskStoreBackupDirs(DiskStoreImpl diskStore, File targetDir) + throws IOException { + // Create the directories for this disk store + DirectoryHolder[] directories = diskStore.getDirectoryHolders(); + for (int i = 0; i < directories.length; i++) { + File dir = getBackupDir(targetDir, i); + if (!dir.mkdirs()) { + throw new IOException("Could not create directory " + dir); + } + restoreScript.addFile(directories[i].getDir(), dir); + } + } + + /** + * Filters and returns the current set of oplogs that aren't already in the baseline for + * incremental backup + * + * @param baselineInspector the inspector for the previous backup. + * @param baselineCopyMap this will be populated with baseline oplogs Files that will be used in + * the restore script. + * @return an array of Oplogs to be copied for an incremental backup. + */ + private Oplog[] filterBaselineOplogs(DiskStoreImpl diskStore, BackupInspector baselineInspector, + Map<File, File> baselineCopyMap) throws IOException { + File baselineDir = + new File(baselineInspector.getBackupDir(), BackupManager.DATA_STORES_DIRECTORY); + baselineDir = new File(baselineDir, getBackupDirName(diskStore)); + + // Find all of the member's diskstore oplogs in the member's baseline + // diskstore directory structure (*.crf,*.krf,*.drf) + Collection<File> baselineOplogFiles = + FileUtils.listFiles(baselineDir, new String[] {"krf", "drf", "crf"}, true); + // Our list of oplogs to copy (those not already in the baseline) + List<Oplog> oplogList = new LinkedList<>(); + + // Total list of member oplogs + Oplog[] allOplogs = diskStore.getAllOplogsForBackup(); + + /* + * Loop through operation logs and see if they are already part of the baseline backup. + */ + for (Oplog log : allOplogs) { + // See if they are backed up in the current baseline + Map<File, File> oplogMap = log.mapBaseline(baselineOplogFiles); + + // No? Then see if they were backed up in previous baselines + if (oplogMap.isEmpty() && baselineInspector.isIncremental()) { + Set<String> matchingOplogs = + log.gatherMatchingOplogFiles(baselineInspector.getIncrementalOplogFileNames()); + if (!matchingOplogs.isEmpty()) { + for (String matchingOplog : matchingOplogs) { + oplogMap.put(new File(baselineInspector.getCopyFromForOplogFile(matchingOplog)), + new File(baselineInspector.getCopyToForOplogFile(matchingOplog))); + } + } + } + + if (oplogMap.isEmpty()) { + /* + * These are fresh operation log files so lets back them up. + */ + oplogList.add(log); + } else { + /* + * These have been backed up before so lets just add their entries from the previous backup + * or restore script into the current one. + */ + baselineCopyMap.putAll(oplogMap); + } + } + + // Convert the filtered oplog list to an array + return oplogList.toArray(new Oplog[oplogList.size()]); + } + + private File getBackupDir(File targetDir, int index) { + return new File(targetDir, BACKUP_DIR_PREFIX + index); + } + + private void backupConfigFiles(RestoreScript restoreScript, File backupDir) throws IOException { + File configBackupDir = new File(backupDir, CONFIG_DIRECTORY); + configBackupDir.mkdirs(); + URL url = cache.getCacheXmlURL(); + if (url != null) { + File cacheXMLBackup = + new File(configBackupDir, DistributionConfig.DEFAULT_CACHE_XML_FILE.getName()); + FileUtils.copyFile(new File(cache.getCacheXmlURL().getFile()), cacheXMLBackup); + } + + URL propertyURL = DistributedSystem.getPropertiesFileURL(); + if (propertyURL != null) { + File propertyBackup = + new File(configBackupDir, DistributionConfig.GEMFIRE_PREFIX + "properties"); + FileUtils.copyFile(new File(DistributedSystem.getPropertiesFile()), propertyBackup); + } + + // TODO: should the gfsecurity.properties file be backed up? + } + + private void backupUserFiles(RestoreScript restoreScript, File backupDir) throws IOException { + List<File> backupFiles = cache.getBackupFiles(); + File userBackupDir = new File(backupDir, USER_FILES); + if (!userBackupDir.exists()) { + userBackupDir.mkdir(); + } + for (File original : backupFiles) { + if (original.exists()) { + original = original.getAbsoluteFile(); + File dest = new File(userBackupDir, original.getName()); + if (original.isDirectory()) { + FileUtils.copyDirectory(original, dest); + } else { + FileUtils.copyFile(original, dest); + } + restoreScript.addExistenceTest(original); + restoreScript.addFile(original, dest); + } + } + } + + /** + * Copies user deployed jars to the backup directory. + * + * @param restoreScript Used to restore from this backup. + * @param backupDir The backup directory for this member. + * @throws IOException one or more of the jars did not successfully copy. + */ + private void backupDeployedJars(RestoreScript restoreScript, File backupDir) throws IOException { + JarDeployer deployer = null; + + try { + /* + * Suspend any user deployed jar file updates during this backup. + */ + deployer = ClassPathLoader.getLatest().getJarDeployer(); + deployer.suspendAll(); + + List<DeployedJar> jarList = deployer.findDeployedJars(); + if (!jarList.isEmpty()) { + File userBackupDir = new File(backupDir, USER_FILES); + if (!userBackupDir.exists()) { + userBackupDir.mkdir(); + } + + for (DeployedJar loader : jarList) { + File source = new File(loader.getFileCanonicalPath()); + File dest = new File(userBackupDir, source.getName()); + if (source.isDirectory()) { + FileUtils.copyDirectory(source, dest); + } else { + FileUtils.copyFile(source, dest); + } + restoreScript.addFile(source, dest); + } + } + } finally { + /* + * Re-enable user deployed jar file updates. + */ + if (null != deployer) { + deployer.resumeAll(); + } + } + } + + private File getBackupDir(File targetDir) throws IOException { + InternalDistributedMember memberId = + cache.getInternalDistributedSystem().getDistributedMember(); + String vmId = memberId.toString(); + vmId = cleanSpecialCharacters(vmId); + return new File(targetDir, vmId); + } + + private void createBackupDir(File backupDir) throws IOException { + if (backupDir.exists()) { + throw new IOException("Backup directory " + backupDir.getAbsolutePath() + " already exists."); + } + + if (!backupDir.mkdirs()) { + throw new IOException("Could not create directory: " + backupDir); + } + + File incompleteFile = new File(backupDir, INCOMPLETE_BACKUP_FILE); + if (!incompleteFile.createNewFile()) { + throw new IOException("Could not create file: " + incompleteFile); + } + + File readme = new File(backupDir, README_FILE); + FileOutputStream fos = new FileOutputStream(readme); + + try { + String text = LocalizedStrings.BackupManager_README.toLocalizedString(); + fos.write(text.getBytes()); + } finally { + fos.close(); + } + } + + private String cleanSpecialCharacters(String string) { + return string.replaceAll("[^\\w]+", "_"); + } + + public void memberDeparted(InternalDistributedMember id, boolean crashed) { + cleanup(); + } + + public void memberJoined(InternalDistributedMember id) {} + + public void quorumLost(Set<InternalDistributedMember> failures, + List<InternalDistributedMember> remaining) {} + + public void memberSuspect(InternalDistributedMember id, InternalDistributedMember whoSuspected, + String reason) {} + + public void waitForBackup() { + try { + allowDestroys.await(); + } catch (InterruptedException e) { + throw new InternalGemFireError(e); + } + } + + public boolean isCancelled() { + return isCancelled; + } + + public DiskStoreBackup getBackupForDiskStore(DiskStoreImpl diskStore) { + return backupByDiskStore.get(diskStore); + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreBackup.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreBackup.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreBackup.java index 309dea3..53c5ca1 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreBackup.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreBackup.java @@ -25,17 +25,16 @@ import org.apache.geode.internal.cache.persistence.BackupInspector; * This class manages the state of the backup of an individual disk store. It holds the list of * oplogs that still need to be backed up, along with the lists of oplog files that should be * deleted when the oplog is backed up. See - * {@link DiskStoreImpl#startBackup(File, BackupInspector, org.apache.geode.internal.cache.persistence.RestoreScript)} */ public class DiskStoreBackup { private final Set<Oplog> pendingBackup; - private final Set<Oplog> deferredCrfDeletes = new HashSet<Oplog>(); - private final Set<Oplog> deferredDrfDeletes = new HashSet<Oplog>(); + private final Set<Oplog> deferredCrfDeletes = new HashSet<>(); + private final Set<Oplog> deferredDrfDeletes = new HashSet<>(); private final File targetDir; public DiskStoreBackup(Oplog[] allOplogs, File targetDir) { - this.pendingBackup = new HashSet<Oplog>(Arrays.asList(allOplogs)); + this.pendingBackup = new HashSet<>(Arrays.asList(allOplogs)); this.targetDir = targetDir; } @@ -70,7 +69,7 @@ public class DiskStoreBackup { } public synchronized Set<Oplog> getPendingBackup() { - return new HashSet<Oplog>(pendingBackup); + return new HashSet<>(pendingBackup); } public synchronized void backupFinished(Oplog oplog) { http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java index 0288ef1..d6d55d6 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreFactoryImpl.java @@ -21,7 +21,6 @@ import org.apache.geode.GemFireIOException; import org.apache.geode.cache.DiskStoreFactory; import org.apache.geode.cache.DiskStore; import org.apache.geode.distributed.internal.ResourceEvent; -import org.apache.geode.internal.cache.persistence.BackupManager; import org.apache.geode.internal.cache.xmlcache.CacheCreation; import org.apache.geode.internal.cache.xmlcache.CacheXml; import org.apache.geode.internal.cache.xmlcache.DiskStoreAttributesCreation; http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreImpl.java index 94d1253..a8a8a53 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreImpl.java @@ -33,8 +33,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -60,7 +58,6 @@ import java.util.regex.Pattern; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.Logger; import org.apache.geode.CancelCriterion; @@ -86,8 +83,6 @@ import org.apache.geode.internal.cache.DiskEntry.RecoveredEntry; import org.apache.geode.internal.cache.ExportDiskRegion.ExportWriter; import org.apache.geode.internal.cache.lru.LRUAlgorithm; import org.apache.geode.internal.cache.lru.LRUStatistics; -import org.apache.geode.internal.cache.persistence.BackupInspector; -import org.apache.geode.internal.cache.persistence.BackupManager; import org.apache.geode.internal.cache.persistence.BytesAndBits; import org.apache.geode.internal.cache.persistence.DiskRecoveryStore; import org.apache.geode.internal.cache.persistence.DiskRegionView; @@ -97,7 +92,6 @@ import org.apache.geode.internal.cache.persistence.OplogType; import org.apache.geode.internal.cache.persistence.PRPersistentConfig; import org.apache.geode.internal.cache.persistence.PersistentMemberID; import org.apache.geode.internal.cache.persistence.PersistentMemberPattern; -import org.apache.geode.internal.cache.persistence.RestoreScript; import org.apache.geode.internal.cache.snapshot.GFSnapshot; import org.apache.geode.internal.cache.snapshot.GFSnapshot.SnapshotWriter; import org.apache.geode.internal.cache.snapshot.SnapshotPacket.SnapshotRecord; @@ -126,8 +120,6 @@ import org.apache.geode.pdx.internal.PeerTypeRegistration; public class DiskStoreImpl implements DiskStore { private static final Logger logger = LogService.getLogger(); - private static final String BACKUP_DIR_PREFIX = "dir"; - public static final boolean KRF_DEBUG = Boolean.getBoolean("disk.KRF_DEBUG"); public static final int MAX_OPEN_INACTIVE_OPLOGS = @@ -302,8 +294,6 @@ public class DiskStoreImpl implements DiskStore { private DiskInitFile initFile = null; - private volatile DiskStoreBackup diskStoreBackup = null; - private final ReentrantReadWriteLock compactorLock = new ReentrantReadWriteLock(); private final WriteLock compactorWriteLock = compactorLock.writeLock(); @@ -672,6 +662,10 @@ public class DiskStoreImpl implements DiskStore { } } + public PersistentOplogSet getPersistentOplogSet() { + return persistentOplogs; + } + PersistentOplogSet getPersistentOplogSet(DiskRegionView drv) { assert drv.isBackup(); return persistentOplogs; @@ -2031,6 +2025,10 @@ public class DiskStoreImpl implements DiskStore { return this.directories[this.infoFileDirIndex]; } + int getInforFileDirIndex() { + return this.infoFileDirIndex; + } + /** * returns the size of the biggest directory available to the region */ @@ -2692,84 +2690,9 @@ public class DiskStoreImpl implements DiskStore { } /** - * Returns the dir name used to back up this DiskStore's directories under. The name is a - * concatenation of the disk store name and id. - */ - public String getBackupDirName() { - String name = getName(); - - if (name == null) { - name = GemFireCacheImpl.getDefaultDiskStoreName(); - } - - return (name + "_" + getDiskStoreID().toString()); - } - - /** - * Filters and returns the current set of oplogs that aren't already in the baseline for - * incremental backup - * - * @param baselineInspector the inspector for the previous backup. - * @param baselineCopyMap this will be populated with baseline oplogs Files that will be used in - * the restore script. - * @return an array of Oplogs to be copied for an incremental backup. - */ - private Oplog[] filterBaselineOplogs(BackupInspector baselineInspector, - Map<File, File> baselineCopyMap) throws IOException { - File baselineDir = new File(baselineInspector.getBackupDir(), BackupManager.DATA_STORES); - baselineDir = new File(baselineDir, getBackupDirName()); - - // Find all of the member's diskstore oplogs in the member's baseline - // diskstore directory structure (*.crf,*.krf,*.drf) - Collection<File> baselineOplogFiles = - FileUtils.listFiles(baselineDir, new String[] {"krf", "drf", "crf"}, true); - // Our list of oplogs to copy (those not already in the baseline) - List<Oplog> oplogList = new LinkedList<Oplog>(); - - // Total list of member oplogs - Oplog[] allOplogs = getAllOplogsForBackup(); - - /* - * Loop through operation logs and see if they are already part of the baseline backup. - */ - for (Oplog log : allOplogs) { - // See if they are backed up in the current baseline - Map<File, File> oplogMap = log.mapBaseline(baselineOplogFiles); - - // No? Then see if they were backed up in previous baselines - if (oplogMap.isEmpty() && baselineInspector.isIncremental()) { - Set<String> matchingOplogs = - log.gatherMatchingOplogFiles(baselineInspector.getIncrementalOplogFileNames()); - if (!matchingOplogs.isEmpty()) { - for (String matchingOplog : matchingOplogs) { - oplogMap.put(new File(baselineInspector.getCopyFromForOplogFile(matchingOplog)), - new File(baselineInspector.getCopyToForOplogFile(matchingOplog))); - } - } - } - - if (oplogMap.isEmpty()) { - /* - * These are fresh operation log files so lets back them up. - */ - oplogList.add(log); - } else { - /* - * These have been backed up before so lets just add their entries from the previous backup - * or restore script into the current one. - */ - baselineCopyMap.putAll(oplogMap); - } - } - - // Convert the filtered oplog list to an array - return oplogList.toArray(new Oplog[oplogList.size()]); - } - - /** * Get all of the oplogs */ - private Oplog[] getAllOplogsForBackup() { + Oplog[] getAllOplogsForBackup() { return persistentOplogs.getAllOplogs(); } @@ -4066,124 +3989,6 @@ public class DiskStoreImpl implements DiskStore { getBackupLock().unlockForBackup(); } - /** - * Start the backup process. This is the second step of the backup process. In this method, we - * define the data we're backing up by copying the init file and rolling to the next file. After - * this method returns operations can proceed as normal, except that we don't remove oplogs. - */ - public void startBackup(File targetDir, BackupInspector baselineInspector, - RestoreScript restoreScript) throws IOException { - getBackupLock().setBackupThread(); - boolean done = false; - try { - for (;;) { - Oplog childOplog = persistentOplogs.getChild(); - if (childOplog == null) { - this.diskStoreBackup = new DiskStoreBackup(new Oplog[0], targetDir); - break; - } - - // Get an appropriate lock object for each set of oplogs. - Object childLock = childOplog.lock; - - // TODO - We really should move this lock into the disk store, but - // until then we need to do this magic to make sure we're actually - // locking the latest child for both types of oplogs - - // This ensures that all writing to disk is blocked while we are - // creating the snapshot - synchronized (childLock) { - if (persistentOplogs.getChild() != childOplog) { - continue; - } - - if (logger.isDebugEnabled()) { - logger.debug("snapshotting oplogs for disk store {}", getName()); - } - - // Create the directories for this disk store - for (int i = 0; i < directories.length; i++) { - File dir = getBackupDir(targetDir, i); - if (!dir.mkdirs()) { - throw new IOException("Could not create directory " + dir); - } - restoreScript.addFile(directories[i].getDir(), dir); - } - - restoreScript.addExistenceTest(this.initFile.getIFFile()); - - // Contains all oplogs that will backed up - Oplog[] allOplogs = null; - - // Incremental backup so filter out oplogs that have already been - // backed up - if (null != baselineInspector) { - Map<File, File> baselineCopyMap = new HashMap<File, File>(); - allOplogs = filterBaselineOplogs(baselineInspector, baselineCopyMap); - restoreScript.addBaselineFiles(baselineCopyMap); - } else { - allOplogs = getAllOplogsForBackup(); - } - - // mark all oplogs as being backed up. This will - // prevent the oplogs from being deleted - this.diskStoreBackup = new DiskStoreBackup(allOplogs, targetDir); - - // copy the init file - File firstDir = getBackupDir(targetDir, infoFileDirIndex); - initFile.copyTo(firstDir); - persistentOplogs.forceRoll(null); - - if (logger.isDebugEnabled()) { - logger.debug("done snaphotting for disk store {}", getName()); - } - break; - } - } - done = true; - } finally { - if (!done) { - clearBackup(); - } - } - } - - private File getBackupDir(File targetDir, int index) { - return new File(targetDir, BACKUP_DIR_PREFIX + index); - } - - /** - * Copy the oplogs to the backup directory. This is the final step of the backup process. The - * oplogs we copy are defined in the startBackup method. - */ - public void finishBackup(BackupManager backupManager) throws IOException { - if (diskStoreBackup == null) { - return; - } - try { - // Wait for oplogs to be unpreblown before backing them up. - waitForDelayedWrites(); - - // Backup all of the oplogs - for (Oplog oplog : this.diskStoreBackup.getPendingBackup()) { - if (backupManager.isCancelled()) { - break; - } - // Copy theoplog to the destination directory - int index = oplog.getDirectoryHolder().getArrayIndex(); - File backupDir = getBackupDir(this.diskStoreBackup.getTargetDir(), index); - // TODO prpersist - We could probably optimize this to *move* the files - // that we know are supposed to be deleted. - oplog.copyTo(backupDir); - - // Allow the oplog to be deleted, and process any pending delete - this.diskStoreBackup.backupFinished(oplog); - } - } finally { - clearBackup(); - } - } - private int getArrayIndexOfDirectory(File searchDir) { for (DirectoryHolder holder : directories) { if (holder.getDir().equals(searchDir)) { @@ -4197,16 +4002,9 @@ public class DiskStoreImpl implements DiskStore { return this.directories; } - private void clearBackup() { - DiskStoreBackup backup = this.diskStoreBackup; - if (backup != null) { - this.diskStoreBackup = null; - backup.cleanup(); - } - } - public DiskStoreBackup getInProgressBackup() { - return diskStoreBackup; + BackupManager backupManager = cache.getBackupManager(); + return backupManager == null ? null : backupManager.getBackupForDiskStore(this); } public Collection<DiskRegionView> getKnown() { http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java index 67c8add..6d250d9 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java @@ -79,6 +79,8 @@ import com.sun.jna.Platform; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.Logger; +import org.apache.geode.internal.cache.event.EventTrackerExpiryTask; +import org.apache.geode.internal.security.SecurityServiceFactory; import org.apache.geode.CancelCriterion; import org.apache.geode.CancelException; import org.apache.geode.ForcedDisconnectException; @@ -184,7 +186,6 @@ import org.apache.geode.internal.cache.locks.TXLockService; import org.apache.geode.internal.cache.lru.HeapEvictor; import org.apache.geode.internal.cache.lru.OffHeapEvictor; import org.apache.geode.internal.cache.partitioned.RedundancyAlreadyMetException; -import org.apache.geode.internal.cache.persistence.BackupManager; import org.apache.geode.internal.cache.persistence.PersistentMemberID; import org.apache.geode.internal.cache.persistence.PersistentMemberManager; import org.apache.geode.internal.cache.snapshot.CacheSnapshotServiceImpl; @@ -4351,7 +4352,7 @@ public class GemFireCacheImpl implements InternalCache, InternalClientCache, Has if (!this.backupManager.compareAndSet(null, manager)) { throw new IOException("Backup already in progress"); } - manager.start(); + manager.validateRequestingAdmin(); return manager; } http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java index d162010..84aa66e 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java @@ -55,7 +55,6 @@ import org.apache.geode.internal.cache.control.InternalResourceManager; import org.apache.geode.internal.cache.control.ResourceAdvisor; import org.apache.geode.internal.cache.event.EventTrackerExpiryTask; import org.apache.geode.internal.cache.extension.Extensible; -import org.apache.geode.internal.cache.persistence.BackupManager; import org.apache.geode.internal.cache.persistence.PersistentMemberManager; import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier; import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID; http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java b/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java index 80f19b5..860db98 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java @@ -5702,6 +5702,7 @@ public class Oplog implements CompactableOplog, Flushable { public void deleteCRF() { oplogSet.crfDelete(this.oplogId); + BackupManager backupManager = getInternalCache().getBackupManager(); DiskStoreBackup inProgressBackup = getParent().getInProgressBackup(); if (inProgressBackup == null || !inProgressBackup.deferCrfDelete(this)) { deleteCRFFileOnly(); http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java index 893ca6b..3d9ac18 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java @@ -42,7 +42,6 @@ import org.apache.geode.internal.cache.execute.PartitionedRegionFunctionResultSe import org.apache.geode.internal.cache.execute.RegionFunctionContextImpl; import org.apache.geode.internal.cache.partitioned.*; import org.apache.geode.internal.cache.partitioned.RemoveBucketMessage.RemoveBucketResponse; -import org.apache.geode.internal.cache.persistence.BackupManager; import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID; import org.apache.geode.internal.cache.tier.sockets.ServerConnection; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/BackupManager.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/BackupManager.java b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/BackupManager.java deleted file mode 100644 index f464e0d..0000000 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/BackupManager.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * 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.persistence; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.io.FileUtils; - -import org.apache.geode.InternalGemFireError; -import org.apache.geode.cache.DiskStore; -import org.apache.geode.cache.persistence.PersistentID; -import org.apache.geode.distributed.DistributedSystem; -import org.apache.geode.distributed.internal.DM; -import org.apache.geode.distributed.internal.DistributionConfig; -import org.apache.geode.distributed.internal.MembershipListener; -import org.apache.geode.distributed.internal.membership.InternalDistributedMember; -import org.apache.geode.internal.ClassPathLoader; -import org.apache.geode.internal.DeployedJar; -import org.apache.geode.internal.JarDeployer; -import org.apache.geode.internal.cache.DiskStoreImpl; -import org.apache.geode.internal.cache.InternalCache; -import org.apache.geode.internal.i18n.LocalizedStrings; - -/** - * This class manages the state an logic to backup a single cache. - */ -public class BackupManager implements MembershipListener { - - // TODO prpersist internationalize this. - public static final String INCOMPLETE_BACKUP = "INCOMPLETE_BACKUP"; - public static final String README = "README.txt"; - public static final String DATA_STORES = "diskstores"; - public static final String USER_FILES = "user"; - public static final String CONFIG = "config"; - private InternalDistributedMember sender; - private InternalCache cache; - private CountDownLatch allowDestroys = new CountDownLatch(1); - private volatile boolean isCancelled = false; - - public BackupManager(InternalDistributedMember sender, InternalCache gemFireCache) { - this.sender = sender; - this.cache = gemFireCache; - } - - public void start() { - final DM distributionManager = cache.getInternalDistributedSystem().getDistributionManager(); - // We need to watch for pure admin guys that depart. this allMembershipListener set - // looks like it should receive those events. - Set allIds = distributionManager.addAllMembershipListenerAndGetAllIds(this); - if (!allIds.contains(sender)) { - cleanup(); - throw new IllegalStateException("The admin member requesting a backup has already departed"); - } - } - - private void cleanup() { - isCancelled = true; - allowDestroys.countDown(); - Collection<DiskStore> diskStores = cache.listDiskStoresIncludingRegionOwned(); - for (DiskStore store : diskStores) { - ((DiskStoreImpl) store).releaseBackupLock(); - } - final DM distributionManager = cache.getInternalDistributedSystem().getDistributionManager(); - distributionManager.removeAllMembershipListener(this); - cache.clearBackupManager(); - } - - public HashSet<PersistentID> prepareBackup() { - HashSet<PersistentID> persistentIds = new HashSet<PersistentID>(); - Collection<DiskStore> diskStores = cache.listDiskStoresIncludingRegionOwned(); - for (DiskStore store : diskStores) { - DiskStoreImpl storeImpl = (DiskStoreImpl) store; - storeImpl.lockStoreBeforeBackup(); - if (storeImpl.hasPersistedData()) { - persistentIds.add(storeImpl.getPersistentID()); - storeImpl.getStats().startBackup(); - } - } - return persistentIds; - } - - /** - * Returns the memberId directory for this member in the baseline. The memberId may have changed - * if this member has been restarted since the last backup. - * - * @param baselineParentDir parent directory of last backup. - * @return null if the baseline for this member could not be located. - */ - private File findBaselineForThisMember(File baselineParentDir) { - File baselineDir = null; - - /* - * Find the first matching DiskStoreId directory for this member. - */ - for (DiskStore diskStore : cache.listDiskStoresIncludingRegionOwned()) { - File[] matchingFiles = baselineParentDir.listFiles(new FilenameFilter() { - Pattern pattern = - Pattern.compile(".*" + ((DiskStoreImpl) diskStore).getBackupDirName() + "$"); - - public boolean accept(File dir, String name) { - Matcher m = pattern.matcher(name); - return m.find(); - } - }); - // We found it? Good. Set this member's baseline to the backed up disk store's member dir (two - // levels up). - if (null != matchingFiles && matchingFiles.length > 0) - baselineDir = matchingFiles[0].getParentFile().getParentFile(); - } - return baselineDir; - } - - /** - * Performs a sanity check on the baseline directory for incremental backups. If a baseline - * directory exists for the member and there is no INCOMPLETE_BACKUP file then return the data - * stores directory for this member. - * - * @param baselineParentDir a previous backup directory. This is used with the incremental backup - * option. May be null if the user specified a full backup. - * @return null if the backup is to be a full backup otherwise return the data store directory in - * the previous backup for this member (if incremental). - */ - private File checkBaseline(File baselineParentDir) throws IOException { - File baselineDir = null; - - if (null != baselineParentDir) { - // Start by looking for this memberId - baselineDir = getBackupDir(baselineParentDir); - - if (!baselineDir.exists()) { - // hmmm, did this member have a restart? - // Determine which member dir might be a match for us - baselineDir = findBaselineForThisMember(baselineParentDir); - } - - if (null != baselineDir) { - // check for existence of INCOMPLETE_BACKUP file - File incompleteBackup = new File(baselineDir, INCOMPLETE_BACKUP); - if (incompleteBackup.exists()) { - baselineDir = null; - } - } - } - - return baselineDir; - } - - public HashSet<PersistentID> finishBackup(File targetDir, File baselineDir, boolean abort) - throws IOException { - try { - if (abort) { - return new HashSet<PersistentID>(); - } - - File backupDir = getBackupDir(targetDir); - - // Make sure our baseline is okay for this member - baselineDir = checkBaseline(baselineDir); - - // Create an inspector for the baseline backup - BackupInspector inspector = - (baselineDir == null ? null : BackupInspector.createInspector(baselineDir)); - - File storesDir = new File(backupDir, DATA_STORES); - RestoreScript restoreScript = new RestoreScript(); - HashSet<PersistentID> persistentIds = new HashSet<PersistentID>(); - Collection<DiskStore> diskStores = - new ArrayList<DiskStore>(cache.listDiskStoresIncludingRegionOwned()); - - boolean foundPersistentData = false; - for (Iterator<DiskStore> itr = diskStores.iterator(); itr.hasNext();) { - DiskStoreImpl store = (DiskStoreImpl) itr.next(); - if (store.hasPersistedData()) { - if (!foundPersistentData) { - createBackupDir(backupDir); - foundPersistentData = true; - } - File diskStoreDir = new File(storesDir, store.getBackupDirName()); - diskStoreDir.mkdir(); - store.startBackup(diskStoreDir, inspector, restoreScript); - } else { - itr.remove(); - } - store.releaseBackupLock(); - } - - allowDestroys.countDown(); - - for (DiskStore store : diskStores) { - DiskStoreImpl storeImpl = (DiskStoreImpl) store; - storeImpl.finishBackup(this); - storeImpl.getStats().endBackup(); - persistentIds.add(storeImpl.getPersistentID()); - } - - if (foundPersistentData) { - backupConfigFiles(restoreScript, backupDir); - backupUserFiles(restoreScript, backupDir); - backupDeployedJars(restoreScript, backupDir); - restoreScript.generate(backupDir); - File incompleteFile = new File(backupDir, INCOMPLETE_BACKUP); - if (!incompleteFile.delete()) { - throw new IOException("Could not delete file " + INCOMPLETE_BACKUP); - } - } - - return persistentIds; - - } finally { - cleanup(); - } - } - - public void abort() { - cleanup(); - } - - private void backupConfigFiles(RestoreScript restoreScript, File backupDir) throws IOException { - File configBackupDir = new File(backupDir, CONFIG); - configBackupDir.mkdirs(); - URL url = cache.getCacheXmlURL(); - if (url != null) { - File cacheXMLBackup = - new File(configBackupDir, DistributionConfig.DEFAULT_CACHE_XML_FILE.getName()); - FileUtils.copyFile(new File(cache.getCacheXmlURL().getFile()), cacheXMLBackup); - } - - URL propertyURL = DistributedSystem.getPropertiesFileURL(); - if (propertyURL != null) { - File propertyBackup = - new File(configBackupDir, DistributionConfig.GEMFIRE_PREFIX + "properties"); - FileUtils.copyFile(new File(DistributedSystem.getPropertiesFile()), propertyBackup); - } - - // TODO: should the gfsecurity.properties file be backed up? - } - - private void backupUserFiles(RestoreScript restoreScript, File backupDir) throws IOException { - List<File> backupFiles = cache.getBackupFiles(); - File userBackupDir = new File(backupDir, USER_FILES); - if (!userBackupDir.exists()) { - userBackupDir.mkdir(); - } - for (File original : backupFiles) { - if (original.exists()) { - original = original.getAbsoluteFile(); - File dest = new File(userBackupDir, original.getName()); - if (original.isDirectory()) { - FileUtils.copyDirectory(original, dest); - } else { - FileUtils.copyFile(original, dest); - } - restoreScript.addExistenceTest(original); - restoreScript.addFile(original, dest); - } - } - } - - /** - * Copies user deployed jars to the backup directory. - * - * @param restoreScript Used to restore from this backup. - * @param backupDir The backup directory for this member. - * @throws IOException one or more of the jars did not successfully copy. - */ - private void backupDeployedJars(RestoreScript restoreScript, File backupDir) throws IOException { - JarDeployer deployer = null; - - try { - /* - * Suspend any user deployed jar file updates during this backup. - */ - deployer = ClassPathLoader.getLatest().getJarDeployer(); - deployer.suspendAll(); - - List<DeployedJar> jarList = deployer.findDeployedJars(); - if (!jarList.isEmpty()) { - File userBackupDir = new File(backupDir, USER_FILES); - if (!userBackupDir.exists()) { - userBackupDir.mkdir(); - } - - for (DeployedJar loader : jarList) { - File source = new File(loader.getFileCanonicalPath()); - File dest = new File(userBackupDir, source.getName()); - if (source.isDirectory()) { - FileUtils.copyDirectory(source, dest); - } else { - FileUtils.copyFile(source, dest); - } - restoreScript.addFile(source, dest); - } - } - } finally { - /* - * Re-enable user deployed jar file updates. - */ - if (null != deployer) { - deployer.resumeAll(); - } - } - } - - private File getBackupDir(File targetDir) throws IOException { - InternalDistributedMember memberId = - cache.getInternalDistributedSystem().getDistributedMember(); - String vmId = memberId.toString(); - vmId = cleanSpecialCharacters(vmId); - return new File(targetDir, vmId); - } - - private void createBackupDir(File backupDir) throws IOException { - if (backupDir.exists()) { - throw new IOException("Backup directory " + backupDir.getAbsolutePath() + " already exists."); - } - - if (!backupDir.mkdirs()) { - throw new IOException("Could not create directory: " + backupDir); - } - - File incompleteFile = new File(backupDir, INCOMPLETE_BACKUP); - if (!incompleteFile.createNewFile()) { - throw new IOException("Could not create file: " + incompleteFile); - } - - File readme = new File(backupDir, README); - FileOutputStream fos = new FileOutputStream(readme); - - try { - String text = LocalizedStrings.BackupManager_README.toLocalizedString(); - fos.write(text.getBytes()); - } finally { - fos.close(); - } - } - - private String cleanSpecialCharacters(String string) { - return string.replaceAll("[^\\w]+", "_"); - } - - public void memberDeparted(InternalDistributedMember id, boolean crashed) { - cleanup(); - } - - public void memberJoined(InternalDistributedMember id) {} - - public void quorumLost(Set<InternalDistributedMember> failures, - List<InternalDistributedMember> remaining) {} - - public void memberSuspect(InternalDistributedMember id, InternalDistributedMember whoSuspected, - String reason) {} - - public void waitForBackup() { - try { - allowDestroys.await(); - } catch (InterruptedException e) { - throw new InternalGemFireError(e); - } - } - - public boolean isCancelled() { - return isCancelled; - } -} http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java index a7f2a11..e5e372d 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java @@ -108,7 +108,7 @@ import org.apache.geode.internal.cache.extension.Extensible; import org.apache.geode.internal.cache.extension.ExtensionPoint; import org.apache.geode.internal.cache.extension.SimpleExtensionPoint; import org.apache.geode.internal.cache.ha.HARegionQueue; -import org.apache.geode.internal.cache.persistence.BackupManager; +import org.apache.geode.internal.cache.BackupManager; import org.apache.geode.internal.cache.persistence.PersistentMemberManager; import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier; import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID; http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java index dd905eb..5105c3d 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java @@ -77,7 +77,7 @@ import org.apache.geode.internal.cache.PartitionedRegionStats; import org.apache.geode.internal.cache.control.ResourceManagerStats; import org.apache.geode.internal.cache.execute.FunctionServiceStats; import org.apache.geode.internal.cache.lru.LRUStatistics; -import org.apache.geode.internal.cache.persistence.BackupManager; +import org.apache.geode.internal.cache.BackupManager; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.internal.logging.LogService; import org.apache.geode.internal.logging.log4j.LocalizedMessage; @@ -1037,10 +1037,10 @@ public class MemberMBeanBridge { Set<PersistentID> existingDataStores; Set<PersistentID> successfulDataStores; try { - existingDataStores = manager.prepareBackup(); + existingDataStores = manager.prepareForBackup(); abort = false; } finally { - successfulDataStores = manager.finishBackup(targetDir, null/* TODO rishi */, abort); + successfulDataStores = manager.doBackup(targetDir, null/* TODO rishi */, abort); } diskBackUpResult = new DiskBackupResult[existingDataStores.size()]; int j = 0; http://git-wip-us.apache.org/repos/asf/geode/blob/3bb6a221/geode-core/src/test/java/org/apache/geode/internal/cache/BackupDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/BackupDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/BackupDUnitTest.java index f2cee71..338c712 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/BackupDUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/BackupDUnitTest.java @@ -46,11 +46,13 @@ import org.apache.geode.test.dunit.DUnitEnv; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.IgnoredException; import org.apache.geode.test.dunit.Invoke; -import org.apache.geode.test.dunit.LogWriterUtils; import org.apache.geode.test.dunit.SerializableCallable; import org.apache.geode.test.dunit.SerializableRunnable; import org.apache.geode.test.dunit.VM; import org.apache.geode.test.junit.categories.DistributedTest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -67,34 +69,38 @@ import java.util.Collection; import java.util.Collections; import java.util.Set; import java.util.TreeSet; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Pattern; @Category(DistributedTest.class) public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { + Logger logger = LogManager.getLogger(BackupDUnitTest.class); - private static final long MAX_WAIT = 30 * 1000; + private static final long MAX_WAIT_SECONDS = 30; + private VM vm0; + private VM vm1; @Override public final void preTearDownCacheTestCase() throws Exception { StringBuilder failures = new StringBuilder(); delete(getBackupDir(), failures); if (failures.length() > 0) { - LogWriterUtils.getLogWriter().error(failures.toString()); + logger.error(failures.toString()); } } @Test public void testBackupPR() throws Throwable { Host host = Host.getHost(0); - VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); VM vm2 = host.getVM(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createPersistentRegion(vm1); long lm0 = setBackupFiles(vm0); @@ -107,7 +113,6 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { assertEquals(2, status.getBackedUpDiskStores().size()); assertEquals(Collections.emptySet(), status.getOfflineDiskStores()); - Pattern pattern = Pattern.compile(".*my.txt.*"); Collection<File> files = FileUtils.listFiles(getBackupDir(), new String[] {"txt"}, true); assertEquals(4, files.size()); deleteOldUserUserFile(vm0); @@ -136,13 +141,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { restoreBackup(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); - AsyncInvocation async0 = createPersistentRegionAsync(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); - AsyncInvocation async1 = createPersistentRegionAsync(vm1); - - async0.getResult(MAX_WAIT); - async1.getResult(MAX_WAIT); + createPersistentRegionsAsync(); checkData(vm0, 0, 5, "A", "region1"); checkData(vm0, 0, 5, "B", "region2"); @@ -156,12 +155,12 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { @Test public void testBackupFromMemberWithDiskStore() throws Throwable { Host host = Host.getHost(0); - VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createPersistentRegion(vm1); createData(vm0, 0, 5, "A", "region1"); @@ -192,25 +191,21 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { restoreBackup(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); - AsyncInvocation async0 = createPersistentRegionAsync(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); - AsyncInvocation async1 = createPersistentRegionAsync(vm1); - - async0.getResult(MAX_WAIT); - async1.getResult(MAX_WAIT); + createPersistentRegionsAsync(); checkData(vm0, 0, 5, "A", "region1"); checkData(vm0, 0, 5, "B", "region2"); } - // public void testLoop() throws Throwable { - // for(int i =0 ;i < 100; i++) { - // testBackupWhileBucketIsCreated(); - // setUp(); - // tearDown(); - // } - // } + private void createPersistentRegionsAsync() throws java.util.concurrent.ExecutionException, + InterruptedException, java.util.concurrent.TimeoutException { + logger.info("Creating region in VM0"); + AsyncInvocation async0 = createPersistentRegionAsync(vm0); + logger.info("Creating region in VM1"); + AsyncInvocation async1 = createPersistentRegionAsync(vm1); + async0.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS); + async1.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS); + } /** * Test for bug 42419 @@ -218,40 +213,27 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { @Test public void testBackupWhileBucketIsCreated() throws Throwable { Host host = Host.getHost(0); - final VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); final VM vm2 = host.getVM(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); // create a bucket on vm0 createData(vm0, 0, 1, "A", "region1"); // create the pr on vm1, which won't have any buckets - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createPersistentRegion(vm1); - final AtomicReference<BackupStatus> statusRef = new AtomicReference<BackupStatus>(); - Thread thread1 = new Thread() { - public void run() { + CompletableFuture<BackupStatus> backupStatusFuture = + CompletableFuture.supplyAsync(() -> backup(vm2)); + CompletableFuture<Void> createDataFuture = + CompletableFuture.runAsync(() -> createData(vm0, 1, 5, "A", "region1")); + CompletableFuture.allOf(backupStatusFuture, createDataFuture); - BackupStatus status = backup(vm2); - statusRef.set(status); - - } - }; - thread1.start(); - Thread thread2 = new Thread() { - public void run() { - createData(vm0, 1, 5, "A", "region1"); - } - }; - thread2.start(); - thread1.join(); - thread2.join(); - - BackupStatus status = statusRef.get(); + BackupStatus status = backupStatusFuture.get(); assertEquals(2, status.getBackedUpDiskStores().size()); assertEquals(Collections.emptySet(), status.getOfflineDiskStores()); @@ -278,13 +260,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { restoreBackup(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); - AsyncInvocation async0 = createPersistentRegionAsync(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); - AsyncInvocation async1 = createPersistentRegionAsync(vm1); - - async0.getResult(MAX_WAIT); - async1.getResult(MAX_WAIT); + createPersistentRegionsAsync(); checkData(vm0, 0, 1, "A", "region1"); } @@ -296,8 +272,6 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { DistributionMessageObserver observer = new SerializableDistributionMessageObserver() { private volatile boolean done; - private AtomicInteger count = new AtomicInteger(); - private volatile int replyId = -0xBAD; @Override public void beforeSendMessage(DistributionManager dm, DistributionMessage msg) { @@ -316,8 +290,8 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { @Test public void testBackupWhileBucketIsMovedBackupAfterSendDestroy() throws Throwable { Host host = Host.getHost(0); - final VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); final VM vm2 = host.getVM(2); DistributionMessageObserver observer = new SerializableDistributionMessageObserver() { @@ -407,12 +381,11 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { * * @param observer - a message observer that triggers at the backup at the correct time. */ - public void backupWhileBucketIsMoved(final DistributionMessageObserver observer) + private void backupWhileBucketIsMoved(final DistributionMessageObserver observer) throws Throwable { Host host = Host.getHost(0); - final VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); - final VM vm2 = host.getVM(2); + vm0 = host.getVM(0); + vm1 = host.getVM(1); vm0.invoke(new SerializableRunnable("Add listener to invoke backup") { @@ -428,14 +401,14 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { }); try { - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); // create twos bucket on vm0 createData(vm0, 0, 2, "A", "region1"); // create the pr on vm1, which won't have any buckets - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createPersistentRegion(vm1); @@ -476,13 +449,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { restoreBackup(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); - AsyncInvocation async0 = createPersistentRegionAsync(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); - AsyncInvocation async1 = createPersistentRegionAsync(vm1); - - async0.getResult(MAX_WAIT); - async1.getResult(MAX_WAIT); + createPersistentRegionsAsync(); checkData(vm0, 0, 2, "A", "region1"); } finally { @@ -502,13 +469,13 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { @Test public void testBackupOverflow() throws Throwable { Host host = Host.getHost(0); - VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); VM vm2 = host.getVM(2); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createOverflowRegion(vm1); createData(vm0, 0, 5, "A", "region1"); @@ -526,16 +493,16 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { @Test public void testBackupPRWithOfflineMembers() throws Throwable { Host host = Host.getHost(0); - VM vm0 = host.getVM(0); - VM vm1 = host.getVM(1); + vm0 = host.getVM(0); + vm1 = host.getVM(1); VM vm2 = host.getVM(2); VM vm3 = host.getVM(3); - LogWriterUtils.getLogWriter().info("Creating region in VM0"); + logger.info("Creating region in VM0"); createPersistentRegion(vm0); - LogWriterUtils.getLogWriter().info("Creating region in VM1"); + logger.info("Creating region in VM1"); createPersistentRegion(vm1); - LogWriterUtils.getLogWriter().info("Creating region in VM2"); + logger.info("Creating region in VM2"); createPersistentRegion(vm2); createData(vm0, 0, 5, "A", "region1"); @@ -562,11 +529,11 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { assertTrue(files.length == 0); } - protected void createPersistentRegion(VM vm) throws Throwable { + private void createPersistentRegion(VM vm) throws Throwable { AsyncInvocation future = createPersistentRegionAsync(vm); - future.join(MAX_WAIT); + future.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS); if (future.isAlive()) { - fail("Region not created within" + MAX_WAIT); + fail("Region not created within" + MAX_WAIT_SECONDS); } if (future.exceptionOccurred()) { throw new RuntimeException(future.getException()); @@ -576,9 +543,8 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { private void deleteOldUserUserFile(final VM vm) { SerializableRunnable validateUserFileBackup = new SerializableRunnable("set user backups") { public void run() { - final int pid = vm.getPid(); try { - FileUtils.deleteDirectory(new File("userbackup_" + pid)); + FileUtils.deleteDirectory(new File("userbackup_" + vm.getPid())); } catch (IOException e) { fail(e.getMessage()); } @@ -587,7 +553,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { vm.invoke(validateUserFileBackup); } - protected long setBackupFiles(final VM vm) { + private long setBackupFiles(final VM vm) { SerializableCallable setUserBackups = new SerializableCallable("set user backups") { public Object call() { final int pid = DUnitEnv.get().getPid(); @@ -595,7 +561,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { File test1 = new File(vmdir, "test1"); File test2 = new File(test1, "test2"); File mytext = new File(test2, "my.txt"); - final ArrayList<File> backuplist = new ArrayList<File>(); + final ArrayList<File> backuplist = new ArrayList<>(); test2.mkdirs(); PrintStream ps = null; try { @@ -619,7 +585,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { return (long) vm.invoke(setUserBackups); } - protected void verifyUserFileRestored(VM vm, final long lm) { + private void verifyUserFileRestored(VM vm, final long lm) { vm.invoke(new SerializableRunnable() { public void run() { final int pid = DUnitEnv.get().getPid(); @@ -640,8 +606,6 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { BufferedReader bin = new BufferedReader(fr); String content = bin.readLine(); assertTrue(content.equals("" + pid)); - } catch (FileNotFoundException e) { - fail(e.getMessage()); } catch (IOException e) { fail(e.getMessage()); } @@ -649,7 +613,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { }); } - protected AsyncInvocation createPersistentRegionAsync(final VM vm) { + private AsyncInvocation createPersistentRegionAsync(final VM vm) { SerializableRunnable createRegion = new SerializableRunnable("Create persistent region") { public void run() { Cache cache = getCache(); @@ -670,7 +634,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { dsf = cache.createDiskStoreFactory(); dsf.setDiskDirs(getDiskDirs(getUniqueName() + 2)); dsf.setMaxOplogSize(1); - ds = dsf.create(getUniqueName() + 2); + dsf.create(getUniqueName() + 2); rf.setDiskStoreName(getUniqueName() + 2); rf.create("region2"); } @@ -678,7 +642,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { return vm.invokeAsync(createRegion); } - protected void createOverflowRegion(final VM vm) { + private void createOverflowRegion(final VM vm) { SerializableRunnable createRegion = new SerializableRunnable("Create persistent region") { public void run() { Cache cache = getCache(); @@ -760,14 +724,14 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { public Object call() throws Exception { Cache cache = getCache(); PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName); - return new TreeSet<Integer>(region.getDataStore().getAllLocalBucketIds()); + return new TreeSet<>(region.getDataStore().getAllLocalBucketIds()); } }; return (Set<Integer>) vm0.invoke(getBuckets); } - public File[] getDiskDirs(String dsName) { + private File[] getDiskDirs(String dsName) { File[] dirs = getDiskDirs(); File[] diskStoreDirs = new File[1]; diskStoreDirs[0] = new File(dirs[0], dsName); @@ -775,7 +739,7 @@ public class BackupDUnitTest extends PersistentPartitionedRegionTestBase { return diskStoreDirs; } - protected DataPolicy getDataPolicy() { + private DataPolicy getDataPolicy() { return DataPolicy.PERSISTENT_PARTITION; }
