diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 20ca49a16c8..70a823dd86e 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -168,6 +168,8 @@ Release 2.5.0 - UNRELEASED YARN-2103. Inconsistency between viaProto flag and initial value of SerializedExceptionProto.Builder (Binglin Chang via junping_du) + YARN-1550. NPE in FairSchedulerAppsBlock#render. (Anubhav Dhoot via kasha) + Release 2.4.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerAppsBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerAppsBlock.java index c36e311e384..b1aff9078ca 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerAppsBlock.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerAppsBlock.java @@ -25,6 +25,8 @@ import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE; import java.util.Collection; import java.util.HashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.lang.StringEscapeUtils; @@ -35,6 +37,7 @@ import org.apache.hadoop.yarn.api.records.YarnApplicationState; import org.apache.hadoop.yarn.server.resourcemanager.RMContext; import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler; import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.FairSchedulerInfo; @@ -60,7 +63,14 @@ public class FairSchedulerAppsBlock extends HtmlBlock { super(ctx); FairScheduler scheduler = (FairScheduler) rm.getResourceScheduler(); fsinfo = new FairSchedulerInfo(scheduler); - apps = rmContext.getRMApps(); + apps = new ConcurrentHashMap(); + for (Map.Entry entry : rmContext.getRMApps().entrySet()) { + if (!(RMAppState.NEW.equals(entry.getValue().getState()) + || RMAppState.NEW_SAVING.equals(entry.getValue().getState()) + || RMAppState.SUBMITTED.equals(entry.getValue().getState()))) { + apps.put(entry.getKey(), entry.getValue()); + } + } this.conf = conf; } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebAppFairScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebAppFairScheduler.java new file mode 100644 index 00000000000..1de64896c55 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebAppFairScheduler.java @@ -0,0 +1,116 @@ +/** + * 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.yarn.server.resourcemanager.webapp; + +import com.google.common.collect.Maps; +import com.google.inject.Binder; +import com.google.inject.Injector; +import com.google.inject.Module; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.server.resourcemanager.RMContext; +import org.apache.hadoop.yarn.server.resourcemanager.RMContextImpl; +import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.MockRMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairSchedulerConfiguration; +import org.apache.hadoop.yarn.server.resourcemanager.security.ClientToAMTokenSecretManagerInRM; +import org.apache.hadoop.yarn.server.resourcemanager.security.NMTokenSecretManagerInRM; +import org.apache.hadoop.yarn.server.resourcemanager.security.RMContainerTokenSecretManager; +import org.apache.hadoop.yarn.webapp.test.WebAppTests; +import org.junit.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ConcurrentMap; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class TestRMWebAppFairScheduler { + + @Test + public void testFairSchedulerWebAppPage() { + List appStates = Arrays.asList(RMAppState.NEW, + RMAppState.NEW_SAVING, RMAppState.SUBMITTED); + final RMContext rmContext = mockRMContext(appStates); + Injector injector = WebAppTests.createMockInjector(RMContext.class, + rmContext, + new Module() { + @Override + public void configure(Binder binder) { + try { + ResourceManager mockRmWithFairScheduler = + mockRm(rmContext); + binder.bind(ResourceManager.class).toInstance + (mockRmWithFairScheduler); + + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + }); + FairSchedulerPage fsViewInstance = injector.getInstance(FairSchedulerPage + .class); + fsViewInstance.render(); + WebAppTests.flushOutput(injector); + } + + private static RMContext mockRMContext(List states) { + final ConcurrentMap applicationsMaps = Maps + .newConcurrentMap(); + int i = 0; + for (RMAppState state : states) { + MockRMApp app = new MockRMApp(i, i, state); + applicationsMaps.put(app.getApplicationId(), app); + i++; + } + + return new RMContextImpl(null, null, null, null, + null, null, null, null, null, null) { + @Override + public ConcurrentMap getRMApps() { + return applicationsMaps; + } + }; + } + + private static ResourceManager mockRm(RMContext rmContext) throws + IOException { + ResourceManager rm = mock(ResourceManager.class); + ResourceScheduler rs = mockFairScheduler(); + when(rm.getResourceScheduler()).thenReturn(rs); + when(rm.getRMContext()).thenReturn(rmContext); + return rm; + } + + private static FairScheduler mockFairScheduler() throws IOException { + FairScheduler fs = new FairScheduler(); + FairSchedulerConfiguration conf = new FairSchedulerConfiguration(); + fs.setRMContext(new RMContextImpl(null, null, null, null, null, + null, new RMContainerTokenSecretManager(conf), + new NMTokenSecretManagerInRM(conf), + new ClientToAMTokenSecretManagerInRM(), null)); + fs.init(conf); + return fs; + } +}