Skip to content

Commit 64d59a0

Browse files
committed
YARN-1157. Fixed ResourceManager UI to behave correctly when apps like distributed-shell do not set tracking urls. Contributed by Xuan Gong.
svn merge --ignore-ancestry -c 1526371 ../../trunk/ git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1526372 13f79535-47bb-0310-9956-ffa450edef68
1 parent a395776 commit 64d59a0

File tree

6 files changed

+115
-106
lines changed

6 files changed

+115
-106
lines changed

hadoop-yarn-project/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ Release 2.1.2 - UNRELEASED
6868
YARN-49. Improve distributed shell application to work on a secure cluster.
6969
(Vinod Kumar Vavilapalli via hitesh)
7070

71+
YARN-1157. Fixed ResourceManager UI to behave correctly when apps like
72+
distributed-shell do not set tracking urls. (Xuan Gong via vinodkv)
73+
7174
Release 2.1.1-beta - 2013-09-23
7275

7376
INCOMPATIBLE CHANGES

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/FinishApplicationMasterRequest.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,22 @@ public static FinishApplicationMasterRequest newInstance(
100100
public abstract String getTrackingUrl();
101101

102102
/**
103-
* Set the <em>tracking URL</em>for the <code>ApplicationMaster</code>
104-
* This url if contains scheme then that will be used by resource manager
105-
* web application proxy otherwise it will default to http.
106-
* @param url <em>tracking URL</em>for the
107-
* <code>ApplicationMaster</code>
103+
* Set the <em>final tracking URL</em>for the <code>ApplicationMaster</code>.
104+
* This is the web-URL to which ResourceManager or web-application proxy will
105+
* redirect client/users once the application is finished and the
106+
* <code>ApplicationMaster</code> is gone.
107+
* <p>
108+
* If the passed url has a scheme then that will be used by the
109+
* ResourceManager and web-application proxy, otherwise the scheme will
110+
* default to http.
111+
* </p>
112+
* <p>
113+
* Empty, null, "N/A" strings are all valid besides a real URL. In case an url
114+
* isn't explicitly passed, it defaults to "N/A" on the ResourceManager.
115+
* <p>
116+
*
117+
* @param url
118+
* <em>tracking URL</em>for the <code>ApplicationMaster</code>
108119
*/
109120
@Public
110121
@Stable

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/RegisterApplicationMasterRequest.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,22 @@ public static RegisterApplicationMasterRequest newInstance(String host,
112112
public abstract String getTrackingUrl();
113113

114114
/**
115-
* Set the <em>tracking URL</em> for the <code>ApplicationMaster</code>.
116-
* This url if contains scheme then that will be used by resource manager
117-
* web application proxy otherwise it will default to http.
118-
* @param trackingUrl <em>tracking URL</em> for the
119-
* <code>ApplicationMaster</code>
115+
* Set the <em>tracking URL</em>for the <code>ApplicationMaster</code> while
116+
* it is running. This is the web-URL to which ResourceManager or
117+
* web-application proxy will redirect client/users while the application and
118+
* the <code>ApplicationMaster</code> are still running.
119+
* <p>
120+
* If the passed url has a scheme then that will be used by the
121+
* ResourceManager and web-application proxy, otherwise the scheme will
122+
* default to http.
123+
* </p>
124+
* <p>
125+
* Empty, null, "N/A" strings are all valid besides a real URL. In case an url
126+
* isn't explicitly passed, it defaults to "N/A" on the ResourceManager.
127+
* <p>
128+
*
129+
* @param trackingUrl
130+
* <em>tracking URL</em>for the <code>ApplicationMaster</code>
120131
*/
121132
@Public
122133
@Stable

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ public void transition(RMAppAttemptImpl appAttempt,
994994
}
995995
}
996996

997-
static final class AMRegisteredTransition extends BaseTransition {
997+
private static final class AMRegisteredTransition extends BaseTransition {
998998
@Override
999999
public void transition(RMAppAttemptImpl appAttempt,
10001000
RMAppAttemptEvent event) {
@@ -1003,7 +1003,8 @@ public void transition(RMAppAttemptImpl appAttempt,
10031003
= (RMAppAttemptRegistrationEvent) event;
10041004
appAttempt.host = registrationEvent.getHost();
10051005
appAttempt.rpcPort = registrationEvent.getRpcport();
1006-
appAttempt.origTrackingUrl = registrationEvent.getTrackingurl();
1006+
appAttempt.origTrackingUrl =
1007+
sanitizeTrackingUrl(registrationEvent.getTrackingurl());
10071008
appAttempt.proxiedTrackingUrl =
10081009
appAttempt.generateProxyUriWithoutScheme(appAttempt.origTrackingUrl);
10091010

@@ -1138,7 +1139,8 @@ public RMAppAttemptState transition(RMAppAttemptImpl appAttempt,
11381139
RMAppAttemptUnregistrationEvent unregisterEvent
11391140
= (RMAppAttemptUnregistrationEvent) event;
11401141
appAttempt.diagnostics.append(unregisterEvent.getDiagnostics());
1141-
appAttempt.origTrackingUrl = unregisterEvent.getTrackingUrl();
1142+
appAttempt.origTrackingUrl =
1143+
sanitizeTrackingUrl(unregisterEvent.getTrackingUrl());
11421144
appAttempt.proxiedTrackingUrl =
11431145
appAttempt.generateProxyUriWithoutScheme(appAttempt.origTrackingUrl);
11441146
appAttempt.finalStatus = unregisterEvent.getFinalApplicationStatus();
@@ -1292,4 +1294,8 @@ private void removeCredentials(RMAppAttemptImpl appAttempt) {
12921294
appAttempt.rmContext.getAMRMTokenSecretManager()
12931295
.applicationMasterFinished(appAttempt.getAppAttemptId());
12941296
}
1297+
1298+
private static String sanitizeTrackingUrl(String url) {
1299+
return (url == null || url.trim().isEmpty()) ? "N/A" : url;
1300+
}
12951301
}

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/TestRMAppAttemptImpl.java

Lines changed: 0 additions & 77 deletions
This file was deleted.

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/TestRMAppAttemptTransitions.java

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@
3030
import static org.mockito.Mockito.verify;
3131
import static org.mockito.Mockito.when;
3232

33+
import java.net.URI;
34+
import java.net.URISyntaxException;
3335
import java.util.Arrays;
3436
import java.util.Collection;
3537
import java.util.Collections;
3638
import java.util.List;
3739

40+
import org.apache.commons.lang.StringUtils;
3841
import org.apache.commons.logging.Log;
3942
import org.apache.commons.logging.LogFactory;
4043
import org.apache.hadoop.conf.Configuration;
44+
import org.apache.hadoop.http.HttpConfig;
4145
import org.apache.hadoop.security.SecurityUtil;
4246
import org.apache.hadoop.security.UserGroupInformation;
4347
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
@@ -85,8 +89,10 @@
8589
import org.apache.hadoop.yarn.server.resourcemanager.security.NMTokenSecretManagerInRM;
8690
import org.apache.hadoop.yarn.server.resourcemanager.security.RMContainerTokenSecretManager;
8791
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
92+
import org.apache.hadoop.yarn.server.webproxy.ProxyUriUtils;
8893
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
8994
import org.junit.After;
95+
import org.junit.Assert;
9096
import org.junit.Before;
9197
import org.junit.Test;
9298
import org.junit.runner.RunWith;
@@ -261,8 +267,22 @@ public void tearDown() throws Exception {
261267

262268

263269
private String getProxyUrl(RMAppAttempt appAttempt) {
264-
return pjoin(RM_WEBAPP_ADDR, "proxy",
265-
appAttempt.getAppAttemptId().getApplicationId(), "");
270+
String url = null;
271+
try {
272+
URI trackingUri =
273+
StringUtils.isEmpty(appAttempt.getOriginalTrackingUrl()) ? null :
274+
ProxyUriUtils
275+
.getUriFromAMUrl(appAttempt.getOriginalTrackingUrl());
276+
String proxy = WebAppUtils.getProxyHostAndPort(conf);
277+
URI proxyUri = ProxyUriUtils.getUriFromAMUrl(proxy);
278+
URI result = ProxyUriUtils.getProxyUri(trackingUri, proxyUri,
279+
appAttempt.getAppAttemptId().getApplicationId());
280+
url = result.toASCIIString().substring(
281+
HttpConfig.getSchemePrefix().length());
282+
} catch (URISyntaxException ex) {
283+
Assert.fail();
284+
}
285+
return url;
266286
}
267287

268288
/**
@@ -448,9 +468,9 @@ private void testAppAttemptRunningState(Container container,
448468
assertEquals(container, applicationAttempt.getMasterContainer());
449469
assertEquals(host, applicationAttempt.getHost());
450470
assertEquals(rpcPort, applicationAttempt.getRpcPort());
451-
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
471+
verifyUrl(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
452472
if (unmanagedAM) {
453-
assertEquals("oldtrackingurl", applicationAttempt.getTrackingUrl());
473+
verifyUrl(trackingUrl, applicationAttempt.getTrackingUrl());
454474
} else {
455475
assertEquals(getProxyUrl(applicationAttempt),
456476
applicationAttempt.getTrackingUrl());
@@ -468,7 +488,7 @@ private void testAppAttemptFinishingState(Container container,
468488
assertEquals(RMAppAttemptState.FINISHING,
469489
applicationAttempt.getAppAttemptState());
470490
assertEquals(diagnostics, applicationAttempt.getDiagnostics());
471-
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
491+
verifyUrl(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
472492
assertEquals(getProxyUrl(applicationAttempt),
473493
applicationAttempt.getTrackingUrl());
474494
assertEquals(container, applicationAttempt.getMasterContainer());
@@ -487,9 +507,9 @@ private void testAppAttemptFinishedState(Container container,
487507
assertEquals(RMAppAttemptState.FINISHED,
488508
applicationAttempt.getAppAttemptState());
489509
assertEquals(diagnostics, applicationAttempt.getDiagnostics());
490-
assertEquals(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
510+
verifyUrl(trackingUrl, applicationAttempt.getOriginalTrackingUrl());
491511
if (unmanagedAM) {
492-
assertEquals("mytrackingurl", applicationAttempt.getTrackingUrl());
512+
verifyUrl(trackingUrl, applicationAttempt.getTrackingUrl());
493513

494514
} else {
495515
assertEquals(getProxyUrl(applicationAttempt),
@@ -603,9 +623,7 @@ private void unregisterApplicationAttempt(Container container,
603623
trackingUrl, diagnostics);
604624
}
605625

606-
607-
@Test
608-
public void testUnmanagedAMSuccess() {
626+
private void testUnmanagedAMSuccess(String url) {
609627
unmanagedAM = true;
610628
when(submissionContext.getUnmanagedAM()).thenReturn(true);
611629
// submit AM and check it goes to LAUNCHED state
@@ -615,21 +633,20 @@ public void testUnmanagedAMSuccess() {
615633
applicationAttempt.getAppAttemptId());
616634

617635
// launch AM
618-
runApplicationAttempt(null, "host", 8042, "oldtrackingurl", true);
636+
runApplicationAttempt(null, "host", 8042, url, true);
619637

620638
// complete a container
621639
applicationAttempt.handle(new RMAppAttemptContainerAcquiredEvent(
622640
applicationAttempt.getAppAttemptId(), mock(Container.class)));
623641
applicationAttempt.handle(new RMAppAttemptContainerFinishedEvent(
624642
applicationAttempt.getAppAttemptId(), mock(ContainerStatus.class)));
625643
// complete AM
626-
String trackingUrl = "mytrackingurl";
627644
String diagnostics = "Successful";
628645
FinalApplicationStatus finalStatus = FinalApplicationStatus.SUCCEEDED;
629646
applicationAttempt.handle(new RMAppAttemptUnregistrationEvent(
630-
applicationAttempt.getAppAttemptId(), trackingUrl, finalStatus,
647+
applicationAttempt.getAppAttemptId(), url, finalStatus,
631648
diagnostics));
632-
testAppAttemptFinishedState(null, finalStatus, trackingUrl, diagnostics, 1,
649+
testAppAttemptFinishedState(null, finalStatus, url, diagnostics, 1,
633650
true);
634651
}
635652

@@ -824,12 +841,42 @@ public void testUnregisterToKilledFinishing() {
824841
"Killed by user");
825842
}
826843

844+
@Test
845+
public void testTrackingUrlUnmanagedAM() {
846+
testUnmanagedAMSuccess("oldTrackingUrl");
847+
}
827848

828849
@Test
829-
public void testNoTrackingUrl() {
850+
public void testEmptyTrackingUrlUnmanagedAM() {
851+
testUnmanagedAMSuccess("");
852+
}
853+
854+
@Test
855+
public void testNullTrackingUrlUnmanagedAM() {
856+
testUnmanagedAMSuccess(null);
857+
}
858+
859+
@Test
860+
public void testManagedAMWithTrackingUrl() {
861+
testTrackingUrlManagedAM("theTrackingUrl");
862+
}
863+
864+
@Test
865+
public void testManagedAMWithEmptyTrackingUrl() {
866+
testTrackingUrlManagedAM("");
867+
}
868+
869+
@Test
870+
public void testManagedAMWithNullTrackingUrl() {
871+
testTrackingUrlManagedAM(null);
872+
}
873+
874+
private void testTrackingUrlManagedAM(String url) {
830875
Container amContainer = allocateApplicationAttempt();
831876
launchApplicationAttempt(amContainer);
832-
runApplicationAttempt(amContainer, "host", 8042, "", false);
877+
runApplicationAttempt(amContainer, "host", 8042, url, false);
878+
unregisterApplicationAttempt(amContainer,
879+
FinalApplicationStatus.SUCCEEDED, url, "Successful");
833880
}
834881

835882
@Test
@@ -927,4 +974,12 @@ private void verifyTokenCount(ApplicationAttemptId appAttemptId, int count) {
927974
}
928975
}
929976
}
977+
978+
private void verifyUrl(String url1, String url2) {
979+
if (url1 == null || url1.trim().isEmpty()) {
980+
assertEquals("N/A", url2);
981+
} else {
982+
assertEquals(url1, url2);
983+
}
984+
}
930985
}

0 commit comments

Comments
 (0)