001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2012-2016 ForgeRock AS.
016 */
017package org.opends.server.protocols.ldap;
018
019import static org.opends.messages.ProtocolMessages.*;
020import static org.opends.server.protocols.ldap.LDAPConstants.*;
021import static org.opends.server.util.ServerConstants.*;
022
023import java.util.concurrent.atomic.AtomicLong;
024
025import org.forgerock.i18n.LocalizableMessage;
026import org.forgerock.opendj.config.server.ConfigException;
027import org.forgerock.opendj.ldap.schema.ObjectClass;
028import org.forgerock.opendj.server.config.server.MonitorProviderCfg;
029import org.opends.server.api.MonitorData;
030import org.opends.server.api.MonitorProvider;
031import org.opends.server.core.DirectoryServer;
032import org.opends.server.types.OperationType;
033
034/**
035 * This class defines a data structure that will be used to keep track
036 * of various metrics related to LDAP communication that the server has
037 * conducted. The statistics that will be tracked include:
038 * <UL>
039 * <LI>The total number of LDAP client connections accepted by the
040 * server.</LI>
041 * <LI>The total number of LDAP client connections that have been
042 * closed.</LI>
043 * <LI>The total number of LDAP messages read, both overall and broken
044 * down by message type.</LI>
045 * <LI>The total number of LDAP messages written, both overall and
046 * broken down by message type.</LI>
047 * <LI>The total number of bytes read from LDAP clients.</LI>
048 * <LI>The total number of bytes written to LDAP clients.</LI>
049 * </UL>
050 * <BR>
051 * <BR>
052 * This class may also be used in a hierarchical form if it is desirable
053 * to get specific and general statistics at the same time (e.g.,
054 * information about the interaction with a specific client or
055 * aggregated for all clients).
056 */
057public class LDAPStatistics extends MonitorProvider<MonitorProviderCfg>
058{
059
060  // The statistics maintained by this class.
061  private AtomicLong abandonRequests = new AtomicLong(0);
062  private AtomicLong addRequests = new AtomicLong(0);
063  private AtomicLong bindRequests = new AtomicLong(0);
064  private AtomicLong addResponses = new AtomicLong(0);
065  private AtomicLong bindResponses = new AtomicLong(0);
066  private AtomicLong bytesRead = new AtomicLong(0);
067  private AtomicLong bytesWritten = new AtomicLong(0);
068  private AtomicLong compareRequests = new AtomicLong(0);
069  private AtomicLong compareResponses = new AtomicLong(0);
070  private AtomicLong connectionsClosed = new AtomicLong(0);
071  private AtomicLong connectionsEstablished = new AtomicLong(0);
072  private AtomicLong deleteRequests = new AtomicLong(0);
073  private AtomicLong deleteResponses = new AtomicLong(0);
074  private AtomicLong extendedRequests = new AtomicLong(0);
075  private AtomicLong extendedResponses = new AtomicLong(0);
076  private AtomicLong messagesRead = new AtomicLong(0);
077  private AtomicLong messagesWritten = new AtomicLong(0);
078  private AtomicLong modifyRequests = new AtomicLong(0);
079  private AtomicLong modifyResponses = new AtomicLong(0);
080  private AtomicLong modifyDNRequests = new AtomicLong(0);
081  private AtomicLong modifyDNResponses = new AtomicLong(0);
082  private AtomicLong operationsAbandoned = new AtomicLong(0);
083  private AtomicLong operationsCompleted = new AtomicLong(0);
084  private AtomicLong operationsInitiated = new AtomicLong(0);
085  private AtomicLong searchRequests = new AtomicLong(0);
086  private AtomicLong searchOneRequests = new AtomicLong(0);
087  private AtomicLong searchSubRequests = new AtomicLong(0);
088  private AtomicLong searchResultEntries = new AtomicLong(0);
089  private AtomicLong searchResultReferences = new AtomicLong(0);
090  private AtomicLong searchResultsDone = new AtomicLong(0);
091  private AtomicLong unbindRequests = new AtomicLong(0);
092
093
094  /** The instance name for this monitor provider instance. */
095  private final String instanceName;
096
097  // Monitor Objects : for Operations (count and time)
098  private AtomicLong addOperationCount = new AtomicLong(0);
099  private AtomicLong addOperationTime = new AtomicLong(0);
100  private AtomicLong searchOperationCount = new AtomicLong(0);
101  private AtomicLong searchOperationTime = new AtomicLong(0);
102  private AtomicLong delOperationCount = new AtomicLong(0);
103  private AtomicLong delOperationTime = new AtomicLong(0);
104  private AtomicLong bindOperationCount = new AtomicLong(0);
105  private AtomicLong bindOperationTime = new AtomicLong(0);
106  private AtomicLong unbindOperationCount = new AtomicLong(0);
107  private AtomicLong unbindOperationTime = new AtomicLong(0);
108  private AtomicLong compOperationCount = new AtomicLong(0);
109  private AtomicLong compOperationTime = new AtomicLong(0);
110  private AtomicLong modOperationCount = new AtomicLong(0);
111  private AtomicLong modOperationTime = new AtomicLong(0);
112  private AtomicLong moddnOperationCount = new AtomicLong(0);
113  private AtomicLong moddnOperationTime = new AtomicLong(0);
114  private AtomicLong abandonOperationCount = new AtomicLong(0);
115  private AtomicLong abandonOperationTime = new AtomicLong(0);
116  private AtomicLong extOperationCount = new AtomicLong(0);
117  private AtomicLong extOperationTime = new AtomicLong(0);
118
119  /**
120   * Creates a new instance of this class with the specified parent.
121   *
122   * @param instanceName
123   *          The name for this monitor provider instance.
124   */
125  public LDAPStatistics(String instanceName)
126  {
127    this.instanceName = instanceName;
128  }
129
130  @Override
131  public void initializeMonitorProvider(MonitorProviderCfg configuration)
132      throws ConfigException
133  {
134    // Throw an exception, because this monitor is not intended to be
135    // dynamically loaded from the configuration. Rather, it should be
136    // explicitly created and registered by the LDAP connection handler
137    // or an LDAP client connection.
138    LocalizableMessage message =
139        ERR_LDAP_STATS_INVALID_MONITOR_INITIALIZATION.get(configuration.dn());
140    throw new ConfigException(message);
141  }
142
143  /**
144   * Retrieves the name of this monitor provider. It should be unique
145   * among all monitor providers, including all instances of the same
146   * monitor provider.
147   *
148   * @return The name of this monitor provider.
149   */
150  @Override
151  public String getMonitorInstanceName()
152  {
153    return instanceName;
154  }
155
156  @Override
157  public ObjectClass getMonitorObjectClass()
158  {
159    return DirectoryServer.getSchema().getObjectClass(OC_MONITOR_CONNHANDLERSTATS);
160  }
161
162  @Override
163  public MonitorData getMonitorData()
164  {
165    // Construct the list of attributes to return.
166    /* TODO : the attribute names should be constant (in ServerConstants.java
167     *        and associated with their objectclass
168     *        OC_MONITOR_CONNHANDLERSTATS
169     */
170    final MonitorData attrs = new MonitorData(31 + 10 * 2);
171    attrs.add("connectionsEstablished", connectionsEstablished);
172    attrs.add("connectionsClosed", connectionsClosed);
173    attrs.add("bytesRead", bytesRead);
174    attrs.add("bytesWritten", bytesWritten);
175    attrs.add("ldapMessagesRead", messagesRead);
176    attrs.add("ldapMessagesWritten", messagesWritten);
177    attrs.add("operationsAbandoned", operationsAbandoned);
178    attrs.add("operationsInitiated", operationsInitiated);
179    attrs.add("operationsCompleted", operationsCompleted);
180    attrs.add("abandonRequests", abandonRequests);
181    attrs.add("addRequests", addRequests);
182    attrs.add("addResponses", addResponses);
183    attrs.add("bindRequests", bindRequests);
184    attrs.add("bindResponses", bindResponses);
185    attrs.add("compareRequests", compareRequests);
186    attrs.add("compareResponses", compareResponses);
187    attrs.add("deleteRequests", deleteRequests);
188    attrs.add("deleteResponses", deleteResponses);
189    attrs.add("extendedRequests", extendedRequests);
190    attrs.add("extendedResponses", extendedResponses);
191    attrs.add("modifyRequests", modifyRequests);
192    attrs.add("modifyResponses", modifyResponses);
193    attrs.add("modifyDNRequests", modifyDNRequests);
194    attrs.add("modifyDNResponses", modifyDNResponses);
195    attrs.add("searchRequests", searchRequests);
196    attrs.add("searchOneRequests", searchOneRequests);
197    attrs.add("searchSubRequests", searchSubRequests);
198    attrs.add("searchResultEntries", searchResultEntries);
199    attrs.add("searchResultReferences", searchResultReferences);
200    attrs.add("searchResultsDone", searchResultsDone);
201    attrs.add("unbindRequests", unbindRequests);
202
203    // adds
204    attrs.add("ds-mon-add-operations-total-count", addOperationCount);
205    attrs.add("ds-mon-resident-time-add-operations-total-time", addOperationTime);
206
207    // search
208    attrs.add("ds-mon-search-operations-total-count", searchOperationCount);
209    attrs.add("ds-mon-resident-time-search-operations-total-time", searchOperationTime);
210
211    // bind
212    attrs.add("ds-mon-bind-operations-total-count", bindOperationCount);
213    attrs.add("ds-mon-resident-time-bind-operations-total-time", bindOperationTime);
214
215    // unbind
216    attrs.add("ds-mon-unbind-operations-total-count", unbindOperationCount);
217    attrs.add("ds-mon-resident-time-unbind-operations-total-time", unbindOperationTime);
218
219    // compare
220    attrs.add("ds-mon-compare-operations-total-count", compOperationCount);
221    attrs.add("ds-mon-resident-time-compare-operations-total-time", compOperationTime);
222
223    // del
224    attrs.add("ds-mon-delete-operations-total-count", delOperationCount);
225    attrs.add("ds-mon-resident-time-delete-operations-total-time", delOperationTime);
226
227    // mod
228    attrs.add("ds-mon-mod-operations-total-count", modOperationCount);
229    attrs.add("ds-mon-resident-time-mod-operations-total-time", modOperationTime);
230
231    // moddn
232    attrs.add("ds-mon-moddn-operations-total-count", moddnOperationCount);
233    attrs.add("ds-mon-resident-time-moddn-operations-total-time", moddnOperationTime);
234
235    // abandon
236    attrs.add("ds-mon-abandon-operations-total-count", abandonOperationCount);
237    attrs.add("ds-mon-resident-time-abandon-operations-total-time", abandonOperationTime);
238
239    // extended
240    attrs.add("ds-mon-extended-operations-total-count", extOperationCount);
241    attrs.add("ds-mon-resident-time-extended-operations-total-time", extOperationTime);
242
243    return attrs;
244  }
245
246  /** Clears any statistical information collected to this point. */
247  public void clearStatistics()
248  {
249      abandonRequests.set(0);
250      addRequests.set(0);
251      addResponses.set(0);
252      bindRequests.set(0);
253      bindResponses.set(0);
254      bytesRead.set(0);
255      bytesWritten.set(0);
256      compareRequests.set(0);
257      compareResponses.set(0);
258      connectionsClosed.set(0);
259      connectionsEstablished.set(0);
260      deleteRequests.set(0);
261      deleteResponses.set(0);
262      extendedRequests.set(0);
263      extendedResponses.set(0);
264      messagesRead.set(0);
265      messagesWritten.set(0);
266      modifyRequests.set(0);
267      modifyResponses.set(0);
268      modifyDNRequests.set(0);
269      modifyDNResponses.set(0);
270      operationsAbandoned.set(0);
271      operationsCompleted.set(0);
272      operationsInitiated.set(0);
273      searchRequests.set(0);
274      searchOneRequests.set(0);
275      searchSubRequests.set(0);
276      searchResultEntries.set(0);
277      searchResultReferences.set(0);
278      searchResultsDone.set(0);
279      unbindRequests.set(0);
280
281      addOperationCount.set(0);
282      addOperationTime.set(0);
283      searchOperationCount.set(0);
284      searchOperationTime.set(0);
285      delOperationCount.set(0);
286      delOperationTime.set(0);
287      bindOperationCount.set(0);
288      bindOperationTime.set(0);
289      unbindOperationCount.set(0);
290      unbindOperationTime.set(0);
291      compOperationCount.set(0);
292      compOperationTime.set(0);
293      modOperationCount.set(0);
294      modOperationTime.set(0);
295      moddnOperationCount.set(0);
296      moddnOperationTime.set(0);
297      abandonOperationCount.set(0);
298      abandonOperationTime.set(0);
299      extOperationCount.set(0);
300      extOperationTime.set(0);
301  }
302
303  /**
304   * Updates the appropriate set of counters to indicate that a new
305   * connection has been established.
306   */
307  public void updateConnect()
308  {
309    connectionsEstablished.getAndIncrement();
310  }
311
312  /** Updates the appropriate set of counters to indicate that a connection has been closed. */
313  public void updateDisconnect()
314  {
315      connectionsClosed.getAndIncrement();
316  }
317
318  /**
319   * Updates the appropriate set of counters to indicate that the
320   * specified number of bytes have been read by the client.
321   *
322   * @param bytesRead
323   *          The number of bytes read by the client.
324   */
325  public void updateBytesRead(int bytesRead)
326  {
327     this.bytesRead.getAndAdd(bytesRead);
328  }
329
330  /**
331   * Updates the appropriate set of counters to indicate that the
332   * specified number of bytes have been written to the client.
333   *
334   * @param bytesWritten
335   *          The number of bytes written to the client.
336   */
337  public void updateBytesWritten(int bytesWritten)
338  {
339     this.bytesWritten.getAndAdd(bytesWritten);
340  }
341
342  /**
343   * Updates the appropriate set of counters based on the provided
344   * message that has been read from the client.
345   *
346   * @param message
347   *          The message that was read from the client.
348   */
349  public void updateMessageRead(LDAPMessage message)
350  {
351      messagesRead.getAndIncrement();
352      operationsInitiated.getAndIncrement();
353
354      switch (message.getProtocolOp().getType())
355      {
356      case OP_TYPE_ABANDON_REQUEST:
357        abandonRequests.getAndIncrement();
358        break;
359      case OP_TYPE_ADD_REQUEST:
360        addRequests.getAndIncrement();
361        break;
362      case OP_TYPE_BIND_REQUEST:
363        bindRequests.getAndIncrement();
364        break;
365      case OP_TYPE_COMPARE_REQUEST:
366        compareRequests.getAndIncrement();
367        break;
368      case OP_TYPE_DELETE_REQUEST:
369        deleteRequests.getAndIncrement();
370        break;
371      case OP_TYPE_EXTENDED_REQUEST:
372        extendedRequests.getAndIncrement();
373        break;
374      case OP_TYPE_MODIFY_REQUEST:
375        modifyRequests.getAndIncrement();
376        break;
377      case OP_TYPE_MODIFY_DN_REQUEST:
378        modifyDNRequests.getAndIncrement();
379        break;
380      case OP_TYPE_SEARCH_REQUEST:
381        searchRequests.getAndIncrement();
382        SearchRequestProtocolOp s = (SearchRequestProtocolOp)message
383            .getProtocolOp();
384        switch (s.getScope().asEnum())
385        {
386        case BASE_OBJECT:
387            // we don't count base object searches as
388            // this value can be derived from the others
389            break;
390        case SINGLE_LEVEL:
391            searchOneRequests.getAndIncrement();
392            break;
393        case WHOLE_SUBTREE:
394            searchSubRequests.getAndIncrement();
395            break;
396        default:
397            break;
398        }
399        break;
400      case OP_TYPE_UNBIND_REQUEST:
401        unbindRequests.getAndIncrement();
402        break;
403      }
404  }
405
406  /**
407   * Updates the appropriate set of counters based on the provided
408   * message that has been written to the client.
409   *
410   * @param message
411   *          The message that was written to the client.
412   */
413  public void updateMessageWritten(LDAPMessage message)
414  {
415      messagesWritten.getAndIncrement();
416
417      switch (message.getProtocolOp().getType())
418      {
419      case OP_TYPE_ADD_RESPONSE:
420        addResponses.getAndIncrement();
421        operationsCompleted.getAndIncrement();
422        break;
423      case OP_TYPE_BIND_RESPONSE:
424        bindResponses.getAndIncrement();
425        operationsCompleted.getAndIncrement();
426        break;
427      case OP_TYPE_COMPARE_RESPONSE:
428        compareResponses.getAndIncrement();
429        operationsCompleted.getAndIncrement();
430        break;
431      case OP_TYPE_DELETE_RESPONSE:
432        deleteResponses.getAndIncrement();
433        operationsCompleted.getAndIncrement();
434        break;
435      case OP_TYPE_EXTENDED_RESPONSE:
436        extendedResponses.getAndIncrement();
437
438        // We don't want to include unsolicited notifications as
439        // "completed" operations.
440        if (message.getMessageID() > 0)
441        {
442          operationsCompleted.getAndIncrement();
443        }
444        break;
445      case OP_TYPE_MODIFY_RESPONSE:
446        modifyResponses.getAndIncrement();
447        operationsCompleted.getAndIncrement();
448        break;
449      case OP_TYPE_MODIFY_DN_RESPONSE:
450        modifyDNResponses.getAndIncrement();
451        operationsCompleted.getAndIncrement();
452        break;
453      case OP_TYPE_SEARCH_RESULT_ENTRY:
454        searchResultEntries.getAndIncrement();
455        break;
456      case OP_TYPE_SEARCH_RESULT_REFERENCE:
457        searchResultReferences.getAndIncrement();
458        break;
459      case OP_TYPE_SEARCH_RESULT_DONE:
460        searchResultsDone.getAndIncrement();
461        operationsCompleted.getAndIncrement();
462        break;
463      }
464  }
465
466  /**
467   * Updates the appropriate set of counters to indicate that an
468   * operation was abandoned without sending a response to the client.
469   */
470  public void updateAbandonedOperation()
471  {
472      operationsAbandoned.getAndIncrement();
473  }
474
475  /**
476   * Retrieves the number of client connections that have been
477   * established.
478   *
479   * @return The number of client connections that have been
480   *         established.
481   */
482  public long getConnectionsEstablished()
483  {
484    return connectionsEstablished.get();
485  }
486
487  /**
488   * Retrieves the number of client connections that have been closed.
489   *
490   * @return The number of client connections that have been closed.
491   */
492  public long getConnectionsClosed()
493  {
494    return connectionsClosed.get();
495  }
496
497  /**
498   * Retrieves the number of bytes that have been received from clients.
499   *
500   * @return The number of bytes that have been received from clients.
501   */
502  public long getBytesRead()
503  {
504      return bytesRead.get();
505  }
506
507  /**
508   * Retrieves the number of bytes that have been written to clients.
509   *
510   * @return The number of bytes that have been written to clients.
511   */
512  public long getBytesWritten()
513  {
514      return bytesWritten.get();
515  }
516
517  /**
518   * Retrieves the number of LDAP messages that have been received from
519   * clients.
520   *
521   * @return The number of LDAP messages that have been received from
522   *         clients.
523   */
524  public long getMessagesRead()
525  {
526    return messagesRead.get();
527  }
528
529  /**
530   * Retrieves the number of LDAP messages that have been written to
531   * clients.
532   *
533   * @return The number of LDAP messages that have been written to
534   *         clients.
535   */
536  public long getMessagesWritten()
537  {
538   return messagesWritten.get();
539  }
540
541  /**
542   * Retrieves the number of operations that have been initiated by
543   * clients.
544   *
545   * @return The number of operations that have been initiated by
546   *         clients.
547   */
548  public long getOperationsInitiated()
549  {
550    return operationsInitiated.get();
551  }
552
553  /**
554   * Retrieves the number of operations for which the server has
555   * completed processing.
556   *
557   * @return The number of operations for which the server has completed
558   *         processing.
559   */
560  public long getOperationsCompleted()
561  {
562      return operationsCompleted.get();
563  }
564
565  /**
566   * Retrieves the number of operations that have been abandoned by
567   * clients.
568   *
569   * @return The number of operations that have been abandoned by
570   *         clients.
571   */
572  public long getOperationsAbandoned()
573  {
574      return operationsAbandoned.get();
575  }
576
577  /**
578   * Retrieves the number of abandon requests that have been received.
579   *
580   * @return The number of abandon requests that have been received.
581   */
582  public long getAbandonRequests()
583  {
584      return abandonRequests.get();
585  }
586
587  /**
588   * Retrieves the number of add requests that have been received.
589   *
590   * @return The number of add requests that have been received.
591   */
592  public long getAddRequests()
593  {
594      return addRequests.get();
595  }
596
597  /**
598   * Retrieves the number of add responses that have been sent.
599   *
600   * @return The number of add responses that have been sent.
601   */
602  public long getAddResponses()
603  {
604      return addResponses.get();
605  }
606
607  /**
608   * Retrieves the number of bind requests that have been received.
609   *
610   * @return The number of bind requests that have been received.
611   */
612  public long getBindRequests()
613  {
614      return bindRequests.get();
615  }
616
617  /**
618   * Retrieves the number of bind responses that have been sent.
619   *
620   * @return The number of bind responses that have been sent.
621   */
622  public long getBindResponses()
623  {
624      return bindResponses.get();
625  }
626
627  /**
628   * Retrieves the number of compare requests that have been received.
629   *
630   * @return The number of compare requests that have been received.
631   */
632  public long getCompareRequests()
633  {
634      return compareRequests.get();
635  }
636
637  /**
638   * Retrieves the number of compare responses that have been sent.
639   *
640   * @return The number of compare responses that have been sent.
641   */
642  public long getCompareResponses()
643  {
644      return compareResponses.get();
645  }
646
647  /**
648   * Retrieves the number of delete requests that have been received.
649   *
650   * @return The number of delete requests that have been received.
651   */
652  public long getDeleteRequests()
653  {
654      return deleteRequests.get();
655  }
656
657  /**
658   * Retrieves the number of delete responses that have been sent.
659   *
660   * @return The number of delete responses that have been sent.
661   */
662  public long getDeleteResponses()
663  {
664      return deleteResponses.get();
665  }
666
667  /**
668   * Retrieves the number of extended requests that have been received.
669   *
670   * @return The number of extended requests that have been received.
671   */
672  public long getExtendedRequests()
673  {
674      return extendedRequests.get();
675  }
676
677  /**
678   * Retrieves the number of extended responses that have been sent.
679   *
680   * @return The number of extended responses that have been sent.
681   */
682  public long getExtendedResponses()
683  {
684      return extendedResponses.get();
685  }
686
687  /**
688   * Retrieves the number of modify requests that have been received.
689   *
690   * @return The number of modify requests that have been received.
691   */
692  public long getModifyRequests()
693  {
694      return modifyRequests.get();
695  }
696
697  /**
698   * Retrieves the number of modify responses that have been sent.
699   *
700   * @return The number of modify responses that have been sent.
701   */
702  public long getModifyResponses()
703  {
704      return modifyResponses.get();
705  }
706
707  /**
708   * Retrieves the number of modify DN requests that have been received.
709   *
710   * @return The number of modify DN requests that have been received.
711   */
712  public long getModifyDNRequests()
713  {
714      return modifyDNRequests.get();
715  }
716
717  /**
718   * Retrieves the number of modify DN responses that have been sent.
719   *
720   * @return The number of modify DN responses that have been sent.
721   */
722  public long getModifyDNResponses()
723  {
724      return modifyDNResponses.get();
725  }
726
727  /**
728   * Retrieves the number of search requests that have been received.
729   *
730   * @return The number of search requests that have been received.
731   */
732  public long getSearchRequests()
733  {
734      return searchRequests.get();
735  }
736
737  /**
738   * Retrieves the number of one-level search requests that have been received.
739   *
740   * @return The number of one-level search requests that have been received.
741   */
742  public long getSearchOneRequests()
743  {
744      return searchOneRequests.get();
745  }
746
747  /**
748   * Retrieves the number of subtree search requests that have been received.
749   *
750   * @return The number of subtree search requests that have been received.
751   */
752  public long getSearchSubRequests()
753  {
754      return searchSubRequests.get();
755  }
756
757  /**
758   * Retrieves the number of search result entries that have been sent.
759   *
760   * @return The number of search result entries that have been sent.
761   */
762  public long getSearchResultEntries()
763  {
764      return searchResultEntries.get();
765  }
766
767  /**
768   * Retrieves the number of search result references that have been
769   * sent.
770   *
771   * @return The number of search result references that have been sent.
772   */
773  public long getSearchResultReferences()
774  {
775      return searchResultReferences.get();
776  }
777
778  /**
779   * Retrieves the number of search result done messages that have been
780   * sent.
781   *
782   * @return The number of search result done messages that have been
783   *         sent.
784   */
785  public long getSearchResultsDone()
786  {
787      return searchResultsDone.get();
788  }
789
790  /**
791   * Retrieves the number of unbind requests that have been received.
792   *
793   * @return The number of unbind requests that have been received.
794   */
795  public long getUnbindRequests()
796  {
797      return unbindRequests.get();
798  }
799
800  /**
801   * Update the operation counters and times depending on the OperationType.
802   * @param type of the operation.
803   * @param time of the operation execution.
804   */
805
806  public void updateOperationMonitoringData(OperationType type, long time) {
807      if (type.equals(OperationType.ADD)) {
808          addOperationCount.getAndIncrement();
809          addOperationTime.getAndAdd(time);
810      }
811      else if (type.equals(OperationType.SEARCH)) {
812          searchOperationCount.getAndIncrement();
813          searchOperationTime.getAndAdd(time);
814      }
815      else if (type.equals(OperationType.ABANDON)) {
816          abandonOperationCount.getAndIncrement();
817          abandonOperationTime.getAndAdd(time);
818      }
819      else if (type.equals(OperationType.BIND)) {
820          bindOperationCount.getAndIncrement();
821          bindOperationTime.getAndAdd(time);
822      }
823      else if (type.equals(OperationType.UNBIND)) {
824          unbindOperationCount.getAndIncrement();
825          unbindOperationTime.getAndAdd(time);
826      }
827      else if (type.equals(OperationType.COMPARE)) {
828          compOperationCount.getAndIncrement();
829          compOperationTime.getAndAdd(time);
830      }
831      else if (type.equals(OperationType.DELETE)) {
832          delOperationCount.getAndIncrement();
833          delOperationTime.getAndAdd(time);
834      }
835      else if (type.equals(OperationType.EXTENDED)) {
836          extOperationCount.getAndIncrement();
837          extOperationTime.getAndAdd(time);
838      }
839      else if (type.equals(OperationType.MODIFY)) {
840          modOperationCount.getAndIncrement();
841          modOperationTime.getAndAdd(time);
842      }
843      else if (type.equals(OperationType.MODIFY_DN)) {
844          moddnOperationCount.getAndIncrement();
845          moddnOperationTime.getAndAdd(time);
846      }
847  }
848}