Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

THREESCALE-2989 - simplify background deletion #3958

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,25 @@ class Account < ApplicationRecord
include ProviderDomains
include Indices::AccountIndex::ForAccount

self.background_deletion = [
:users,
:mail_dispatch_rules,
[:api_docs_services, { class_name: 'ApiDocs::Service' }],
:services,
:contracts,
:account_plans,
[:settings, { action: :destroy, class_name: 'Settings', has_many: false }],
[:payment_detail, { action: :destroy, has_many: false }],
[:buyer_accounts, { action: :destroy, class_name: 'Account' }],
[:payment_gateway_setting, { action: :destroy, has_many: false }],
[:profile, { action: :delete, has_many: false }],
[:templates, { action: :delete, class_name: 'CMS::Template' }],
[:sections, { action: :delete, class_name: 'CMS::Section' }],
[:provided_sections, { action: :delete, class_name: 'CMS::Section' }],
[:redirects, { action: :delete, class_name: 'CMS::Redirect' }],
[:files, { action: :delete, class_name: 'CMS::File' }],
[:builtin_pages, { action: :delete, class_name: 'CMS::BuiltinPage' }],
[:provided_groups, { action: :delete, class_name: 'CMS::Group' }]
self.background_deletion = %i[
users
mail_dispatch_rules
api_docs_services
services
contracts
account_plans
settings
payment_detail
payment_gateway_setting
buyer_accounts
Comment on lines +61 to +62
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice that these two are highlighted. Reading the original logic, all the reason for separate DeleteAccountHierarchyWorker and DeletePaymentSettingHierarchyWorker appears to be enforcing and order of executing the deletions. Since we do deleting serially here, the order is enforced by the order of entries put in background_deletion so I removed all that and just arranged the entries like this.

I must say that I cannot definitively claim that I understood all implications of the original code. More like I vaguely understood it. I found it more important to understand the intentions of the original authors because the code was misbehaving anyways and is heavily been refactored.

Although further testing may lead to a realization of details that I missed. So don't blindly trust me!

profile
templates
sections
provided_sections
redirects
files
builtin_pages
provided_groups
].freeze

#TODO: this needs testing?
Expand Down
8 changes: 8 additions & 0 deletions app/models/alert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ class Alert < ApplicationRecord
self.default_sort_direction = :desc
self.allowed_search_scopes = %w[cinstance_id account_id timestamp level]

self.background_deletion_method = :delete_truly
# commenting out this here just to make a note that to me it seems like state machine overrides
# the #delete AR method but what background deletion actually expects is indeed the AR #delete method
# self.background_deletion_scope_name = :non_deleted
#
# scope :non_deleted, -> { where.not(state: :deleted) }
alias delete_truly delete # keep reference to the original AR #delete method to use for background deletion

ALERT_LEVELS = [ 50, 80, 90, 100, 120, 150, 200, 300 ]
VIOLATION_LEVEL = 100

Expand Down
2 changes: 1 addition & 1 deletion app/models/cinstance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class Cinstance < Contract
# Maximum number of cinstances permitted between provider and buyer
MAX = 10

self.background_deletion = [:referrer_filters, :application_keys, [:alerts, { action: :delete }]]
self.background_deletion = %i[referrer_filters application_keys alerts]

delegate :backend_version, to: :service, allow_nil: true

Expand Down
2 changes: 2 additions & 0 deletions app/models/cms/builtin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class StaticPage < CMS::Builtin
# CMS::Builtin::Page
class Page < CMS::Builtin

validates :user_id, :forum_id, presence: true

def content_type
'text/html'
end
Expand Down
2 changes: 2 additions & 0 deletions app/models/cms/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class CMS::File < ApplicationRecord

self.table_name = :cms_files

self.background_deletion_method = :delete

self.allowed_search_scopes = %i[section_id]

scope :by_section_id, ->(section_id) { where(section_id: section_id) }
Expand Down
2 changes: 2 additions & 0 deletions app/models/cms/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class CMS::Group < ApplicationRecord
# This is BuyerGroup
self.table_name = :cms_groups

self.background_deletion_method = :delete

belongs_to :provider, :class_name => "Account"

validates :name, :provider, presence: true, length: { maximum: 255 }
Expand Down
2 changes: 2 additions & 0 deletions app/models/cms/redirect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ class CMS::Redirect < ApplicationRecord

include NormalizePathAttribute
verify_path_format :source, :target

self.background_deletion_method = :delete
end
2 changes: 2 additions & 0 deletions app/models/cms/section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class CMS::Section < ApplicationRecord

self.table_name = :cms_sections

self.background_deletion_method = :delete

self.allowed_search_scopes = %i[parent_id]

scope :by_parent_id, ->(parent_id) { where(parent_id: parent_id) }
Expand Down
2 changes: 2 additions & 0 deletions app/models/cms/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ class CMS::Template < ApplicationRecord
include ThreeScale::Search::Scopes
include CMS::Filtering

self.background_deletion_method = :delete

scope :with_draft, ->{ where(['draft IS NOT NULL'])}
scope :for_rails_view, ->(path) { where(rails_view_path: path.to_s) }

Expand Down
31 changes: 8 additions & 23 deletions app/models/concerns/background_deletion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,17 @@ module BackgroundDeletion

included do
class_attribute :background_deletion, default: [], instance_writer: false
class_attribute :background_deletion_method, default: :destroy!, instance_writer: false
class_attribute :background_deletion_scope_name, default: :all, instance_writer: false
end

class Reflection

DEFAULT_DESTROY_METHOD = 'destroy'
DEFAULT_HAS_MANY_OPTION = true

attr_reader :name, :options

def initialize(association_config)
config = Array(association_config)

@name = config[0]
@options = config[1].presence || {}
end

def many?
options.fetch(:has_many) { DEFAULT_HAS_MANY_OPTION }
end

def class_name
options[:class_name].presence || name.to_s.singularize.classify
class_methods do
def background_deletion_scope
send background_deletion_scope_name
end
end

def background_destroy_method
options[:action].to_s.presence || DEFAULT_DESTROY_METHOD
end
def background_deletion_method_call
send background_deletion_method
end
end
2 changes: 2 additions & 0 deletions app/models/moderatorship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Moderatorship < ApplicationRecord

attr_protected :forum_id, :user_id, :tenant_id

self.background_deletion_method = :delete

protected

def uniqueness_of_relationship
Expand Down
2 changes: 2 additions & 0 deletions app/models/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Notification < ApplicationRecord

self.available_notifications = NotificationMailer.available_notifications.map(&:to_s).freeze

self.background_deletion_method = :delete

delegate :hidden_onprem_multitenancy, to: NotificationMailer
delegate :account, to: :user

Expand Down
2 changes: 2 additions & 0 deletions app/models/notification_preferences.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def self.preferences_to_hash(list, value:)
self.enabled_by_default = (available_notifications - disabled_by_default).freeze
self.hidden_notifications = NotificationMailer.hidden_notifications.freeze

self.background_deletion_method = :delete

enabled = preferences_to_hash(enabled_by_default, value: true)
disabled = preferences_to_hash(disabled_by_default, value: false)

Expand Down
2 changes: 2 additions & 0 deletions app/models/oidc_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def attributes
end
end

self.background_deletion_method = :delete

belongs_to :oidc_configurable, polymorphic: true, inverse_of: :oidc_configuration
serialize :config, OIDCConfiguration::Config

Expand Down
3 changes: 1 addition & 2 deletions app/models/plan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ class PeriodRangeCalculationError < StandardError; end
include SystemName
include Logic::MetricVisibility::Plan

self.background_deletion = [:contracts, :plan_metrics, :pricing_rules,
:usage_limits, [:customizations, { action: :destroy, class_name: 'Plan' }]]
self.background_deletion = %i[contracts plan_metrics pricing_rules usage_limits customizations]

has_system_name :uniqueness_scope => [ :type, :issuer_id, :issuer_type ]

Expand Down
3 changes: 2 additions & 1 deletion app/models/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class Profile < ApplicationRecord

after_initialize :set_company_size

audited :allow_mass_assignment => true
self.background_deletion_method = :delete
audited
state_machine :initial => :private do

state :private
Expand Down
2 changes: 1 addition & 1 deletion app/models/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Proxy < ApplicationRecord # rubocop:disable Metrics/ClassLength

define_proxy_config_affecting_attributes except: %i[api_test_path api_test_success lock_version]

self.background_deletion = [:proxy_rules, [:proxy_configs, { action: :delete }], [:oidc_configuration, { action: :delete, has_many: false }]]
self.background_deletion = %i[proxy_rules proxy_configs oidc_configuration]

belongs_to :service, touch: true, inverse_of: :proxy, required: true
attr_readonly :service_id
Expand Down
2 changes: 2 additions & 0 deletions app/models/proxy_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class InvalidEnvironmentError < StandardError; end
# Do not set it too high though the column accept until 16.megabytes
MAX_CONTENT_LENGTH = 2.megabytes

self.background_deletion_method = :delete

belongs_to :proxy, optional: false
belongs_to :user, optional: true

Expand Down
14 changes: 7 additions & 7 deletions app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ class Service < ApplicationRecord # rubocop:disable Metrics/ClassLength

define_proxy_config_affecting_attributes :backend_version

self.background_deletion = [
:service_plans,
:application_plans,
[:api_docs_services, class_name: 'ApiDocs::Service'],
:backend_api_configs,
:metrics,
[:proxy, { action: :destroy, has_many: false }]
self.background_deletion = %i[
service_plans
application_plans
api_docs_services
backend_api_configs
metrics
proxy
].freeze

DELETE_STATE = 'deleted'
Expand Down
2 changes: 2 additions & 0 deletions app/models/sso_authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class SSOAuthorization < ApplicationRecord

scope :newest, -> { order(updated_at: :desc).first }

self.background_deletion_method = :delete

def mark_as_used(id_token)
self.id_token = id_token
self.updated_at = Time.now.utc
Expand Down
14 changes: 7 additions & 7 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ class User < ApplicationRecord
include ProvidedAccessTokens
include Indices::AccountIndex::ForDependency

self.background_deletion = [
:user_sessions,
:access_tokens,
[:sso_authorizations, { action: :delete }],
[:moderatorships, { action: :delete }],
[:notifications, { action: :delete }],
[:notification_preferences, { action: :delete, class_name: 'NotificationPreferences', has_many: false }]
self.background_deletion = %i[
user_sessions
access_tokens
sso_authorizations
moderatorships
notifications
notification_preferences
].freeze

audited except: %i[salt posts_count janrain_identifier cas_identifier
Expand Down
2 changes: 1 addition & 1 deletion app/subscribers/service_deletion_subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class ServiceDeletionSubscriber < AfterCommitSubscriber
def after_commit(event)
case event
when Services::ServiceScheduledForDeletionEvent
DeleteObjectHierarchyWorker.perform_later(Service.find(event.service_id))
DeleteObjectHierarchyWorker.delete_later(Service.find(event.service_id))
else
raise "Unknown event type #{event.class}"
end
Expand Down
31 changes: 1 addition & 30 deletions app/workers/delete_account_hierarchy_worker.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1 @@
# frozen_string_literal: true

class DeleteAccountHierarchyWorker < DeleteObjectHierarchyWorker
def perform(*)
return unless account.should_be_deleted?
super
end

private

alias account object

def batch_description
id = account.id
org_name = account.org_name
if account.provider?
"Deleting provider [##{id}] #{org_name} - #{account.internal_admin_domain}"
else
"Deleting buyer [##{id}] of provider #{org_name}"
end
end

def destroyable_association?(association)
if called_from_provider_hierarchy? && account.gateway_setting.persisted?
association != :buyer_accounts
else
super
end
end
end
DeleteAccountHierarchyWorker = DeleteObjectHierarchyWorker
Loading