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

io.gravitee.plugin.apiservice.healthcheck.common.HealthCheckManagedEndpoint Maven / Gradle / Ivy

There is a newer version: 4.5.5
Show newest version
/*
 * Copyright © 2015 The Gravitee team (http://gravitee.io)
 *
 * 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.gravitee.plugin.apiservice.healthcheck.common;

import io.gravitee.alert.api.event.Event;
import io.gravitee.definition.model.v4.endpointgroup.Endpoint;
import io.gravitee.gateway.reactive.api.connector.endpoint.EndpointConnector;
import io.gravitee.gateway.reactive.core.v4.endpoint.EndpointManager;
import io.gravitee.gateway.reactive.core.v4.endpoint.ManagedEndpoint;
import io.gravitee.gateway.reactive.core.v4.endpoint.ManagedEndpointGroup;
import io.gravitee.gateway.reactive.handlers.api.v4.Api;
import io.gravitee.gateway.report.ReporterService;
import io.gravitee.node.api.Node;
import io.gravitee.plugin.alert.AlertEventProducer;
import io.gravitee.reporter.api.health.EndpointStatus;
import io.gravitee.reporter.api.health.Step;
import lombok.EqualsAndHashCode;

/**
 * Enhance a managed endpoint to add health check capabilities on top of it.
 * It basically manages different things:
 * 
    *
  • disable the endpoint from the endpoint manager when the health status moves to DOWN and re-enable it when it goes back to UP
  • *
  • report the health check status to the reporter service
  • *
  • report the health check status transition event to the alert engine
  • *
* * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ @EqualsAndHashCode(onlyExplicitlyIncluded = true) public class HealthCheckManagedEndpoint implements ManagedEndpoint { public static final int DEFAULT_SUCCESS_THRESHOLD = 2; public static final int DEFAULT_FAILURE_THRESHOLD = 3; private static final String EVENT_TYPE = "ENDPOINT_HEALTH_CHECK"; private static final String CONTEXT_NODE_ID = "node.id"; private static final String CONTEXT_NODE_HOSTNAME = "node.hostname"; private static final String CONTEXT_NODE_APPLICATION = "node.application"; private static final String PROP_RESPONSE_TIME = "response_time"; private static final String PROP_TENANT = "tenant"; private static final String PROP_API = "api"; private static final String PROP_ENDPOINT_NAME = "endpoint.name"; private static final String PROP_STATUS_OLD = "status.old"; private static final String PROP_STATUS_NEW = "status.new"; private static final String PROP_SUCCESS = "success"; private static final String PROP_MESSAGE = "message"; private final Api api; private final Node node; @EqualsAndHashCode.Include private final ManagedEndpoint endpoint; private final HealthCheckStatus healthCheckStatus; private final EndpointManager endpointManager; private final ReporterService reporterService; private final AlertEventProducer alertEventProducer; public HealthCheckManagedEndpoint( final Api api, final Node node, final ManagedEndpoint endpoint, final EndpointManager endpointManager, final ReporterService reporterService, final AlertEventProducer alertEventProducer, final int successThreshold, final int failureThreshold ) { this.api = api; this.node = node; this.endpoint = endpoint; this.reporterService = reporterService; this.alertEventProducer = alertEventProducer; this.healthCheckStatus = new HealthCheckStatus(endpoint.getStatus(), successThreshold, failureThreshold); this.endpointManager = endpointManager; } /** * Report the result of an health check. * * @param success true to notify a success, false otherwise. */ public void reportStatus(boolean success, final EndpointStatus status) { if (success) { reportSuccess(status); } else { reportFailure(status); } } private void reportSuccess(final EndpointStatus endpointStatus) { final ManagedEndpoint.Status oldStatus = healthCheckStatus.getCurrentStatus(); final ManagedEndpoint.Status newStatus = healthCheckStatus.reportSuccess(); if (!newStatus.isDown() && oldStatus.isDown()) { endpointManager.enable(endpoint); } report(endpointStatus, oldStatus, newStatus); } private void reportFailure(final EndpointStatus status) { final ManagedEndpoint.Status oldStatus = healthCheckStatus.getCurrentStatus(); final ManagedEndpoint.Status newStatus = healthCheckStatus.reportFailure(); if (newStatus.isDown() && !oldStatus.isDown()) { endpointManager.disable(endpoint); } report(status, oldStatus, newStatus); } private void report( final EndpointStatus endpointStatus, final ManagedEndpoint.Status oldStatus, final ManagedEndpoint.Status newStatus ) { endpointStatus.setTransition(oldStatus != newStatus); endpointStatus.setState(newStatus.code()); endpointStatus.setAvailable(!newStatus.isDown()); endpointStatus.setResponseTime(endpointStatus.getSteps().stream().mapToLong(Step::getResponseTime).sum()); reporterService.report(endpointStatus); if (endpointStatus.isTransition() && alertEventProducer != null && !alertEventProducer.isEmpty()) { final Event event = Event .at(endpointStatus.getTimestamp()) .context(CONTEXT_NODE_ID, node.id()) .context(CONTEXT_NODE_HOSTNAME, node.hostname()) .context(CONTEXT_NODE_APPLICATION, node.application()) .type(EVENT_TYPE) .property(PROP_API, api.getId()) .property(PROP_ENDPOINT_NAME, endpoint.getDefinition().getName()) .property(PROP_STATUS_OLD, oldStatus.name()) .property(PROP_STATUS_NEW, newStatus.name()) .property(PROP_SUCCESS, endpointStatus.isSuccess()) .property(PROP_TENANT, () -> node.metadata().get("tenant")) .property(PROP_RESPONSE_TIME, endpointStatus.getResponseTime()) .property(PROP_MESSAGE, endpointStatus.getSteps().get(0).getMessage()) .organization(api.getOrganizationId()) .environment(api.getEnvironmentId()) .build(); alertEventProducer.send(event); } } @Override public Endpoint getDefinition() { return endpoint.getDefinition(); } @Override public ManagedEndpointGroup getGroup() { return endpoint.getGroup(); } @Override public T getConnector() { return endpoint.getConnector(); } @Override public ManagedEndpoint.Status getStatus() { return healthCheckStatus.getCurrentStatus(); } @Override public void setStatus(ManagedEndpoint.Status status) { healthCheckStatus.setCurrentStatus(status); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy