001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.monitors;
028    
029    
030    
031    import java.util.ArrayList;
032    import java.util.LinkedHashSet;
033    
034    import org.opends.server.admin.std.server.MonitorProviderCfg;
035    import org.opends.server.api.AttributeSyntax;
036    import org.opends.server.api.MonitorProvider;
037    import org.opends.server.config.ConfigException;
038    import org.opends.server.core.DirectoryServer;
039    import org.opends.server.extensions.TraditionalWorkQueue;
040    import org.opends.server.protocols.asn1.ASN1OctetString;
041    import org.opends.server.types.Attribute;
042    import org.opends.server.types.AttributeType;
043    import org.opends.server.types.AttributeValue;
044    import org.opends.server.types.InitializationException;
045    
046    
047    
048    
049    /**
050     * This class defines a Directory Server monitor that can be used to provide
051     * information about the state of the work queue.
052     */
053    public class TraditionalWorkQueueMonitor
054           extends MonitorProvider<MonitorProviderCfg>
055    {
056      /**
057       * The name to use for the monitor attribute that provides the current request
058       * backlog.
059       */
060      public static final String ATTR_CURRENT_BACKLOG = "currentRequestBacklog";
061    
062    
063    
064      /**
065       * The name to use for the monitor attribute that provides the average request
066       * backlog.
067       */
068      public static final String ATTR_AVERAGE_BACKLOG = "averageRequestBacklog";
069    
070    
071    
072      /**
073       * The name to use for the monitor attribute that provides the maximum
074       * observed request backlog.
075       */
076      public static final String ATTR_MAX_BACKLOG = "maxRequestBacklog";
077    
078    
079    
080      /**
081       * The name to use for the monitor attribute that provides the total number of
082       * operations submitted.
083       */
084      public static final String ATTR_OPS_SUBMITTED = "requestsSubmitted";
085    
086    
087    
088      /**
089       * The name to use for the monitor attribute that provides the total number of
090       * requests that have been rejected because the work queue was full.
091       */
092      public static final String ATTR_OPS_REJECTED_QUEUE_FULL =
093           "requestsRejectedDueToQueueFull";
094    
095    
096    
097      // The maximum backlog observed by polling the queue.
098      private int maxBacklog;
099    
100      // The total number of times the backlog has been polled.
101      private long numPolls;
102    
103      // The total backlog observed from periodic polling.
104      private long totalBacklog;
105    
106      // The traditional work queue instance with which this monitor is associated.
107      private TraditionalWorkQueue workQueue;
108    
109    
110    
111      /**
112       * Initializes this monitor provider.  Note that no initialization should be
113       * done here, since it should be performed in the
114       * <CODE>initializeMonitorProvider</CODE> class.
115       *
116       * @param  workQueue  The work queue with which this monitor is associated.
117       */
118      public TraditionalWorkQueueMonitor(TraditionalWorkQueue workQueue)
119      {
120        super("Work Queue Monitor Provider");
121    
122    
123        this.workQueue = workQueue;
124      }
125    
126    
127    
128      /**
129       * {@inheritDoc}
130       */
131      public void initializeMonitorProvider(MonitorProviderCfg configuration)
132             throws ConfigException, InitializationException
133      {
134        maxBacklog   = 0;
135        totalBacklog = 0;
136        numPolls     = 0;
137      }
138    
139    
140    
141      /**
142       * Retrieves the name of this monitor provider.  It should be unique among all
143       * monitor providers, including all instances of the same monitor provider.
144       *
145       * @return  The name of this monitor provider.
146       */
147      public String getMonitorInstanceName()
148      {
149        return "Work Queue";
150      }
151    
152    
153    
154      /**
155       * Retrieves the length of time in milliseconds that should elapse between
156       * calls to the <CODE>updateMonitorData()</CODE> method.  A negative or zero
157       * return value indicates that the <CODE>updateMonitorData()</CODE> method
158       * should not be periodically invoked.
159       *
160       * @return  The length of time in milliseconds that should elapse between
161       *          calls to the <CODE>updateMonitorData()</CODE> method.
162       */
163      public long getUpdateInterval()
164      {
165        // We will poll the work queue every 10 seconds.
166        return 10000;
167      }
168    
169    
170    
171      /**
172       * Performs any processing periodic processing that may be desired to update
173       * the information associated with this monitor.  Note that best-effort
174       * attempts will be made to ensure that calls to this method come
175       * <CODE>getUpdateInterval()</CODE> milliseconds apart, but no guarantees will
176       * be made.
177       */
178      public void updateMonitorData()
179      {
180        int backlog = workQueue.size();
181        totalBacklog += backlog;
182        numPolls++;
183    
184        if (backlog > maxBacklog)
185        {
186          maxBacklog = backlog;
187        }
188      }
189    
190    
191    
192      /**
193       * Retrieves a set of attributes containing monitor data that should be
194       * returned to the client if the corresponding monitor entry is requested.
195       *
196       * @return  A set of attributes containing monitor data that should be
197       *          returned to the client if the corresponding monitor entry is
198       *          requested.
199       */
200      public ArrayList<Attribute> getMonitorData()
201      {
202        int backlog = workQueue.size();
203        totalBacklog += backlog;
204        numPolls++;
205        if (backlog > maxBacklog)
206        {
207          maxBacklog = backlog;
208        }
209    
210        long averageBacklog = (long) (1.0 * totalBacklog / numPolls);
211    
212        long opsSubmitted      = workQueue.getOpsSubmitted();
213        long rejectedQueueFull = workQueue.getOpsRejectedDueToQueueFull();
214    
215        ArrayList<Attribute> monitorAttrs = new ArrayList<Attribute>();
216        AttributeSyntax integerSyntax = DirectoryServer.getDefaultIntegerSyntax();
217    
218    
219        // The current backlog.
220        AttributeType attrType =
221             DirectoryServer.getDefaultAttributeType(ATTR_CURRENT_BACKLOG,
222                                                     integerSyntax);
223        ASN1OctetString valueString = new ASN1OctetString(String.valueOf(backlog));
224        LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
225        values.add(new AttributeValue(valueString, valueString));
226        monitorAttrs.add(new Attribute(attrType, ATTR_CURRENT_BACKLOG, values));
227    
228    
229        // The average backlog.
230        attrType = DirectoryServer.getDefaultAttributeType(ATTR_AVERAGE_BACKLOG,
231                                                           integerSyntax);
232        valueString = new ASN1OctetString(String.valueOf(averageBacklog));
233        values = new LinkedHashSet<AttributeValue>();
234        values.add(new AttributeValue(valueString, valueString));
235        monitorAttrs.add(new Attribute(attrType, ATTR_AVERAGE_BACKLOG, values));
236    
237    
238        // The maximum backlog.
239        attrType = DirectoryServer.getDefaultAttributeType(ATTR_MAX_BACKLOG,
240                                                           integerSyntax);
241        valueString = new ASN1OctetString(String.valueOf(maxBacklog));
242        values = new LinkedHashSet<AttributeValue>();
243        values.add(new AttributeValue(valueString, valueString));
244        monitorAttrs.add(new Attribute(attrType, ATTR_MAX_BACKLOG, values));
245    
246    
247        // The total number of operations submitted.
248        attrType = DirectoryServer.getDefaultAttributeType(ATTR_OPS_SUBMITTED,
249                                                           integerSyntax);
250        valueString = new ASN1OctetString(String.valueOf(opsSubmitted));
251        values = new LinkedHashSet<AttributeValue>();
252        values.add(new AttributeValue(valueString, valueString));
253        monitorAttrs.add(new Attribute(attrType, ATTR_OPS_SUBMITTED, values));
254    
255    
256        // The total number of operations rejected due to a full work queue.
257        attrType =
258             DirectoryServer.getDefaultAttributeType(ATTR_OPS_REJECTED_QUEUE_FULL,
259                                                     integerSyntax);
260        valueString = new ASN1OctetString(String.valueOf(rejectedQueueFull));
261        values = new LinkedHashSet<AttributeValue>();
262        values.add(new AttributeValue(valueString, valueString));
263        monitorAttrs.add(new Attribute(attrType, ATTR_OPS_REJECTED_QUEUE_FULL,
264                                       values));
265    
266    
267        return monitorAttrs;
268      }
269    }
270