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 * Mixin flavor of the built-in health/readiness/liveness probe capability.
025 *
026 * <p>
027 * Composes the {@code /healthz}, {@code /readyz}, and {@code /livez} probe endpoints into a host
028 * resource via {@link Rest#mixins() @Rest(mixins=HealthMixin.class)}. The ops self-pin their absolute
029 * paths so they merge into the host's namespace. Delegates to a shared {@link HealthAggregator} worker
030 * bean &mdash; the same logic the {@link HealthServlet} servlet flavor uses.
031 *
032 * <p>
033 * Indicators are resolved from the host's bean store, so a host registers its own
034 * {@link HealthIndicator} beans (e.g. via Spring {@code @Bean} or a Juneau {@code BeanStore}).
035 *
036 * <h5 class='section'>See Also:</h5><ul>
037 *    <li class='jc'>{@link HealthServlet}
038 *    <li class='jc'>{@link HealthAggregator}
039 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Mixins and Multi-Mount Paths</a>
040 * </ul>
041 *
042 * @since 10.0.0
043 */
044@Rest
045public class HealthMixin extends RestMixin {
046
047   private final HealthAggregator aggregator = new HealthAggregator();
048
049   /**
050    * Health probe endpoint.
051    *
052    * @param req The request.
053    * @param res The response.
054    * @return Aggregated health payload.
055    */
056   @RestGet(path="/healthz")
057   public HealthResponse healthz(RestRequest req, RestResponse res) {
058      return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), null, res);
059   }
060
061   /**
062    * Readiness probe endpoint.
063    *
064    * @param req The request.
065    * @param res The response.
066    * @return Aggregated health payload.
067    */
068   @RestGet(path="/readyz")
069   public HealthResponse readyz(RestRequest req, RestResponse res) {
070      return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.READY, res);
071   }
072
073   /**
074    * Liveness probe endpoint.
075    *
076    * @param req The request.
077    * @param res The response.
078    * @return Aggregated health payload.
079    */
080   @RestGet(path="/livez")
081   public HealthResponse livez(RestRequest req, RestResponse res) {
082      return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.LIVE, res);
083   }
084}