diff --git a/lib/templates/initializer.rb b/lib/templates/activerecord_initializer.rb similarity index 100% rename from lib/templates/initializer.rb rename to lib/templates/activerecord_initializer.rb diff --git a/lib/templates/outbox.rb b/lib/templates/activerecrod_outbox.rb similarity index 100% rename from lib/templates/outbox.rb rename to lib/templates/activerecrod_outbox.rb diff --git a/lib/templates/mongoid_initializer..rb b/lib/templates/mongoid_initializer..rb new file mode 100644 index 0000000..2c09ac0 --- /dev/null +++ b/lib/templates/mongoid_initializer..rb @@ -0,0 +1,38 @@ +require 'simple_enum/mongoid' + +# This monkey patch allows you to customize the message format that you publish to your broker. +# By default, Outboxable publishes a CloudEvent message to your broker. +module Outboxable + module RabbitMq + class Publisher + # Override this method to customize the message format that you publish to your broker + # DO NOT CHANGE THE METHOD SIGNATURE + def to_envelope(resource:) + { + id: resource.id, + source: 'http://localhost:3000', + specversion: '1.0', + type: resource.routing_key, + datacontenttype: 'application/json', + data: resource.payload + }.to_json + end + end + end +end + +Outboxable.configure do |config| + # Specify the ORM you are using. For now, only ActiveRecord is supported. + config.orm = :mongoid + + # Specify the message broker you are using. For now, only RabbitMQ is supported. + config.message_broker = :rabbitmq + + # RabbitMQ configurations + config.rabbitmq_host = ENV.fetch('RABBITMQ__HOST') + config.rabbitmq_port = ENV.fetch('RABBITMQ__PORT', 5672) + config.rabbitmq_user = ENV.fetch('RABBITMQ__USERNAME') + config.rabbitmq_password = ENV.fetch('RABBITMQ__PASSWORD') + config.rabbitmq_vhost = ENV.fetch('RABBITMQ__VHOST') + config.rabbitmq_event_bus_exchange = ENV.fetch('EVENTBUS__EXCHANGE_NAME') +end diff --git a/lib/templates/mongoid_outbox.rb b/lib/templates/mongoid_outbox.rb new file mode 100644 index 0000000..fb0a3bb --- /dev/null +++ b/lib/templates/mongoid_outbox.rb @@ -0,0 +1,56 @@ +class Outbox + include Mongoid::Document + include Mongoid::Timestamps + include SimpleEnum::Mongoid + + attr_accessor :allow_publish + + # Fields + field :status, type: String, default: 'pending' + field :size, type: String, default: 'single' + + field :exchange, type: String, default: '' + field :routing_key, type: String, default: '' + + field :attempts, type: Integer, default: 0 + + field :last_attempted_at, type: DateTime, default: nil + + field :retry_at, type: DateTime, default: nil + + field :payload, type: Hash, default: {} + field :headers, type: Hash, default: {} + + before_save :check_publishing + + # Callbacks + before_create :set_last_attempted_at + after_commit :publish, if: :allow_publish? + + # Enums + as_enum :status, { pending: 0, processing: 1, published: 2, failed: 3 }, pluralize_scopes: false, map: :string + as_enum :size, { single: 0, batch: 1 }, pluralize_scopes: false, map: :string + + # Validations + validates :payload, :exchange, :routing_key, presence: true + + # Associations + belongs_to :outboxable, polymorphic: true, optional: true + + def set_last_attempted_at + self.last_attempted_at = 10.seconds.from_now + end + + def publish + Outboxable::Worker.perform_async(id) + update(status: :processing, last_attempted_at: 1.minute.from_now, allow_publish: false) + end + + def check_publishing + self.allow_publish = false if published? + end + + def allow_publish + @allow_publish || true + end +end