Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-documentstore/src/main/java/org/apache/hadoop/yarn/server/timelineservice/documentstore/DocumentStoreTimelineReaderImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-documentstore/src/main/java/org/apache/hadoop/yarn/server/timelineservice/documentstore/DocumentStoreTimelineReaderImpl.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-documentstore/src/main/java/org/apache/hadoop/yarn/server/timelineservice/documentstore/DocumentStoreTimelineReaderImpl.java (date 1558528482000) @@ -100,6 +100,11 @@ return collectionReader.fetchEntityTypes(context); } + @Override + public boolean isConnectionAlive() { + return (collectionReader != null); + } + // for honoring all filters from {@link TimelineEntityFilters} private Set applyFilters(TimelineEntityFilters filters, TimelineDataToRetrieve dataToRetrieve, Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/NoOpTimelineReaderImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/NoOpTimelineReaderImpl.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/NoOpTimelineReaderImpl.java (date 1558526433000) @@ -71,4 +71,9 @@ "requests would be empty"); return new HashSet<>(); } + + @Override + public boolean isConnectionAlive() { + return true; + } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/TimelineReader.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/TimelineReader.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/TimelineReader.java (date 1558526429000) @@ -192,4 +192,11 @@ * storage. */ Set getEntityTypes(TimelineReaderContext context) throws IOException; + + /** + * Check if reader connection is working properly. + * + * @return True if reader connection works as expected, false otherwise. + */ + boolean isConnectionAlive(); } \ No newline at end of file Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/reader/TimelineReaderWebServices.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/reader/TimelineReaderWebServices.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/reader/TimelineReaderWebServices.java (date 1558520174000) @@ -48,6 +48,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.Time; import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout; +import org.apache.hadoop.yarn.api.records.timeline.TimelineHealth; import org.apache.hadoop.yarn.api.records.timelineservice.FlowActivityEntity; import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntity; import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntityType; @@ -218,6 +219,45 @@ return TimelineUtils.createTimelineAbout("Timeline Reader API"); } + /** + * Health check rest end point. + * + * @param req Servlet request. + * @param res Servlet response. + * + * @return TimelineHealth.OK with 200 OK if service is running + * TimlineHeaalth.BAD with 500 if reader connection fails + */ + @GET + @Path("/health") + @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8) + public Response health( + @Context HttpServletRequest req, + @Context HttpServletResponse res + ) { + Response response; + + TimelineReaderContext timelineReaderContext = TimelineReaderWebServicesUtils + .createTimelineReaderContext("", "", "", "0", + "", TimelineEntityType.YARN_FLOW_RUN.toString(), "0", + "0"); + try { + + this.getTimelineReaderManager().getEntityTypes(timelineReaderContext); + response = + Response.ok(new TimelineHealth(TimelineHealth.TimelineHealthStatus.RUNNING, + "")).build(); + } catch (Exception e) { + LOG.info("Exception during health check: " + e.getMessage(), e); + response = Response.serverError().entity( + new TimelineHealth(TimelineHealth.TimelineHealthStatus.WRITER_CONNECTION_FAILURE, + e.getMessage()) + ).build(); + } + + return response; + } + /** * Return a single entity for a given entity type and UID which is a delimited * string containing clusterid, userid, flow name, flowrun id and app id. Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-hbase/hadoop-yarn-server-timelineservice-hbase-client/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/HBaseTimelineReaderImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-hbase/hadoop-yarn-server-timelineservice-hbase-client/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/HBaseTimelineReaderImpl.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-hbase/hadoop-yarn-server-timelineservice-hbase-client/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/HBaseTimelineReaderImpl.java (date 1558536421000) @@ -158,6 +158,11 @@ return reader.readEntityTypes(hbaseConf, conn); } + @Override + public boolean isConnectionAlive() { + return !this.isHBaseDown(); + } + protected static final TimelineEntityFilters MONITOR_FILTERS = new TimelineEntityFilters.Builder().entityLimit(1L).build(); protected static final TimelineDataToRetrieve DATA_TO_RETRIEVE = Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/FileSystemTimelineReaderImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/FileSystemTimelineReaderImpl.java (revision 64f30da42813182e9cf69ec306c1f1c0c633ece0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/storage/FileSystemTimelineReaderImpl.java (date 1558527951000) @@ -442,4 +442,14 @@ } return result; } + + @Override + public boolean isConnectionAlive() { + try { + fs.open(rootPath); + } catch (IOException e) { + return false; + } + return true; + } } \ No newline at end of file Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineHealth.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineHealth.java (date 1558431642000) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/timeline/TimelineHealth.java (date 1558431642000) @@ -0,0 +1,61 @@ +/** + * 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; + +/** + * This class holds health information for ATS. + */ +@XmlRootElement(name = "health") +@XmlAccessorType(XmlAccessType.NONE) +@InterfaceAudience.Public +@InterfaceStability.Unstable +public class TimelineHealth { + + public enum TimelineHealthStatus { + RUNNING, + WRITER_CONNECTION_FAILURE + } + + private TimelineHealthStatus healthStatus; + private String diagnosticsInfo; + + public TimelineHealth(TimelineHealthStatus healthy, String diagnosticsInfo) { + this.healthStatus = healthy; + this.diagnosticsInfo = diagnosticsInfo; + } + + @XmlElement(name = "healthStatus") + public TimelineHealthStatus getHealthStatus() { + return healthStatus; + } + + @XmlElement(name = "diagnosticsInfo") + public String getDiagnosticsInfo() { + return diagnosticsInfo; + } +} +