/* * Copyright (c) 2014, Paessler AG <support@paessler.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.paessler.prtg.jmx.sensors.profile; import java.util.HashMap; import java.util.Map; import org.apache.commons.digester3.Digester; import org.snmp4j.smi.Null; import com.paessler.prtg.jmx.Logger; import com.paessler.prtg.jmx.channels.Channel; import com.paessler.prtg.jmx.channels.Channel.Mode; import com.paessler.prtg.jmx.channels.FloatChannel; import com.paessler.prtg.jmx.channels.LongChannel; import com.paessler.prtg.jmx.channels.Channel.Unit; public abstract class Attribute<T extends Comparable<T>> implements Comparable<Attribute<T>> { public static double DEFAULT_NOOPVAL = 1.0d; public T object; public String description = null, shortDescription = null; public String displayValue; public String unit; public String mode; public String customUnit; public Mode eMode = Channel.Mode.INTEGER; public Unit eUnit = Unit.COUNT; public String comment; public double mpy = DEFAULT_NOOPVAL, div = DEFAULT_NOOPVAL; public boolean enabled = true; // --------------------------------------------- // --------------------------------------------- public Map<String,Object> propMap = new HashMap<String,Object>(); // --------------------------------------------- public Map<String,Object> getProperties() {return propMap;} public Object getProperty(String key) {return propMap.get(key);} public Object setProperty(String key, Object value) {return propMap.put(key, value);} public Object addProperty(PropertyEntry prope) {return propMap.put(prope.getName(), prope.getValue());} // -------------------------------- /** Define an upper error limit for the channel. If enabled, the sensor will be set to a "Down" status if this value is overrun and the LimitMode is activated. Note: Please provide the limit value in the unit of the base data type, just as used in the <Value> element of this section. While a sensor shows a "Down" status triggered by a limit, it will still receive data in its channels. The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. Integer */ public Integer limitMaxError = null; /** Define an upper warning limit for the channel. If enabled, the sensor will be set to a "Warning" status if this value is overrun and the LimitMode is activated. Note: Please provide the limit value in the unit of the base data type, just as used in the <Value> element of this section. The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. Integer */ public Integer limitMaxWarning = null; /** Define a lower warning limit for the channel. If enabled, the sensor will be set to a "Warning" status if this value is undercut and the LimitMode is activated. Note: Please provide the limit value in the unit of the base data type, just as used in the <Value> element of this section. The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. Integer */ public Integer limitMinWarning = null; /** Define a lower error limit for the channel. If enabled, the sensor will be set to a "Down" status if this value is undercut and the LimitMode is activated. Note: Please provide the limit value in the unit of the base data type, just as used in the <Value> element of this section. While a sensor shows a "Down" status triggered by a limit, it will still receive data in its channels. The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. Integer */ public Integer limitMinError = null; /** Define an additional message. It will be added to the sensor's message when entering a "Down" status that is triggered by a limit. Note: The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor.*/ public String limitErrorMsg = null; /** Define an additional message. It will be added to the sensor's message when entering a "Warning" status that is triggered by a limit. Note: The values defined with this element will be considered only on the first sensor scan, when the channel is newly created; they are ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. */ public String limitWarningMsg = null; /** Define if the limit settings defined above will be active. Default is 0 (no; limits inactive). If 0 is used the limits will be written to the sensor channel settings as predefined values, but limits will be disabled. Note: This setting will be considered only on the first sensor scan, when the channel is newly created; it is ignored on all further sensor scans (and may be omitted). You can change this initial setting later in the Channel settings of the sensor. 0 (= no) 1 (= yes) */ public int limitMode = 0; // -------------------------------- public Attribute() { setUnitEnum(Unit.COUNT); unit = getUnitEnum().toString(); } public Attribute(Attribute<?> attr){ setObject(toObjectType(attr.object)); setDescription(attr.description); setShortDescription(attr.shortDescription); setDisplayValue(attr.displayValue); setMode(attr.mode); setUnit(attr.unit); setComment(attr.comment); setMpy(attr.mpy); setDiv(attr.div); // attr.enabled = true; setLimitMaxError(attr.getLimitMaxError()); setLimitMaxWarning(attr.getLimitMaxWarning()); setLimitMinWarning(attr.getLimitMinWarning()); setLimitMinError(attr.getLimitMinError()); setLimitErrorMsg(attr.getLimitErrorMsg()); setLimitWarningMsg(attr.getLimitWarningMsg()); setLimitMode(attr.getLimitMode()); } // -------------------------------- public T getObject() {return object;} public void setObject(T object) {this.object = object;} public abstract T toObjectType(Object objectstr); // -------------------------------- public String getDisplayValue() {return displayValue;} public void setDisplayValue(String displayValue) { this.displayValue = displayValue;} // -------------------------------- public String getUnit() {return unit;} public void setUnit(String unit) {this.unit = unit; setUnitEnum(Channel.toUnit(unit));} public Unit getUnitEnum() {return eUnit; } public void setUnitEnum(Unit eunit) {eUnit = eunit; } // public void setUnit(String mUnit) {this.unit = Channel.toUnit(mUnit); } // -------------------------------- public String getMode() {return mode;} public void setMode(String mode) {this.mode = mode; setModeEnum(Channel.toMode(mode));} public Mode getModeEnum() {return eMode; } public void setModeEnum(Mode emode) {eMode = emode; } // public void setUnit(String mUnit) {this.unit = Channel.toUnit(mUnit); } // -------------------------------- public String getCustomUnit() { return customUnit;} public void setCustomUnit(String customunit) {this.customUnit = customunit; } // -------------------------------- public boolean isEnabled() {return enabled;} public void setEnabled(boolean val) {enabled = val;} // ---------------------------------- public String getDescription() { return (description == null ? shortDescription :description); } public void setDescription(String description) { this.description = description; } // ---------------------------------- public String getShortDescription() {return shortDescription;} public void setShortDescription(String shortDescription) { this.shortDescription = shortDescription; } // ---------------------------------- public String getComment() {return comment;} public void setComment(String comment) { this.comment = comment; } // ---------------------------------- public double getMpy() {return mpy; } public void setMpy(double mpy) {this.mpy = mpy; } // ---------------------------------- public double getDiv() {return div; } public void setDiv(double div) {this.div = div; } // ---------------------------------- public Integer getLimitMaxError() {return limitMaxError;} public void setLimitMaxError(Integer limitMaxError) { this.limitMaxError = limitMaxError; } // ---------------------------------- public Integer getLimitMaxWarning() {return limitMaxWarning;} public void setLimitMaxWarning(Integer limitMaxWarning) { this.limitMaxWarning = limitMaxWarning; } // ---------------------------------- public Integer getLimitMinWarning() {return limitMinWarning;} public void setLimitMinWarning(Integer limitMinWarning) { this.limitMinWarning = limitMinWarning; } // ---------------------------------- public Integer getLimitMinError() { return limitMinError; } public void setLimitMinError(Integer limitMinError) { this.limitMinError = limitMinError; } // ---------------------------------- public String getLimitErrorMsg() { return limitErrorMsg;} public void setLimitErrorMsg(String limitErrorMsg) { this.limitErrorMsg = limitErrorMsg; } // ---------------------------------- public String getLimitWarningMsg() {return limitWarningMsg; } public void setLimitWarningMsg(String limitWarningMsg) { this.limitWarningMsg = limitWarningMsg; } // ---------------------------------- public int getLimitMode() {return limitMode; } public void setLimitMode(int limitMode) { this.limitMode = limitMode; } // -------------------------------------------------- public long adjustValue(long val){ long retVal = val; if(mpy != DEFAULT_NOOPVAL){ retVal *= mpy; } if(div != DEFAULT_NOOPVAL && div != 0.0d){ retVal /= div; } return retVal; } // -------------------------------------------------- public float adjustValue(double val){ double retVal = val; if(mpy != DEFAULT_NOOPVAL){ retVal *= mpy; } if(div != DEFAULT_NOOPVAL && div != 0.0d){ retVal /= div; } return (float)retVal; } // -------------------------------------------------- public Channel checkInvalid(Object obj){ Channel retVal = null; if(obj == null){ String tmp = obj.toString(); retVal = new LongChannel(getDescription(), getUnit(), -1); String logString = "["+getObject()+"] "+getDescription()+" returned: "+obj; retVal.setMessage(logString); retVal.setWarning(1); Logger.log(logString ); } return retVal; } // -------------------------------------------------- private boolean haveSetChannels = false; public Channel getChannel(Object obj){ Channel retVal = checkInvalid(obj); if(retVal != null) { return retVal;} // ------------------------------ if (obj instanceof Number) { Number number = (Number) obj; if (obj instanceof Integer || obj instanceof Long) { long val = adjustValue(number.longValue()); retVal = new LongChannel(getDescription(), getUnit(), val); } else if (obj instanceof Float || obj instanceof Double) { float val = adjustValue(number.floatValue()); retVal = new FloatChannel(getDescription(), getUnit(), val); } } if(getLimitMode() > 0 && !haveSetChannels){ retVal.setLimitMode(getLimitMode()); retVal.setLimitMaxError(getLimitMaxError()); retVal.setLimitMaxWarning(getLimitMaxWarning()); retVal.setLimitMinWarning(getLimitMinWarning()); retVal.setLimitMinError(getLimitMinError()); retVal.setLimitErrorMsg(getLimitErrorMsg()); retVal.setLimitWarningMsg(getLimitWarningMsg()); haveSetChannels = true; } if(retVal != null && retVal.getUnit() == Unit.CUSTOM){ retVal.setCustomunit(getCustomUnit()); } return retVal; } // ---------------------------------- public static Digester describe4Digester(Digester digester, String base) throws Exception{ digester.addBeanPropertySetter( base+"/object", "object" ); digester.addBeanPropertySetter( base+"/displayvalue", "displayValue" ); digester.addBeanPropertySetter( base+"/description", "description" ); digester.addBeanPropertySetter( base+"/comment", "comment" ); digester.addBeanPropertySetter( base+"/shortdescription", "shortDescription" ); digester.addBeanPropertySetter( base+"/enabled", "enabled" ); digester.addBeanPropertySetter( base+"/unit", "unit" ); digester.addBeanPropertySetter( base+"/mode", "mode" ); digester.addBeanPropertySetter( base+"/customunit", "customUnit" ); // digester.addCallMethod(base+"/unit", "setUnit", 1, new String[]{"java.lang.String"}); digester.addBeanPropertySetter( base+"/mpy", "mpy" ); digester.addBeanPropertySetter( base+"/div", "div" ); digester.addBeanPropertySetter( base+"/limitmaxerror", "limitMaxError" ); digester.addBeanPropertySetter( base+"/limitmaxwarning", "limitMaxWarning" ); digester.addBeanPropertySetter( base+"/limitminwarning", "limitMinWarning" ); digester.addBeanPropertySetter( base+"/limitminerror", "limitMinError" ); digester.addBeanPropertySetter( base+"/limiterrormsg", "limitErrorMsg" ); digester.addBeanPropertySetter( base+"/limitwarningmsg", "limitWarningMsg" ); digester.addBeanPropertySetter( base+"/limitmode", "limitMode" ); // digester.addBeanPropertySetter( base+"/limitmode", "limitMode" ); // Properties String tmp = base + "/properties/property"; digester.addObjectCreate( tmp , PropertyEntry.class ); PropertyEntry.describe4Digester(digester, tmp); digester.addSetNext( tmp, "addProperty" ); return digester; } // ------------------------------------------- public StringBuilder toXML(StringBuilder target, String prefix, String suffix){ target.append(prefix); target.append("<attribute>"); target.append(suffix); String tmp = prefix + "\t"; ProfileFactory.addXMLElement(target, "object", getObject(), tmp, suffix); ProfileFactory.addXMLElement(target, "displayvalue", getDisplayValue(), tmp, suffix); ProfileFactory.addXMLElement(target, "description", getDescription(), tmp, suffix); ProfileFactory.addXMLElement(target, "shortdescription", getShortDescription(), tmp, suffix); ProfileFactory.addXMLElement(target, "comment", getComment(), tmp, suffix); ProfileFactory.addXMLElement(target, "unit", getUnit(), tmp, suffix); ProfileFactory.addXMLElement(target, "mode", getMode(), tmp, suffix); ProfileFactory.addXMLElement(target, "customunit", getCustomUnit(), tmp, suffix); ProfileFactory.addXMLElement(target, "enabled", isEnabled(), tmp, suffix); if(getMpy() != DEFAULT_NOOPVAL){ ProfileFactory.addXMLElement(target, "mpy", getMpy(), tmp, suffix); } if(getDiv() != DEFAULT_NOOPVAL){ ProfileFactory.addXMLElement(target, "div", getMpy(), tmp, suffix); } if(getLimitMaxError() != null) ProfileFactory.addXMLElement(target, "limitMaxError", getLimitMaxError(), tmp, suffix); if(getLimitMaxWarning() != null) ProfileFactory.addXMLElement(target, "limitmaxwarning", getLimitMaxWarning(), tmp, suffix); if(getLimitMinWarning() != null) ProfileFactory.addXMLElement(target, "limitMinWarning", getLimitMinWarning(), tmp, suffix); if(getLimitMinError() != null) ProfileFactory.addXMLElement(target, "limitMinError", getLimitMinError(), tmp, suffix); if(getLimitErrorMsg() != null) ProfileFactory.addXMLElement(target, "limitErrorMsg", getLimitErrorMsg(), tmp, suffix); if(getLimitWarningMsg() != null) ProfileFactory.addXMLElement(target, "limitWarningMsg", getLimitWarningMsg(), tmp, suffix); if(getLimitMode() > 0) ProfileFactory.addXMLElement(target, "limitMode", getLimitMode(), tmp, suffix); // ------------------------------------- ProfileFactory.toXML(target, getProperties(), tmp, suffix); // ------------------------------------- target.append(prefix); target.append("</attribute>"); target.append(suffix); return target; } // ------------------------------------------- public String toXML(String prefix, String suffix){ StringBuilder retVal = toXML(new StringBuilder(), prefix, suffix); return retVal.toString(); } // ------------------------------------------- @Override public abstract int compareTo(Attribute<T> other); }