/******************************************************************************* * Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved * * 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. *******************************************************************************/ package org.openspaces.grid.gsm.autoscaling.exceptions; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.openspaces.admin.internal.pu.InternalProcessingUnit; import org.openspaces.admin.internal.pu.elastic.events.DefaultElasticAutoScalingFailureEvent; import org.openspaces.admin.internal.pu.elastic.events.InternalElasticProcessingUnitFailureEvent; import org.openspaces.admin.pu.elastic.config.AutomaticCapacityScaleRuleConfig; import org.openspaces.grid.gsm.sla.exceptions.SlaEnforcementFailure; /** * An exception that is raised when there is more than one scaling rule, * and one or more scaling rule requires scale out, while the other requires scale down. * @author itaif * @since 9.0.0 */ public class RulesConflictAutoScalingException extends AutoScalingSlaEnforcementInProgressException implements SlaEnforcementFailure{ private static final long serialVersionUID = 1L; private final Set<AutomaticCapacityScaleRuleConfig> valuesBelowLowThresholdPerRule; private final Set<AutomaticCapacityScaleRuleConfig> valuesAboveHighThresholdPerRule; public RulesConflictAutoScalingException(InternalProcessingUnit pu, Map<AutomaticCapacityScaleRuleConfig, Object> valuesBelowLowThresholdPerRule, Map<AutomaticCapacityScaleRuleConfig, Object> valuesAboveHighThresholdPerRule) { super(pu, message(valuesBelowLowThresholdPerRule, valuesAboveHighThresholdPerRule)); this.valuesBelowLowThresholdPerRule = valuesBelowLowThresholdPerRule.keySet(); this.valuesAboveHighThresholdPerRule = valuesAboveHighThresholdPerRule.keySet(); } private static String message( Map<AutomaticCapacityScaleRuleConfig, Object> valuesBelowLowThresholdPerRule, Map<AutomaticCapacityScaleRuleConfig, Object> valuesAboveHighThresholdPerRule) { List<String> messages = new ArrayList<String>(valuesAboveHighThresholdPerRule.size() + valuesBelowLowThresholdPerRule.size()); for (Entry<AutomaticCapacityScaleRuleConfig, Object> pair : valuesAboveHighThresholdPerRule.entrySet()) { AutomaticCapacityScaleRuleConfig rule = pair.getKey(); Object value = pair.getValue(); messages.add(rule.getStatistics().getMetric() + " value (" + value +") is above high threshold " + rule.getHighThreshold()); } for (Entry<AutomaticCapacityScaleRuleConfig, Object> pair : valuesBelowLowThresholdPerRule.entrySet()) { AutomaticCapacityScaleRuleConfig rule = pair.getKey(); Object value = pair.getValue(); messages.add(rule.getStatistics().getMetric() + " value (" + value +") is below low threshold " + rule.getHighThreshold()); } String message = Arrays.toString(messages.toArray(new String[messages.size()])); return "Rule conflict, taking no automatic action. " + message; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((valuesAboveHighThresholdPerRule == null) ? 0 : valuesAboveHighThresholdPerRule.hashCode()); result = prime * result + ((valuesBelowLowThresholdPerRule == null) ? 0 : valuesBelowLowThresholdPerRule.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; RulesConflictAutoScalingException other = (RulesConflictAutoScalingException) obj; if (valuesAboveHighThresholdPerRule == null) { if (other.valuesAboveHighThresholdPerRule != null) return false; } else if (!valuesAboveHighThresholdPerRule.equals(other.valuesAboveHighThresholdPerRule)) return false; if (valuesBelowLowThresholdPerRule == null) { if (other.valuesBelowLowThresholdPerRule != null) return false; } else if (!valuesBelowLowThresholdPerRule.equals(other.valuesBelowLowThresholdPerRule)) return false; return true; } @Override public InternalElasticProcessingUnitFailureEvent toEvent() { DefaultElasticAutoScalingFailureEvent event = new DefaultElasticAutoScalingFailureEvent(); event.setFailureDescription(getMessage()); event.setProcessingUnitName(getProcessingUnitName()); return event; } }