All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.webserver.observe.health.SingleCheckHandler Maven / Gradle / Ivy

There is a newer version: 4.1.2
Show newest version
/*
 * Copyright (c) 2022, 2023 Oracle and/or its affiliates.
 *
 * Licensed 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 io.helidon.webserver.observe.health;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.helidon.health.HealthCheck;
import io.helidon.health.HealthCheckResponse;
import io.helidon.http.HtmlEncoder;
import io.helidon.http.NotFoundException;
import io.helidon.http.Status;
import io.helidon.http.media.EntityWriter;
import io.helidon.http.media.jsonp.JsonpSupport;
import io.helidon.webserver.http.Handler;
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;

import jakarta.json.JsonObject;

class SingleCheckHandler implements Handler {
    private static final System.Logger LOGGER = System.getLogger(SingleCheckHandler.class.getName());

    private final EntityWriter entityWriter;
    private final boolean details;
    private final List allChecks;
    private final Map checks;

    SingleCheckHandler(EntityWriter entityWriter, boolean details, List checks) {
        this.entityWriter = entityWriter;
        this.details = details;
        this.allChecks = checks;
        this.checks = new HashMap<>();
    }

    @Override
    public void beforeStart() {
        allChecks.forEach(it -> this.checks.putIfAbsent(it.path(), it));
    }

    @Override
    public void handle(ServerRequest req, ServerResponse res) {
        String name = req.path().pathParameters().get("name");
        HealthCheck check = checks.get(name);
        if (check == null) {
            throw new NotFoundException(name);
        }

        HealthCheckResponse response;

        try {
            response = check.call();
        } catch (Exception e) {
            response = HealthCheckResponse.builder()
                    .status(HealthCheckResponse.Status.ERROR)
                    .detail("error", e.getClass().getName())
                    .detail("message", HtmlEncoder.encode(e.getMessage()))
                    .build();
            LOGGER.log(System.Logger.Level.ERROR, "Unexpected failure of health check", e);
        }

        Status responseStatus = switch (response.status()) {
            case UP -> details ? Status.OK_200 : Status.NO_CONTENT_204;
            case DOWN -> Status.SERVICE_UNAVAILABLE_503;
            case ERROR -> Status.INTERNAL_SERVER_ERROR_500;
        };

        res.status(responseStatus);

        if (details) {
            try (OutputStream out = res.outputStream()) {
                entityWriter.write(JsonpSupport.JSON_OBJECT_TYPE,
                                   HealthHelper.toJson(check.name(), response),
                                   out,
                                   req.headers(),
                                   res.headers());
            } catch (IOException e) {
                LOGGER.log(System.Logger.Level.TRACE, "Failed to write health check response", e);
                res.status(Status.INTERNAL_SERVER_ERROR_500)
                        .send();
            }
        } else {
            res.send();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy