This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 79c5de4  Improve the quality of the health check
79c5de4 is described below

commit 79c5de4deee98c2a8c5d6f6674db9fbee88f52d8
Author: remm <r...@apache.org>
AuthorDate: Fri Sep 11 13:26:44 2020 +0200

    Improve the quality of the health check
    
    The valve will check if its associated container and all its children
    are available. Will return down if any is not available.
---
 .../apache/catalina/valves/HealthCheckValve.java   | 43 +++++++++++++++++++++-
 webapps/docs/changelog.xml                         |  8 ++++
 webapps/docs/config/valve.xml                      | 15 +++++---
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/java/org/apache/catalina/valves/HealthCheckValve.java 
b/java/org/apache/catalina/valves/HealthCheckValve.java
index fb4a8e2..5b75fd6 100644
--- a/java/org/apache/catalina/valves/HealthCheckValve.java
+++ b/java/org/apache/catalina/valves/HealthCheckValve.java
@@ -19,11 +19,14 @@ package org.apache.catalina.valves;
 import java.io.IOException;
 
 import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
+import org.apache.catalina.util.LifecycleBase;
 import org.apache.tomcat.util.buf.MessageBytes;
 
 
@@ -38,6 +41,12 @@ public class HealthCheckValve extends ValveBase {
             "  \"checks\": []\n" +
             "}";
 
+    private static final String DOWN =
+            "{\n" +
+            "  \"status\": \"DOWN\",\n" +
+            "  \"checks\": []\n" +
+            "}";
+
     private String path = "/health";
 
     /**
@@ -45,6 +54,11 @@ public class HealthCheckValve extends ValveBase {
      */
     protected boolean context = false;
 
+    /**
+     * Check if all child containers are available.
+     */
+    protected boolean checkContainersAvailable = true;
+
     public HealthCheckValve() {
         super(true);
     }
@@ -57,6 +71,14 @@ public class HealthCheckValve extends ValveBase {
         this.path = path;
     }
 
+    public boolean getCheckContainersAvailable() {
+        return this.checkContainersAvailable;
+    }
+
+    public void setCheckContainersAvailable(boolean checkContainersAvailable) {
+        this.checkContainersAvailable = checkContainersAvailable;
+    }
+
     @Override
     protected synchronized void startInternal() throws LifecycleException {
         super.startInternal();
@@ -74,9 +96,28 @@ public class HealthCheckValve extends ValveBase {
                 context ? request.getRequestPathMB() : 
request.getDecodedRequestURIMB();
         if (urlMB.equals(path)) {
             response.setContentType("application/json");
-            response.getOutputStream().print(UP);
+            if (isAvailable(getContainer())) {
+                response.getOutputStream().print(UP);
+            } else {
+                response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                response.getOutputStream().print(DOWN);
+            }
         } else {
             getNext().invoke(request, response);
         }
     }
+
+    protected boolean isAvailable(Container container) {
+        for (Container child : container.findChildren()) {
+            if (!isAvailable(child)) {
+                return false;
+            }
+        }
+        if (container instanceof LifecycleBase) {
+            return ((LifecycleBase) container).getState().isAvailable();
+        } else {
+            return true;
+        }
+    }
+
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index cb6b9c6..fad0a39 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -45,6 +45,14 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 9.0.39 (markt)" rtext="in development">
+  <subsection name="Catalina">
+    <changelog>
+      <update>
+        The health check valve will now check the state of its associated
+        containers to report availability. (remm)
+      </update>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 9.0.38 (markt)" rtext="release in progress">
   <subsection name="Catalina">
diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml
index aac0d5a..0a6b0c3 100644
--- a/webapps/docs/config/valve.xml
+++ b/webapps/docs/config/valve.xml
@@ -2232,10 +2232,7 @@
   <subsection name="Introduction">
 
     <p>The <strong>Health Check Valve</strong> responds to
-    cloud orchestrators health checks. Note that it checks
-    that a context is mapped (so that an application is deployed),
-    for example if you don't have a ROOT context but demo-1.0
-    you have to check for <code>/demo-1.0/health</code></p>
+    cloud orchestrators health checks.</p>
   </subsection>
 
   <subsection name="Attributes">
@@ -2251,10 +2248,18 @@
       </attribute>
 
       <attribute name="path" required="false">
-        <p>Path by the cloud orchestrators health check logic.
+        <p>Path by the cloud orchestrators health check logic. If the valve
+        is associated with a context, then this will be relative to the context
+        path. Otherwise, the valve will match the full URI.
         The default value is <strong>/health</strong>.</p>
       </attribute>
 
+      <attribute name="checkContainersAvailable" required="false">
+        <p>If <code>true</code> the valve will check if its associated
+        container and all its children are available.
+        The default value is <strong>true</strong>.</p>
+      </attribute>
+
     </attributes>
 
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to