blob: c639e3fb467bcbb963e03643a22db3e567017843 [file] [log] [blame]
/*
* 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 java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.geode.admin.RegionNotFoundException;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.snapshot.CacheSnapshotService;
import org.apache.geode.cache.snapshot.RegionSnapshotService;
import org.apache.geode.cache.snapshot.SnapshotOptions;
import org.apache.geode.cache.snapshot.SnapshotOptions.SnapshotFormat;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.snapshot.GFSnapshot.GFSnapshotImporter;
/**
* Provides an implementation for cache snapshots. Most of the implementation delegates to
* {@link RegionSnapshotService}.
*/
public class CacheSnapshotServiceImpl implements CacheSnapshotService {
/** the cache */
private final InternalCache cache;
public CacheSnapshotServiceImpl(InternalCache cache) {
this.cache = cache;
}
@Override
public SnapshotOptions<Object, Object> createOptions() {
return new SnapshotOptionsImpl<>();
}
@Override
public void save(File dir, SnapshotFormat format) throws IOException {
save(dir, format, createOptions());
}
@Override
public void save(File dir, SnapshotFormat format, SnapshotOptions<Object, Object> options)
throws IOException {
createDirectoryIfNeeded(dir);
for (Region<?, ?> region : cache.rootRegions()) {
for (Region<?, ?> subRegion : region.subregions(true)) {
saveRegion(subRegion, dir, format, options);
}
saveRegion(region, dir, format, options);
}
}
private void createDirectoryIfNeeded(File dir) throws IOException {
if (!dir.exists()) {
boolean created = dir.mkdirs();
if (!created) {
throw new IOException(
String.format("Unable to create snapshot directory %s", dir));
}
}
}
@Override
public void load(File dir, SnapshotFormat format) throws IOException, ClassNotFoundException {
if (!dir.exists() || !dir.isDirectory()) {
throw new FileNotFoundException("Unable to load snapshot from " + dir.getCanonicalPath()
+ " as the file does not exist or is not a directory");
}
File[] snapshotFiles = getSnapshotFiles(dir);
load(snapshotFiles, format, createOptions());
}
private File[] getSnapshotFiles(File dir) throws IOException {
File[] snapshotFiles = dir.listFiles(pathname -> pathname.getName().endsWith(".gfd"));
if (snapshotFiles == null) {
throw new IOException("Unable to access " + dir.getCanonicalPath());
} else if (snapshotFiles.length == 0) {
throw new FileNotFoundException(
String.format("No snapshot files found in %s", dir));
}
return snapshotFiles;
}
@Override
public void load(File[] snapshotFiles, SnapshotFormat format,
SnapshotOptions<Object, Object> options) throws IOException, ClassNotFoundException {
for (File file : snapshotFiles) {
GFSnapshotImporter in = new GFSnapshotImporter(file, cache.getPdxRegistry());
try {
byte version = in.getVersion();
if (version == GFSnapshot.SNAP_VER_1) {
throw new IOException(
String.format("Unsupported snapshot version: %s", version));
}
String regionName = in.getRegionName();
Region<Object, Object> region = cache.getRegion(regionName);
if (region == null) {
throw new RegionNotFoundException(String.format(
"Could not find region %s. Ensure that the region is created prior to importing the snapshot file %s.",
regionName, file));
}
RegionSnapshotService<Object, Object> rs = region.getSnapshotService();
rs.load(file, format, options);
} finally {
in.close();
}
}
}
private void saveRegion(Region<?, ?> region, File dir, SnapshotFormat format,
SnapshotOptions options) throws IOException {
RegionSnapshotService<?, ?> regionSnapshotService = region.getSnapshotService();
String name = "snapshot" + region.getFullPath().replace('/', '-')
+ RegionSnapshotService.SNAPSHOT_FILE_EXTENSION;
File f = new File(dir, name);
regionSnapshotService.save(f, format, options);
}
}