You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ar...@apache.org on 2015/06/26 23:39:03 UTC
[08/19] hadoop git commit: HDFS-8462. Implement GETXATTRS and
LISTXATTRS operations for WebImageViewer. Contributed by Jagadesh Kiran N.
HDFS-8462. Implement GETXATTRS and LISTXATTRS operations for WebImageViewer. Contributed by Jagadesh Kiran N.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/bc433908
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/bc433908
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/bc433908
Branch: refs/heads/HDFS-7240
Commit: bc433908d35758ff0a7225cd6f5662959ef4d294
Parents: b381f88
Author: Akira Ajisaka <aa...@apache.org>
Authored: Fri Jun 26 00:20:12 2015 +0900
Committer: Akira Ajisaka <aa...@apache.org>
Committed: Fri Jun 26 00:20:12 2015 +0900
----------------------------------------------------------------------
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +
.../offlineImageViewer/FSImageHandler.java | 57 ++--
.../tools/offlineImageViewer/FSImageLoader.java | 75 +++++-
.../src/site/markdown/HdfsImageViewer.md | 2 +
.../TestOfflineImageViewerForXAttr.java | 262 +++++++++++++++++++
5 files changed, 380 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/bc433908/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
index 4268154..e5c30bd 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
+++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
@@ -666,6 +666,9 @@ Release 2.8.0 - UNRELEASED
HDFS-8639. Add Option for NameNode HTTP port in MiniDFSClusterManager.
(Kai Sasaki via jing9)
+ HDFS-8462. Implement GETXATTRS and LISTXATTRS operations for WebImageViewer.
+ (Jagadesh Kiran N via aajisaka)
+
OPTIMIZATIONS
HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than
http://git-wip-us.apache.org/repos/asf/hadoop/blob/bc433908/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageHandler.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageHandler.java
index 37db8b7..da02805 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageHandler.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageHandler.java
@@ -22,6 +22,7 @@ import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaderValues.CLOSE;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
+import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
@@ -74,10 +75,10 @@ class FSImageHandler extends SimpleChannelInboundHandler<HttpRequest> {
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpRequest request)
- throws Exception {
+ throws Exception {
if (request.method() != HttpMethod.GET) {
DefaultHttpResponse resp = new DefaultHttpResponse(HTTP_1_1,
- METHOD_NOT_ALLOWED);
+ METHOD_NOT_ALLOWED);
resp.headers().set(CONNECTION, CLOSE);
ctx.write(resp).addListener(ChannelFutureListener.CLOSE);
return;
@@ -89,25 +90,33 @@ class FSImageHandler extends SimpleChannelInboundHandler<HttpRequest> {
final String content;
String path = getPath(decoder);
switch (op) {
- case "GETFILESTATUS":
- content = image.getFileStatus(path);
- break;
- case "LISTSTATUS":
- content = image.listStatus(path);
- break;
- case "GETACLSTATUS":
- content = image.getAclStatus(path);
- break;
- default:
- throw new IllegalArgumentException(
- "Invalid value for webhdfs parameter" + " \"op\"");
+ case "GETFILESTATUS":
+ content = image.getFileStatus(path);
+ break;
+ case "LISTSTATUS":
+ content = image.listStatus(path);
+ break;
+ case "GETACLSTATUS":
+ content = image.getAclStatus(path);
+ break;
+ case "GETXATTRS":
+ List<String> names = getXattrNames(decoder);
+ String encoder = getEncoder(decoder);
+ content = image.getXAttrs(path, names, encoder);
+ break;
+ case "LISTXATTRS":
+ content = image.listXAttrs(path);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid value for webhdfs parameter"
+ + " \"op\"");
}
LOG.info("op=" + op + " target=" + path);
- DefaultFullHttpResponse resp = new DefaultFullHttpResponse(
- HTTP_1_1, HttpResponseStatus.OK,
- Unpooled.wrappedBuffer(content.getBytes(Charsets.UTF_8)));
+ DefaultFullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1,
+ HttpResponseStatus.OK, Unpooled.wrappedBuffer(content
+ .getBytes(Charsets.UTF_8)));
resp.headers().set(CONTENT_TYPE, APPLICATION_JSON_UTF8);
resp.headers().set(CONTENT_LENGTH, resp.content().readableBytes());
resp.headers().set(CONNECTION, CLOSE);
@@ -134,8 +143,9 @@ class FSImageHandler extends SimpleChannelInboundHandler<HttpRequest> {
resp.setStatus(BAD_REQUEST);
} else if (e instanceof FileNotFoundException) {
resp.setStatus(NOT_FOUND);
+ } else if (e instanceof IOException) {
+ resp.setStatus(FORBIDDEN);
}
-
resp.headers().set(CONTENT_LENGTH, resp.content().readableBytes());
resp.headers().set(CONNECTION, CLOSE);
ctx.write(resp).addListener(ChannelFutureListener.CLOSE);
@@ -147,6 +157,17 @@ class FSImageHandler extends SimpleChannelInboundHandler<HttpRequest> {
? StringUtils.toUpperCase(parameters.get("op").get(0)) : null;
}
+ private static List<String> getXattrNames(QueryStringDecoder decoder) {
+ Map<String, List<String>> parameters = decoder.parameters();
+ return parameters.get("xattr.name");
+ }
+
+ private static String getEncoder(QueryStringDecoder decoder) {
+ Map<String, List<String>> parameters = decoder.parameters();
+ return parameters.containsKey("encoding") ? parameters.get("encoding").get(
+ 0) : null;
+ }
+
private static String getPath(QueryStringDecoder decoder)
throws FileNotFoundException {
String path = decoder.path();
http://git-wip-us.apache.org/repos/asf/hadoop/blob/bc433908/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java
index 351ff03..2a11734 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java
@@ -18,7 +18,6 @@
package org.apache.hadoop.hdfs.tools.offlineImageViewer;
import java.io.BufferedInputStream;
-import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -38,10 +37,12 @@ import com.google.protobuf.InvalidProtocolBufferException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.XAttr;
import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.permission.AclStatus;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.permission.PermissionStatus;
+import org.apache.hadoop.hdfs.XAttrHelper;
import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos;
import org.apache.hadoop.hdfs.server.namenode.FSImageFormatPBINode;
import org.apache.hadoop.hdfs.server.namenode.FSImageFormatProtobuf;
@@ -49,6 +50,7 @@ import org.apache.hadoop.hdfs.server.namenode.FSImageUtil;
import org.apache.hadoop.hdfs.server.namenode.FsImageProto;
import org.apache.hadoop.hdfs.server.namenode.INodeId;
import org.apache.hadoop.hdfs.web.JsonUtil;
+import org.apache.hadoop.hdfs.web.resources.XAttrEncodingParam;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.LimitInputStream;
import org.codehaus.jackson.map.ObjectMapper;
@@ -309,6 +311,77 @@ class FSImageLoader {
}
/**
+ * Return the JSON formatted XAttrNames of the specified file.
+ *
+ * @param path
+ * a path specifies a file
+ * @return JSON formatted XAttrNames
+ * @throws IOException
+ * if failed to serialize fileStatus to JSON.
+ */
+ String listXAttrs(String path) throws IOException {
+ return JsonUtil.toJsonString(getXAttrList(path));
+ }
+
+ /**
+ * Return the JSON formatted XAttrs of the specified file.
+ *
+ * @param path
+ * a path specifies a file
+ * @return JSON formatted XAttrs
+ * @throws IOException
+ * if failed to serialize fileStatus to JSON.
+ */
+ String getXAttrs(String path, List<String> names, String encoder)
+ throws IOException {
+
+ List<XAttr> xAttrs = getXAttrList(path);
+ List<XAttr> filtered;
+ if (names == null || names.size() == 0) {
+ filtered = xAttrs;
+ } else {
+ filtered = Lists.newArrayListWithCapacity(names.size());
+ for (String name : names) {
+ XAttr search = XAttrHelper.buildXAttr(name);
+
+ boolean found = false;
+ for (XAttr aXAttr : xAttrs) {
+ if (aXAttr.getNameSpace() == search.getNameSpace()
+ && aXAttr.getName().equals(search.getName())) {
+
+ filtered.add(aXAttr);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new IOException(
+ "At least one of the attributes provided was not found.");
+ }
+ }
+
+ }
+ return JsonUtil.toJsonString(filtered,
+ new XAttrEncodingParam(encoder).getEncoding());
+ }
+
+ private List<XAttr> getXAttrList(String path) throws IOException {
+ long id = lookup(path);
+ FsImageProto.INodeSection.INode inode = fromINodeId(id);
+ switch (inode.getType()) {
+ case FILE:
+ return FSImageFormatPBINode.Loader.loadXAttrs(
+ inode.getFile().getXAttrs(), stringTable);
+ case DIRECTORY:
+ return FSImageFormatPBINode.Loader.loadXAttrs(inode.getDirectory()
+ .getXAttrs(), stringTable);
+ default:
+ return null;
+ }
+ }
+
+ /**
* Return the JSON formatted ACL status of the specified file.
* @param path a path specifies a file
* @return JSON formatted AclStatus
http://git-wip-us.apache.org/repos/asf/hadoop/blob/bc433908/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HdfsImageViewer.md
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HdfsImageViewer.md b/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HdfsImageViewer.md
index e3952cd..9b9d80a 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HdfsImageViewer.md
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HdfsImageViewer.md
@@ -98,6 +98,8 @@ The Web processor now supports the following operations:
* [LISTSTATUS](./WebHDFS.html#List_a_Directory)
* [GETFILESTATUS](./WebHDFS.html#Status_of_a_FileDirectory)
* [GETACLSTATUS](./WebHDFS.html#Get_ACL_Status)
+* [GETXATTRS](./WebHDFS.html#Get_an_XAttr)
+* [LISTXATTRS](./WebHDFS.html#List_all_XAttrs)
### XML Processor
http://git-wip-us.apache.org/repos/asf/hadoop/blob/bc433908/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/TestOfflineImageViewerForXAttr.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/TestOfflineImageViewerForXAttr.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/TestOfflineImageViewerForXAttr.java
new file mode 100644
index 0000000..3f23f64
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/TestOfflineImageViewerForXAttr.java
@@ -0,0 +1,262 @@
+/**
+ * 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.hadoop.hdfs.tools.offlineImageViewer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.XAttr;
+import org.apache.hadoop.hdfs.DistributedFileSystem;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.hdfs.XAttrHelper;
+import org.apache.hadoop.hdfs.protocol.HdfsConstants;
+import org.apache.hadoop.hdfs.server.namenode.FSImageTestUtil;
+import org.apache.hadoop.hdfs.web.JsonUtil;
+import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
+import org.apache.hadoop.net.NetUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests OfflineImageViewer if the input fsimage has XAttributes
+ */
+public class TestOfflineImageViewerForXAttr {
+
+ private static final Log LOG = LogFactory
+ .getLog(TestOfflineImageViewerForXAttr.class);
+
+ private static File originalFsimage = null;
+
+ static String attr1JSon;
+
+ /**
+ * Create a populated namespace for later testing. Save its contents to a data
+ * structure and store its fsimage location. We only want to generate the
+ * fsimage file once and use it for multiple tests.
+ */
+ @BeforeClass
+ public static void createOriginalFSImage() throws IOException {
+ MiniDFSCluster cluster = null;
+ Configuration conf = new Configuration();
+
+ try {
+ cluster = new MiniDFSCluster.Builder(conf).build();
+ cluster.waitActive();
+ DistributedFileSystem hdfs = cluster.getFileSystem();
+ // Create a name space with XAttributes
+ Path dir = new Path("/dir1");
+ hdfs.mkdirs(dir);
+ hdfs.setXAttr(dir, "user.attr1", "value1".getBytes());
+ hdfs.setXAttr(dir, "user.attr2", "value2".getBytes());
+ // Write results to the fsimage file
+ hdfs.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_ENTER, false);
+ hdfs.saveNamespace();
+
+ List<XAttr> attributes = new ArrayList<XAttr>();
+ attributes.add(XAttrHelper.buildXAttr("user.attr1", "value1".getBytes()));
+
+ attr1JSon = JsonUtil.toJsonString(attributes, null);
+
+ attributes.add(XAttrHelper.buildXAttr("user.attr2", "value2".getBytes()));
+
+ // Determine the location of the fsimage file
+ originalFsimage = FSImageTestUtil.findLatestImageFile(FSImageTestUtil
+ .getFSImage(cluster.getNameNode()).getStorage().getStorageDir(0));
+ if (originalFsimage == null) {
+ throw new RuntimeException("Didn't generate or can't find fsimage");
+ }
+ LOG.debug("original FS image file is " + originalFsimage);
+ } finally {
+ if (cluster != null)
+ cluster.shutdown();
+ }
+ }
+
+ @AfterClass
+ public static void deleteOriginalFSImage() throws IOException {
+ if (originalFsimage != null && originalFsimage.exists()) {
+ originalFsimage.delete();
+ }
+ }
+
+ @Test
+ public void testWebImageViewerForListXAttrs() throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ URL url = new URL("http://localhost:" + port
+ + "/webhdfs/v1/dir1/?op=LISTXATTRS");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+
+ String content = IOUtils.toString(connection.getInputStream());
+
+ assertTrue("Missing user.attr1 in response ",
+ content.contains("user.attr1"));
+ assertTrue("Missing user.attr2 in response ",
+ content.contains("user.attr2"));
+
+ }
+ }
+
+ @Test
+ public void testWebImageViewerForGetXAttrsWithOutParameters()
+ throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ URL url = new URL("http://localhost:" + port
+ + "/webhdfs/v1/dir1/?op=GETXATTRS");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ String content = IOUtils.toString(connection.getInputStream());
+
+ assertTrue("Missing user.attr1 in response ",
+ content.contains("user.attr1"));
+ assertTrue("Missing user.attr2 in response ",
+ content.contains("user.attr2"));
+ }
+ }
+
+ @Test
+ public void testWebImageViewerForGetXAttrsWithParameters() throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ URL url = new URL("http://localhost:" + port
+ + "/webhdfs/v1/dir1/?op=GETXATTRS&xattr.name=attr8");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_BAD_REQUEST,
+ connection.getResponseCode());
+
+ url = new URL("http://localhost:" + port
+ + "/webhdfs/v1/dir1/?op=GETXATTRS&xattr.name=user.attr1");
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ String content = IOUtils.toString(connection.getInputStream());
+ assertEquals(attr1JSon, content);
+ }
+ }
+
+ @Test
+ public void testWebImageViewerForGetXAttrsWithCodecParameters()
+ throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ URL url = new URL(
+ "http://localhost:"
+ + port
+ + "/webhdfs/v1/dir1/?op=GETXATTRS&xattr.name=USER.attr1&encoding=TEXT");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ String content = IOUtils.toString(connection.getInputStream());
+ assertEquals(attr1JSon, content);
+
+ }
+ }
+
+ @Test
+ public void testWithWebHdfsFileSystem() throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ // create a WebHdfsFileSystem instance
+ URI uri = new URI("webhdfs://localhost:" + String.valueOf(port));
+ Configuration conf = new Configuration();
+ WebHdfsFileSystem webhdfs = (WebHdfsFileSystem) FileSystem.get(uri, conf);
+
+ List<String> names = webhdfs.listXAttrs(new Path("/dir1"));
+ assertTrue(names.contains("user.attr1"));
+ assertTrue(names.contains("user.attr2"));
+
+ String value = new String(webhdfs.getXAttr(new Path("/dir1"),
+ "user.attr1"));
+ assertEquals("value1", value);
+
+ Map<String, byte[]> contentMap = webhdfs.getXAttrs(new Path("/dir1"),
+ names);
+
+ assertEquals("value1", new String(contentMap.get("user.attr1")));
+ assertEquals("value2", new String(contentMap.get("user.attr2")));
+ }
+ }
+
+ @Test
+ public void testResponseCode() throws Exception {
+ try (WebImageViewer viewer = new WebImageViewer(
+ NetUtils.createSocketAddr("localhost:0"))) {
+ viewer.initServer(originalFsimage.getAbsolutePath());
+ int port = viewer.getPort();
+
+ URL url = new URL(
+ "http://localhost:"
+ + port
+ + "/webhdfs/v1/dir1/?op=GETXATTRS&xattr.name=user.notpresent&encoding=TEXT");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ assertEquals(HttpURLConnection.HTTP_FORBIDDEN,
+ connection.getResponseCode());
+
+ }
+ }
+}