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