From 605747d55121dfc5681d281f18d19e81c39ac27d Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 20 Sep 2023 15:15:57 +0000 Subject: [PATCH] Add "gone" event handling; rename publish->ing - Amend `PublishingEvent` to be able to cope with "gone" document types (which don't have an `update_type`) - Add fixture for "gone" document types - Refactor naming across various parts to "publishing" rather than "publish" to refer to events and pipeline to better capture semantics --- Gemfile | 2 +- .../message_processor.rb | 10 ++-- .../publishing_event.rb} | 10 ++-- ...ne.rake => publishing_event_pipeline.rake} | 10 ++-- .../files/message_queue/gone_message.json | 21 ++++++++ .../{message.json => republish_message.json} | 0 .../publish_event_spec.rb | 33 ------------ .../message_processor_spec.rb | 6 +-- .../publishing_event_spec.rb | 51 +++++++++++++++++++ 9 files changed, 91 insertions(+), 52 deletions(-) rename lib/{publish_event_pipeline => publishing_event_pipeline}/message_processor.rb (72%) rename lib/{publish_event_pipeline/publish_event.rb => publishing_event_pipeline/publishing_event.rb} (69%) rename lib/tasks/{publish_event_pipeline.rake => publishing_event_pipeline.rake} (69%) create mode 100644 spec/fixtures/files/message_queue/gone_message.json rename spec/fixtures/files/message_queue/{message.json => republish_message.json} (100%) delete mode 100644 spec/lib/publish_event_pipeline/publish_event_spec.rb rename spec/lib/{publish_event_pipeline => publishing_event_pipeline}/message_processor_spec.rb (85%) create mode 100644 spec/lib/publishing_event_pipeline/publishing_event_spec.rb diff --git a/Gemfile b/Gemfile index b48168a..f19a2ab 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem "railties", RAILS_GEMS_VERSION gem "bootsnap", require: false gem "govuk_app_config" -# Gems for publish_event_pipeline +# Gems for publishing_event_pipeline gem "govuk_message_queue_consumer", require: false group :test do diff --git a/lib/publish_event_pipeline/message_processor.rb b/lib/publishing_event_pipeline/message_processor.rb similarity index 72% rename from lib/publish_event_pipeline/message_processor.rb rename to lib/publishing_event_pipeline/message_processor.rb index 2010201..c9384d4 100644 --- a/lib/publish_event_pipeline/message_processor.rb +++ b/lib/publishing_event_pipeline/message_processor.rb @@ -1,6 +1,6 @@ -require_relative "publish_event" +require_relative "publishing_event" -module PublishEventPipeline +module PublishingEventPipeline # Processes incoming content changes from the publishing message queue. class MessageProcessor # Implements the callback interface required by `govuk_message_queue_consumer` @@ -15,12 +15,12 @@ def initialize(message) end def call - publish_event = PublishEvent.from_message_hash(message.payload) - document = publish_event.document + publishing_event = PublishingEvent.from_message_hash(message.payload) + document = publishing_event.document Rails.logger.info( sprintf( "Received %s: %s ('%s')", - publish_event.update_type, document.content_id, document.title + publishing_event.update_type, document.content_id, document.title ), ) message.ack diff --git a/lib/publish_event_pipeline/publish_event.rb b/lib/publishing_event_pipeline/publishing_event.rb similarity index 69% rename from lib/publish_event_pipeline/publish_event.rb rename to lib/publishing_event_pipeline/publishing_event.rb index d5fc78f..f55820a 100644 --- a/lib/publish_event_pipeline/publish_event.rb +++ b/lib/publishing_event_pipeline/publishing_event.rb @@ -1,19 +1,19 @@ require "domain/searchable_document_data" -module PublishEventPipeline +module PublishingEventPipeline # Domain model for a content change event coming through from a publishing system # # @attr_reader [String] update_type The type of update that has occurred # @attr_reader [Integer] payload_version The payload version of the update # @attr_reader [Document] document The document that has been added/modified/deleted - PublishEvent = Data.define(:update_type, :payload_version, :document) do - # Creates a PublishEvent from a message hash conforming to the publishing schema. + PublishingEvent = Data.define(:update_type, :payload_version, :document) do + # Creates a PublishingEvent from a message hash conforming to the publishing schema. # # @param message_hash [Hash] The message hash to create the document from. - # @return [PublishEvent] The newly created PublishEvent instance. + # @return [PublishingEvent] The newly created PublishingEvent instance. def self.from_message_hash(message_hash) new( - update_type: message_hash.fetch("update_type"), + update_type: message_hash["update_type"], payload_version: message_hash.fetch("payload_version"), document: SearchableDocumentData.new( content_id: message_hash.fetch("content_id"), diff --git a/lib/tasks/publish_event_pipeline.rake b/lib/tasks/publishing_event_pipeline.rake similarity index 69% rename from lib/tasks/publish_event_pipeline.rake rename to lib/tasks/publishing_event_pipeline.rake index ed26d80..85b2dda 100644 --- a/lib/tasks/publish_event_pipeline.rake +++ b/lib/tasks/publishing_event_pipeline.rake @@ -1,8 +1,8 @@ require "govuk_message_queue_consumer" -require "publish_event_pipeline/message_processor" +require "publishing_event_pipeline/message_processor" -namespace :publish_event_pipeline do +namespace :publishing_event_pipeline do desc "Create RabbitMQ queue for development environment" task create_queue: :environment do # The exchange, queue, and binding are created via Terraform outside of local development: @@ -12,14 +12,14 @@ namespace :publish_event_pipeline do bunny = Bunny.new channel = bunny.start.create_channel exch = Bunny::Exchange.new(channel, :topic, "published_documents") - channel.queue(ENV.fetch("PUBLISH_EVENT_MESSAGE_QUEUE_NAME")).bind(exch, routing_key: "*.*") + channel.queue(ENV.fetch("PUBLISHING_EVENT_MESSAGE_QUEUE_NAME")).bind(exch, routing_key: "*.*") end desc "Listens to and processes messages from the published documents queue" task process_messages: :environment do GovukMessageQueueConsumer::Consumer.new( - queue_name: ENV.fetch("PUBLISH_EVENT_MESSAGE_QUEUE_NAME"), - processor: PublishEventPipeline::MessageProcessor, + queue_name: ENV.fetch("PUBLISHING_EVENT_MESSAGE_QUEUE_NAME"), + processor: PublishingEventPipeline::MessageProcessor, ).run end end diff --git a/spec/fixtures/files/message_queue/gone_message.json b/spec/fixtures/files/message_queue/gone_message.json new file mode 100644 index 0000000..4c59f09 --- /dev/null +++ b/spec/fixtures/files/message_queue/gone_message.json @@ -0,0 +1,21 @@ +{ + "document_type": "gone", + "schema_name": "gone", + "base_path": "/government/publications/guidance-for-parents-and-carers-on-safeguarding-children-in-out-of-school-settings.lt", + "locale": "lt", + "publishing_app": "whitehall", + "public_updated_at": "2023-09-15T10:25:05Z", + "details": { + "explanation": "

This translation is no longer available. You can find the original version of this content at https://www.gov.uk/government/publications/guidance-for-parents-and-carers-on-safeguarding-children-in-out-of-school-settings

\n
", + "alternative_path": "" + }, + "routes": [ + { + "path": "/government/publications/guidance-for-parents-and-carers-on-safeguarding-children-in-out-of-school-settings.lt", + "type": "exact" + } + ], + "content_id": "966bae6d-223e-4102-a6e5-e874012390e5", + "govuk_request_id": "21-1695137029.556-10.13.22.59-107886", + "payload_version": 65893230 +} diff --git a/spec/fixtures/files/message_queue/message.json b/spec/fixtures/files/message_queue/republish_message.json similarity index 100% rename from spec/fixtures/files/message_queue/message.json rename to spec/fixtures/files/message_queue/republish_message.json diff --git a/spec/lib/publish_event_pipeline/publish_event_spec.rb b/spec/lib/publish_event_pipeline/publish_event_spec.rb deleted file mode 100644 index 839cceb..0000000 --- a/spec/lib/publish_event_pipeline/publish_event_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require "publish_event_pipeline/publish_event" - -RSpec.describe PublishEventPipeline::PublishEvent do - describe ".from_message_hash" do - subject(:publish_event) { described_class.from_message_hash(message_hash) } - - context "with a valid message hash" do - let(:message_hash) { json_fixture_as_hash("message_queue/message.json") } - - it "maps the message onto a PublishEvent" do - expected_document = SearchableDocumentData.new( - content_id: "f75d26a3-25a4-4c31-beea-a77cada4ce12", - title: "Ebola medal for over 3000 heroes", - ) - expected_publish_event = described_class.new( - update_type: "republish", - payload_version: 65_861_808, - document: expected_document, - ) - - expect(publish_event).to eq(expected_publish_event) - end - end - - context "with a message hash missing required fields" do - let(:message_hash) { { "title" => "I'm incomplete" } } - - it "raises an error" do - expect { publish_event }.to raise_error(KeyError) - end - end - end -end diff --git a/spec/lib/publish_event_pipeline/message_processor_spec.rb b/spec/lib/publishing_event_pipeline/message_processor_spec.rb similarity index 85% rename from spec/lib/publish_event_pipeline/message_processor_spec.rb rename to spec/lib/publishing_event_pipeline/message_processor_spec.rb index 947fbe2..f3006ba 100644 --- a/spec/lib/publish_event_pipeline/message_processor_spec.rb +++ b/spec/lib/publishing_event_pipeline/message_processor_spec.rb @@ -1,9 +1,9 @@ -require "publish_event_pipeline/message_processor" +require "publishing_event_pipeline/message_processor" require "govuk_message_queue_consumer" require "govuk_message_queue_consumer/test_helpers" -RSpec.describe PublishEventPipeline::MessageProcessor do +RSpec.describe PublishingEventPipeline::MessageProcessor do describe ".process" do subject(:class_acting_as_processor) { described_class } @@ -14,7 +14,7 @@ subject(:command) { described_class.new(message) } let(:message) { GovukMessageQueueConsumer::MockMessage.new(payload) } - let(:payload) { json_fixture_as_hash("message_queue/message.json") } + let(:payload) { json_fixture_as_hash("message_queue/republish_message.json") } before do allow(Rails.logger).to receive(:info) diff --git a/spec/lib/publishing_event_pipeline/publishing_event_spec.rb b/spec/lib/publishing_event_pipeline/publishing_event_spec.rb new file mode 100644 index 0000000..e394cd0 --- /dev/null +++ b/spec/lib/publishing_event_pipeline/publishing_event_spec.rb @@ -0,0 +1,51 @@ +require "publishing_event_pipeline/publishing_event" + +RSpec.describe PublishingEventPipeline::PublishingEvent do + describe ".from_message_hash" do + subject(:publishing_event) { described_class.from_message_hash(message_hash) } + + context "with a valid republish message" do + let(:message_hash) { json_fixture_as_hash("message_queue/republish_message.json") } + + it "maps the message onto a PublishingEvent" do + expected_document = SearchableDocumentData.new( + content_id: "f75d26a3-25a4-4c31-beea-a77cada4ce12", + title: "Ebola medal for over 3000 heroes", + ) + expected_publishing_event = described_class.new( + update_type: "republish", + payload_version: 65_861_808, + document: expected_document, + ) + + expect(publishing_event).to eq(expected_publishing_event) + end + end + + context "with a valid gone message" do + let(:message_hash) { json_fixture_as_hash("message_queue/gone_message.json") } + + it "maps the message onto a PublishingEvent" do + expected_document = SearchableDocumentData.new( + content_id: "966bae6d-223e-4102-a6e5-e874012390e5", + title: nil, + ) + expected_publishing_event = described_class.new( + update_type: nil, + payload_version: 65_893_230, + document: expected_document, + ) + + expect(publishing_event).to eq(expected_publishing_event) + end + end + + context "with a message hash missing required fields" do + let(:message_hash) { { "title" => "I'm incomplete" } } + + it "raises an error" do + expect { publishing_event }.to raise_error(KeyError) + end + end + end +end