From: Imre Farkas <ifarkas(a)redhat.com>
---
src/config/locales/strategies/en.yml | 7 ++
.../strategies/penalty_for_failure/config.rb | 65 +++++++++++++++++
.../penalty_for_failure/penalty_for_failure.rb | 37 ++++++++++
.../strategies/penalty_for_failure/strategy.rb | 81 ++++++++++++++++++++++
.../views/penalty_for_failure/_edit.html.haml | 17 +++++
5 files changed, 207 insertions(+)
create mode 100644
src/vendor/provider_selection/strategies/penalty_for_failure/config.rb
create mode 100644
src/vendor/provider_selection/strategies/penalty_for_failure/penalty_for_failure.rb
create mode 100644
src/vendor/provider_selection/strategies/penalty_for_failure/strategy.rb
create mode 100644
src/vendor/provider_selection/views/penalty_for_failure/_edit.html.haml
diff --git a/src/config/locales/strategies/en.yml b/src/config/locales/strategies/en.yml
index 49d706b..33b6e79 100644
--- a/src/config/locales/strategies/en.yml
+++ b/src/config/locales/strategies/en.yml
@@ -2,3 +2,10 @@ en:
strategies:
strict_order:
name: 'Strict Order'
+ penalty_for_failure:
+ name: 'Penalty for Failure'
+ views:
+ edit:
+ penalty_percentage: 'Penalty for each failure (in percentage)'
+ time_period_minutes: 'Time period over which the failures are aggregated
(in minutes)'
+ failure_count_hard_limit: 'The number of failures over which the provider
account should not be used if possible'
diff --git a/src/vendor/provider_selection/strategies/penalty_for_failure/config.rb
b/src/vendor/provider_selection/strategies/penalty_for_failure/config.rb
new file mode 100644
index 0000000..466f346
--- /dev/null
+++ b/src/vendor/provider_selection/strategies/penalty_for_failure/config.rb
@@ -0,0 +1,65 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#
http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module ProviderSelection
+ module Strategies
+ module PenaltyForFailure
+
+ class Config
+
+ include ActiveModel::Validations
+ include ActiveModel::Conversion
+ extend ActiveModel::Naming
+
+ attr_accessor :penalty_percentage
+ attr_accessor :time_period_minutes
+ attr_accessor :failure_count_hard_limit
+
+ validates_presence_of :penalty_percentage
+ validates_presence_of :time_period_minutes
+ validates_numericality_of :penalty_percentage,
+ :greater_than => 0, :less_than => 100
+ validates_numericality_of :time_period_minutes,
+ :greater_than => 0, :less_than => 2147483647
+ validates_numericality_of :failure_count_hard_limit,
+ :greater_than => 0, :less_than => 1000,
+ :allow_blank => true
+
+ def initialize(attributes = {})
+ attributes ||=
ProviderSelection::Strategies::PenaltyForFailure::Strategy.default_options
+
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
+ def persisted?
+ false
+ end
+
+ def to_hash
+ {
+ :penalty_percentage => @penalty_percentage.to_i,
+ :time_period_minutes => @time_period_minutes.to_i,
+ :failure_count_hard_limit => @failure_count_hard_limit.to_i
+ }
+ end
+
+ end
+
+ end
+ end
+end
diff --git
a/src/vendor/provider_selection/strategies/penalty_for_failure/penalty_for_failure.rb
b/src/vendor/provider_selection/strategies/penalty_for_failure/penalty_for_failure.rb
new file mode 100644
index 0000000..8d37e20
--- /dev/null
+++ b/src/vendor/provider_selection/strategies/penalty_for_failure/penalty_for_failure.rb
@@ -0,0 +1,37 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#
http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require File.join(File.dirname(__FILE__), 'strategy')
+require File.join(File.dirname(__FILE__), 'config')
+
+module ProviderSelection
+ module Strategies
+ module PenaltyForFailure
+
+ class Base
+
+ extend ProviderSelection::ChainableStrategyOptions::ClassMethods
+
+ @properties = {
+ :edit_partial => 'penalty_for_failure/edit',
+ :config_klass => Config
+ }
+
+ end
+
+ end
+ end
+end
diff --git a/src/vendor/provider_selection/strategies/penalty_for_failure/strategy.rb
b/src/vendor/provider_selection/strategies/penalty_for_failure/strategy.rb
new file mode 100644
index 0000000..3f4820b
--- /dev/null
+++ b/src/vendor/provider_selection/strategies/penalty_for_failure/strategy.rb
@@ -0,0 +1,81 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#
http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module ProviderSelection
+ module Strategies
+ module PenaltyForFailure
+
+ class Strategy
+
+ include ProviderSelection::ChainableStrategy::InstanceMethods
+
+ @default_options = {
+ :penalty_percentage => 5,
+ :time_period_minutes => 4 * 60
+ }
+
+ def self.default_options
+ @default_options
+ end
+
+ def calculate
+ rank = @strategies.calculate
+
+ # Query the number of failures for each provider account
+ failures_count = {}
+ rank.default_priority_group.matches.map(&:provider_account).uniq.each do
|provider_account|
+ failures_count[provider_account] = provider_account.failure_count
+ end
+
+
+ # Modify the score of each match in every priority groups
+ rank.priority_groups.each do |priority_group|
+ priority_group.matches.each do |match|
+ match.penalize_by(failures_count[match.provider_account] *
@options[:penalty_percentage])
+ end
+ end
+
+ return rank unless @options.has_key?(:failure_count_hard_limit)
+
+ # Create priority group for failing provider accounts with higher
+ # score than the default one
+ failing_provider_accounts = failures_count.inject([]) do |result,
(provider_account, failure_count)|
+ if failure_count >= @options[:failure_count_hard_limit]
+ result << provider_account
+ end
+
+ result
+ end.uniq
+
+ rank.priority_groups.each do |priority_group|
+ priority_group.delete_matches(:provider_account, failing_provider_accounts)
+ end
+
+ failing_priority_group =
ProviderSelection::PriorityGroup.new(rank.default_priority_group.score * 100)
+ failing_provider_accounts.each do |provider_account|
+ failing_priority_group.matches << Match.new(:provider_account =>
provider_account)
+ end
+
+ rank.priority_groups << failing_priority_group
+
+ rank
+ end
+
+ end
+
+ end
+ end
+end
diff --git a/src/vendor/provider_selection/views/penalty_for_failure/_edit.html.haml
b/src/vendor/provider_selection/views/penalty_for_failure/_edit.html.haml
new file mode 100644
index 0000000..83c8ec3
--- /dev/null
+++ b/src/vendor/provider_selection/views/penalty_for_failure/_edit.html.haml
@@ -0,0 +1,17 @@
+.strategy-options
+ - if @config.errors.any?
+ = render 'layouts/error_messages', :object => @config
+
+ %fieldset
+ .field
+ = form.label(:penalty_percentage,
t('strategies.penalty_for_failure.views.edit.penalty_percentage'))
+ .input
+ = form.text_field(:penalty_percentage)
+ .field
+ = form.label(:time_period_minutes,
t('strategies.penalty_for_failure.views.edit.time_period_minutes'))
+ .input
+ = form.text_field(:time_period_minutes)
+ .field
+ = form.label(:failure_count_hard_limit,
t('strategies.penalty_for_failure.views.edit.failure_count_hard_limit'))
+ .input
+ = form.text_field(:failure_count_hard_limit)
--
1.7.11.2