001 /* ============================================================
002 * JRobin : Pure java implementation of RRDTool's functionality
003 * ============================================================
004 *
005 * Project Info: http://www.jrobin.org
006 * Project Lead: Sasa Markovic (saxon@jrobin.org);
007 *
008 * (C) Copyright 2003-2005, by Sasa Markovic.
009 *
010 * Developers: Sasa Markovic (saxon@jrobin.org)
011 *
012 *
013 * This library is free software; you can redistribute it and/or modify it under the terms
014 * of the GNU Lesser General Public License as published by the Free Software Foundation;
015 * either version 2.1 of the License, or (at your option) any later version.
016 *
017 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
018 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
019 * See the GNU Lesser General Public License for more details.
020 *
021 * You should have received a copy of the GNU Lesser General Public License along with this
022 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
023 * Boston, MA 02111-1307, USA.
024 */
025
026 package org.jrobin.core;
027
028 /**
029 * Class to represent single data source definition within the RRD.
030 * Datasource definition consists of the following five elements:
031 * <p/>
032 * <ul>
033 * <li>data source name
034 * <li>data soruce type
035 * <li>heartbeat
036 * <li>minimal value
037 * <li>maximal value
038 * </ul>
039 * <p>For the complete explanation of all source definition parameters, see RRDTool's
040 * <a href="../../../../man/rrdcreate.html" target="man">rrdcreate man page</a>.</p>
041 *
042 * @author <a href="mailto:saxon@jrobin.org">Sasa Markovic</a>
043 */
044 public class DsDef implements DsTypes {
045 /**
046 * array of valid source types
047 */
048 public static final String[] DS_TYPES = {DT_GAUGE, DT_COUNTER, DT_DERIVE, DT_ABSOLUTE};
049 static final String FORCE_ZEROS_FOR_NANS_SUFFIX = "!";
050
051 private String dsName, dsType;
052 private long heartbeat;
053 private double minValue, maxValue;
054
055 /**
056 * <p>Creates new data source definition object. This object should be passed as argument
057 * to {@link RrdDef#addDatasource(DsDef) addDatasource()}
058 * method of {@link RrdDb RrdDb} object.</p>
059 * <p/>
060 * <p>For the complete explanation of all source definition parameters, see RRDTool's
061 * <a href="../../../../man/rrdcreate.html" target="man">rrdcreate man page</a></p>
062 * <p/>
063 * <p><b>IMPORTANT NOTE:</b> If datasource name ends with '!', corresponding archives will never
064 * store NaNs as datasource values. In that case, NaN datasource values will be silently
065 * replaced with zeros by the framework.</p>
066 *
067 * @param dsName Data source name.
068 * @param dsType Data source type. Valid values are "COUNTER", "GAUGE", "DERIVE"
069 * and "ABSOLUTE" (these string constants are conveniently defined in the
070 * {@link DsTypes} class).
071 * @param heartbeat Hearbeat
072 * @param minValue Minimal value. Use <code>Double.NaN</code> if unknown.
073 * @param maxValue Maximal value. Use <code>Double.NaN</code> if unknown.
074 * @throws RrdException Thrown if any parameter has illegal value.
075 */
076 public DsDef(String dsName, String dsType, long heartbeat,
077 double minValue, double maxValue) throws RrdException {
078 this.dsName = dsName;
079 this.dsType = dsType;
080 this.heartbeat = heartbeat;
081 this.minValue = minValue;
082 this.maxValue = maxValue;
083 validate();
084 }
085
086 /**
087 * Returns data source name.
088 *
089 * @return Data source name.
090 */
091 public String getDsName() {
092 return dsName;
093 }
094
095 /**
096 * Returns source type.
097 *
098 * @return Source type ("COUNTER", "GAUGE", "DERIVE" or "ABSOLUTE").
099 */
100 public String getDsType() {
101 return dsType;
102 }
103
104 /**
105 * Returns source heartbeat.
106 *
107 * @return Source heartbeat.
108 */
109 public long getHeartbeat() {
110 return heartbeat;
111 }
112
113 /**
114 * Returns minimal calculated source value.
115 *
116 * @return Minimal value.
117 */
118 public double getMinValue() {
119 return minValue;
120 }
121
122 /**
123 * Returns maximal calculated source value.
124 *
125 * @return Maximal value.
126 */
127 public double getMaxValue() {
128 return maxValue;
129 }
130
131 private void validate() throws RrdException {
132 if (dsName == null) {
133 throw new RrdException("Null datasource name specified");
134 }
135 if (dsName.length() == 0) {
136 throw new RrdException("Datasource name length equal to zero");
137 }
138 if (dsName.length() > RrdPrimitive.STRING_LENGTH) {
139 throw new RrdException("Datasource name [" + dsName + "] to long (" +
140 dsName.length() + " chars found, only " + RrdPrimitive.STRING_LENGTH + " allowed");
141 }
142 if (!isValidDsType(dsType)) {
143 throw new RrdException("Invalid datasource type specified: " + dsType);
144 }
145 if (heartbeat <= 0) {
146 throw new RrdException("Invalid heartbeat, must be positive: " + heartbeat);
147 }
148 if (!Double.isNaN(minValue) && !Double.isNaN(maxValue) && minValue >= maxValue) {
149 throw new RrdException("Invalid min/max values specified: " +
150 minValue + "/" + maxValue);
151 }
152 }
153
154 /**
155 * Checks if function argument represents valid source type.
156 *
157 * @param dsType Source type to be checked.
158 * @return <code>true</code> if <code>dsType</code> is valid type,
159 * <code>false</code> otherwise.
160 */
161 public static boolean isValidDsType(String dsType) {
162 for (String type : DS_TYPES) {
163 if (type.equals(dsType)) {
164 return true;
165 }
166 }
167 return false;
168 }
169
170 /**
171 * Returns string representing source definition (RRDTool format).
172 *
173 * @return String containing all data source definition parameters.
174 */
175 public String dump() {
176 return "DS:" + dsName + ":" + dsType + ":" + heartbeat +
177 ":" + Util.formatDouble(minValue, "U", false) +
178 ":" + Util.formatDouble(maxValue, "U", false);
179 }
180
181 /**
182 * Checks if two datasource definitions are equal.
183 * Source definitions are treated as equal if they have the same source name.
184 * It is not possible to create RRD with two equal archive definitions.
185 *
186 * @param obj Archive definition to compare with.
187 * @return <code>true</code> if archive definitions are equal,
188 * <code>false</code> otherwise.
189 */
190 public boolean equals(Object obj) {
191 if (obj instanceof DsDef) {
192 DsDef dsObj = (DsDef) obj;
193 return dsName.equals(dsObj.dsName);
194 }
195 return false;
196 }
197
198 boolean exactlyEqual(DsDef def) {
199 return dsName.equals(def.dsName) && dsType.equals(def.dsType) &&
200 heartbeat == def.heartbeat && Util.equal(minValue, def.minValue) &&
201 Util.equal(maxValue, def.maxValue);
202 }
203 }