Skip to content

Commit

Permalink
[AuthenticationMixin] authentication_status to virtual_delegate
Browse files Browse the repository at this point in the history
Creates a virtual_delegate for AuthenticationMixin#authentication_status
which allows it to be included in reports and put in as part of the main
query.

The biggest thing of note in this change is how the status_severity_arel
is being used to handle the sorting properly in the SQL query.  It makes
use of a SQL's case statement to handle what would normally be a
`sort_by` on the hash lookup of Authentication::STATUS_SEVERITY.
Instead, we match each key to the status column and use that as the
value for the `ORDER BY exp DESC` in the `has_one`, which allows for the
same affect.

This also means that it can inject itself in the `SELECT` of a
`MiqReport`, and avoid N+1's on things like quadicons and such for pages
that use `MiqReport#paged_view_search`.
  • Loading branch information
NickLaMuro committed Nov 14, 2018
1 parent 3b7f61a commit e02cf66
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
20 changes: 20 additions & 0 deletions app/models/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ def self.db_name
"auth_key_pair_cloud"
end

# Builds a case statement that case be used in a sql ORDER BY.
#
# Generated SQL looks like:
#
# CASE
# WHEN LOWER(status) = '' THEN -1
# WHEN LOWER(status) = 'valid' THEN 0
# ...
# ELSE -1
#
def self.status_severity_arel
arel_case = Arel::Nodes::Case.new

STATUS_SEVERITY.each do |value, sort_weight|
arel_case.when(arel_table[:status].lower.eq(value)).then(sort_weight)
end

arel_case.else(-1)
end

def status_severity
STATUS_SEVERITY[status.to_s.downcase]
end
Expand Down
16 changes: 10 additions & 6 deletions app/models/mixins/authentication_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ module AuthenticationMixin
included do
has_many :authentications, :as => :resource, :dependent => :destroy, :autosave => true

virtual_column :authentication_status, :type => :string
has_one :authentication_status_severity_level,
-> { order(Authentication.status_severity_arel.desc) },
:as => :resource,
:inverse_of => :resource,
:class_name => "Authentication"

virtual_delegate :authentication_status,
:to => "authentication_status_severity_level.status",
:default => "None",
:allow_nil => true

def self.authentication_check_schedule
zone = MiqServer.my_server.zone
Expand Down Expand Up @@ -117,11 +126,6 @@ def missing_credentials?(type = nil)
!has_credentials?(type)
end

def authentication_status
ordered_auths = authentication_for_providers.sort_by(&:status_severity)
ordered_auths.last.try(:status) || "None"
end

def authentication_status_ok?(type = nil)
authentication_best_fit(type).try(:status) == "Valid"
end
Expand Down

0 comments on commit e02cf66

Please sign in to comment.