/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2007-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) 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, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.dao.support; import java.io.File; import java.io.InputStream; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.dao.RrdDao; import org.opennms.netmgt.model.OnmsAttribute; import org.opennms.netmgt.model.RrdGraphAttribute; import org.opennms.netmgt.rrd.RrdGraphDetails; import org.opennms.netmgt.rrd.RrdStrategy; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * <p>DefaultRrdDao class.</p> * * @author <a href="mailto:dj@opennms.org">DJ Gregor</a> * @version $Id: $ */ public class DefaultRrdDao implements RrdDao, InitializingBean { private RrdStrategy<?, ?> m_rrdStrategy; private File m_rrdBaseDirectory; private String m_rrdBinaryPath; /** {@inheritDoc} */ public double getPrintValue(OnmsAttribute attribute, String cf, long start, long end) { return getPrintValues(attribute, cf, start, end)[0]; } /** * <p>getPrintValues</p> * * @param attribute a {@link org.opennms.netmgt.model.OnmsAttribute} object. * @param rraConsolidationFunction a {@link java.lang.String} object. * @param startTimeInMillis a long. * @param endTimeInMillis a long. * @param printFunctions a {@link java.lang.String} object. * @return an array of double. */ public double[] getPrintValues(OnmsAttribute attribute, String rraConsolidationFunction, long startTimeInMillis, long endTimeInMillis, String... printFunctions) { Assert.notNull(attribute, "attribute argument must not be null"); Assert.notNull(rraConsolidationFunction, "rraConsolicationFunction argument must not be null"); Assert.isTrue(endTimeInMillis > startTimeInMillis, "end argument must be after start argument"); Assert.isAssignable(attribute.getClass(), RrdGraphAttribute.class, "attribute argument must be assignable to RrdGraphAttribute"); // if no printFunctions are given just use the rraConsolidationFunction if (printFunctions.length < 1) { printFunctions = new String[] { rraConsolidationFunction }; } RrdGraphAttribute rrdAttribute = (RrdGraphAttribute) attribute; String[] command = new String[] { m_rrdBinaryPath, "graph", "-", "--start=" + (startTimeInMillis / 1000), "--end=" + (endTimeInMillis / 1000), "DEF:ds=" + RrdFileConstants.escapeForGraphing(rrdAttribute.getRrdRelativePath()) + ":" + attribute.getName() + ":" + rraConsolidationFunction, }; String[] printDefs = new String[printFunctions.length]; for (int i = 0; i < printFunctions.length; i++) { printDefs[i] = "PRINT:ds:" + printFunctions[i] + ":\"%le\""; } String commandString = StringUtils.arrayToDelimitedString(command, " ") + ' ' + StringUtils.arrayToDelimitedString(printDefs, " "); LogUtils.debugf(this, "commandString: %s", commandString); RrdGraphDetails graphDetails; try { graphDetails = m_rrdStrategy.createGraphReturnDetails(commandString, m_rrdBaseDirectory); } catch (Throwable e) { throw new DataAccessResourceFailureException("Failure when generating graph to get data with command '" + commandString + "'", e); } String[] printLines; try { printLines = graphDetails.getPrintLines(); } catch (Throwable e) { throw new DataAccessResourceFailureException("Failure to get print lines from graph after graphing with command '" + commandString + "'", e); } if (printLines.length != printFunctions.length) { throw new DataAccessResourceFailureException("Returned number of print lines should be "+printFunctions.length+", but was " + printLines.length + " from command: " + commandString); } double[] values = new double[printLines.length]; for (int i = 0; i < printLines.length; i++) { if (printLines[i].endsWith("nan")) { values[i] = Double.NaN; } else { try { values[i] = Double.parseDouble(printLines[i]); } catch (NumberFormatException e) { throw new DataAccessResourceFailureException("Value of line " + (i + 1) + " of output from RRD is not a valid floating point number: '" + printLines[i] + "'"); } } } return values; } /** * <p>afterPropertiesSet</p> * * @throws java.lang.Exception if any. */ @Override public void afterPropertiesSet() throws Exception { Assert.state(m_rrdStrategy != null, "property rrdStrategy must be set and be non-null"); Assert.state(m_rrdBaseDirectory != null, "property rrdBaseDirectory must be set and be non-null"); Assert.state(m_rrdBinaryPath != null, "property rrdBinaryPath must be set and be non-null"); } /** * <p>getRrdStrategy</p> * * @return a {@link org.opennms.netmgt.rrd.RrdStrategy} object. */ public RrdStrategy<?, ?> getRrdStrategy() { return m_rrdStrategy; } /** * <p>setRrdStrategy</p> * * @param rrdStrategy a {@link org.opennms.netmgt.rrd.RrdStrategy} object. */ public void setRrdStrategy(RrdStrategy<?, ?> rrdStrategy) { m_rrdStrategy = rrdStrategy; } /** * <p>getRrdBaseDirectory</p> * * @return a {@link java.io.File} object. */ public File getRrdBaseDirectory() { return m_rrdBaseDirectory; } /** * <p>setRrdBaseDirectory</p> * * @param rrdBaseDirectory a {@link java.io.File} object. */ public void setRrdBaseDirectory(File rrdBaseDirectory) { m_rrdBaseDirectory = rrdBaseDirectory; } /** * <p>getRrdBinaryPath</p> * * @return a {@link java.lang.String} object. */ public String getRrdBinaryPath() { return m_rrdBinaryPath; } /** * <p>setRrdBinaryPath</p> * * @param rrdBinaryPath a {@link java.lang.String} object. */ public void setRrdBinaryPath(String rrdBinaryPath) { m_rrdBinaryPath = rrdBinaryPath; } /** * {@inheritDoc} * * Create an RRD graph. * @see org.opennms.netmgt.dao.RrdDao#createGraph(java.lang.String, java.io.File) */ public InputStream createGraph(String command, File workDir) throws DataRetrievalFailureException { try { return m_rrdStrategy.createGraph(command, workDir); } catch (Throwable e) { throw new DataRetrievalFailureException("Could not create graph: " + e, e); } } /** * <p>getGraphTopOffsetWithText</p> * * @see org.opennms.netmgt.dao.RrdDao#getGraphTopOffsetWithText() * @return a int. */ public int getGraphTopOffsetWithText() { return m_rrdStrategy.getGraphTopOffsetWithText(); } /** * <p>getGraphLeftOffset</p> * * @see org.opennms.netmgt.dao.RrdDao#getGraphLeftOffset() * @return a int. */ public int getGraphLeftOffset() { return m_rrdStrategy.getGraphLeftOffset(); } /** * <p>getGraphRightOffset</p> * * @see org.opennms.netmgt.dao.RrdDao#getGraphRightOffset() * @return a int. */ public int getGraphRightOffset() { return m_rrdStrategy.getGraphRightOffset(); } /** {@inheritDoc} */ public Double getLastFetchValue(OnmsAttribute attribute, int interval) throws DataAccessResourceFailureException { Assert.notNull(attribute, "attribute argument must not be null"); Assert.isTrue(interval > 0, "interval argument must be greater than zero"); Assert.isAssignable(attribute.getClass(), RrdGraphAttribute.class, "attribute argument must be assignable to RrdGraphAttribute"); RrdGraphAttribute rrdAttribute = (RrdGraphAttribute) attribute; File rrdFile = new File(m_rrdBaseDirectory, rrdAttribute.getRrdRelativePath()); try { return m_rrdStrategy.fetchLastValue(rrdFile.getAbsolutePath(), attribute.getName(), interval); } catch (Throwable e) { throw new DataAccessResourceFailureException("Failure to fetch last value from file '" + rrdFile + "' with interval " + interval, e); } } /** {@inheritDoc} */ public Double getLastFetchValue(OnmsAttribute attribute, int interval, int range) throws DataAccessResourceFailureException { Assert.notNull(attribute, "attribute argument must not be null"); Assert.isTrue(interval > 0, "interval argument must be greater than zero"); Assert.isTrue(range > 0, "range argument must be greater than zero"); Assert.isAssignable(attribute.getClass(), RrdGraphAttribute.class, "attribute argument must be assignable to RrdGraphAttribute"); RrdGraphAttribute rrdAttribute = (RrdGraphAttribute) attribute; File rrdFile = new File(m_rrdBaseDirectory, rrdAttribute.getRrdRelativePath()); try { return m_rrdStrategy.fetchLastValueInRange(rrdFile.getAbsolutePath(), attribute.getName(), interval, range); } catch (Throwable e) { throw new DataAccessResourceFailureException("Failure to fetch last value from file '" + rrdFile + "' with interval " + interval + " and range " + range, e); } } }