001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import java.io.IOException; 021import org.apache.commons.lang3.StringUtils; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.HBaseClassTestRule; 025import org.apache.hadoop.hbase.HBaseTestingUtility; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.client.RegionInfo; 028import org.apache.hadoop.hbase.client.Table; 029import org.apache.hadoop.hbase.testclassification.MediumTests; 030import org.apache.hadoop.hbase.testclassification.RegionServerTests; 031import org.apache.hadoop.hbase.util.Bytes; 032import org.apache.hadoop.hbase.util.CommonFSUtils; 033import org.apache.hadoop.hdfs.DFSClient; 034import org.junit.After; 035import org.junit.Assert; 036import org.junit.Before; 037import org.junit.ClassRule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040 041@Category({ RegionServerTests.class, MediumTests.class }) 042public class TestHdfsSnapshotHRegion { 043 044 @ClassRule 045 public static final HBaseClassTestRule CLASS_RULE = 046 HBaseClassTestRule.forClass(TestHdfsSnapshotHRegion.class); 047 048 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 049 private static final String SNAPSHOT_NAME = "foo_snapshot"; 050 private Table table; 051 public static final TableName TABLE_NAME = TableName.valueOf("foo"); 052 public static final byte[] FAMILY = Bytes.toBytes("f1"); 053 private DFSClient client; 054 private String baseDir; 055 056 @Before 057 public void setUp() throws Exception { 058 Configuration c = TEST_UTIL.getConfiguration(); 059 c.setBoolean("dfs.support.append", true); 060 TEST_UTIL.startMiniCluster(1); 061 table = TEST_UTIL.createMultiRegionTable(TABLE_NAME, FAMILY); 062 TEST_UTIL.loadTable(table, FAMILY); 063 064 // setup the hdfssnapshots 065 client = new DFSClient(TEST_UTIL.getDFSCluster().getURI(), TEST_UTIL.getConfiguration()); 066 String fullUrIPath = TEST_UTIL.getDefaultRootDirPath().toString(); 067 String uriString = TEST_UTIL.getTestFileSystem().getUri().toString(); 068 baseDir = StringUtils.removeStart(fullUrIPath, uriString); 069 client.allowSnapshot(baseDir); 070 } 071 072 @After 073 public void tearDown() throws Exception { 074 client.deleteSnapshot(baseDir, SNAPSHOT_NAME); 075 TEST_UTIL.shutdownMiniCluster(); 076 } 077 078 @Test 079 public void testOpeningReadOnlyRegionBasic() throws Exception { 080 String snapshotDir = client.createSnapshot(baseDir, SNAPSHOT_NAME); 081 RegionInfo firstRegion = TEST_UTIL.getConnection().getRegionLocator(table.getName()) 082 .getAllRegionLocations().stream().findFirst().get().getRegion(); 083 Path tableDir = CommonFSUtils.getTableDir(new Path(snapshotDir), TABLE_NAME); 084 HRegion snapshottedRegion = openSnapshotRegion(firstRegion, tableDir); 085 Assert.assertNotNull(snapshottedRegion); 086 snapshottedRegion.close(); 087 } 088 089 @Test 090 public void testSnapshottingWithTmpSplitsAndMergeDirectoriesPresent() throws Exception { 091 // lets get a region and create those directories and make sure we ignore them 092 RegionInfo firstRegion = TEST_UTIL.getConnection().getRegionLocator(table.getName()) 093 .getAllRegionLocations().stream().findFirst().get().getRegion(); 094 String encodedName = firstRegion.getEncodedName(); 095 Path tableDir = CommonFSUtils.getTableDir(TEST_UTIL.getDefaultRootDirPath(), TABLE_NAME); 096 Path regionDirectoryPath = new Path(tableDir, encodedName); 097 TEST_UTIL.getTestFileSystem() 098 .create(new Path(regionDirectoryPath, HRegionFileSystem.REGION_TEMP_DIR)); 099 TEST_UTIL.getTestFileSystem() 100 .create(new Path(regionDirectoryPath, HRegionFileSystem.REGION_SPLITS_DIR)); 101 TEST_UTIL.getTestFileSystem() 102 .create(new Path(regionDirectoryPath, HRegionFileSystem.REGION_MERGES_DIR)); 103 // now snapshot 104 String snapshotDir = client.createSnapshot(baseDir, "foo_snapshot"); 105 // everything should still open just fine 106 HRegion snapshottedRegion = 107 openSnapshotRegion(firstRegion, CommonFSUtils.getTableDir(new Path(snapshotDir), TABLE_NAME)); 108 Assert.assertNotNull(snapshottedRegion); // no errors and the region should open 109 snapshottedRegion.close(); 110 } 111 112 private HRegion openSnapshotRegion(RegionInfo firstRegion, Path tableDir) throws IOException { 113 return HRegion.openReadOnlyFileSystemHRegion(TEST_UTIL.getConfiguration(), 114 TEST_UTIL.getTestFileSystem(), tableDir, firstRegion, table.getDescriptor()); 115 } 116}