Commit 01c65e1b authored by Fabio Pitino's avatar Fabio Pitino

Merge branch 'jh-overage_notification_field' into 'master'

Trigger EE EventStore event when new members are added to a group

See merge request gitlab-org/gitlab!79291
parents 8dcdbafc 0b07c47c
# frozen_string_literal: true
module Members
class MembersAddedEvent < ::Gitlab::EventStore::Event
def schema
{
'type' => 'object',
'required' => %w[source_id source_type],
'properties' => {
'source_id' => { 'type' => 'integer' },
'source_type' => { 'type' => 'string' }
}
}
end
end
end
......@@ -24,6 +24,9 @@ module Members
add_members
enqueue_onboarding_progress_action
publish_event!
result
rescue BlankInvitesError, TooManyInvitesError, MembershipLockedError => e
error(e.message)
......@@ -144,6 +147,15 @@ module Members
def formatted_errors
errors.to_sentence
end
def publish_event!
Gitlab::EventStore.publish(
Members::MembersAddedEvent.new(data: {
source_id: source.id,
source_type: source.class.name
})
)
end
end
end
......
......@@ -177,6 +177,8 @@
- 1
- - gitlab_shell
- 2
- - gitlab_subscriptions_notify_seats_exceeded
- 1
- - group_destroy
- 1
- - group_export
......
......@@ -252,8 +252,7 @@ add a line like this to the `Gitlab::EventStore.configure!` method:
```ruby
module Gitlab
module EventStore
def self.configure!
Store.new.tap do |store|
def self.configure!(store)
# ...
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
......@@ -261,10 +260,12 @@ module Gitlab
# ...
end
end
end
end
```
A worker that is only defined in the EE codebase can subscribe to an event in the same way by
declaring the subscription in `ee/lib/ee/gitlab/event_store.rb`.
Subscriptions are stored in memory when the Rails app is loaded and they are immediately frozen.
It's not possible to modify subscriptions at runtime.
......
......@@ -1020,6 +1020,15 @@
:weight: 1
:idempotent:
:tags: []
- :name: gitlab_subscriptions_notify_seats_exceeded
:worker_name: GitlabSubscriptions::NotifySeatsExceededWorker
:feature_category: :purchase
:has_external_dependencies: true
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: group_saml_group_sync
:worker_name: GroupSamlGroupSyncWorker
:feature_category: :authentication_and_authorization
......
# frozen_string_literal: true
module GitlabSubscriptions
class NotifySeatsExceededWorker
include ApplicationWorker
include Gitlab::EventStore::Subscriber
feature_category :purchase
data_consistency :delayed
deduplicate :until_executing, including_scheduled: true
idempotent!
worker_has_external_dependencies!
def handle_event(event)
# no-op for now, to be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/348487
end
end
end
# frozen_string_literal: true
module EE
module Gitlab
module EventStore
extend ActiveSupport::Concern
class_methods do
extend ::Gitlab::Utils::Override
# Define event subscriptions using:
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent)
#
# It is possible to subscribe to a subset of events matching a condition:
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
#
# Only EE subscriptions should be declared in this module.
override :configure!
def configure!(store)
super(store)
###
# Add EE only subscriptions here:
store.subscribe ::GitlabSubscriptions::NotifySeatsExceededWorker, to: ::Members::MembersAddedEvent
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::EventStore do
describe '.instance' do
it 'returns a store with CE and EE subscriptions' do
instance = described_class.instance
expect(instance.subscriptions.keys).to include(
::Ci::PipelineCreatedEvent,
::Members::MembersAddedEvent
)
end
end
end
......@@ -18,7 +18,7 @@ module Gitlab
end
def self.instance
@instance ||= configure!
@instance ||= Store.new { |store| configure!(store) }
end
# Define all event subscriptions using:
......@@ -29,14 +29,14 @@ module Gitlab
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
#
def self.configure!
Store.new do |store|
def self.configure!(store)
###
# Add subscriptions here:
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
end
end
private_class_method :configure!
end
end
Gitlab::EventStore.prepend_mod_with('Gitlab::EventStore')
......@@ -29,7 +29,7 @@ module Gitlab
raise InvalidEvent, "Event being published is not an instance of Gitlab::EventStore::Event: got #{event.inspect}"
end
subscriptions[event.class].each do |subscription|
subscriptions.fetch(event.class, []).each do |subscription|
subscription.consume_event(event)
end
end
......
......@@ -224,6 +224,26 @@ RSpec.describe Gitlab::EventStore::Store do
store.publish(event)
end
end
context 'when the event does not have any subscribers' do
let(:store) do
described_class.new do |s|
s.subscribe unrelated_worker, to: another_event_klass
end
end
let(:event) { event_klass.new(data: data) }
it 'returns successfully' do
expect { store.publish(event) }.not_to raise_error
end
it 'does not dispatch the event to another subscription' do
expect(unrelated_worker).not_to receive(:perform_async)
store.publish(event)
end
end
end
describe 'subscriber' do
......
......@@ -39,6 +39,15 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_
expect(source.users).to include member
expect(OnboardingProgress.completed?(source, :user_added)).to be(true)
end
it 'triggers a members added event' do
expect(Gitlab::EventStore)
.to receive(:publish)
.with(an_instance_of(Members::MembersAddedEvent))
.and_call_original
expect(execute_service[:status]).to eq(:success)
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment