1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hdfs.tools.offlineImageViewer; 19 20 import java.io.File; 21 import java.io.IOException; 22 import java.net.HttpURLConnection; 23 import java.net.URI; 24 import java.net.URISyntaxException; 25 import java.net.URL; 26 import java.util.HashMap; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 import org.apache.hadoop.conf.Configuration; 31 import org.apache.hadoop.fs.FSDataOutputStream; 32 import org.apache.hadoop.fs.FileSystem; 33 import org.apache.hadoop.fs.Path; 34 import org.apache.hadoop.fs.permission.AclStatus; 35 import org.apache.hadoop.hdfs.DFSConfigKeys; 36 import org.apache.hadoop.hdfs.DistributedFileSystem; 37 import org.apache.hadoop.hdfs.MiniDFSCluster; 38 import org.apache.hadoop.hdfs.protocol.HdfsConstants; 39 import org.apache.hadoop.hdfs.server.namenode.FSImageTestUtil; 40 import org.apache.hadoop.hdfs.web.WebHdfsFileSystem; 41 import org.apache.hadoop.net.NetUtils; 42 import org.junit.AfterClass; 43 import org.junit.BeforeClass; 44 import org.junit.Test; 45 46 import static org.apache.hadoop.fs.permission.AclEntryScope.ACCESS; 47 import static org.apache.hadoop.fs.permission.AclEntryScope.DEFAULT; 48 import static org.apache.hadoop.fs.permission.AclEntryType.GROUP; 49 import static org.apache.hadoop.fs.permission.AclEntryType.OTHER; 50 import static org.apache.hadoop.fs.permission.AclEntryType.USER; 51 import static org.apache.hadoop.fs.permission.FsAction.ALL; 52 import static org.apache.hadoop.fs.permission.FsAction.READ; 53 import static org.apache.hadoop.fs.permission.FsAction.READ_WRITE; 54 import static org.apache.hadoop.fs.permission.FsAction.READ_EXECUTE; 55 import static org.apache.hadoop.fs.permission.FsAction.NONE; 56 import static org.apache.hadoop.hdfs.server.namenode.AclTestHelpers.aclEntry; 57 import static org.junit.Assert.assertEquals; 58 59 import com.google.common.collect.Lists; 60 import com.google.common.collect.Maps; 61 62 /** 63 * Tests OfflineImageViewer if the input fsimage has HDFS ACLs 64 */ 65 public class TestOfflineImageViewerForAcl { 66 67 private static final Log LOG = 68 LogFactory.getLog(TestOfflineImageViewerForAcl.class); 69 70 private static File originalFsimage = null; 71 72 // ACLs as set to dfs, to be compared with viewer's output 73 final static HashMap<String, AclStatus> writtenAcls = Maps.newHashMap(); 74 75 /** 76 * Create a populated namespace for later testing. Save its contents to a 77 * data structure and store its fsimage location. 78 * We only want to generate the fsimage file once and use it for 79 * multiple tests. 80 */ 81 @BeforeClass createOriginalFSImage()82 public static void createOriginalFSImage() throws IOException { 83 MiniDFSCluster cluster = null; 84 try { 85 Configuration conf = new Configuration(); 86 conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true); 87 cluster = new MiniDFSCluster.Builder(conf).build(); 88 cluster.waitActive(); 89 DistributedFileSystem hdfs = cluster.getFileSystem(); 90 91 // Create a reasonable namespace with ACLs 92 Path dir = new Path("/dirWithNoAcl"); 93 hdfs.mkdirs(dir); 94 writtenAcls.put(dir.toString(), hdfs.getAclStatus(dir)); 95 96 dir = new Path("/dirWithDefaultAcl"); 97 hdfs.mkdirs(dir); 98 hdfs.setAcl(dir, Lists.newArrayList( 99 aclEntry(DEFAULT, USER, ALL), 100 aclEntry(DEFAULT, USER, "foo", ALL), 101 aclEntry(DEFAULT, GROUP, READ_EXECUTE), 102 aclEntry(DEFAULT, OTHER, NONE))); 103 writtenAcls.put(dir.toString(), hdfs.getAclStatus(dir)); 104 105 Path file = new Path("/noAcl"); 106 FSDataOutputStream o = hdfs.create(file); 107 o.write(23); 108 o.close(); 109 writtenAcls.put(file.toString(), hdfs.getAclStatus(file)); 110 111 file = new Path("/withAcl"); 112 o = hdfs.create(file); 113 o.write(23); 114 o.close(); 115 hdfs.setAcl(file, Lists.newArrayList( 116 aclEntry(ACCESS, USER, READ_WRITE), 117 aclEntry(ACCESS, USER, "foo", READ), 118 aclEntry(ACCESS, GROUP, READ), 119 aclEntry(ACCESS, OTHER, NONE))); 120 writtenAcls.put(file.toString(), hdfs.getAclStatus(file)); 121 122 file = new Path("/withSeveralAcls"); 123 o = hdfs.create(file); 124 o.write(23); 125 o.close(); 126 hdfs.setAcl(file, Lists.newArrayList( 127 aclEntry(ACCESS, USER, READ_WRITE), 128 aclEntry(ACCESS, USER, "foo", READ_WRITE), 129 aclEntry(ACCESS, USER, "bar", READ), 130 aclEntry(ACCESS, GROUP, READ), 131 aclEntry(ACCESS, GROUP, "group", READ), 132 aclEntry(ACCESS, OTHER, NONE))); 133 writtenAcls.put(file.toString(), hdfs.getAclStatus(file)); 134 135 // Write results to the fsimage file 136 hdfs.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_ENTER, false); 137 hdfs.saveNamespace(); 138 139 // Determine the location of the fsimage file 140 originalFsimage = FSImageTestUtil.findLatestImageFile(FSImageTestUtil 141 .getFSImage(cluster.getNameNode()).getStorage().getStorageDir(0)); 142 if (originalFsimage == null) { 143 throw new RuntimeException("Didn't generate or can't find fsimage"); 144 } 145 LOG.debug("original FS image file is " + originalFsimage); 146 } finally { 147 if (cluster != null) 148 cluster.shutdown(); 149 } 150 } 151 152 @AfterClass deleteOriginalFSImage()153 public static void deleteOriginalFSImage() throws IOException { 154 if (originalFsimage != null && originalFsimage.exists()) { 155 originalFsimage.delete(); 156 } 157 } 158 159 @Test testWebImageViewerForAcl()160 public void testWebImageViewerForAcl() throws Exception { 161 WebImageViewer viewer = new WebImageViewer( 162 NetUtils.createSocketAddr("localhost:0")); 163 try { 164 viewer.initServer(originalFsimage.getAbsolutePath()); 165 int port = viewer.getPort(); 166 167 // create a WebHdfsFileSystem instance 168 URI uri = new URI("webhdfs://localhost:" + String.valueOf(port)); 169 Configuration conf = new Configuration(); 170 WebHdfsFileSystem webhdfs = (WebHdfsFileSystem)FileSystem.get(uri, conf); 171 172 // GETACLSTATUS operation to a directory without ACL 173 AclStatus acl = webhdfs.getAclStatus(new Path("/dirWithNoAcl")); 174 assertEquals(writtenAcls.get("/dirWithNoAcl"), acl); 175 176 // GETACLSTATUS operation to a directory with a default ACL 177 acl = webhdfs.getAclStatus(new Path("/dirWithDefaultAcl")); 178 assertEquals(writtenAcls.get("/dirWithDefaultAcl"), acl); 179 180 // GETACLSTATUS operation to a file without ACL 181 acl = webhdfs.getAclStatus(new Path("/noAcl")); 182 assertEquals(writtenAcls.get("/noAcl"), acl); 183 184 // GETACLSTATUS operation to a file with a ACL 185 acl = webhdfs.getAclStatus(new Path("/withAcl")); 186 assertEquals(writtenAcls.get("/withAcl"), acl); 187 188 // GETACLSTATUS operation to a file with several ACL entries 189 acl = webhdfs.getAclStatus(new Path("/withSeveralAcls")); 190 assertEquals(writtenAcls.get("/withSeveralAcls"), acl); 191 192 // GETACLSTATUS operation to a invalid path 193 URL url = new URL("http://localhost:" + port + 194 "/webhdfs/v1/invalid/?op=GETACLSTATUS"); 195 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 196 connection.setRequestMethod("GET"); 197 connection.connect(); 198 assertEquals(HttpURLConnection.HTTP_NOT_FOUND, 199 connection.getResponseCode()); 200 } finally { 201 // shutdown the viewer 202 viewer.close(); 203 } 204 } 205 } 206