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.protocols.ldap;
028
029
030
031 import java.util.ArrayList;
032 import java.util.LinkedHashSet;
033
034 import org.opends.messages.Message;
035 import org.opends.server.admin.std.server.MonitorProviderCfg;
036 import org.opends.server.api.MonitorProvider;
037 import org.opends.server.core.DirectoryServer;
038 import org.opends.server.config.ConfigException;
039 import org.opends.server.loggers.debug.DebugTracer;
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.DebugLogLevel;
045
046 import static org.opends.messages.ProtocolMessages.*;
047 import static org.opends.server.loggers.debug.DebugLogger.*;
048 import static org.opends.server.protocols.ldap.LDAPConstants.*;
049
050
051
052 /**
053 * This class defines a data structure that will be used to keep track of
054 * various metrics related to LDAP communication that the server has conducted.
055 * The statistics that will be tracked include:
056 *
057 * <UL>
058 * <LI>The total number of LDAP client connections accepted by the
059 * server.</LI>
060 * <LI>The total number of LDAP client connections that have been closed.</LI>
061 * <LI>The total number of LDAP messages read, both overall and broken down
062 * by message type.</LI>
063 * <LI>The total number of LDAP messages written, both overall and broken down
064 * by message type.</LI>
065 * <LI>The total number of bytes read from LDAP clients.</LI>
066 * <LI>The total number of bytes written to LDAP clients.</LI>
067 * </UL>
068 *
069 * <BR><BR>
070 * This class may also be used in a hierarchical form if it is desirable to
071 * get specific and general statistics at the same time (e.g., information
072 * about the interaction with a specific client or aggregated for all clients).
073 */
074 public class LDAPStatistics
075 extends MonitorProvider<MonitorProviderCfg>
076 {
077 /**
078 * The tracer object for the debug logger.
079 */
080 private static final DebugTracer TRACER = getTracer();
081
082
083
084 // The statistics maintained by this class.
085 private long abandonRequests;
086 private long addRequests;
087 private long addResponses;
088 private long bindRequests;
089 private long bindResponses;
090 private long bytesRead;
091 private long bytesWritten;
092 private long compareRequests;
093 private long compareResponses;
094 private long connectionsClosed;
095 private long connectionsEstablished;
096 private long deleteRequests;
097 private long deleteResponses;
098 private long extendedRequests;
099 private long extendedResponses;
100 private long messagesRead;
101 private long messagesWritten;
102 private long modifyRequests;
103 private long modifyResponses;
104 private long modifyDNRequests;
105 private long modifyDNResponses;
106 private long operationsAbandoned;
107 private long operationsCompleted;
108 private long operationsInitiated;
109 private long searchRequests;
110 private long searchResultEntries;
111 private long searchResultReferences;
112 private long searchResultsDone;
113 private long unbindRequests;
114
115 // The parent that should also be updated whenever statistics in this object
116 // are updated.
117 private LDAPStatistics parent;
118
119 // The locks used to provide threadsafe access to this class. In this case,
120 // read and write refer to the type of LDAP communication, not access to the
121 // protected data.
122 private Object abandonLock;
123 private Object connectLock;
124 private Object disconnectLock;
125 private Object readLock;
126 private Object writeLock;
127
128 // The instance name for this monitor provider instance.
129 private String instanceName;
130
131
132
133
134 /**
135 * Creates a new instance of this class with no parent.
136 *
137 * @param instanceName The name for this monitor provider instance.
138 */
139 public LDAPStatistics(String instanceName)
140 {
141 this(instanceName, null);
142
143 DirectoryServer.registerMonitorProvider(this);
144 }
145
146
147
148 /**
149 * Creates a new instance of this class with the specified parent.
150 *
151 * @param instanceName The name for this monitor provider instance.
152 * @param parent The parent object that should also be updated
153 * whenever this class is updated. It may be null if
154 * there should not be a parent.
155 */
156 public LDAPStatistics(String instanceName, LDAPStatistics parent)
157 {
158 super("LDAP Statistics Monitor Provider");
159
160
161 this.instanceName = instanceName;
162 this.parent = parent;
163
164 abandonLock = new Object();
165 connectLock = new Object();
166 disconnectLock = new Object();
167 readLock = new Object();
168 writeLock = new Object();
169
170 abandonRequests = 0;
171 addRequests = 0;
172 addResponses = 0;
173 bindRequests = 0;
174 bindResponses = 0;
175 bytesRead = 0;
176 bytesWritten = 0;
177 compareRequests = 0;
178 compareResponses = 0;
179 connectionsClosed = 0;
180 connectionsEstablished = 0;
181 deleteRequests = 0;
182 deleteResponses = 0;
183 extendedRequests = 0;
184 extendedResponses = 0;
185 messagesRead = 0;
186 messagesWritten = 0;
187 modifyRequests = 0;
188 modifyResponses = 0;
189 modifyDNRequests = 0;
190 modifyDNResponses = 0;
191 operationsAbandoned = 0;
192 operationsCompleted = 0;
193 operationsInitiated = 0;
194 searchRequests = 0;
195 searchResultEntries = 0;
196 searchResultReferences = 0;
197 searchResultsDone = 0;
198 unbindRequests = 0;
199 }
200
201
202
203 /**
204 * {@inheritDoc}
205 */
206 public void initializeMonitorProvider(MonitorProviderCfg configuration)
207 throws ConfigException
208 {
209 // Throw an exception, because this monitor is not intended to be
210 // dynamically loaded from the configuration. Rather, it should be
211 // explicitly created and registered by the LDAP connection handler or an
212 // LDAP client connection.
213 Message message = ERR_LDAP_STATS_INVALID_MONITOR_INITIALIZATION.get(
214 String.valueOf(configuration.dn()));
215 throw new ConfigException(message);
216 }
217
218
219
220 /**
221 * Retrieves the name of this monitor provider. It should be unique among all
222 * monitor providers, including all instances of the same monitor provider.
223 *
224 * @return The name of this monitor provider.
225 */
226 public String getMonitorInstanceName()
227 {
228 return instanceName;
229 }
230
231
232
233 /**
234 * Retrieves the length of time in milliseconds that should elapse between
235 * calls to the <CODE>updateMonitorData()</CODE> method. A negative or zero
236 * return value indicates that the <CODE>updateMonitorData()</CODE> method
237 * should not be periodically invoked.
238 *
239 * @return The length of time in milliseconds that should elapse between
240 * calls to the <CODE>updateMonitorData()</CODE> method.
241 */
242 public long getUpdateInterval()
243 {
244 // This monitor should not run periodically.
245 return -1;
246 }
247
248
249
250 /**
251 * Performs any processing periodic processing that may be desired to update
252 * the information associated with this monitor. Note that best-effort
253 * attempts will be made to ensure that calls to this method come
254 * <CODE>getUpdateInterval()</CODE> milliseconds apart, but no guarantees will
255 * be made.
256 */
257 public void updateMonitorData()
258 {
259 // No implementation is required since this does not do periodic updates.
260 }
261
262
263
264 /**
265 * Retrieves a set of attributes containing monitor data that should be
266 * returned to the client if the corresponding monitor entry is requested.
267 *
268 * @return A set of attributes containing monitor data that should be
269 * returned to the client if the corresponding monitor entry is
270 * requested.
271 */
272 public ArrayList<Attribute> getMonitorData()
273 {
274 ArrayList<Attribute> attrs = new ArrayList<Attribute>(29);
275
276 long tmpAbandonRequests;
277 long tmpAddRequests;
278 long tmpAddResponses;
279 long tmpBindRequests;
280 long tmpBindResponses;
281 long tmpBytesRead;
282 long tmpBytesWritten;
283 long tmpCompareRequests;
284 long tmpCompareResponses;
285 long tmpConnectionsClosed;
286 long tmpConnectionsEstablished;
287 long tmpDeleteRequests;
288 long tmpDeleteResponses;
289 long tmpExtendedRequests;
290 long tmpExtendedResponses;
291 long tmpMessagesRead;
292 long tmpMessagesWritten;
293 long tmpModifyRequests;
294 long tmpModifyResponses;
295 long tmpModifyDNRequests;
296 long tmpModifyDNResponses;
297 long tmpOperationsAbandoned;
298 long tmpOperationsCompleted;
299 long tmpOperationsInitiated;
300 long tmpSearchRequests;
301 long tmpSearchEntries;
302 long tmpSearchReferences;
303 long tmpSearchResultsDone;
304 long tmpUnbindRequests;
305
306 // Quickly grab the locks and store consistent copies of the information.
307 // Note that when grabbing multiple locks, it is essential that they are all
308 // acquired in the same order to prevent deadlocks.
309 synchronized (abandonLock)
310 {
311 synchronized (connectLock)
312 {
313 synchronized (disconnectLock)
314 {
315 synchronized (writeLock)
316 {
317 synchronized (readLock)
318 {
319 tmpAbandonRequests = abandonRequests;
320 tmpAddRequests = addRequests;
321 tmpAddResponses = addResponses;
322 tmpBindRequests = bindRequests;
323 tmpBindResponses = bindResponses;
324 tmpBytesRead = bytesRead;
325 tmpBytesWritten = bytesWritten;
326 tmpCompareRequests = compareRequests;
327 tmpCompareResponses = compareResponses;
328 tmpConnectionsClosed = connectionsClosed;
329 tmpConnectionsEstablished = connectionsEstablished;
330 tmpDeleteRequests = deleteRequests;
331 tmpDeleteResponses = deleteResponses;
332 tmpExtendedRequests = extendedRequests;
333 tmpExtendedResponses = extendedResponses;
334 tmpMessagesRead = messagesRead;
335 tmpMessagesWritten = messagesWritten;
336 tmpModifyRequests = modifyRequests;
337 tmpModifyResponses = modifyResponses;
338 tmpModifyDNRequests = modifyDNRequests;
339 tmpModifyDNResponses = modifyDNResponses;
340 tmpOperationsAbandoned = operationsAbandoned;
341 tmpOperationsCompleted = operationsCompleted;
342 tmpOperationsInitiated = operationsInitiated;
343 tmpSearchRequests = searchRequests;
344 tmpSearchEntries = searchResultEntries;
345 tmpSearchReferences = searchResultReferences;
346 tmpSearchResultsDone = searchResultsDone;
347 tmpUnbindRequests = unbindRequests;
348 }
349 }
350 }
351 }
352 }
353
354
355 // Construct the list of attributes to return.
356 attrs.add(createAttribute("connectionsEstablished",
357 String.valueOf(tmpConnectionsEstablished)));
358 attrs.add(createAttribute("connectionsClosed",
359 String.valueOf(tmpConnectionsClosed)));
360 attrs.add(createAttribute("bytesRead", String.valueOf(tmpBytesRead)));
361 attrs.add(createAttribute("bytesWritten", String.valueOf(tmpBytesWritten)));
362 attrs.add(createAttribute("ldapMessagesRead",
363 String.valueOf(tmpMessagesRead)));
364 attrs.add(createAttribute("ldapMessagesWritten",
365 String.valueOf(tmpMessagesWritten)));
366 attrs.add(createAttribute("operationsAbandoned",
367 String.valueOf(tmpOperationsAbandoned)));
368 attrs.add(createAttribute("operationsInitiated",
369 String.valueOf(tmpOperationsInitiated)));
370 attrs.add(createAttribute("operationsCompleted",
371 String.valueOf(tmpOperationsCompleted)));
372 attrs.add(createAttribute("abandonRequests",
373 String.valueOf(tmpAbandonRequests)));
374 attrs.add(createAttribute("addRequests", String.valueOf(tmpAddRequests)));
375 attrs.add(createAttribute("addResponses", String.valueOf(tmpAddResponses)));
376 attrs.add(createAttribute("bindRequests", String.valueOf(tmpBindRequests)));
377 attrs.add(createAttribute("bindResponses",
378 String.valueOf(tmpBindResponses)));
379 attrs.add(createAttribute("compareRequests",
380 String.valueOf(tmpCompareRequests)));
381 attrs.add(createAttribute("compareResponses",
382 String.valueOf(tmpCompareResponses)));
383 attrs.add(createAttribute("deleteRequests",
384 String.valueOf(tmpDeleteRequests)));
385 attrs.add(createAttribute("deleteResponses",
386 String.valueOf(tmpDeleteResponses)));
387 attrs.add(createAttribute("extendedRequests",
388 String.valueOf(tmpExtendedRequests)));
389 attrs.add(createAttribute("extendedResponses",
390 String.valueOf(tmpExtendedResponses)));
391 attrs.add(createAttribute("modifyRequests",
392 String.valueOf(tmpModifyRequests)));
393 attrs.add(createAttribute("modifyResponses",
394 String.valueOf(tmpModifyResponses)));
395 attrs.add(createAttribute("modifyDNRequests",
396 String.valueOf(tmpModifyDNRequests)));
397 attrs.add(createAttribute("modifyDNResponses",
398 String.valueOf(tmpModifyDNResponses)));
399 attrs.add(createAttribute("searchRequests",
400 String.valueOf(tmpSearchRequests)));
401 attrs.add(createAttribute("searchResultEntries",
402 String.valueOf(tmpSearchEntries)));
403 attrs.add(createAttribute("searchResultReferences",
404 String.valueOf(tmpSearchReferences)));
405 attrs.add(createAttribute("searchResultsDone",
406 String.valueOf(tmpSearchResultsDone)));
407 attrs.add(createAttribute("unbindRequests",
408 String.valueOf(tmpUnbindRequests)));
409
410 return attrs;
411 }
412
413
414
415 /**
416 * Clears any statistical information collected to this point.
417 */
418 public void clearStatistics()
419 {
420 // Quickly grab the locks and store consistent copies of the information.
421 // Note that when grabbing multiple locks, it is essential that they are all
422 // acquired in the same order to prevent deadlocks.
423 synchronized (abandonLock)
424 {
425 synchronized (connectLock)
426 {
427 synchronized (disconnectLock)
428 {
429 synchronized (writeLock)
430 {
431 synchronized (readLock)
432 {
433 abandonRequests = 0;
434 addRequests = 0;
435 addResponses = 0;
436 bindRequests = 0;
437 bindResponses = 0;
438 bytesRead = 0;
439 bytesWritten = 0;
440 compareRequests = 0;
441 compareResponses = 0;
442 connectionsClosed = 0;
443 connectionsEstablished = 0;
444 deleteRequests = 0;
445 deleteResponses = 0;
446 extendedRequests = 0;
447 extendedResponses = 0;
448 messagesRead = 0;
449 messagesWritten = 0;
450 modifyRequests = 0;
451 modifyResponses = 0;
452 modifyDNRequests = 0;
453 modifyDNResponses = 0;
454 operationsAbandoned = 0;
455 operationsCompleted = 0;
456 operationsInitiated = 0;
457 searchRequests = 0;
458 searchResultEntries = 0;
459 searchResultReferences = 0;
460 searchResultsDone = 0;
461 unbindRequests = 0;
462 }
463 }
464 }
465 }
466 }
467 }
468
469
470
471 /**
472 * Updates the appropriate set of counters to indicate that a new connection
473 * has been established.
474 */
475 public void updateConnect()
476 {
477 synchronized (connectLock)
478 {
479 connectionsEstablished++;
480 }
481
482 // Update the parent if there is one.
483 if (parent != null)
484 {
485 parent.updateConnect();
486 }
487 }
488
489
490
491 /**
492 * Updates the appropriate set of counters to indicate that a connection has
493 * been closed.
494 */
495 public void updateDisconnect()
496 {
497 synchronized (disconnectLock)
498 {
499 connectionsClosed++;
500 }
501
502 // Update the parent if there is one.
503 if (parent != null)
504 {
505 parent.updateDisconnect();
506 }
507 }
508
509
510
511 /**
512 * Updates the appropriate set of counters to indicate that the specified
513 * number of bytes have been read by the client.
514 *
515 * @param bytesRead The number of bytes read by the client.
516 */
517 public void updateBytesRead(int bytesRead)
518 {
519 synchronized (readLock)
520 {
521 this.bytesRead += bytesRead;
522 }
523
524 // Update the parent if there is one.
525 if (parent != null)
526 {
527 parent.updateBytesRead(bytesRead);
528 }
529 }
530
531
532
533 /**
534 * Updates the appropriate set of counters based on the provided message that
535 * has been read from the client.
536 *
537 * @param message The message that was read from the client.
538 */
539 public void updateMessageRead(LDAPMessage message)
540 {
541 synchronized (readLock)
542 {
543 messagesRead++;
544 operationsInitiated++;
545
546 switch (message.getProtocolOp().getType())
547 {
548 case OP_TYPE_ABANDON_REQUEST:
549 abandonRequests++;
550 break;
551 case OP_TYPE_ADD_REQUEST:
552 addRequests++;
553 break;
554 case OP_TYPE_BIND_REQUEST:
555 bindRequests++;
556 break;
557 case OP_TYPE_COMPARE_REQUEST:
558 compareRequests++;
559 break;
560 case OP_TYPE_DELETE_REQUEST:
561 deleteRequests++;
562 break;
563 case OP_TYPE_EXTENDED_REQUEST:
564 extendedRequests++;
565 break;
566 case OP_TYPE_MODIFY_REQUEST:
567 modifyRequests++;
568 break;
569 case OP_TYPE_MODIFY_DN_REQUEST:
570 modifyDNRequests++;
571 break;
572 case OP_TYPE_SEARCH_REQUEST:
573 searchRequests++;
574 break;
575 case OP_TYPE_UNBIND_REQUEST:
576 unbindRequests++;
577 break;
578 }
579 }
580
581 // Update the parent if there is one.
582 if (parent != null)
583 {
584 parent.updateMessageRead(message);
585 }
586 }
587
588
589
590 /**
591 * Updates the appropriate set of counters based on the provided message that
592 * has been written to the client.
593 *
594 * @param message The message that was written to the client.
595 * @param bytesWritten The size of the message written in bytes.
596 */
597 public void updateMessageWritten(LDAPMessage message, int bytesWritten)
598 {
599 synchronized (writeLock)
600 {
601 this.bytesWritten += bytesWritten;
602 messagesWritten++;
603
604 switch (message.getProtocolOp().getType())
605 {
606 case OP_TYPE_ADD_RESPONSE:
607 addResponses++;
608 operationsCompleted++;
609 break;
610 case OP_TYPE_BIND_RESPONSE:
611 bindResponses++;
612 operationsCompleted++;
613 break;
614 case OP_TYPE_COMPARE_RESPONSE:
615 compareResponses++;
616 operationsCompleted++;
617 break;
618 case OP_TYPE_DELETE_RESPONSE:
619 deleteResponses++;
620 operationsCompleted++;
621 break;
622 case OP_TYPE_EXTENDED_RESPONSE:
623 extendedResponses++;
624
625 // We don't want to include unsolicited notifications as "completed"
626 // operations.
627 if (message.getMessageID() > 0)
628 {
629 operationsCompleted++;
630 }
631 break;
632 case OP_TYPE_MODIFY_RESPONSE:
633 modifyResponses++;
634 operationsCompleted++;
635 break;
636 case OP_TYPE_MODIFY_DN_RESPONSE:
637 modifyDNResponses++;
638 operationsCompleted++;
639 break;
640 case OP_TYPE_SEARCH_RESULT_ENTRY:
641 searchResultEntries++;
642 break;
643 case OP_TYPE_SEARCH_RESULT_REFERENCE:
644 searchResultReferences++;
645 break;
646 case OP_TYPE_SEARCH_RESULT_DONE:
647 searchResultsDone++;
648 operationsCompleted++;
649 break;
650 }
651 }
652
653 // Update the parent if there is one.
654 if (parent != null)
655 {
656 parent.updateMessageWritten(message, bytesWritten);
657 }
658 }
659
660
661
662 /**
663 * Updates the appropriate set of counters to indicate that an operation was
664 * abandoned without sending a response to the client.
665 */
666 public void updateAbandonedOperation()
667 {
668 synchronized (abandonLock)
669 {
670 operationsAbandoned++;
671 }
672
673 // Update the parent if there is one.
674 if (parent != null)
675 {
676 parent.updateAbandonedOperation();
677 }
678 }
679
680
681
682 /**
683 * Constructs an attribute using the provided information. It will have the
684 * default syntax.
685 *
686 * @param name The name to use for the attribute.
687 * @param value The value to use for the attribute.
688 *
689 * @return the constructed attribute.
690 */
691 private Attribute createAttribute(String name, String value)
692 {
693 AttributeType attrType = DirectoryServer.getDefaultAttributeType(name);
694
695 ASN1OctetString encodedValue = new ASN1OctetString(value);
696 LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1);
697
698 try
699 {
700 values.add(new AttributeValue(encodedValue,
701 attrType.normalize(encodedValue)));
702 }
703 catch (Exception e)
704 {
705 if (debugEnabled())
706 {
707 TRACER.debugCaught(DebugLogLevel.ERROR, e);
708 }
709
710 values.add(new AttributeValue(encodedValue, encodedValue));
711 }
712
713 return new Attribute(attrType, name, values);
714 }
715
716
717
718 /**
719 * Retrieves the number of client connections that have been established.
720 *
721 * @return The number of client connections that have been established.
722 */
723 public long getConnectionsEstablished()
724 {
725 synchronized (connectLock)
726 {
727 return connectionsEstablished;
728 }
729 }
730
731
732
733 /**
734 * Retrieves the number of client connections that have been closed.
735 *
736 * @return The number of client connections that have been closed.
737 */
738 public long getConnectionsClosed()
739 {
740 synchronized (disconnectLock)
741 {
742 return connectionsClosed;
743 }
744 }
745
746
747
748 /**
749 * Retrieves the number of bytes that have been received from clients.
750 *
751 * @return The number of bytes that have been received from clients.
752 */
753 public long getBytesRead()
754 {
755 synchronized (readLock)
756 {
757 return bytesRead;
758 }
759 }
760
761
762
763 /**
764 * Retrieves the number of bytes that have been written to clients.
765 *
766 * @return The number of bytes that have been written to clients.
767 */
768 public long getBytesWritten()
769 {
770 synchronized (writeLock)
771 {
772 return bytesWritten;
773 }
774 }
775
776
777
778 /**
779 * Retrieves the number of LDAP messages that have been received from clients.
780 *
781 * @return The number of LDAP messages that have been received from clients.
782 */
783 public long getMessagesRead()
784 {
785 synchronized (readLock)
786 {
787 return messagesRead;
788 }
789 }
790
791
792
793 /**
794 * Retrieves the number of LDAP messages that have been written to clients.
795 *
796 * @return The number of LDAP messages that have been written to clients.
797 */
798 public long getMessagesWritten()
799 {
800 synchronized (writeLock)
801 {
802 return messagesWritten;
803 }
804 }
805
806
807
808 /**
809 * Retrieves the number of operations that have been initiated by clients.
810 *
811 * @return The number of operations that have been initiated by clients.
812 */
813 public long getOperationsInitiated()
814 {
815 synchronized (readLock)
816 {
817 return operationsInitiated;
818 }
819 }
820
821
822
823 /**
824 * Retrieves the number of operations for which the server has completed
825 * processing.
826 *
827 * @return The number of operations for which the server has completed
828 * processing.
829 */
830 public long getOperationsCompleted()
831 {
832 synchronized (writeLock)
833 {
834 return operationsCompleted;
835 }
836 }
837
838
839
840 /**
841 * Retrieves the number of operations that have been abandoned by clients.
842 *
843 * @return The number of operations that have been abandoned by clients.
844 */
845 public long getOperationsAbandoned()
846 {
847 synchronized (abandonLock)
848 {
849 return operationsAbandoned;
850 }
851 }
852
853
854
855 /**
856 * Retrieves the number of abandon requests that have been received.
857 *
858 * @return The number of abandon requests that have been received.
859 */
860 public long getAbandonRequests()
861 {
862 synchronized (readLock)
863 {
864 return abandonRequests;
865 }
866 }
867
868
869
870 /**
871 * Retrieves the number of add requests that have been received.
872 *
873 * @return The number of add requests that have been received.
874 */
875 public long getAddRequests()
876 {
877 synchronized (readLock)
878 {
879 return addRequests;
880 }
881 }
882
883
884
885 /**
886 * Retrieves the number of add responses that have been sent.
887 *
888 * @return The number of add responses that have been sent.
889 */
890 public long getAddResponses()
891 {
892 synchronized (writeLock)
893 {
894 return addResponses;
895 }
896 }
897
898
899
900 /**
901 * Retrieves the number of bind requests that have been received.
902 *
903 * @return The number of bind requests that have been received.
904 */
905 public long getBindRequests()
906 {
907 synchronized (readLock)
908 {
909 return bindRequests;
910 }
911 }
912
913
914
915 /**
916 * Retrieves the number of bind responses that have been sent.
917 *
918 * @return The number of bind responses that have been sent.
919 */
920 public long getBindResponses()
921 {
922 synchronized (writeLock)
923 {
924 return bindResponses;
925 }
926 }
927
928
929
930 /**
931 * Retrieves the number of compare requests that have been received.
932 *
933 * @return The number of compare requests that have been received.
934 */
935 public long getCompareRequests()
936 {
937 synchronized (readLock)
938 {
939 return compareRequests;
940 }
941 }
942
943
944
945 /**
946 * Retrieves the number of compare responses that have been sent.
947 *
948 * @return The number of compare responses that have been sent.
949 */
950 public long getCompareResponses()
951 {
952 synchronized (writeLock)
953 {
954 return compareResponses;
955 }
956 }
957
958
959
960 /**
961 * Retrieves the number of delete requests that have been received.
962 *
963 * @return The number of delete requests that have been received.
964 */
965 public long getDeleteRequests()
966 {
967 synchronized (readLock)
968 {
969 return deleteRequests;
970 }
971 }
972
973
974
975 /**
976 * Retrieves the number of delete responses that have been sent.
977 *
978 * @return The number of delete responses that have been sent.
979 */
980 public long getDeleteResponses()
981 {
982 synchronized (writeLock)
983 {
984 return deleteResponses;
985 }
986 }
987
988
989
990 /**
991 * Retrieves the number of extended requests that have been received.
992 *
993 * @return The number of extended requests that have been received.
994 */
995 public long getExtendedRequests()
996 {
997 synchronized (readLock)
998 {
999 return extendedRequests;
1000 }
1001 }
1002
1003
1004
1005 /**
1006 * Retrieves the number of extended responses that have been sent.
1007 *
1008 * @return The number of extended responses that have been sent.
1009 */
1010 public long getExtendedResponses()
1011 {
1012 synchronized (writeLock)
1013 {
1014 return extendedResponses;
1015 }
1016 }
1017
1018
1019
1020 /**
1021 * Retrieves the number of modify requests that have been received.
1022 *
1023 * @return The number of modify requests that have been received.
1024 */
1025 public long getModifyRequests()
1026 {
1027 synchronized (readLock)
1028 {
1029 return modifyRequests;
1030 }
1031 }
1032
1033
1034
1035 /**
1036 * Retrieves the number of modify responses that have been sent.
1037 *
1038 * @return The number of modify responses that have been sent.
1039 */
1040 public long getModifyResponses()
1041 {
1042 synchronized (writeLock)
1043 {
1044 return modifyResponses;
1045 }
1046 }
1047
1048
1049
1050 /**
1051 * Retrieves the number of modify DN requests that have been received.
1052 *
1053 * @return The number of modify DN requests that have been received.
1054 */
1055 public long getModifyDNRequests()
1056 {
1057 synchronized (readLock)
1058 {
1059 return modifyDNRequests;
1060 }
1061 }
1062
1063
1064
1065 /**
1066 * Retrieves the number of modify DN responses that have been sent.
1067 *
1068 * @return The number of modify DN responses that have been sent.
1069 */
1070 public long getModifyDNResponses()
1071 {
1072 synchronized (writeLock)
1073 {
1074 return modifyDNResponses;
1075 }
1076 }
1077
1078
1079
1080 /**
1081 * Retrieves the number of search requests that have been received.
1082 *
1083 * @return The number of search requests that have been received.
1084 */
1085 public long getSearchRequests()
1086 {
1087 synchronized (readLock)
1088 {
1089 return searchRequests;
1090 }
1091 }
1092
1093
1094
1095 /**
1096 * Retrieves the number of search result entries that have been sent.
1097 *
1098 * @return The number of search result entries that have been sent.
1099 */
1100 public long getSearchResultEntries()
1101 {
1102 synchronized (writeLock)
1103 {
1104 return searchResultEntries;
1105 }
1106 }
1107
1108
1109
1110 /**
1111 * Retrieves the number of search result references that have been sent.
1112 *
1113 * @return The number of search result references that have been sent.
1114 */
1115 public long getSearchResultReferences()
1116 {
1117 synchronized (writeLock)
1118 {
1119 return searchResultReferences;
1120 }
1121 }
1122
1123
1124
1125 /**
1126 * Retrieves the number of search result done messages that have been sent.
1127 *
1128 * @return The number of search result done messages that have been sent.
1129 */
1130 public long getSearchResultsDone()
1131 {
1132 synchronized (writeLock)
1133 {
1134 return searchResultsDone;
1135 }
1136 }
1137
1138
1139
1140 /**
1141 * Retrieves the number of unbind requests that have been received.
1142 *
1143 * @return The number of unbind requests that have been received.
1144 */
1145 public long getUnbindRequests()
1146 {
1147 synchronized (readLock)
1148 {
1149 return unbindRequests;
1150 }
1151 }
1152
1153
1154
1155 /**
1156 * Retrieves the parent statistics tracker that will also be updated whenever
1157 * this tracker is updated.
1158 *
1159 * @return The parent statistics tracker, or {@code null} if there is none.
1160 */
1161 public LDAPStatistics getParent()
1162 {
1163 return parent;
1164 }
1165 }
1166