class ServingServiceGRpcController extends ServingServiceImplBase {

  @Override
  public void getOnlineFeatures(
      GetOnlineFeaturesRequest request,
      StreamObserver<GetOnlineFeaturesResponse> responseObserver) {
    Span span = tracer.buildSpan("getOnlineFeatures").start();
    try (Scope scope = tracer.scopeManager().activate(span, false)) {
      // authorize for the project in request object.
      if (request.getProject() != null && !request.getProject().isEmpty()) {
        // project set at root level overrides the project set at feature set level
        this.authorizationService.authorizeRequest(
            SecurityContextHolder.getContext(), request.getProject());
      } else {
        // authorize for projects set in feature list, backward compatibility for
        // <=v0.5.X
        this.checkProjectAccess(request.getFeaturesList());
      }
      RequestHelper.validateOnlineRequest(request);
      GetOnlineFeaturesResponse onlineFeatures = servingService.getOnlineFeatures(request);
      responseObserver.onNext(onlineFeatures);
      responseObserver.onCompleted();
    } catch (SpecRetrievalException e) {
      log.error("Failed to retrieve specs in SpecService", e);
      responseObserver.onError(
          Status.NOT_FOUND.withDescription(e.getMessage()).withCause(e).asException());
    } catch (AccessDeniedException e) {
      log.info(String.format("User prevented from accessing one of the projects in request"));
      responseObserver.onError(
          Status.PERMISSION_DENIED
              .withDescription(e.getMessage())
              .withCause(e)
              .asRuntimeException());
    } catch (Exception e) {
      log.warn("Failed to get Online Features", e);
      responseObserver.onError(e);
    }
    span.finish();
  }

  @Autowired public  ServingServiceGRpcController(
      AuthorizationService authorizationService,
      ServingService servingService,
      FeastProperties feastProperties,
      Tracer tracer);

}