diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 82174e7cec..c6f753d460 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -114,6 +114,9 @@ Release 2.8.0 - UNRELEASED YARN-3505. Node's Log Aggregation Report with SUCCEED should not cached in RMApps. (Xuan Gong via junping_du) + YARN-3541. Add version info on timeline service / generic history web UI + and REST API. (Zhijie Shen via xgong) + IMPROVEMENTS YARN-644. Basic null check is not performed on passed in arguments before diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineAbout.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineAbout.java new file mode 100644 index 0000000000..0a2625cc50 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineAbout.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.api.records.timeline; + + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "about") +@XmlAccessorType(XmlAccessType.NONE) +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class TimelineAbout { + + private String about; + private String timelineServiceVersion; + private String timelineServiceBuildVersion; + private String timelineServiceVersionBuiltOn; + private String hadoopVersion; + private String hadoopBuildVersion; + private String hadoopVersionBuiltOn; + + public TimelineAbout() { + } + + public TimelineAbout(String about) { + this.about = about; + } + + @XmlElement(name = "About") + public String getAbout() { + return about; + } + + public void setAbout(String about) { + this.about = about; + } + + @XmlElement(name = "timeline-service-version") + public String getTimelineServiceVersion() { + return timelineServiceVersion; + } + + public void setTimelineServiceVersion(String timelineServiceVersion) { + this.timelineServiceVersion = timelineServiceVersion; + } + + @XmlElement(name = "timeline-service-build-version") + public String getTimelineServiceBuildVersion() { + return timelineServiceBuildVersion; + } + + public void setTimelineServiceBuildVersion( + String timelineServiceBuildVersion) { + this.timelineServiceBuildVersion = timelineServiceBuildVersion; + } + + @XmlElement(name = "timeline-service-version-built-on") + public String getTimelineServiceVersionBuiltOn() { + return timelineServiceVersionBuiltOn; + } + + public void setTimelineServiceVersionBuiltOn( + String timelineServiceVersionBuiltOn) { + this.timelineServiceVersionBuiltOn = timelineServiceVersionBuiltOn; + } + + @XmlElement(name = "hadoop-version") + public String getHadoopVersion() { + return hadoopVersion; + } + + public void setHadoopVersion(String hadoopVersion) { + this.hadoopVersion = hadoopVersion; + } + + @XmlElement(name = "hadoop-build-version") + public String getHadoopBuildVersion() { + return hadoopBuildVersion; + } + + public void setHadoopBuildVersion(String hadoopBuildVersion) { + this.hadoopBuildVersion = hadoopBuildVersion; + } + + @XmlElement(name = "hadoop-version-built-on") + public String getHadoopVersionBuiltOn() { + return hadoopVersionBuiltOn; + } + + public void setHadoopVersionBuiltOn(String hadoopVersionBuiltOn) { + this.hadoopVersionBuiltOn = hadoopVersionBuiltOn; + } +} + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/timeline/TimelineUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/timeline/TimelineUtils.java index 02b5eb4eab..4f838e659e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/timeline/TimelineUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/timeline/TimelineUtils.java @@ -26,7 +26,10 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.io.Text; import org.apache.hadoop.security.SecurityUtil; +import org.apache.hadoop.util.VersionInfo; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.util.YarnVersionInfo; import org.apache.hadoop.yarn.webapp.YarnJacksonJaxbJsonProvider; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; @@ -83,6 +86,17 @@ public static String dumpTimelineRecordtoJSON(Object o, boolean pretty) } } + public static TimelineAbout createTimelineAbout(String about) { + TimelineAbout tsInfo = new TimelineAbout(about); + tsInfo.setHadoopBuildVersion(VersionInfo.getBuildVersion()); + tsInfo.setHadoopVersion(VersionInfo.getVersion()); + tsInfo.setHadoopVersionBuiltOn(VersionInfo.getDate()); + tsInfo.setTimelineServiceBuildVersion(YarnVersionInfo.getBuildVersion()); + tsInfo.setTimelineServiceVersion(YarnVersionInfo.getVersion()); + tsInfo.setTimelineServiceVersionBuiltOn(YarnVersionInfo.getDate()); + return tsInfo; + } + public static InetSocketAddress getTimelineTokenServiceAddress( Configuration conf) { InetSocketAddress timelineServiceAddr = null; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSController.java index 4037f51756..2e5e97c96a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSController.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSController.java @@ -34,6 +34,10 @@ public void index() { setTitle("Application History"); } + public void about() { + render(AboutPage.class); + } + public void app() { render(AppPage.class); } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java index 80c45502cb..0193cbd5df 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java @@ -56,6 +56,7 @@ public void setup() { bind(ApplicationBaseProtocol.class).toInstance(historyClientService); bind(TimelineDataManager.class).toInstance(timelineDataManager); route("/", AHSController.class); + route("/about", AHSController.class, "about"); route(pajoin("/apps", APP_STATE), AHSController.class); route(pajoin("/app", APPLICATION_ID), AHSController.class, "app"); route(pajoin("/appattempt", APPLICATION_ATTEMPT_ID), AHSController.class, diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java index 9edc9ab197..e7a22bd168 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java @@ -34,6 +34,7 @@ import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.yarn.api.records.YarnApplicationState; import org.apache.hadoop.yarn.api.ApplicationBaseProtocol; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; import org.apache.hadoop.yarn.server.webapp.WebServices; import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo; import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptsInfo; @@ -41,6 +42,7 @@ import org.apache.hadoop.yarn.server.webapp.dao.AppsInfo; import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo; import org.apache.hadoop.yarn.server.webapp.dao.ContainersInfo; +import org.apache.hadoop.yarn.util.timeline.TimelineUtils; import org.apache.hadoop.yarn.webapp.BadRequestException; import com.google.inject.Inject; @@ -55,6 +57,16 @@ public AHSWebServices(ApplicationBaseProtocol appBaseProt) { super(appBaseProt); } + @GET + @Path("/about") + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public TimelineAbout about( + @Context HttpServletRequest req, + @Context HttpServletResponse res) { + init(res); + return TimelineUtils.createTimelineAbout("Generic History Service API"); + } + @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public AppsInfo get(@Context HttpServletRequest req, diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutBlock.java new file mode 100644 index 0000000000..b2419e9ac6 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutBlock.java @@ -0,0 +1,47 @@ +/** + * 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.applicationhistoryservice.webapp; + +import com.google.inject.Inject; +import org.apache.hadoop.util.VersionInfo; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; +import org.apache.hadoop.yarn.util.YarnVersionInfo; +import org.apache.hadoop.yarn.util.timeline.TimelineUtils; +import org.apache.hadoop.yarn.webapp.View; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; +import org.apache.hadoop.yarn.webapp.view.InfoBlock; + +public class AboutBlock extends HtmlBlock { + @Inject + AboutBlock(View.ViewContext ctx) { + super(ctx); + } + + @Override + protected void render(Block html) { + TimelineAbout tsInfo = TimelineUtils.createTimelineAbout( + "Timeline Server - Generic History Service UI"); + info("Timeline Server Overview"). + _("Timeline Server Version:", tsInfo.getTimelineServiceBuildVersion() + + " on " + tsInfo.getTimelineServiceVersionBuiltOn()). + _("Hadoop Version:", tsInfo.getHadoopBuildVersion() + + " on " + tsInfo.getHadoopVersionBuiltOn()); + html._(InfoBlock.class); + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutPage.java new file mode 100644 index 0000000000..b50073af64 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AboutPage.java @@ -0,0 +1,36 @@ +/** + * 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.applicationhistoryservice.webapp; + + +import org.apache.hadoop.yarn.webapp.SubView; +import org.apache.hadoop.yarn.webapp.YarnWebParams; + +import static org.apache.hadoop.yarn.util.StringHelper.join; + +public class AboutPage extends AHSView { + @Override protected void preHead(Page.HTML<_> html) { + commonPreHead(html); + set(TITLE, "Timeline Server - Generic History Service"); + } + + @Override protected Class content() { + return AboutBlock.class; + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/NavBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/NavBlock.java index 498503f1aa..25ee4f0a22 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/NavBlock.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/NavBlock.java @@ -43,6 +43,8 @@ public void render(Block html) { div("#nav"). h3("Application History"). ul(). + li().a(url("about"), "About"). + _(). li().a(url("apps"), "Applications"). ul(). li().a(url("apps", diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/timeline/webapp/TimelineWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/timeline/webapp/TimelineWebServices.java index 915e3f2ed6..90f4d39613 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/timeline/webapp/TimelineWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/timeline/webapp/TimelineWebServices.java @@ -42,17 +42,12 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.classification.InterfaceAudience.Public; -import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.util.VersionInfo; import org.apache.hadoop.yarn.api.records.timeline.TimelineDomain; import org.apache.hadoop.yarn.api.records.timeline.TimelineDomains; import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities; @@ -65,6 +60,9 @@ import org.apache.hadoop.yarn.server.timeline.NameValuePair; import org.apache.hadoop.yarn.server.timeline.TimelineDataManager; import org.apache.hadoop.yarn.server.timeline.TimelineReader.Field; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; +import org.apache.hadoop.yarn.util.YarnVersionInfo; +import org.apache.hadoop.yarn.util.timeline.TimelineUtils; import org.apache.hadoop.yarn.webapp.BadRequestException; import org.apache.hadoop.yarn.webapp.ForbiddenException; import org.apache.hadoop.yarn.webapp.NotFoundException; @@ -86,43 +84,16 @@ public TimelineWebServices(TimelineDataManager timelineDataManager) { this.timelineDataManager = timelineDataManager; } - @XmlRootElement(name = "about") - @XmlAccessorType(XmlAccessType.NONE) - @Public - @Unstable - public static class AboutInfo { - - private String about; - - public AboutInfo() { - - } - - public AboutInfo(String about) { - this.about = about; - } - - @XmlElement(name = "About") - public String getAbout() { - return about; - } - - public void setAbout(String about) { - this.about = about; - } - - } - /** * Return the description of the timeline web services. */ @GET @Produces({ MediaType.APPLICATION_JSON /* , MediaType.APPLICATION_XML */}) - public AboutInfo about( + public TimelineAbout about( @Context HttpServletRequest req, @Context HttpServletResponse res) { init(res); - return new AboutInfo("Timeline API"); + return TimelineUtils.createTimelineAbout("Timeline API"); } /** diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java index 2cd7580006..1e0886f36c 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java @@ -87,6 +87,20 @@ public void testView() throws Exception { WebAppTests.flushOutput(injector); } + @Test + public void testAboutPage() throws Exception { + Injector injector = + WebAppTests.createMockInjector(ApplicationBaseProtocol.class, + mockApplicationHistoryClientService(0, 0, 0)); + AboutPage aboutPageInstance = injector.getInstance(AboutPage.class); + + aboutPageInstance.render(); + WebAppTests.flushOutput(injector); + + aboutPageInstance.render(); + WebAppTests.flushOutput(injector); + } + @Test public void testAppPage() throws Exception { Injector injector = diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebServices.java index 913b80dd06..613df72da3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebServices.java @@ -49,6 +49,8 @@ import org.apache.hadoop.yarn.server.timeline.TimelineDataManager; import org.apache.hadoop.yarn.server.timeline.TimelineStore; import org.apache.hadoop.yarn.server.timeline.security.TimelineACLsManager; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; +import org.apache.hadoop.yarn.util.timeline.TimelineUtils; import org.apache.hadoop.yarn.webapp.GenericExceptionHandler; import org.apache.hadoop.yarn.webapp.JerseyTestBase; import org.apache.hadoop.yarn.webapp.WebServicesTestUtils; @@ -57,6 +59,7 @@ import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -215,6 +218,34 @@ public void testInvalidAccept() throws JSONException, Exception { } } + @Test + public void testAbout() throws Exception { + WebResource r = resource(); + ClientResponse response = r + .path("ws").path("v1").path("applicationhistory").path("about") + .queryParam("user.name", USERS[round]) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + TimelineAbout actualAbout = response.getEntity(TimelineAbout.class); + TimelineAbout expectedAbout = + TimelineUtils.createTimelineAbout("Generic History Service API"); + Assert.assertNotNull( + "Timeline service about response is null", actualAbout); + Assert.assertEquals(expectedAbout.getAbout(), actualAbout.getAbout()); + Assert.assertEquals(expectedAbout.getTimelineServiceVersion(), + actualAbout.getTimelineServiceVersion()); + Assert.assertEquals(expectedAbout.getTimelineServiceBuildVersion(), + actualAbout.getTimelineServiceBuildVersion()); + Assert.assertEquals(expectedAbout.getTimelineServiceVersionBuiltOn(), + actualAbout.getTimelineServiceVersionBuiltOn()); + Assert.assertEquals(expectedAbout.getHadoopVersion(), + actualAbout.getHadoopVersion()); + Assert.assertEquals(expectedAbout.getHadoopBuildVersion(), + actualAbout.getHadoopBuildVersion()); + Assert.assertEquals(expectedAbout.getHadoopVersionBuiltOn(), + actualAbout.getHadoopVersionBuiltOn()); + } + @Test public void testAppsQuery() throws Exception { WebResource r = resource(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/timeline/webapp/TestTimelineWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/timeline/webapp/TestTimelineWebServices.java index 7e96d2a364..ab7cffd878 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/timeline/webapp/TestTimelineWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/timeline/webapp/TestTimelineWebServices.java @@ -29,7 +29,6 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; @@ -59,6 +58,8 @@ import org.apache.hadoop.yarn.server.timeline.TimelineStore; import org.apache.hadoop.yarn.server.timeline.security.TimelineACLsManager; import org.apache.hadoop.yarn.server.timeline.security.TimelineAuthenticationFilter; +import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; +import org.apache.hadoop.yarn.util.timeline.TimelineUtils; import org.apache.hadoop.yarn.webapp.GenericExceptionHandler; import org.apache.hadoop.yarn.webapp.JerseyTestBase; import org.apache.hadoop.yarn.webapp.YarnJacksonJaxbJsonProvider; @@ -184,10 +185,24 @@ public void testAbout() throws Exception { .accept(MediaType.APPLICATION_JSON) .get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); - TimelineWebServices.AboutInfo about = - response.getEntity(TimelineWebServices.AboutInfo.class); - Assert.assertNotNull(about); - Assert.assertEquals("Timeline API", about.getAbout()); + TimelineAbout actualAbout = response.getEntity(TimelineAbout.class); + TimelineAbout expectedAbout = + TimelineUtils.createTimelineAbout("Timeline API"); + Assert.assertNotNull( + "Timeline service about response is null", actualAbout); + Assert.assertEquals(expectedAbout.getAbout(), actualAbout.getAbout()); + Assert.assertEquals(expectedAbout.getTimelineServiceVersion(), + actualAbout.getTimelineServiceVersion()); + Assert.assertEquals(expectedAbout.getTimelineServiceBuildVersion(), + actualAbout.getTimelineServiceBuildVersion()); + Assert.assertEquals(expectedAbout.getTimelineServiceVersionBuiltOn(), + actualAbout.getTimelineServiceVersionBuiltOn()); + Assert.assertEquals(expectedAbout.getHadoopVersion(), + actualAbout.getHadoopVersion()); + Assert.assertEquals(expectedAbout.getHadoopBuildVersion(), + actualAbout.getHadoopBuildVersion()); + Assert.assertEquals(expectedAbout.getHadoopVersionBuiltOn(), + actualAbout.getHadoopVersionBuiltOn()); } private static void verifyEntities(TimelineEntities entities) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/TimelineServer.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/TimelineServer.md index acdd8ff4b9..e17721523a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/TimelineServer.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/TimelineServer.md @@ -358,9 +358,17 @@ Here is a non-normative description of the API. GET /ws/v1/timeline/ -Returns a JSON object describing the server instance. +Returns a JSON object describing the server instance and version information. - {"About":"Timeline API"} + { + About: "Timeline API", + timeline-service-version: "3.0.0-SNAPSHOT", + timeline-service-build-version: "3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum e9ec74ea3ff7bc9f3d35e9cac694fb", + timeline-service-version-built-on: "2015-05-13T19:45Z", + hadoop-version: "3.0.0-SNAPSHOT", + hadoop-build-version: "3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum 95874b192923b43cdb96a6e483afd60", + hadoop-version-built-on: "2015-05-13T19:44Z" + } ## Domains `/ws/v1/timeline/domain` @@ -889,6 +897,92 @@ Response Body: Users can access the generic historic information of applications via REST APIs. +## About + +With the about API, you can get an timeline about resource that contains +generic history REST API description and version information. + +It is essentially a XML/JSON-serialized form of the YARN `TimelineAbout` +structure. + +### URI: + +Use the following URI to obtain an timeline about object. + + http(s):///ws/v1/applicationhistory/about + +### HTTP Operations Supported: + + GET + +### Query Parameters Supported: + +None + +### Elements of the `about` (Application) Object: + +| Item | Data Type | Description | +|:---- |:---- |:---- | +| `About` | string | The description about the service | +| `timeline-service-version` | string | The timeline service version | +| `timeline-service-build-version` | string | The timeline service build version | +| `timeline-service-version-built-on` | string | On what time the timeline service is built | +| `hadoop-version` | string | Hadoop version | +| `hadoop-build-version` | string | Hadoop build version | +| `hadoop-version-built-on` | string | On what time Hadoop is built | + +### Response Examples: + +#### JSON response + +HTTP Request: + + http://localhost:8188/ws/v1/applicationhistory/about + +Response Header: + + HTTP/1.1 200 OK + Content-Type: application/json + Transfer-Encoding: chunked + +Response Body: + + { + About: "Generic History Service API", + timeline-service-version: "3.0.0-SNAPSHOT", + timeline-service-build-version: "3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum e9ec74ea3ff7bc9f3d35e9cac694fb", + timeline-service-version-built-on: "2015-05-13T19:45Z", + hadoop-version: "3.0.0-SNAPSHOT", + hadoop-build-version: "3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum 95874b192923b43cdb96a6e483afd60", + hadoop-version-built-on: "2015-05-13T19:44Z" + } + +#### XML response + +HTTP Request: + + GET http://localhost:8188/ws/v1/applicationhistory/about + Accept: application/xml + +Response Header: + + HTTP/1.1 200 OK + Content-Type: application/xml + Content-Length: 748 + +Response Body: + + + + Generic History Service API + 3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum 95874b192923b43cdb96a6e483afd60 + 3.0.0-SNAPSHOT + 2015-05-13T19:44Z + 3.0.0-SNAPSHOT from fcd0702c10ce574b887280476aba63d6682d5271 by zshen source checksum e9ec74ea3ff7bc9f3d35e9cac694fb + 3.0.0-SNAPSHOT + 2015-05-13T19:45Z + + ## Application List With the Application List API, you can obtain a collection of resources, each @@ -1129,7 +1223,8 @@ With the Application API, you can get an application resource contains information about a particular application that was running on an YARN cluster. -It is essentially a JSON-serialized form of the YARN `ApplicationReport` structure. +It is essentially a XML/JSON-serialized form of the YARN `ApplicationReport` +structure. ### URI: