diff options
Diffstat (limited to 'lib/gitlab/endpoint_attributes')
-rw-r--r-- | lib/gitlab/endpoint_attributes/config.rb | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/gitlab/endpoint_attributes/config.rb b/lib/gitlab/endpoint_attributes/config.rb new file mode 100644 index 00000000000..e31a3095736 --- /dev/null +++ b/lib/gitlab/endpoint_attributes/config.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Gitlab + module EndpointAttributes + class Config + RequestUrgency = Struct.new(:name, :duration) + REQUEST_URGENCIES = [ + RequestUrgency.new(:high, 0.25), + RequestUrgency.new(:medium, 0.5), + RequestUrgency.new(:default, 1), + RequestUrgency.new(:low, 5) + ].index_by(&:name).freeze + SUPPORTED_ATTRIBUTES = %i[feature_category urgency].freeze + + def initialize + @default_attributes = {} + @action_attributes = {} + end + + def defined_actions + @action_attributes.keys + end + + def set(actions, attributes) + sanitize_attributes!(attributes) + + if actions.empty? + conflicted = conflicted_attributes(attributes, @default_attributes) + raise ArgumentError, "Attributes already defined: #{conflicted.join(", ")}" if conflicted.present? + + @default_attributes.merge!(attributes) + else + set_attributes_for_actions(actions, attributes) + end + + nil + end + + def attribute_for_action(action, attribute_name) + value = @action_attributes.dig(action.to_s, attribute_name) || @default_attributes[attribute_name] + # Translate urgency to a representative struct + value = REQUEST_URGENCIES[value] if attribute_name == :urgency + value + end + + private + + def sanitize_attributes!(attributes) + unsupported_attributes = (attributes.keys - SUPPORTED_ATTRIBUTES).present? + raise ArgumentError, "Attributes not supported: #{unsupported_attributes.join(", ")}" if unsupported_attributes + + if attributes[:urgency].present? && !REQUEST_URGENCIES.key?(attributes[:urgency]) + raise ArgumentError, "Urgency not supported: #{attributes[:urgency]}" + end + end + + def set_attributes_for_actions(actions, attributes) + conflicted = conflicted_attributes(attributes, @default_attributes) + if conflicted.present? + raise ArgumentError, "#{conflicted.join(", ")} are already defined for all actions, but re-defined for #{actions.join(", ")}" + end + + actions.each do |action| + action = action.to_s + if @action_attributes[action].blank? + @action_attributes[action] = attributes.dup + else + conflicted = conflicted_attributes(attributes, @action_attributes[action]) + raise ArgumentError, "Attributes re-defined for action #{action}: #{conflicted.join(", ")}" if conflicted.present? + + @action_attributes[action].merge!(attributes) + end + end + end + + def conflicted_attributes(attributes, existing_attributes) + attributes.keys.filter { |attr| existing_attributes[attr].present? && existing_attributes[attr] != attributes[attr] } + end + end + end +end |