diff --git a/.github/workflows/svc-bgs-api-integration-test.yml b/.github/workflows/svc-bgs-api-integration-test.yml index c79730d3da..ca5861accd 100644 --- a/.github/workflows/svc-bgs-api-integration-test.yml +++ b/.github/workflows/svc-bgs-api-integration-test.yml @@ -60,45 +60,8 @@ jobs: # Quit after 60 seconds retries: 30 - # Temporary step added to avoid race condition. Currently, there is no health check in 'svc-bgs-api'; therefore, - # at this step, it is unknown if svc-bgs-api has yet to create the 'bgs-api' exchange. - - name: 'Create bgs-api exchange' - uses: indiesdev/curl@v1.1 - with: - url: 'http://localhost:15672/api/exchanges/%2f/bgs-api' - method: 'PUT' - basic-auth-token: '${{env.RABBITMQ_BASIC_AUTH}}' - body: '{"type":"direct", "durable":true, "auto_delete":true}' - accept: 201, 204 - retries: 3 - log-response: true - - # Temporary step added to avoid race condition. Currently, there is no health check in 'svc-bgs-api'; therefore, - # at this step, it is unknown if svc-bgs-api has yet to create the 'add-note' queue. - - name: 'Create add-note queue' - uses: indiesdev/curl@v1.1 - with: - url: 'http://localhost:15672/api/queues/%2f/add-note' - method: 'PUT' - basic-auth-token: '${{env.RABBITMQ_BASIC_AUTH}}' - body: '{"durable":true, "auto_delete":true}' - accept: 201, 204 - retries: 3 - log-response: true - - # Temporary step added to avoid race condition. Currently, there is no health check in 'svc-bgs-api'; therefore, - # at this step, it is unknown if svc-bgs-api has yet to create the binding from 'bgs-api' exchange to 'add-note' - # queue. - - name: 'Create binding for add-note queue to bgs-api exchange' - uses: indiesdev/curl@v1.1 - with: - url: 'http://localhost:15672/api/bindings/%2f/e/bgs-api/q/add-note' - method: 'POST' - basic-auth-token: '${{env.RABBITMQ_BASIC_AUTH}}' - body: '{"routing_key":"add-note","arguments":{}}' - accept: 201, 204 - retries: 3 - log-response: true + - name: 'Check for healthy BGS container' + run: timeout 180s sh -c 'until docker ps | grep ".*svc-bgs-api.*" | grep -q healthy; do echo "Waiting for container to be healthy..."; sleep 2; done' - name: 'Create add-note-response queue' uses: indiesdev/curl@v1.1 diff --git a/svc-bgs-api/Dockerfile b/svc-bgs-api/Dockerfile index 09275c141e..364fed5a89 100644 --- a/svc-bgs-api/Dockerfile +++ b/svc-bgs-api/Dockerfile @@ -35,5 +35,4 @@ ENTRYPOINT ["/app/entrypoint-wrapper.sh"] ARG HEALTHCHECK_PORT_ARG=8080 ENV HEALTHCHECK_PORT=${HEALTHCHECK_PORT_ARG} -# TODO: add healthcheck for Ruby microservice -# HEALTHCHECK CMD curl --fail http://localhost:${HEALTHCHECK_PORT}/actuator/health || exit 1 +HEALTHCHECK CMD bundle exec ruby healthcheck/healthcheck.rb diff --git a/svc-bgs-api/src/config/constants.rb b/svc-bgs-api/src/config/constants.rb new file mode 100644 index 0000000000..0e0a99bafc --- /dev/null +++ b/svc-bgs-api/src/config/constants.rb @@ -0,0 +1,15 @@ +# Contains constant definitions for queues, exchanges, and fields + +BUNNY_ARGS = { + host: ENV['RABBITMQ_PLACEHOLDERS_HOST'] || "localhost", + user: ENV['RABBITMQ_USERNAME'] || "guest", + password: ENV['RABBITMQ_PASSWORD'] || "guest" +} + +CAMEL_MQ_PROPERTIES = { durable: true, auto_delete: true } + +BGS_EXCHANGE_NAME = "bgs-api" + +HEALTHCHECK_REPLY_QUEUE = "healthcheck-reply" +HEALTHCHECK_QUEUE = "healthcheck" +ADD_NOTE_QUEUE = "add-note" diff --git a/svc-bgs-api/src/healthcheck/healthcheck.rb b/svc-bgs-api/src/healthcheck/healthcheck.rb new file mode 100644 index 0000000000..2666bc2500 --- /dev/null +++ b/svc-bgs-api/src/healthcheck/healthcheck.rb @@ -0,0 +1,23 @@ +# Inspired by the README at https://github.com/ruby-amqp/bunny + +require 'bunny' +require 'json' + +require_relative '../config/constants' + +conn = Bunny.new(BUNNY_ARGS) +conn.start + +ch = conn.create_channel +x = ch.direct(BGS_EXCHANGE_NAME, CAMEL_MQ_PROPERTIES) + +r = ch.queue(HEALTHCHECK_REPLY_QUEUE, CAMEL_MQ_PROPERTIES).bind(x, :routing_key => HEALTHCHECK_REPLY_QUEUE) + +q = ch.queue(HEALTHCHECK_QUEUE, CAMEL_MQ_PROPERTIES).bind(x, :routing_key => HEALTHCHECK_QUEUE) +q.publish('{"health": "check"}', :reply_to => HEALTHCHECK_REPLY_QUEUE) + +delivery_info, properties, payload = r.pop + +if JSON.parse(payload)["statusCode"] != 200 then + raise "svc-bgs-api healthcheck failed" +end diff --git a/svc-bgs-api/src/main_consumer.rb b/svc-bgs-api/src/main_consumer.rb index 406b6ec9c0..88e7abd802 100644 --- a/svc-bgs-api/src/main_consumer.rb +++ b/svc-bgs-api/src/main_consumer.rb @@ -2,20 +2,25 @@ require 'active_support' require_relative 'config/setup' +require_relative 'config/constants' require 'rabbit_subscriber' require 'bgs_client' -BUNNY_ARGS = { - host: ENV['RABBITMQ_PLACEHOLDERS_HOST'].presence || "localhost", - user: ENV['RABBITMQ_USERNAME'].presence || "guest", - password: ENV['RABBITMQ_PASSWORD'].presence || "guest" -} - def initialize_subscriber(bgs_client) subscriber = RabbitSubscriber.new(BUNNY_ARGS) - subscriber.setup_queue(exchange_name: 'bgs-api', queue_name: 'add-note') - subscriber.subscribe_to('bgs-api', 'add-note') do |json| + + # Setup queue/subscription for healthcheck + subscriber.setup_queue(exchange_name: BGS_EXCHANGE_NAME, queue_name: HEALTHCHECK_QUEUE) + subscriber.subscribe_to(BGS_EXCHANGE_NAME, HEALTHCHECK_QUEUE) do |json| + $logger.info "Subscriber received healthcheck request #{json}" + { statusCode: 200 } + end + subscriber + + # Setup queue/subscription for BGS + subscriber.setup_queue(exchange_name: BGS_EXCHANGE_NAME, queue_name: ADD_NOTE_QUEUE) + subscriber.subscribe_to(BGS_EXCHANGE_NAME, ADD_NOTE_QUEUE) do |json| $logger.info "Subscriber received request #{json}" begin bgs_client.handle_request(json)