我有一个 Spring 引导应用程序,它通过由 Kerberos 保护的 Apache Knox 保护的 Webhdfs 访问 HDFS。我KnoxWebHdfsFileSystem
使用自定义方案 ( swebhdfsknox ) 创建了自己的子类WebHdfsFilesystem
,它只更改 URL 以包含 Knox 代理前缀。所以它有效地重新映射来自表单的请求:
http://host:port/webhdfs/v1/...
到诺克斯一号:
http://host:port/gateway/default/webhdfs/v1/...
我通过覆盖两种方法来做到这一点:
public URI getUri()
URL toUrl(Op op, Path fspath, Param<?, ?>... parameters)
到现在为止还挺好。我让 spring bootFsShell
为我创建并将其用于各种操作,例如列表文件、mkdir等。一切正常。除了copyFromLocal,如文档所述,它需要 2 个步骤和重定向。最后一步,当文件系统尝试访问在LocationPUT
标头中接收到的最终 URL时,它会失败并出现错误:
org.apache.hadoop.security.AccessControlException: Authentication required
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem.validateResponse(WebHdfsFileSystem.java:334) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem.access$200(WebHdfsFileSystem.java:91) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.hdfs.web.WebHdfsFileSystem$FsPathOutputStreamRunner$1.close(WebHdfsFileSystem.java:787) ~[hadoop-hdfs-2.6.0.jar:na]
at org.apache.hadoop.io.IOUtils.copyBytes(IOUtils.java:54) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.io.IOUtils.copyBytes(IOUtils.java:112) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:366) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:338) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:302) ~[hadoop-common-2.6.0.jar:na]
at org.apache.hadoop.fs.FileSystem.copyFromLocalFile(FileSystem.java:1889) ~[hadoop-common-2.6.0.jar:na]
at org.springframework.data.hadoop.fs.FsShell.copyFromLocal(FsShell.java:265) ~[spring-data-hadoop-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.data.hadoop.fs.FsShell.copyFromLocal(FsShell.java:254) ~[spring-data-hadoop-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
我怀疑问题出在重定向,但无法弄清楚这里可能存在什么问题。如果我通过curl执行相同的请求,则文件成功上传到 HDFS。