/* * 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 java.io.File; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.MiniYARNCluster; 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 YarnLocalCluster implements MiniCluster { // Logger private static final Logger LOG = LoggerFactory.getLogger(YarnLocalCluster.class); private String testName = getClass().getName(); private Integer numResourceManagers = 1; private String inJvmContainerExecutorClass = "com.github.sakserv.minicluster.yarn.InJvmContainerExecutor"; private Boolean enableHa = false; private Integer numNodeManagers; private Integer numLocalDirs; private Integer numLogDirs; private String resourceManagerAddress; private String resourceManagerHostname; private String resourceManagerSchedulerAddress; private String resourceManagerResourceTrackerAddress; private String resourceManagerWebappAddress; private Boolean useInJvmContainerExecutor; private Configuration configuration; private MiniYARNCluster miniYARNCluster; public String getTestName() { return testName; } public Integer getNumNodeManagers() { return numNodeManagers; } public Integer getNumLocalDirs() { return numLocalDirs; } public Integer getNumLogDirs() { return numLogDirs; } public String getResourceManagerAddress() { return resourceManagerAddress; } public String getResourceManagerHostname() { return resourceManagerHostname; } public String getResourceManagerSchedulerAddress() { return resourceManagerSchedulerAddress; } public String getResourceManagerResourceTrackerAddress() { return resourceManagerResourceTrackerAddress; } public String getResourceManagerWebappAddress() { return resourceManagerWebappAddress; } public Boolean getUseInJvmContainerExecutor() { return useInJvmContainerExecutor; } public Configuration getConfig() { return configuration; } private YarnLocalCluster(Builder builder) { this.numNodeManagers = builder.numNodeManagers; this.numLocalDirs = builder.numLocalDirs; this.numLogDirs = builder.numLogDirs; this.resourceManagerAddress = builder.resourceManagerAddress; this.resourceManagerHostname = builder.resourceManagerHostname; this.resourceManagerSchedulerAddress = builder.resourceManagerSchedulerAddress; this.resourceManagerResourceTrackerAddress = builder.resourceManagerResourceTrackerAddress; this.resourceManagerWebappAddress = builder.resourceManagerWebappAddress; this.useInJvmContainerExecutor = builder.useInJvmContainerExecutor; this.configuration = builder.configuration; } public static class Builder { private Integer numNodeManagers; private Integer numLocalDirs; private Integer numLogDirs; private String resourceManagerAddress; private String resourceManagerHostname; private String resourceManagerSchedulerAddress; private String resourceManagerResourceTrackerAddress; private String resourceManagerWebappAddress; private Boolean useInJvmContainerExecutor; private Configuration configuration; public Builder setNumNodeManagers(Integer numNodeManagers) { this.numNodeManagers = numNodeManagers; return this; } public Builder setNumLocalDirs(Integer numLocalDirs) { this.numLocalDirs = numLocalDirs; return this; } public Builder setNumLogDirs(Integer numLogDirs) { this.numLogDirs = numLogDirs; return this; } public Builder setResourceManagerAddress(String resourceManagerAddress) { this.resourceManagerAddress = resourceManagerAddress; return this; } public Builder setResourceManagerHostname(String resourceManagerHostname) { this.resourceManagerHostname = resourceManagerHostname; return this; } public Builder setResourceManagerSchedulerAddress(String resourceManagerSchedulerAddress) { this.resourceManagerSchedulerAddress = resourceManagerSchedulerAddress; return this; } public Builder setResourceManagerResourceTrackerAddress(String resourceManagerResourceTrackerAddress) { this.resourceManagerResourceTrackerAddress = resourceManagerResourceTrackerAddress; return this; } public Builder setResourceManagerWebappAddress(String resourceManagerWebappAddress) { this.resourceManagerWebappAddress = resourceManagerWebappAddress; return this; } public Builder setUseInJvmContainerExecutor(Boolean useInJvmContainerExecutor) { this.useInJvmContainerExecutor = useInJvmContainerExecutor; return this; } public Builder setConfig(Configuration configuration) { this.configuration = configuration; return this; } public YarnLocalCluster build() { YarnLocalCluster yarnLocalCluster = new YarnLocalCluster(this); validateObject(yarnLocalCluster); return yarnLocalCluster; } public void validateObject(YarnLocalCluster yarnLocalCluster) { if (yarnLocalCluster.getNumNodeManagers() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Number of Node Managers"); } if (yarnLocalCluster.getNumLocalDirs() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Number of Local Dirs"); } if (yarnLocalCluster.getNumLogDirs() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Number of Log Dirs"); } if(yarnLocalCluster.getResourceManagerAddress() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Yarn Resource Manager Address"); } if(yarnLocalCluster.getResourceManagerHostname() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Yarn Resource Manager Hostname"); } if(yarnLocalCluster.getResourceManagerSchedulerAddress() == null) { throw new IllegalArgumentException("ERROR: Missing required config: " + "Yarn Resource Manager Scheduler Address"); } if(yarnLocalCluster.getResourceManagerResourceTrackerAddress() == null) { throw new IllegalArgumentException("ERROR: Missing required config: " + "Yarn Resource Manager Resource Tracker Address"); } if(yarnLocalCluster.getResourceManagerWebappAddress() == null) { throw new IllegalArgumentException("ERROR: Missing required config: " + "Yarn Resource Manager Webapp Address"); } if(yarnLocalCluster.getUseInJvmContainerExecutor() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Use In JVM Container Executor"); } if (yarnLocalCluster.getConfig() == null) { throw new IllegalArgumentException("ERROR: Missing required config: Configuration"); } } } @Override public void start() throws Exception { LOG.info("YARN: Starting MiniYarnCluster"); configure(); miniYARNCluster = new MiniYARNCluster(testName, numResourceManagers, numNodeManagers, numLocalDirs, numLogDirs, enableHa); miniYARNCluster.serviceInit(configuration); miniYARNCluster.init(configuration); miniYARNCluster.start(); } @Override public void stop() throws Exception { stop(true); } @Override public void stop(boolean cleanUp) throws Exception { LOG.info("YARN: Stopping MiniYarnCluster"); miniYARNCluster.stop(); if(cleanUp) { cleanUp(); } } @Override public void configure() throws Exception { // Handle Windows WindowsLibsUtils.setHadoopHome(); configuration.set(YarnConfiguration.RM_ADDRESS, resourceManagerAddress); configuration.set(YarnConfiguration.RM_HOSTNAME, resourceManagerHostname); configuration.set(YarnConfiguration.RM_SCHEDULER_ADDRESS, resourceManagerSchedulerAddress); configuration.set(YarnConfiguration.RM_RESOURCE_TRACKER_ADDRESS, resourceManagerResourceTrackerAddress); configuration.set(YarnConfiguration.RM_WEBAPP_ADDRESS, resourceManagerWebappAddress); configuration.set(YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, "true"); if (getUseInJvmContainerExecutor()) { configuration.set(YarnConfiguration.NM_CONTAINER_EXECUTOR, inJvmContainerExecutorClass); configuration.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()); configuration.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName()); } } @Override public void cleanUp() throws Exception { // Depending on if we are running in the module or the parent // project, the target folder will be in a different location. // We don't want to nuke the entire target directory, unless only // the mini cluster is using it. // A reasonable check to keep things clean is to check for the existence // of ./target/classes and only delete the mini cluster temporary dir if true. // Delete the entire ./target if false if (new File("./target/classes").exists()) { FileUtils.deleteFolder("./target/" + testName); } else { FileUtils.deleteFolder("./target"); } } }