/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.alert.engine.internal; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.alert.AlertCondition; import org.rhq.core.domain.alert.AlertConditionCategory; import org.rhq.core.domain.alert.AlertConditionOperator; import org.rhq.enterprise.server.alert.engine.model.AbstractCacheElement; import org.rhq.enterprise.server.alert.engine.model.UnsupportedAlertConditionOperatorException; /** * @author Joseph Marques */ class AlertConditionCacheUtils { private static final Log log = LogFactory.getLog(AlertConditionCacheCoordinator.class); public static AlertConditionOperator getAlertConditionOperator(AlertCondition alertCondition) { AlertConditionCategory category = alertCondition.getCategory(); String name = alertCondition.getName(); String comparator = alertCondition.getComparator(); switch (category) { case CONTROL: // the UI currently only supports one operator for control return AlertConditionOperator.EQUALS; case EVENT: // the UI currently only supports one operator for events return AlertConditionOperator.GREATER_THAN_OR_EQUAL_TO; case DRIFT: // any drift that is detected infers a change to its previous state return AlertConditionOperator.CHANGES; case RESOURCE_CONFIG: case CHANGE: // the model currently supports CHANGE as a category type instead of a comparator return AlertConditionOperator.CHANGES; case TRAIT: String regex = alertCondition.getOption(); return (null == regex || regex.isEmpty()) ? AlertConditionOperator.CHANGES : AlertConditionOperator.REGEX; case AVAILABILITY: { AlertConditionOperator operator = AlertConditionOperator.valueOf(name.toUpperCase()); switch (operator) { case AVAIL_GOES_DISABLED: case AVAIL_GOES_DOWN: case AVAIL_GOES_UNKNOWN: case AVAIL_GOES_UP: case AVAIL_GOES_NOT_UP: return operator; default: throw new UnsupportedAlertConditionOperatorException( "Invalid alertConditionValue for AVAILABILITY category:" + operator); } } case AVAIL_DURATION: { AlertConditionOperator operator = AlertConditionOperator.valueOf(name.toUpperCase()); switch (operator) { case AVAIL_DURATION_DOWN: case AVAIL_DURATION_NOT_UP: return operator; default: throw new UnsupportedAlertConditionOperatorException( "Invalid alertConditionValue for AVAILABILITY_DURATION category:" + operator); } } case RANGE: // range can support <= and >=, which we look for here. It can also support < and >, which is checked down below further. // note that RANGE does not support =, so we throw an exception if caller tries that if (comparator.equals("<=")) { return AlertConditionOperator.LESS_THAN_OR_EQUAL_TO; } else if (comparator.equals(">=")) { return AlertConditionOperator.GREATER_THAN_OR_EQUAL_TO; } else if (comparator.equals("=")) { throw new UnsupportedAlertConditionOperatorException("Comparator [" + comparator + "] " + "is not supported for category: " + category.name()); } default: if (comparator.equals("<")) { return AlertConditionOperator.LESS_THAN; } else if (comparator.equals(">")) { return AlertConditionOperator.GREATER_THAN; } else if (comparator.equals("=")) { return AlertConditionOperator.EQUALS; } else { throw new UnsupportedAlertConditionOperatorException("Comparator [" + comparator + "] " + "is not supported for category: " + category.name()); } } } public static String getCacheElementErrorString(int conditionId, AlertConditionOperator operator, Object option, Object value, Throwable exception) { return "id=" + conditionId + ", " + "operator=" + operator + ", " + ((option != null) ? ("option=" + option + ", ") : "") + "value=" + value + ", error message: " + exception.getMessage(); } public static <T extends AbstractCacheElement<?>> void printListCache(String cacheName, Map<Integer, List<T>> cache) { log.debug("Printing " + cacheName + "..."); for (Map.Entry<Integer, List<T>> cacheElement : cache.entrySet()) { log.debug("key=" + cacheElement.getKey() + ", " + "value=" + cacheElement.getValue()); } } public static <T extends AbstractCacheElement<?>> void printNestedCache(String cacheName, Map<Integer, Map<Integer, List<T>>> nestedCache) { log.debug("Printing " + cacheName + "..."); for (Map.Entry<Integer, Map<Integer, List<T>>> cache : nestedCache.entrySet()) { for (Map.Entry<Integer, List<T>> cacheElement : cache.getValue().entrySet()) { log.debug("key1=" + cache.getKey() + ", " + "key2=" + cacheElement.getKey() + ", " + "value=" + cacheElement.getValue()); } } } public static boolean isInvalidDouble(Double d) { return (d == null || Double.isNaN(d) || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY); } public static <S, T> int getMapListCount(Map<S, List<T>> mapList) { int count = 0; try { for (List<?> listValue : mapList.values()) { count += listValue.size(); } } catch (Throwable t) { // don't let any exceptions bubble up to the calling SLSB layer log.error("Error counting MapList", t); } return count; } public static <R, S, T> int getMapMapListCount(Map<R, Map<S, List<T>>> mapMapList) { int count = 0; try { for (Map<S, List<T>> mapListValue : mapMapList.values()) { count += getMapListCount(mapListValue); } } catch (Throwable t) { // don't let any exceptions bubble up to the calling SLSB layer log.error("Error counting MapMapList", t); } return count; } }