From d66f6a369b05b23fb483beb62277ec37d0c31c47 Mon Sep 17 00:00:00 2001 From: FinnIckler Date: Wed, 10 Jul 2024 12:02:33 +0200 Subject: [PATCH] Use shoryuken to allow workers to access Rails so we can trigger emails from the worker (#602) * fix missing self in email API * remove unnecessary initializers * use shuryuken to enqueue to sqs * correct seeds * switch name in email API * code changes to make shoryuken work * add worker to wca-main network * run rubocop * add QUEUE_NAME to test * stub registration email request * fix test docker compose * stub mailer in bulk update * set a message_group_id * use custom message_deduplication id and message_group_id * run rubocop * use set to change SQS SendMessage Parameters * introduce variables for better readability * change QUEUE_URL to QUEUE_NAME in infra * add entrypoint for worker * add missing parameters * add shoryuken config file * Add +x for entrypoint * add BUILD_TAG to worker as well --- .github/workflows/deploy.yaml | 2 + .github/workflows/pr.yaml | 2 + Gemfile | 3 + Gemfile.lock | 5 ++ app/controllers/registration_controller.rb | 16 ++--- .../registration_processor.rb | 40 ++++--------- app/worker/env_config.rb | 27 --------- app/worker/queue_poller.rb | 59 ------------------- bin/entrypoint-worker.sh | 2 + config/application.rb | 2 +- config/initializers/aws.rb | 12 ---- config/initializers/shoryuken.rb | 25 ++++++++ config/shoryuken.yml | 4 ++ db/seeds.rb | 29 ++++----- docker-compose.backend-test.yml | 9 +-- docker-compose.yml | 15 +++-- dockerfile.worker | 7 ++- env_config.rb | 2 +- infra/handler/main.tf | 4 +- infra/handler/variables.tf | 2 +- infra/staging/lambda.tf | 4 ++ infra/staging/main.tf | 36 +---------- infra/worker/lambda.tf | 6 ++ infra/worker/main.tf | 8 +-- infra/worker/variables.tf | 3 +- lib/email_api.rb | 16 ++++- .../registration_controller_spec.rb | 4 ++ 27 files changed, 132 insertions(+), 212 deletions(-) rename app/{worker => jobs}/registration_processor.rb (62%) delete mode 100644 app/worker/env_config.rb delete mode 100644 app/worker/queue_poller.rb create mode 100755 bin/entrypoint-worker.sh delete mode 100644 config/initializers/aws.rb create mode 100644 config/initializers/shoryuken.rb create mode 100644 config/shoryuken.yml diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index cba3d8d0..239d2dcd 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -38,6 +38,8 @@ jobs: tags: ${{ steps.login-ecr.outputs.registry }}/wca-registration-worker:latest cache-from: type=gha cache-to: type=gha,mode=max + build-args: | + BUILD_TAG=${{ github.sha }} - name: Deploy worker run: | aws ecs update-service --cluster wca-registration --service wca-registration-worker --force-new-deployment diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index ef172d71..316da0d4 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -68,6 +68,8 @@ jobs: ${{ steps.login-ecr.outputs.registry }}/wca-registration-worker:staging cache-from: type=gha cache-to: type=gha,mode=max + build-args: | + BUILD_TAG=${{ github.sha }} - name: Deploy if triggered if: steps.trigger-deployment.outputs.triggered == 'true' env: diff --git a/Gemfile b/Gemfile index 6200505a..e4c60644 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,9 @@ gem 'dynamoid', '3.8.0' # SQS for adding data into a queue gem 'aws-sdk-sqs' +# SQS Job Management +gem 'shoryuken' + # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] gem 'kredis' diff --git a/Gemfile.lock b/Gemfile.lock index 9ec2dea3..525ea163 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -326,6 +326,10 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-prof (1.7.0) ruby-progressbar (1.13.0) + shoryuken (6.2.1) + aws-sdk-core (>= 2) + concurrent-ruby + thor sqlite3 (1.7.3-aarch64-linux) sqlite3 (1.7.3-x86_64-linux) stringio (3.1.1) @@ -381,6 +385,7 @@ DEPENDENCIES rubocop rubocop-rails ruby-prof + shoryuken sqlite3 (~> 1.4) superconfig tzinfo-data diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index 0bd8e9a0..052113c0 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -32,11 +32,9 @@ def count end def create - queue_url = ENV['QUEUE_URL'] || $sqs.get_queue_url(queue_name: 'registrations.fifo').queue_url event_ids = params.dig('competing', 'event_ids') comment = params.dig('competing', 'comment') || '' guests = params['guests'] || 0 - id = SecureRandom.uuid step_data = { created_at: Time.now.utc, @@ -44,7 +42,7 @@ def create user_id: @user_id, competition_id: @competition_id, lane_name: 'competing', - step: 'Event Registration', + step: 'EventRegistration', step_details: { registration_status: 'pending', event_ids: event_ids, @@ -52,13 +50,10 @@ def create guests: guests, }, } + message_deduplication_id = "#{step_data[:lane_name]}-#{step_data[:step]}-#{step_data[:attendee_id]}" + message_group_id = step_data[:competition_id] - $sqs.send_message({ - queue_url: queue_url, - message_body: step_data.to_json, - message_group_id: id, - message_deduplication_id: id, - }) + RegistrationProcessor.set(message_group_id: message_group_id, message_deduplication_id: message_deduplication_id).perform_later(step_data) render json: { status: 'accepted', message: 'Started Registration Process' }, status: :accepted end @@ -136,8 +131,7 @@ def process_update(update_request) # Don't send email if we only change the waiting list position if waiting_list_position.blank? - # commented out until shuryuken PR is merged - # EmailApi.send_update_email(@competition_id, user_id, status, @current_user) + EmailApi.send_update_email(@competition_id, user_id, status, @current_user) end { diff --git a/app/worker/registration_processor.rb b/app/jobs/registration_processor.rb similarity index 62% rename from app/worker/registration_processor.rb rename to app/jobs/registration_processor.rb index a026c763..a2070a11 100644 --- a/app/worker/registration_processor.rb +++ b/app/jobs/registration_processor.rb @@ -1,31 +1,19 @@ # frozen_string_literal: true -require 'aws-sdk-dynamodb' -require 'dynamoid' -require 'httparty' +class RegistrationProcessor < ApplicationJob + include Shoryuken::Worker -class RegistrationProcessor - def initialize - Dynamoid.configure do |config| - config.region = EnvConfig.AWS_REGION - config.namespace = nil - if EnvConfig.CODE_ENVIRONMENT == 'development' - config.endpoint = EnvConfig.LOCALSTACK_ENDPOINT - else - config.credentials = Aws::ECSCredentials.new(retries: 3) - end - end - end + queue_as EnvConfig.QUEUE_NAME - def process_message(message) - puts "Working on Message: #{message}" - if message['step'] == 'Event Registration' - event_registration(message['competition_id'], - message['user_id'], - message['step_details']['event_ids'], - message['step_details']['comment'], - message['step_details']['guests'], - message['created_at']) + def perform(message) + Rails.logger.debug { "Working on Message: #{message}" } + if message[:step] == 'EventRegistration' + event_registration(message[:competition_id], + message[:user_id], + message[:step_details][:event_ids], + message[:step_details][:comment], + message[:step_details][:guests], + message[:created_at]) end end @@ -56,9 +44,7 @@ def event_registration(competition_id, user_id, event_ids, comment, guests, crea else registration.update_attributes(lanes: registration.lanes.append(competing_lane), guests: guests) end - if EnvConfig.CODE_ENVIRONMENT == 'production' - EmailApi.send_creation_email(competition_id, user_id) - end + EmailApi.send_creation_email(competition_id, user_id) end # rubocop:enable Metrics/ParameterLists end diff --git a/app/worker/env_config.rb b/app/worker/env_config.rb deleted file mode 100644 index 1b4f08c4..00000000 --- a/app/worker/env_config.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require 'superconfig' - -# Don't run this on the handler -unless defined?(Rails) - EnvConfig = SuperConfig.new do - # We don't have RAILS_ENV in ruby - if ENV.fetch('CODE_ENVIRONMENT', 'development') == 'development' - mandatory :LOCALSTACK_ENDPOINT, :string - # Have to be the same as in localstack to simulate authentication - mandatory :AWS_ACCESS_KEY_ID, :string - mandatory :AWS_SECRET_ACCESS_KEY, :string - optional :WCA_HOST, :string, '' - optional :CODE_ENVIRONMENT, :string, 'development' - else - mandatory :QUEUE_URL, :string - mandatory :WCA_HOST, :string - mandatory :CODE_ENVIRONMENT, :string - end - # We even need the AWS_REGION in dev because we fake authenticate with localstack - mandatory :AWS_REGION, :string - mandatory :PROMETHEUS_EXPORTER, :string - mandatory :DYNAMO_REGISTRATIONS_TABLE, :string - mandatory :REGISTRATION_HISTORY_DYNAMO_TABLE, :string - end -end diff --git a/app/worker/queue_poller.rb b/app/worker/queue_poller.rb deleted file mode 100644 index 6a67e457..00000000 --- a/app/worker/queue_poller.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -require 'zeitwerk' -loader = Zeitwerk::Loader.new -loader.push_dir("#{__dir__}/../../lib") -loader.push_dir("#{__dir__}/../models") -loader.setup - -require 'json' -require 'aws-sdk-sqs' -require 'prometheus_exporter/client' -require 'prometheus_exporter/instrumentation' -require 'prometheus_exporter/metric' -require_relative 'env_config' -require_relative 'registration_processor' - -class QueuePoller - # Wait for 1 second so we can start work on 10 messages at at time - # These numbers can be tweaked after load testing - WAIT_TIME = 1 - MAX_MESSAGES = 10 - MAX_RETRY = 5 - - def self.perform - PrometheusExporter::Client.default = PrometheusExporter::Client.new(host: ENV.fetch('PROMETHEUS_EXPORTER'), port: 9091) - # Instrumentation of the worker process is currently disabled per https://github.com/discourse/prometheus_exporter/issues/282 - suffix = "-#{ENV.fetch("CODE_ENVIRONMENT", "development")}" - registrations_counter = PrometheusExporter::Client.default.register('counter', "registrations_counter-#{suffix}", 'The number of Registrations processed') - error_counter = PrometheusExporter::Client.default.register('counter', "worker_error_counter-#{suffix}", 'The number of Errors in the worker') - - @sqs ||= if ENV['LOCALSTACK_ENDPOINT'] - Aws::SQS::Client.new(endpoint: ENV['LOCALSTACK_ENDPOINT']) - else - Aws::SQS::Client.new - end - queue_url = ENV['QUEUE_URL'] || @sqs.get_queue_url(queue_name: 'registrations.fifo').queue_url - processor = RegistrationProcessor.new - poller = Aws::SQS::QueuePoller.new(queue_url) - poller.poll(wait_time_seconds: WAIT_TIME, max_number_of_messages: MAX_MESSAGES) do |messages| - messages.each do |msg| - # messages are deleted from the queue when the block returns normally! - puts "Received message with ID: #{msg.message_id}" - puts "Message body: #{msg.body}" - body = JSON.parse msg.body - begin - processor.process_message(body) - registrations_counter.increment - rescue StandardError => e - # unexpected error occurred while processing messages, - # log it, and skip delete so it can be re-processed later - puts "Error #{e} when processing message with ID #{msg}" - error_counter.increment - - throw :skip_delete - end - end - end - end -end diff --git a/bin/entrypoint-worker.sh b/bin/entrypoint-worker.sh new file mode 100755 index 00000000..1b8a5102 --- /dev/null +++ b/bin/entrypoint-worker.sh @@ -0,0 +1,2 @@ +#!/bin/bash -e +bundle exec shoryuken -R -C config/shoryuken.yml diff --git a/config/application.rb b/config/application.rb index b7b4d19d..ba4a1e8d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,7 +16,7 @@ class Application < Rails::Application config.load_defaults 7.0 config.autoload_paths += Dir["#{config.root}/lib"] - Rails.autoloaders.main.ignore("#{config.root}/app/worker") + config.active_job.queue_adapter = :shoryuken # Only loads a smaller set of middleware suitable for API only apps. # Middleware like session, flash, cookies can be added back manually. diff --git a/config/initializers/aws.rb b/config/initializers/aws.rb deleted file mode 100644 index 67648653..00000000 --- a/config/initializers/aws.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -# config/initializers/aws.rb - -if Rails.env.production? - $dynamodb = Aws::DynamoDB::Client.new - $sqs = Aws::SQS::Client.new -else - # We are using localstack to emulate AWS in dev - $dynamodb = Aws::DynamoDB::Client.new(endpoint: EnvConfig.LOCALSTACK_ENDPOINT) - $sqs = Aws::SQS::Client.new(endpoint: EnvConfig.LOCALSTACK_ENDPOINT) -end diff --git a/config/initializers/shoryuken.rb b/config/initializers/shoryuken.rb new file mode 100644 index 00000000..1beec62c --- /dev/null +++ b/config/initializers/shoryuken.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +Shoryuken.configure_client do |config| + if Rails.env.local? + config.sqs_client = Aws::SQS::Client.new( + region: EnvConfig.AWS_REGION, + access_key_id: EnvConfig.AWS_ACCESS_KEY_ID, + secret_access_key: EnvConfig.AWS_SECRET_ACCESS_KEY, + endpoint: EnvConfig.LOCALSTACK_ENDPOINT, + verify_checksums: false, + ) + end +end + +Shoryuken.configure_server do |config| + if Rails.env.local? + config.sqs_client = Aws::SQS::Client.new( + region: EnvConfig.AWS_REGION, + access_key_id: EnvConfig.AWS_ACCESS_KEY_ID, + secret_access_key: EnvConfig.AWS_SECRET_ACCESS_KEY, + endpoint: EnvConfig.LOCALSTACK_ENDPOINT, + verify_checksums: false, + ) + end +end diff --git a/config/shoryuken.yml b/config/shoryuken.yml new file mode 100644 index 00000000..1d62f2f2 --- /dev/null +++ b/config/shoryuken.yml @@ -0,0 +1,4 @@ +queues: + - <%= ENV['QUEUE_NAME'] %> +delay: 1 +concurrency: 2 diff --git a/db/seeds.rb b/db/seeds.rb index ac25c3b6..6dd94cb9 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -2,6 +2,8 @@ # Failsafe so this is never run in production (the task doesn't have permissions to create tables anyway) unless Rails.env.production? + dynamodb = Aws::DynamoDB::Client.new(endpoint: EnvConfig.LOCALSTACK_ENDPOINT) + sqs = Aws::SQS::Client.new(endpoint: EnvConfig.LOCALSTACK_ENDPOINT) # Create the DynamoDB Tables table_name = EnvConfig.DYNAMO_REGISTRATIONS_TABLE key_schema = [ @@ -45,23 +47,22 @@ }, ] begin - $dynamodb.create_table({ - table_name: table_name, - key_schema: key_schema, - attribute_definitions: attribute_definitions, - provisioned_throughput: provisioned_throughput, - global_secondary_indexes: global_secondary_indexes, - }) + dynamodb.create_table({ + table_name: table_name, + key_schema: key_schema, + attribute_definitions: attribute_definitions, + provisioned_throughput: provisioned_throughput, + global_secondary_indexes: global_secondary_indexes, + }) rescue Aws::DynamoDB::Errors::ResourceInUseException Rails.logger.debug 'Database Already exists' end # Create SQS Queue - queue_name = 'registrations.fifo' - $sqs.create_queue({ - queue_name: queue_name, - attributes: { - FifoQueue: 'true', - }, - }) + sqs.create_queue({ + queue_name: EnvConfig.QUEUE_NAME, + attributes: { + FifoQueue: 'true', + }, + }) end diff --git a/docker-compose.backend-test.yml b/docker-compose.backend-test.yml index 62f8d0e9..95923dbc 100644 --- a/docker-compose.backend-test.yml +++ b/docker-compose.backend-test.yml @@ -11,6 +11,7 @@ services: PROMETHEUS_EXPORTER: "prometheus_exporter" REDIS_URL: "redis://redis:6379" RAILS_ENV: test + QUEUE_NAME: "registrations.fifo" volumes: - .:/app - gems_volume_handler:/usr/local/bundle @@ -54,6 +55,7 @@ services: AWS_SECRET_ACCESS_KEY: "fake-access-key" PROMETHEUS_EXPORTER: "prometheus_exporter" DYNAMO_REGISTRATIONS_TABLE: "registrations-development" + QUEUE_NAME: "registrations.fifo" volumes: - .:/app - gems_volume_worker:/usr/local/bundle @@ -61,14 +63,9 @@ services: # First, install Ruby and Node dependencies # Start the server and bind to 0.0.0.0 (vs 127.0.0.1) so Docker's port mappings work correctly command: > - bash -c 'bundle install && - while ! curl http://wca_registration_handler:3000/healthcheck >/dev/null 2>&1; do - echo "Waiting for Handler to be ready" && sleep 5 ; - done && ruby -r "/app/app/worker/queue_poller.rb" -e "QueuePoller.perform"' + bash -c 'bundle install && bundle exec shoryuken -R -q registrations.fifo' networks: - wca-registration - healthcheck: - test: pgrep ruby || exit 1 dns: # Set the DNS server to be the LocalStack container - 10.0.2.20 diff --git a/docker-compose.yml b/docker-compose.yml index fac55d41..5951597b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ services: PROMETHEUS_EXPORTER: "prometheus_exporter" REDIS_URL: "redis://redis:6379" RAILS_ENV: development + QUEUE_NAME: "registrations.fifo" volumes: - .:/app - gems_volume_handler:/usr/local/bundle @@ -28,6 +29,8 @@ services: - localstack - prometheus_exporter - redis + healthcheck: + test: curl --fail http://localhost:3000/healthcheck dns: # Set the DNS server to be the LocalStack container - 10.0.2.20 @@ -58,6 +61,7 @@ services: DYNAMO_REGISTRATIONS_TABLE: "registrations-development" REGISTRATION_HISTORY_DYNAMO_TABLE: "registration-history-development" CODE_ENVIRONMENT: "development" + QUEUE_NAME: "registrations.fifo" volumes: - .:/app - gems_volume_worker:/usr/local/bundle @@ -65,14 +69,13 @@ services: # First, install Ruby and Node dependencies # Start the server and bind to 0.0.0.0 (vs 127.0.0.1) so Docker's port mappings work correctly command: > - bash -c 'bundle install && - while ! curl http://wca_registration_handler:3000/healthcheck >/dev/null 2>&1; do - echo "Waiting for Handler to be ready" && sleep 5 ; - done && ruby -r "/app/app/worker/queue_poller.rb" -e "QueuePoller.perform"' + bash -c 'bundle install && bundle exec shoryuken -R -C config/shoryuken.yml' networks: - wca-registration + - wca-main depends_on: - - wca_registration_handler + wca_registration_handler: + condition: service_healthy dns: # Set the DNS server to be the LocalStack container - 10.0.2.20 @@ -85,7 +88,7 @@ services: - "127.0.0.1:4566:4566" # LocalStack Gateway - "127.0.0.1:4510-4559:4510-4559" # external services port range environment: - - DEBUG=${DEBUG-} + - LS_LOG=error - DOCKER_HOST=unix:///var/run/docker.sock volumes: - "./localstack/volume:/var/lib/localstack" diff --git a/dockerfile.worker b/dockerfile.worker index 681b3b81..1aafc029 100644 --- a/dockerfile.worker +++ b/dockerfile.worker @@ -1,7 +1,8 @@ FROM ruby:3.3.0 EXPOSE 3000 - -ENV DEBIAN_FRONTEND noninteractive +ARG BUILD_TAG=local +ENV DEBIAN_FRONTEND=noninteractive \ + BUILD_TAG=$BUILD_TAG WORKDIR /app # Add PPA needed to install nodejs. @@ -28,4 +29,4 @@ ENV RAILS_ENV production RUN bundle install --without development test # Install production gems for the worker -CMD ["ruby", "-r", "/app/app/worker/queue_poller.rb", "-e" , "QueuePoller.perform"] +ENTRYPOINT ["/app/bin/entrypoint-worker.sh"] diff --git a/env_config.rb b/env_config.rb index 98f31078..a798e38b 100644 --- a/env_config.rb +++ b/env_config.rb @@ -8,7 +8,6 @@ mandatory :VAULT_ADDR, :string mandatory :TASK_ROLE, :string mandatory :REGISTRATION_LIVE_SITE, :bool - mandatory :QUEUE_URL, :string mandatory :WCA_HOST, :string mandatory :REDIS_URL, :string mandatory :VAULT_APPLICATION, :string @@ -27,4 +26,5 @@ mandatory :PROMETHEUS_EXPORTER, :string mandatory :DYNAMO_REGISTRATIONS_TABLE, :string mandatory :REGISTRATION_HISTORY_DYNAMO_TABLE, :string + mandatory :QUEUE_NAME, :string end diff --git a/infra/handler/main.tf b/infra/handler/main.tf index a152de8c..5d095874 100644 --- a/infra/handler/main.tf +++ b/infra/handler/main.tf @@ -41,8 +41,8 @@ locals { value = var.shared_resources.dynamo_registration_history_table.name }, { - name = "QUEUE_URL", - value = var.shared_resources.queue.url + name = "QUEUE_NAME", + value = var.shared_resources.queue.name }, { name = "PROMETHEUS_EXPORTER" diff --git a/infra/handler/variables.tf b/infra/handler/variables.tf index 7ba3dea4..a1f2afa3 100644 --- a/infra/handler/variables.tf +++ b/infra/handler/variables.tf @@ -59,7 +59,7 @@ variable "shared_resources" { }), queue: object({ arn: string, - url: string + name: string }), ecs_cluster: object({ id: string, diff --git a/infra/staging/lambda.tf b/infra/staging/lambda.tf index 71dc2ae5..09c6d42c 100644 --- a/infra/staging/lambda.tf +++ b/infra/staging/lambda.tf @@ -108,6 +108,7 @@ resource "aws_api_gateway_method_response" "staging_method_response" { response_parameters = { "method.response.header.Content-Type" = true + "method.response.header.Access-Control-Allow-Origin" = false } } @@ -123,5 +124,8 @@ resource "aws_api_gateway_integration_response" "registration_status_integration queue_count = "Queue Count" }) } + response_parameters = { + "method.response.header.Access-Control-Allow-Origin" = "'*'" + } depends_on = [aws_api_gateway_resource.prod, aws_api_gateway_method.poll_registration_status_method, aws_api_gateway_method_response.staging_method_response, aws_api_gateway_integration.poll_registration_integration] } diff --git a/infra/staging/main.tf b/infra/staging/main.tf index f013cadb..a8a067eb 100644 --- a/infra/staging/main.tf +++ b/infra/staging/main.tf @@ -3,36 +3,6 @@ resource "aws_cloudwatch_log_group" "this" { } locals { - worker_environment = [ - { - name = "PROMETHEUS_EXPORTER" - value = var.prometheus_address - }, - { - name = "AWS_REGION" - value = var.region - }, - { - name = "WCA_HOST" - value = var.wca_host - }, - { - name = "DYNAMO_REGISTRATIONS_TABLE", - value = aws_dynamodb_table.registrations.name - }, - { - name = "REGISTRATION_HISTORY_DYNAMO_TABLE", - value = aws_dynamodb_table.registration_history.name - }, - { - name = "QUEUE_URL", - value = aws_sqs_queue.this.url - }, - { # We don't have access to RAILS_ENV as the worker uses plain ruby - name = "CODE_ENVIRONMENT", - value = "staging" - } - ] app_environment = [ { name = "WCA_HOST" @@ -59,8 +29,8 @@ locals { value = var.vault_address }, { - name = "QUEUE_URL", - value = aws_sqs_queue.this.url + name = "QUEUE_NAME", + value = aws_sqs_queue.this.name }, { name = "TASK_ROLE" @@ -251,7 +221,7 @@ resource "aws_ecs_task_definition" "this" { awslogs-stream-prefix = "${var.name_prefix}-worker" } } - environment = local.worker_environment + environment = local.app_environment healthCheck = { command = ["CMD-SHELL", "pgrep ruby || exit 1"] interval = 30 diff --git a/infra/worker/lambda.tf b/infra/worker/lambda.tf index eb833536..5b52b28c 100644 --- a/infra/worker/lambda.tf +++ b/infra/worker/lambda.tf @@ -108,6 +108,7 @@ resource "aws_api_gateway_method_response" "registration_status_method" { response_parameters = { "method.response.header.Content-Type" = true + "method.response.header.Access-Control-Allow-Origin" = false } } @@ -123,6 +124,11 @@ resource "aws_api_gateway_integration_response" "registration_status_integration queue_count = "Queue Count" }) } + + response_parameters = { + "method.response.header.Access-Control-Allow-Origin" = "'*'" + } + depends_on = [aws_api_gateway_resource.prod, aws_api_gateway_method.poll_registration_status_method, aws_api_gateway_method_response.registration_status_method, aws_api_gateway_integration.poll_registration_integration] } resource "aws_api_gateway_deployment" "this" { diff --git a/infra/worker/main.tf b/infra/worker/main.tf index 712964a5..c827a819 100644 --- a/infra/worker/main.tf +++ b/infra/worker/main.tf @@ -13,12 +13,8 @@ locals { value = var.region }, { - name = "QUEUE_URL", - value = var.shared_resources.queue.url - }, - { - name = "CODE_ENVIRONMENT" - value = "production" + name = "QUEUE_NAME", + value = var.shared_resources.queue.name }, { name = "PROMETHEUS_EXPORTER" diff --git a/infra/worker/variables.tf b/infra/worker/variables.tf index 392745e3..c318a612 100644 --- a/infra/worker/variables.tf +++ b/infra/worker/variables.tf @@ -46,7 +46,8 @@ variable "shared_resources" { }), queue: object({ arn: string, - url: string + url: string, + name: string }), ecs_cluster: object({ id: string, diff --git a/lib/email_api.rb b/lib/email_api.rb index 7e9f7773..50fa8090 100644 --- a/lib/email_api.rb +++ b/lib/email_api.rb @@ -9,10 +9,22 @@ def self.registration_email_path end def self.send_update_email(competition_id, user_id, status, current_user) - HTTParty.post(EmailApi.registration_email_path, headers: { WCA_API_HEADER => self.wca_token }, body: { competition_id: competition_id, user_id: user_id, status: status, action: 'update', current_user: current_user }) + HTTParty.post(EmailApi.registration_email_path, headers: { WCA_API_HEADER => self.wca_token }, body: { + competition_id: competition_id, + user_id: user_id, + registration_status: status, + registration_action: 'update', + current_user: current_user, + }) end def self.send_creation_email(competition_id, user_id) - HTTParty.post(EmailApi.registration_email_path, headers: { WCA_API_HEADER => self.wca_token }, body: { competition_id: competition_id, user_id: user_id, status: 'pending', action: 'create', current_user: user_id }) + HTTParty.post(EmailApi.registration_email_path, headers: { WCA_API_HEADER => self.wca_token }, body: { + competition_id: competition_id, + user_id: user_id, + registration_status: 'pending', + registration_action: 'create', + current_user: user_id, + }) end end diff --git a/spec/controllers/registration_controller_spec.rb b/spec/controllers/registration_controller_spec.rb index d15cf9d6..95ae93e7 100644 --- a/spec/controllers/registration_controller_spec.rb +++ b/spec/controllers/registration_controller_spec.rb @@ -8,6 +8,7 @@ before do @competition = FactoryBot.build(:competition) stub_request(:get, CompetitionApi.comp_api_url(@competition['id'])).to_return(status: 200, body: @competition.to_json) + stub_request(:post, EmailApi.registration_email_path).to_return(status: 200, body: { emails_sent: 1 }.to_json) @registration = FactoryBot.create(:registration) @@ -54,6 +55,9 @@ end describe '#bulk_update' do + before do + stub_request(:post, EmailApi.registration_email_path).to_return(status: 200, body: { emails_sent: 1 }.to_json) + end # TODO: Consider refactor into separate contexts with one expect() per it-block it 'returns a 422 if there are validation errors' do registration = FactoryBot.create(:registration)