YARN-165. RM should point tracking URL to RM web page for app when AM fails (jlowe via bobby)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1404211 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Joseph Evans 2012-10-31 15:47:11 +00:00
parent aac5c149c7
commit c15c192ad0
4 changed files with 59 additions and 21 deletions

View File

@ -187,6 +187,9 @@ Release 0.23.5 - UNRELEASED
YARN-139. Interrupted Exception within AsyncDispatcher leads to user YARN-139. Interrupted Exception within AsyncDispatcher leads to user
confusion. (Vinod Kumar Vavilapalli via jlowe) confusion. (Vinod Kumar Vavilapalli via jlowe)
YARN-165. RM should point tracking URL to RM web page for app when AM fails
(jlowe via bobby)
Release 0.23.4 - UNRELEASED Release 0.23.4 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -531,7 +531,7 @@ public class RMAppImpl implements RMApp {
RMAppAttempt attempt = new RMAppAttemptImpl(appAttemptId, RMAppAttempt attempt = new RMAppAttemptImpl(appAttemptId,
clientTokenStr, rmContext, scheduler, masterService, clientTokenStr, rmContext, scheduler, masterService,
submissionContext, YarnConfiguration.getProxyHostAndPort(conf)); submissionContext, conf);
attempts.put(appAttemptId, attempt); attempts.put(appAttemptId, attempt);
currentAttempt = attempt; currentAttempt = attempt;
handler.handle( handler.handle(

View File

@ -18,6 +18,8 @@
package org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt; package org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt;
import static org.apache.hadoop.yarn.util.StringHelper.pjoin;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
@ -33,6 +35,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.http.HttpConfig; import org.apache.hadoop.http.HttpConfig;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport; import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
@ -45,6 +48,7 @@ import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.Priority; import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.ResourceRequest; import org.apache.hadoop.yarn.api.records.ResourceRequest;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.event.EventHandler; import org.apache.hadoop.yarn.event.EventHandler;
import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
@ -128,7 +132,7 @@ public class RMAppAttemptImpl implements RMAppAttempt {
private FinalApplicationStatus finalStatus = null; private FinalApplicationStatus finalStatus = null;
private final StringBuilder diagnostics = new StringBuilder(); private final StringBuilder diagnostics = new StringBuilder();
private final String proxy; private Configuration conf;
private static final StateMachineFactory<RMAppAttemptImpl, private static final StateMachineFactory<RMAppAttemptImpl,
RMAppAttemptState, RMAppAttemptState,
@ -285,9 +289,9 @@ public class RMAppAttemptImpl implements RMAppAttempt {
String clientToken, RMContext rmContext, YarnScheduler scheduler, String clientToken, RMContext rmContext, YarnScheduler scheduler,
ApplicationMasterService masterService, ApplicationMasterService masterService,
ApplicationSubmissionContext submissionContext, ApplicationSubmissionContext submissionContext,
String proxy) { Configuration conf) {
this.proxy = proxy; this.conf = conf;
this.applicationAttemptId = appAttemptId; this.applicationAttemptId = appAttemptId;
this.rmContext = rmContext; this.rmContext = rmContext;
this.eventHandler = rmContext.getDispatcher().getEventHandler(); this.eventHandler = rmContext.getDispatcher().getEventHandler();
@ -397,6 +401,7 @@ public class RMAppAttemptImpl implements RMAppAttempt {
try { try {
URI trackingUri = trackingUriWithoutScheme == null ? null : URI trackingUri = trackingUriWithoutScheme == null ? null :
ProxyUriUtils.getUriFromAMUrl(trackingUriWithoutScheme); ProxyUriUtils.getUriFromAMUrl(trackingUriWithoutScheme);
String proxy = YarnConfiguration.getProxyHostAndPort(conf);
URI proxyUri = ProxyUriUtils.getUriFromAMUrl(proxy); URI proxyUri = ProxyUriUtils.getUriFromAMUrl(proxy);
URI result = ProxyUriUtils.getProxyUri(trackingUri, proxyUri, URI result = ProxyUriUtils.getProxyUri(trackingUri, proxyUri,
applicationAttemptId.getApplicationId()); applicationAttemptId.getApplicationId());
@ -977,15 +982,13 @@ public class RMAppAttemptImpl implements RMAppAttempt {
" due to: " + containerStatus.getDiagnostics() + "." + " due to: " + containerStatus.getDiagnostics() + "." +
"Failing this attempt."); "Failing this attempt.");
/* // When the AM dies, the trackingUrl is left pointing to the AM's URL,
* In the case when the AM dies, the trackingUrl is left pointing to the AM's // which shows up in the scheduler UI as a broken link. Direct the
* URL, which shows up in the scheduler UI as a broken link. Setting it here // user to the app page on the RM so they can see the status and logs.
* to empty string will prevent any link from being displayed. appAttempt.origTrackingUrl = pjoin(
* NOTE: don't set trackingUrl to 'null'. That will cause null-pointer exceptions YarnConfiguration.getRMWebAppHostAndPort(appAttempt.conf),
* in the generated proto code. "cluster", "app", appAttempt.getAppAttemptId().getApplicationId());
*/ appAttempt.proxiedTrackingUrl = appAttempt.origTrackingUrl;
appAttempt.origTrackingUrl = "";
appAttempt.proxiedTrackingUrl = "";
new FinalTransition(RMAppAttemptState.FAILED).transition( new FinalTransition(RMAppAttemptState.FAILED).transition(
appAttempt, containerFinishedEvent); appAttempt, containerFinishedEvent);

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt; package org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt;
import static org.apache.hadoop.yarn.util.StringHelper.pjoin;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -43,6 +44,7 @@ import org.apache.hadoop.yarn.api.records.ContainerState;
import org.apache.hadoop.yarn.api.records.ContainerStatus; import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.event.AsyncDispatcher; import org.apache.hadoop.yarn.event.AsyncDispatcher;
import org.apache.hadoop.yarn.event.EventHandler; import org.apache.hadoop.yarn.event.EventHandler;
import org.apache.hadoop.yarn.server.resourcemanager.ApplicationMasterService; import org.apache.hadoop.yarn.server.resourcemanager.ApplicationMasterService;
@ -85,6 +87,8 @@ public class TestRMAppAttemptTransitions {
LogFactory.getLog(TestRMAppAttemptTransitions.class); LogFactory.getLog(TestRMAppAttemptTransitions.class);
private static final String EMPTY_DIAGNOSTICS = ""; private static final String EMPTY_DIAGNOSTICS = "";
private static final String RM_WEBAPP_ADDR =
YarnConfiguration.getRMWebAppHostAndPort(new Configuration());
private RMContext rmContext; private RMContext rmContext;
private YarnScheduler scheduler; private YarnScheduler scheduler;
@ -203,7 +207,7 @@ public class TestRMAppAttemptTransitions {
application = mock(RMApp.class); application = mock(RMApp.class);
applicationAttempt = applicationAttempt =
new RMAppAttemptImpl(applicationAttemptId, null, rmContext, scheduler, new RMAppAttemptImpl(applicationAttemptId, null, rmContext, scheduler,
masterService, submissionContext, null); masterService, submissionContext, new Configuration());
when(application.getCurrentAppAttempt()).thenReturn(applicationAttempt); when(application.getCurrentAppAttempt()).thenReturn(applicationAttempt);
when(application.getApplicationId()).thenReturn(applicationId); when(application.getApplicationId()).thenReturn(applicationId);
@ -216,6 +220,11 @@ public class TestRMAppAttemptTransitions {
} }
private String getProxyUrl(RMAppAttempt appAttempt) {
return pjoin(RM_WEBAPP_ADDR, "proxy",
appAttempt.getAppAttemptId().getApplicationId(), "");
}
/** /**
* {@link RMAppAttemptState#NEW} * {@link RMAppAttemptState#NEW}
*/ */
@ -373,8 +382,8 @@ public class TestRMAppAttemptTransitions {
assertEquals(host, applicationAttempt.getHost()); assertEquals(host, applicationAttempt.getHost());
assertEquals(rpcPort, applicationAttempt.getRpcPort()); assertEquals(rpcPort, applicationAttempt.getRpcPort());
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl()); assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
assertEquals("null/proxy/"+applicationAttempt.getAppAttemptId(). assertEquals(getProxyUrl(applicationAttempt),
getApplicationId()+"/", applicationAttempt.getTrackingUrl()); applicationAttempt.getTrackingUrl());
// TODO - need to add more checks relevant to this state // TODO - need to add more checks relevant to this state
} }
@ -390,8 +399,8 @@ public class TestRMAppAttemptTransitions {
applicationAttempt.getAppAttemptState()); applicationAttempt.getAppAttemptState());
assertEquals(diagnostics, applicationAttempt.getDiagnostics()); assertEquals(diagnostics, applicationAttempt.getDiagnostics());
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl()); assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
assertEquals("null/proxy/"+applicationAttempt.getAppAttemptId(). assertEquals(getProxyUrl(applicationAttempt),
getApplicationId()+"/", applicationAttempt.getTrackingUrl()); applicationAttempt.getTrackingUrl());
assertEquals(container, applicationAttempt.getMasterContainer()); assertEquals(container, applicationAttempt.getMasterContainer());
assertEquals(finalStatus, applicationAttempt.getFinalApplicationStatus()); assertEquals(finalStatus, applicationAttempt.getFinalApplicationStatus());
} }
@ -408,8 +417,8 @@ public class TestRMAppAttemptTransitions {
applicationAttempt.getAppAttemptState()); applicationAttempt.getAppAttemptState());
assertEquals(diagnostics, applicationAttempt.getDiagnostics()); assertEquals(diagnostics, applicationAttempt.getDiagnostics());
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl()); assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
assertEquals("null/proxy/"+applicationAttempt.getAppAttemptId(). assertEquals(getProxyUrl(applicationAttempt),
getApplicationId()+"/", applicationAttempt.getTrackingUrl()); applicationAttempt.getTrackingUrl());
assertEquals(finishedContainerCount, applicationAttempt assertEquals(finishedContainerCount, applicationAttempt
.getJustFinishedContainers().size()); .getJustFinishedContainers().size());
assertEquals(container, applicationAttempt.getMasterContainer()); assertEquals(container, applicationAttempt.getMasterContainer());
@ -596,7 +605,30 @@ public class TestRMAppAttemptTransitions {
diagnostics)); diagnostics));
testAppAttemptFailedState(amContainer, diagnostics); testAppAttemptFailedState(amContainer, diagnostics);
} }
@Test
public void testRunningToFailed() {
Container amContainer = allocateApplicationAttempt();
launchApplicationAttempt(amContainer);
runApplicationAttempt(amContainer, "host", 8042, "oldtrackingurl");
String containerDiagMsg = "some error";
int exitCode = 123;
ContainerStatus cs = BuilderUtils.newContainerStatus(amContainer.getId(),
ContainerState.COMPLETE, containerDiagMsg, exitCode);
ApplicationAttemptId appAttemptId = applicationAttempt.getAppAttemptId();
applicationAttempt.handle(new RMAppAttemptContainerFinishedEvent(
appAttemptId, cs));
assertEquals(RMAppAttemptState.FAILED,
applicationAttempt.getAppAttemptState());
assertEquals(0,applicationAttempt.getJustFinishedContainers().size());
assertEquals(amContainer, applicationAttempt.getMasterContainer());
assertEquals(0, applicationAttempt.getRanNodes().size());
String rmAppPageUrl = pjoin(RM_WEBAPP_ADDR, "cluster", "app",
applicationAttempt.getAppAttemptId().getApplicationId());
assertEquals(rmAppPageUrl, applicationAttempt.getOriginalTrackingUrl());
assertEquals(rmAppPageUrl, applicationAttempt.getTrackingUrl());
}
@Test @Test
public void testUnregisterToKilledFinishing() { public void testUnregisterToKilledFinishing() {
Container amContainer = allocateApplicationAttempt(); Container amContainer = allocateApplicationAttempt();