001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server.health; 018 019import org.apache.juneau.rest.server.*; 020import org.apache.juneau.rest.server.health.HealthAggregator.*; 021import org.apache.juneau.rest.server.servlet.*; 022 023/** 024 * Child-resource flavor of the built-in health/readiness/liveness probe capability. 025 * 026 * <p> 027 * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=HealthResource.class)} 028 * under a parent at the subtree {@code /health} and serves the {@code /healthz}, {@code /readyz}, and 029 * {@code /livez} probe endpoints by delegating to a shared {@link HealthAggregator} worker bean — 030 * the same logic the {@link HealthServlet servlet} and {@link HealthMixin mixin} flavors use, so the 031 * three forms cannot drift. 032 * 033 * <p> 034 * Indicators are resolved from the host's bean store, so a host registers its own 035 * {@link HealthIndicator} beans (e.g. via Spring {@code @Bean} or a Juneau {@code BeanStore}). 036 * 037 * <p> 038 * Extends {@link BasicRestResource} — the child-flavor mirror of {@link BasicRestServlet} that the 039 * {@link HealthServlet} servlet flavor extends — so the {@link HealthAggregator.HealthResponse} 040 * bean returned by the probe ops is serialized out of the box via the {@code BasicUniversalConfig} 041 * serializer set (JSON/XML/HTML/…). A bare {@code RestResource} child would carry no serializers 042 * and force every consumer to re-declare one; deriving from {@code BasicRestResource} keeps the child 043 * flavor at parity with its servlet twin. 044 * 045 * <h5 class='section'>See Also:</h5><ul> 046 * <li class='jc'>{@link HealthServlet} 047 * <li class='jc'>{@link HealthMixin} 048 * <li class='jc'>{@link HealthAggregator} 049 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Mixins and Multi-Mount Paths</a> 050 * </ul> 051 * 052 * @since 10.0.0 053 */ 054@Rest(path="/health") 055public class HealthResource extends BasicRestResource { 056 057 private final HealthAggregator aggregator = new HealthAggregator(); 058 059 /** 060 * Health probe endpoint. 061 * 062 * @param req The request. 063 * @param res The response. 064 * @return Aggregated health payload. 065 */ 066 @RestGet(path="/healthz") 067 public HealthResponse healthz(RestRequest req, RestResponse res) { 068 return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), null, res); 069 } 070 071 /** 072 * Readiness probe endpoint. 073 * 074 * @param req The request. 075 * @param res The response. 076 * @return Aggregated health payload. 077 */ 078 @RestGet(path="/readyz") 079 public HealthResponse readyz(RestRequest req, RestResponse res) { 080 return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.READY, res); 081 } 082 083 /** 084 * Liveness probe endpoint. 085 * 086 * @param req The request. 087 * @param res The response. 088 * @return Aggregated health payload. 089 */ 090 @RestGet(path="/livez") 091 public HealthResponse livez(RestRequest req, RestResponse res) { 092 return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.LIVE, res); 093 } 094}