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 ...@@ -24,6 +24,9 @@ module Members
add_members add_members
enqueue_onboarding_progress_action enqueue_onboarding_progress_action
publish_event!
result result
rescue BlankInvitesError, TooManyInvitesError, MembershipLockedError => e rescue BlankInvitesError, TooManyInvitesError, MembershipLockedError => e
error(e.message) error(e.message)
...@@ -144,6 +147,15 @@ module Members ...@@ -144,6 +147,15 @@ module Members
def formatted_errors def formatted_errors
errors.to_sentence errors.to_sentence
end end
def publish_event!
Gitlab::EventStore.publish(
Members::MembersAddedEvent.new(data: {
source_id: source.id,
source_type: source.class.name
})
)
end
end end
end end
......
...@@ -177,6 +177,8 @@ ...@@ -177,6 +177,8 @@
- 1 - 1
- - gitlab_shell - - gitlab_shell
- 2 - 2
- - gitlab_subscriptions_notify_seats_exceeded
- 1
- - group_destroy - - group_destroy
- 1 - 1
- - group_export - - group_export
......
...@@ -252,19 +252,20 @@ add a line like this to the `Gitlab::EventStore.configure!` method: ...@@ -252,19 +252,20 @@ add a line like this to the `Gitlab::EventStore.configure!` method:
```ruby ```ruby
module Gitlab module Gitlab
module EventStore module EventStore
def self.configure! def self.configure!(store)
Store.new.tap do |store| # ...
# ...
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
# ... # ...
end
end end
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. 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. It's not possible to modify subscriptions at runtime.
......
...@@ -1020,6 +1020,15 @@ ...@@ -1020,6 +1020,15 @@
:weight: 1 :weight: 1
:idempotent: :idempotent:
:tags: [] :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 - :name: group_saml_group_sync
:worker_name: GroupSamlGroupSyncWorker :worker_name: GroupSamlGroupSyncWorker
:feature_category: :authentication_and_authorization :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 ...@@ -18,7 +18,7 @@ module Gitlab
end end
def self.instance def self.instance
@instance ||= configure! @instance ||= Store.new { |store| configure!(store) }
end end
# Define all event subscriptions using: # Define all event subscriptions using:
...@@ -29,14 +29,14 @@ module Gitlab ...@@ -29,14 +29,14 @@ module Gitlab
# #
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value } # store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
# #
def self.configure! def self.configure!(store)
Store.new do |store| ###
### # Add subscriptions here:
# Add subscriptions here:
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
end
end end
private_class_method :configure! private_class_method :configure!
end end
end end
Gitlab::EventStore.prepend_mod_with('Gitlab::EventStore')
...@@ -29,7 +29,7 @@ module Gitlab ...@@ -29,7 +29,7 @@ module Gitlab
raise InvalidEvent, "Event being published is not an instance of Gitlab::EventStore::Event: got #{event.inspect}" raise InvalidEvent, "Event being published is not an instance of Gitlab::EventStore::Event: got #{event.inspect}"
end end
subscriptions[event.class].each do |subscription| subscriptions.fetch(event.class, []).each do |subscription|
subscription.consume_event(event) subscription.consume_event(event)
end end
end end
......
...@@ -224,6 +224,26 @@ RSpec.describe Gitlab::EventStore::Store do ...@@ -224,6 +224,26 @@ RSpec.describe Gitlab::EventStore::Store do
store.publish(event) store.publish(event)
end end
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 end
describe 'subscriber' do describe 'subscriber' do
......
...@@ -39,6 +39,15 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ ...@@ -39,6 +39,15 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_
expect(source.users).to include member expect(source.users).to include member
expect(OnboardingProgress.completed?(source, :user_added)).to be(true) expect(OnboardingProgress.completed?(source, :user_added)).to be(true)
end 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
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