/*
* Licensed 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 com.github.sakserv.minicluster.impl;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sakserv.minicluster.MiniCluster;
import com.github.sakserv.minicluster.util.FileUtils;
import com.github.sakserv.minicluster.util.WindowsLibsUtils;
public class HdfsLocalCluster implements MiniCluster {
// Logger
private static final Logger LOG = LoggerFactory.getLogger(HdfsLocalCluster.class);
MiniDFSCluster miniDFSCluster;
private Integer hdfsNamenodePort;
private Integer hdfsNamenodeHttpPort;
private String hdfsTempDir;
private Integer hdfsNumDatanodes;
private Boolean hdfsEnablePermissions;
private Boolean hdfsFormat;
private Boolean hdfsEnableRunningUserAsProxyUser;
private Configuration hdfsConfig;
public Integer getHdfsNamenodePort() {
return hdfsNamenodePort;
}
public String getHdfsTempDir() {
return hdfsTempDir;
}
public Integer getHdfsNumDatanodes() {
return hdfsNumDatanodes;
}
public Boolean getHdfsEnablePermissions() {
return hdfsEnablePermissions;
}
public Boolean getHdfsFormat() {
return hdfsFormat;
}
public Boolean getHdfsEnableRunningUserAsProxyUser() {
return hdfsEnableRunningUserAsProxyUser;
}
public Configuration getHdfsConfig() {
return hdfsConfig;
}
private HdfsLocalCluster(Builder builder) {
this.hdfsNamenodePort = builder.hdfsNamenodePort;
this.hdfsNamenodeHttpPort = builder.hdfsNamenodeHttpPort;
this.hdfsTempDir = builder.hdfsTempDir;
this.hdfsNumDatanodes = builder.hdfsNumDatanodes;
this.hdfsEnablePermissions = builder.hdfsEnablePermissions;
this.hdfsFormat = builder.hdfsFormat;
this.hdfsEnableRunningUserAsProxyUser = builder.hdfsEnableRunningUserAsProxyUser;
this.hdfsConfig = builder.hdfsConfig;
}
public static class Builder {
private Integer hdfsNamenodePort;
private Integer hdfsNamenodeHttpPort;
private String hdfsTempDir;
private Integer hdfsNumDatanodes;
private Boolean hdfsEnablePermissions;
private Boolean hdfsFormat;
private Boolean hdfsEnableRunningUserAsProxyUser;
private Configuration hdfsConfig;
public Builder setHdfsNamenodePort(Integer hdfsNameNodePort) {
this.hdfsNamenodePort = hdfsNameNodePort;
return this;
}
public Builder setHdfsNamenodeHttpPort(Integer hdfsNameNodeHttpPort) {
this.hdfsNamenodeHttpPort = hdfsNameNodeHttpPort;
return this;
}
public Builder setHdfsTempDir(String hdfsTempDir) {
this.hdfsTempDir = hdfsTempDir;
return this;
}
public Builder setHdfsNumDatanodes(Integer hdfsNumDatanodes) {
this.hdfsNumDatanodes = hdfsNumDatanodes;
return this;
}
public Builder setHdfsEnablePermissions(Boolean hdfsEnablePermissions) {
this.hdfsEnablePermissions = hdfsEnablePermissions;
return this;
}
public Builder setHdfsFormat(Boolean hdfsFormat) {
this.hdfsFormat = hdfsFormat;
return this;
}
public Builder setHdfsEnableRunningUserAsProxyUser(Boolean hdfsEnableRunningUserAsProxyUser) {
this.hdfsEnableRunningUserAsProxyUser = hdfsEnableRunningUserAsProxyUser;
return this;
}
public Builder setHdfsConfig(Configuration hdfsConfig) {
this.hdfsConfig = hdfsConfig;
return this;
}
public HdfsLocalCluster build() {
HdfsLocalCluster hdfsLocalCluster = new HdfsLocalCluster(this);
validateObject(hdfsLocalCluster);
return hdfsLocalCluster;
}
public void validateObject(HdfsLocalCluster hdfsLocalCluster) {
if(hdfsLocalCluster.hdfsNamenodePort == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Namenode Port");
}
if(hdfsLocalCluster.hdfsTempDir == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Temp Dir");
}
if(hdfsLocalCluster.hdfsNumDatanodes == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Num Datanodes");
}
if(hdfsLocalCluster.hdfsEnablePermissions == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Enable Permissions");
}
if(hdfsLocalCluster.hdfsFormat == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Format");
}
if(hdfsLocalCluster.hdfsConfig == null) {
throw new IllegalArgumentException("ERROR: Missing required config: HDFS Config");
}
}
}
@Override
public void start() throws Exception {
LOG.info("HDFS: Starting MiniDfsCluster");
configure();
miniDFSCluster = new MiniDFSCluster.Builder(hdfsConfig)
.nameNodePort(hdfsNamenodePort)
.nameNodeHttpPort(hdfsNamenodeHttpPort==null? 0 : hdfsNamenodeHttpPort.intValue() )
.numDataNodes(hdfsNumDatanodes)
.format(hdfsFormat)
.racks(null)
.build();
}
@Override
public void stop() throws Exception {
stop(true);
}
@Override
public void stop(boolean cleanUp) throws Exception {
LOG.info("HDFS: Stopping MiniDfsCluster");
miniDFSCluster.shutdown();
if(cleanUp) {
cleanUp();
}
}
@Override
public void configure() throws Exception {
if(null != hdfsEnableRunningUserAsProxyUser && hdfsEnableRunningUserAsProxyUser) {
hdfsConfig.set("hadoop.proxyuser." + System.getProperty("user.name") + ".hosts", "*");
hdfsConfig.set("hadoop.proxyuser." + System.getProperty("user.name") + ".groups", "*");
}
hdfsConfig.setBoolean("dfs.permissions", hdfsEnablePermissions);
System.setProperty("test.build.data", hdfsTempDir);
// Handle Windows
WindowsLibsUtils.setHadoopHome();
}
@Override
public void cleanUp() throws Exception {
FileUtils.deleteFolder(hdfsTempDir);
}
public FileSystem getHdfsFileSystemHandle() throws Exception {
FileSystem hdfsFileSystemHandle = null;
hdfsFileSystemHandle = miniDFSCluster.getFileSystem();
return hdfsFileSystemHandle;
}
}