KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > graph > FetchSource


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org)
7  *
8  * Developers: Sasa Markovic (saxon@jrobin.org)
9  * Arne Vandamme (cobralord@jrobin.org)
10  *
11  * (C) Copyright 2003, by Sasa Markovic.
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25 package org.jrobin.graph;
26
27 import java.util.ArrayList JavaDoc;
28 import java.io.IOException JavaDoc;
29
30 import org.jrobin.core.*;
31
32 /**
33  * <p>Class used to group datasources per RRD db, for faster fetching.
34  * A FetchSource represents one RRD database file, and will take care of all datasource
35  * fetching using objects of the <code>core</code> package. Fetching will be done in such
36  * a way that all datasources per consolidation function are fetched with the minimum possible
37  * file reads.</p>
38  *
39  * @author Arne Vandamme (cobralord@jrobin.org)
40  */

41 class FetchSource
42 {
43     // ================================================================
44
// -- Members
45
// ================================================================
46
protected static final int AVG = 0;
47     protected static final int MAX = 1;
48     protected static final int MIN = 2;
49     protected static final int LAST = 3;
50     protected static final int MAX_CF = 4;
51     
52     protected static final String JavaDoc[] cfNames = new String JavaDoc[] { "AVERAGE", "MAX", "MIN", "LAST" };
53
54     private RrdDb rrd;
55     private RrdDef rrdDef;
56
57     private String JavaDoc rrdFile; // Holds the name of the RRD file
58
private String JavaDoc backendName;
59
60     private int numSources = 0;
61     private ArrayList JavaDoc[] datasources = new ArrayList JavaDoc[MAX_CF];
62
63     private FetchSourceList listReference = null;
64
65
66     // ================================================================
67
// -- Constructors
68
// ================================================================
69
/**
70      * Constructs a FetchSource object based on a RRD file name.
71      *
72      * @param rrdFile Name of the RRD file holding all datasources.
73      * @param listRef Reference to the FetchSourceList this FetchSource belongs to.
74      */

75     protected FetchSource( String JavaDoc rrdFile, FetchSourceList listRef )
76     {
77         this.rrdFile = rrdFile;
78         listReference = listRef;
79
80         // Initialization of datasource lists per CF
81
for (int i = 0; i < datasources.length; i++)
82             datasources[i] = new ArrayList JavaDoc( 10 );
83     }
84     
85     /**
86      * Constructs a FetchSource object based on a RRD file name, and
87      * adds a given datasource to the datasources list.
88      *
89      * @param rrdFile Name of the RRD file holding all datasources.
90      * @param consolFunc Consolidation function of the datasource to fetch.
91      * @param dsName Internal name of the datasource in the RRD file.
92      * @param name Variable name of the datasource in the graph definition.
93      * @param listRef Reference to the FetchSourceList this FetchSource belongs to.
94      * @throws RrdException Thrown in case of a JRobin specific error.
95      */

96     protected FetchSource( String JavaDoc rrdFile, String JavaDoc consolFunc, String JavaDoc dsName, String JavaDoc name, FetchSourceList listRef ) throws RrdException
97     {
98         this( rrdFile, listRef );
99         addSource( consolFunc, dsName, name );
100     }
101
102     /**
103      * Constructs a FetchSource object based on a RRD file name, and
104      * adds a given datasource to the datasources list.
105      *
106      * @param rrdFile Name of the RRD file holding all datasources.
107      * @param consolFunc Consolidation function of the datasource to fetch.
108      * @param dsName Internal name of the datasource in the RRD file.
109      * @param name Variable name of the datasource in the graph definition.
110      * @param backendName Name of the RrdBackendFactory to use for this RrdDb.
111      * @param listRef Reference to the FetchSourceList this FetchSource belongs to.
112      * @throws RrdException Thrown in case of a JRobin specific error.
113      */

114     protected FetchSource( String JavaDoc rrdFile, String JavaDoc consolFunc, String JavaDoc dsName, String JavaDoc name, String JavaDoc backendName, FetchSourceList listRef ) throws RrdException
115     {
116         this( rrdFile, consolFunc, dsName, name, listRef );
117         setBackendFactory( backendName );
118     }
119
120     // ================================================================
121
// -- Protected methods
122
// ================================================================
123
/**
124      * Adds a given datasource to the datasources list for this FetchSource.
125      *
126      * @param consolFunc Consolidation function of the datasource to fetch.
127      * @param dsName Internal name of the datasource in the RRD file.
128      * @param name Variable name of the datasource in the graph definition.
129      * @throws RrdException Thrown in case of a JRobin specific error.
130      */

131     protected void addSource( String JavaDoc consolFunc, String JavaDoc dsName, String JavaDoc name ) throws RrdException
132     {
133         if ( consolFunc.equalsIgnoreCase("AVERAGE") || consolFunc.equalsIgnoreCase("AVG") )
134             datasources[AVG].add( new String JavaDoc[] { dsName, name } );
135         else if ( consolFunc.equalsIgnoreCase("MAX") || consolFunc.equalsIgnoreCase("MAXIMUM") )
136             datasources[MAX].add( new String JavaDoc[] { dsName, name } );
137         else if ( consolFunc.equalsIgnoreCase("MIN") || consolFunc.equalsIgnoreCase("MINIMUM") )
138             datasources[MIN].add( new String JavaDoc[] { dsName, name } );
139         else if ( consolFunc.equalsIgnoreCase("LAST") )
140             datasources[LAST].add( new String JavaDoc[] { dsName, name } );
141         else
142             throw new RrdException( "Invalid consolidation function specified." );
143         
144         numSources++;
145     }
146
147     /**
148      * Sets the name of the RrdBackendFactory that should be used for this FetchSource.
149      * The factory should be registered with RrdBackendFactory static.
150      *
151      * @param backendName Name of the RrdBackendFactory to use for this RrdDb.
152      */

153     protected void setBackendFactory( String JavaDoc backendName ) {
154         this.backendName = backendName;
155     }
156
157     /**
158      * Fetches all datavalues for a given timespan out of the provided RRD file.
159      *
160      * @param startTime Start time of the given timespan.
161      * @param endTime End time of the given timespan.
162      * @param resolution Resolution for the fetch request.
163      * @return A <code>ValueExtractor</code> object holding all fetched data.
164      * @throws IOException Thrown in case of fetching I/O error.
165      * @throws RrdException Thrown in case of a JRobin specific error.
166      */

167     protected ValueExtractor fetch ( long startTime, long endTime, long resolution, int reduceFactor ) throws IOException JavaDoc, RrdException
168     {
169         if ( rrd == null )
170             openRrd();
171
172         int dsSize = 0;
173         String JavaDoc[] dsNames, vNames;
174
175         long rrdStep = rrdDef.getStep();
176         FetchData[] result = new FetchData[datasources.length];
177         
178         String JavaDoc[] names = new String JavaDoc[numSources];
179         int tblPos = 0;
180         
181         for (int i = 0; i < datasources.length; i++)
182         {
183             dsSize = datasources[i].size();
184
185             if ( dsSize > 0 )
186             {
187                 // Set the list of ds names
188
dsNames = new String JavaDoc[ dsSize ];
189                 vNames = new String JavaDoc[ dsSize ];
190                 
191                 for (int j = 0; j < dsSize; j++ ) {
192                     String JavaDoc[] spair = (String JavaDoc[]) datasources[i].get(j);
193                     dsNames[j] = spair[0];
194                     vNames[j] = spair[1];
195                 }
196                 
197                 // Fetch datasources
198
FetchRequest request = rrd.createFetchRequest( cfNames[i], startTime, endTime, resolution );
199                 request.setFilter( dsNames );
200
201                 FetchData data = request.fetchData();
202
203                 for (int j = 0; j < dsSize; j++)
204                     names[ data.getDsIndex(dsNames[j]) + tblPos ] = vNames[j];
205                 tblPos += dsSize;
206                 
207                 result[i] = data;
208             }
209         }
210         
211         return new ValueExtractor( names, result, reduceFactor );
212     }
213
214     /**
215      * Retrieves the RrdDb connected to this FetchSource.
216      * The RrdDb instance is retrieved through the use of the
217      * RrdOpener that is referred internally in the FetchSourceList.
218      * It is okay to call this method multiple times in a row.
219      *
220      * @throws IOException Thrown in case of fetching I/O error.
221      * @throws RrdException Thrown in case of a JRobin specific error.
222      */

223     protected void openRrd() throws RrdException, IOException JavaDoc
224     {
225         if ( rrd == null )
226         {
227             org.jrobin.core.RrdOpener opener = listReference.getRrdOpener();
228
229             if ( opener == null )
230                 throw new RrdException( "No RrdOpener specified for RRD management." );
231
232             // Only open if not open yet
233
if ( rrd == null )
234                 rrd = opener.getRrd( rrdFile, getRrdBackendFactory() );
235
236             rrdDef = rrd.getRrdDef();
237         }
238     }
239
240     /**
241      * Gets the RrdDb instance for this FetchSource. If the
242      * RrdDb has not been retrieved yet, it is before this
243      * method returns. It is okay to call this method multiple
244      * times in a row.
245      *
246      * @return Reference to the RrdDb instance.
247      * @throws IOException Thrown in case of fetching I/O error.
248      * @throws RrdException Thrown in case of a JRobin specific error.
249      */

250     protected RrdDb getRrd() throws RrdException, IOException JavaDoc
251     {
252         if ( rrd == null )
253             openRrd();
254
255         return rrd;
256     }
257
258     /**
259      * Releases the internal RrdDb reference for this FetchSource.
260      * It is okay to call this method multiple times in a row.
261      *
262      * @throws IOException Thrown in case of fetching I/O error.
263      * @throws RrdException Thrown in case of a JRobin specific error.
264      */

265     protected void release() throws RrdException, IOException JavaDoc
266     {
267         if ( rrd != null )
268         {
269             org.jrobin.core.RrdOpener opener = listReference.getRrdOpener();
270
271             if ( opener == null )
272                 throw new RrdException( "No RrdOpener specified for RRD management." );
273
274             opener.releaseRrd( rrd );
275             rrd = null;
276         }
277     }
278
279     /**
280      * Returns the timestamp of the last completed sample before or on the given time.
281      * This method is useful to find out the actual last timestamp for graphing, if the
282      * current time is after the last update time. This sample can contain bad (Unknown)
283      * values, as long as the interval for it has been completed. This is not the
284      * timestamp of the last non-unknown sample!
285      *
286      * @param startTime Timestamp for which the last sample time should be calculated.
287      * @param endTime Timestamp for which the last sample time should be calculated.
288      * @param resolution Last timestamp for this particular fetch resolution.
289      * @return Last sample timestamp in seconds.
290      * @throws IOException Thrown in case of fetching I/O error.
291      * @throws RrdException Thrown in case of a JRobin specific error.
292      */

293     protected long getLastSampleTime( long startTime, long endTime, long resolution ) throws RrdException, IOException JavaDoc
294     {
295         if ( rrd == null )
296             openRrd();
297
298         long minSampleTime = Long.MAX_VALUE, sampleTime = 0;
299
300         for ( int i = 0; i < datasources.length; i++ )
301         {
302             if ( datasources[i].size() > 0 )
303             {
304                 sampleTime = rrd.findStartMatchArchive( cfNames[i], startTime, resolution ).getEndTime();
305
306                 if ( sampleTime < minSampleTime )
307                     minSampleTime = sampleTime;
308             }
309         }
310
311         return minSampleTime;
312     }
313
314     /**
315      * Returns an array of the smallest and the largest step in the set.
316      *
317      * @param startTime
318      * @param endTime
319      * @param resolution
320      * @return
321      * @throws RrdException
322      * @throws IOException
323      */

324     protected long[] getFetchStep( long startTime, long endTime, long resolution ) throws RrdException, IOException JavaDoc
325     {
326         if ( rrd == null )
327             openRrd();
328
329         long maxStep = Long.MIN_VALUE, minStep = Long.MAX_VALUE, step = 0;
330
331         for ( int i = 0; i < datasources.length; i++ )
332         {
333             if ( datasources[i].size() > 0 )
334             {
335                 FetchRequest request = rrd.createFetchRequest( cfNames[i], startTime, endTime, resolution );
336                 step = rrd.findMatchingArchive( request ).getArcStep();
337
338                 if ( step < minStep )
339                     minStep = step;
340                 if ( step > maxStep )
341                     maxStep = step;
342             }
343         }
344
345         return new long[] { minStep, maxStep };
346     }
347
348     protected String JavaDoc getRrdFile() {
349         return rrdFile;
350     }
351
352     protected RrdBackendFactory getRrdBackendFactory() throws RrdException
353     {
354         if ( backendName != null )
355             return RrdBackendFactory.getFactory( backendName );
356
357         return RrdBackendFactory.getDefaultFactory();
358     }
359
360     public void exportXml(XmlWriter xml) {
361         for ( int i = 0; i < datasources.length; i++ ) {
362             for ( int j = 0; j < datasources[i].size(); j++ ) {
363                 String JavaDoc[] pair = (String JavaDoc[]) datasources[i].get(j);
364                 xml.startTag("def");
365                 xml.writeTag("name", pair[1]);
366                 xml.writeTag("rrd", rrdFile);
367                 xml.writeTag("source", pair[0]);
368                 xml.writeTag("cf", cfNames[i]);
369                 xml.closeTag(); // def
370
}
371         }
372     }
373 }
374
Popular Tags