package com.atlassian.bitbucket.mesh.grpc;

import com.atlassian.bitbucket.mesh.health.rpc.v1.HealthCheckRequest;
import com.atlassian.bitbucket.mesh.health.rpc.v1.HealthCheckResponse;
import com.atlassian.bitbucket.mesh.health.rpc.v1.HealthGrpc;
import io.grpc.stub.StreamObserver;

/**
 * Implements the <a href="https://github.com/grpc/grpc/blob/master/doc/health-checking.md">GRPC Health Checking Protocol</a>
 * <p>
 * This implementation simply returns "SERVING" when the application is able to service GRPC requests. The intended
 * purpose is so automations can know when a Mesh node is running such that the control plane can begin to make
 * requests on it. For example, callers may use this to block/poll between when starting a Mesh node and when
 * attempting to "add it" to Bitbucket Server.
 * <p>
 * What this is not: Another common use for health checks is when the GRPC service is deployed behind a load balancer
 * and is ready to service requests. Note that this is NOT the case here; nor should Mesh nodes be placed behind a
 * load balancer. The control plane is responsible for deciding when a node is responsible for handing Git requests,
 * and for making decisions around routing.
 */
public class GrpcHealthService extends HealthGrpc.HealthImplBase {

    public void check(HealthCheckRequest request, StreamObserver<HealthCheckResponse> responseObserver) {
        responseObserver.onNext(buildStatus());
        responseObserver.onCompleted();
    }

    private HealthCheckResponse buildStatus() {
        return HealthCheckResponse.newBuilder()
                .setStatus(HealthCheckResponse.ServingStatus.SERVING)
                .build();
    }
}
