diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index abfeb52d..76c84e0e 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,5 +1,44 @@ class HealthController < ApplicationController + def index - head :ok + database_check_results = check_db_connections + if all_database_healthy?(database_check_results) + render json: {status: "ok"}, status: :ok + else + render json: {status: "fail"}, status: :internal_server_error + end + rescue StandardError + render json: {status: "fail"}, status: :internal_server_error + end + + private + def all_database_healthy?(database_check_results) + database_check_results.values.all? { |status| status[:status] == "ok" } + end + + def check_db_connections + db_status = {} + databases.each do |role, connection| + db_status[role] = perform_health_check(connection) + ensure + ActiveRecord::Base.clear_active_connections! + end + db_status + end + + def databases + { + primary: ActiveRecord::Base.connected_to(role: :writing) { ApplicationRecord.connection }, + datahub: ActiveRecord::Base.connected_to(role: :reading) { DatahubRecord.connection } + } + end + + def perform_health_check(connection) + if connection + connection.execute('SELECT 1') + {status: 'ok'} + else + {status: 'fail'} + end end end diff --git a/spec/features/health_spec.rb b/spec/features/health_spec.rb index eca08d9c..f3852c3e 100644 --- a/spec/features/health_spec.rb +++ b/spec/features/health_spec.rb @@ -1,9 +1,50 @@ require 'rails_helper' RSpec.feature "Healthcheck", type: :feature do - scenario 'As a healthcheck bot I want to check if everything is ok' do - visit health_path + context 'when healthcheck passes' do + scenario 'With healthcheck I want to check if everything is ok' do + visit health_path - expect(page.status_code).to be(200) + expect(page.status_code).to be(200) + + returned_data = JSON.parse(page.body) + + expect(returned_data["status"]).to eq("ok") + end + end + + context 'when healthcheck fails' do + scenario 'unexpected error in health check' do + allow_any_instance_of(HealthController).to receive(:all_database_healthy?).and_raise(StandardError, 'Unexpected error') + + visit health_path + + expect(page.status_code).to be(500) + returned_data = JSON.parse(page.body) + + expect(returned_data["status"]).to eq("fail") + end + + scenario 'primary database fails' do + allow(ApplicationRecord.connection).to receive(:execute).and_raise(StandardError, 'Something went wrong in primary db') + + visit health_path + + expect(page.status_code).to be(500) + returned_data = JSON.parse(page.body) + + expect(returned_data["status"]).to eq("fail") + end + + scenario 'datahub database fails' do + allow(DatahubRecord.connection).to receive(:execute).and_raise(StandardError, 'Something went wrong in datahub db') + + visit health_path + + expect(page.status_code).to be(500) + returned_data = JSON.parse(page.body) + + expect(returned_data["status"]).to eq("fail") + end end end