| | |
| | | * Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.protocols.ldap; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.std.server.MonitorProviderCfg; |
| | | import org.opends.server.api.MonitorProvider; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.protocols.asn1.ASN1OctetString; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import static org.opends.messages.ProtocolMessages.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.protocols.ldap.LDAPConstants.*; |
| | | |
| | | |
| | |
| | | // The locks used to provide threadsafe access to this class. In this case, |
| | | // read and write refer to the type of LDAP communication, not access to the |
| | | // protected data. |
| | | private ReentrantLock abandonLock; |
| | | private ReentrantLock connectLock; |
| | | private ReentrantLock disconnectLock; |
| | | private ReentrantLock readLock; |
| | | private ReentrantLock writeLock; |
| | | private Object abandonLock; |
| | | private Object connectLock; |
| | | private Object disconnectLock; |
| | | private Object readLock; |
| | | private Object writeLock; |
| | | |
| | | // The instance name for this monitor provider instance. |
| | | private String instanceName; |
| | |
| | | this.instanceName = instanceName; |
| | | this.parent = parent; |
| | | |
| | | abandonLock = new ReentrantLock(); |
| | | connectLock = new ReentrantLock(); |
| | | disconnectLock = new ReentrantLock(); |
| | | readLock = new ReentrantLock(); |
| | | writeLock = new ReentrantLock(); |
| | | abandonLock = new Object(); |
| | | connectLock = new Object(); |
| | | disconnectLock = new Object(); |
| | | readLock = new Object(); |
| | | writeLock = new Object(); |
| | | |
| | | abandonRequests = 0; |
| | | addRequests = 0; |
| | |
| | | // Quickly grab the locks and store consistent copies of the information. |
| | | // Note that when grabbing multiple locks, it is essential that they are all |
| | | // acquired in the same order to prevent deadlocks. |
| | | abandonLock.lock(); |
| | | |
| | | try |
| | | synchronized (abandonLock) |
| | | { |
| | | connectLock.lock(); |
| | | |
| | | try |
| | | synchronized (connectLock) |
| | | { |
| | | disconnectLock.lock(); |
| | | |
| | | try |
| | | synchronized (disconnectLock) |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | tmpAbandonRequests = abandonRequests; |
| | | tmpAddRequests = addRequests; |
| | |
| | | tmpSearchResultsDone = searchResultsDone; |
| | | tmpUnbindRequests = unbindRequests; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | finally |
| | | { |
| | | disconnectLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | finally |
| | | { |
| | | connectLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | finally |
| | | { |
| | | abandonLock.unlock(); |
| | | } |
| | | |
| | | |
| | |
| | | // Quickly grab the locks and store consistent copies of the information. |
| | | // Note that when grabbing multiple locks, it is essential that they are all |
| | | // acquired in the same order to prevent deadlocks. |
| | | abandonLock.lock(); |
| | | |
| | | try |
| | | synchronized (abandonLock) |
| | | { |
| | | connectLock.lock(); |
| | | |
| | | try |
| | | synchronized (connectLock) |
| | | { |
| | | disconnectLock.lock(); |
| | | |
| | | try |
| | | synchronized (disconnectLock) |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | abandonRequests = 0; |
| | | addRequests = 0; |
| | |
| | | searchResultsDone = 0; |
| | | unbindRequests = 0; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | disconnectLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | connectLock.unlock(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | abandonLock.unlock(); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public void updateConnect() |
| | | { |
| | | connectLock.lock(); |
| | | |
| | | try |
| | | synchronized (connectLock) |
| | | { |
| | | connectionsEstablished++; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | connectLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public void updateDisconnect() |
| | | { |
| | | disconnectLock.lock(); |
| | | |
| | | try |
| | | synchronized (disconnectLock) |
| | | { |
| | | connectionsClosed++; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | disconnectLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public void updateBytesRead(int bytesRead) |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | this.bytesRead += bytesRead; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public void updateMessageRead(LDAPMessage message) |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | messagesRead++; |
| | | operationsInitiated++; |
| | |
| | | break; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public void updateMessageWritten(LDAPMessage message, int bytesWritten) |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | this.bytesWritten += bytesWritten; |
| | | messagesWritten++; |
| | |
| | | break; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public void updateAbandonedOperation() |
| | | { |
| | | abandonLock.lock(); |
| | | |
| | | try |
| | | synchronized (abandonLock) |
| | | { |
| | | operationsAbandoned++; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | abandonLock.unlock(); |
| | | } |
| | | |
| | | // Update the parent if there is one. |
| | | if (parent != null) |
| | |
| | | */ |
| | | public long getConnectionsEstablished() |
| | | { |
| | | connectLock.lock(); |
| | | |
| | | try |
| | | synchronized (connectLock) |
| | | { |
| | | return connectionsEstablished; |
| | | } |
| | | finally |
| | | { |
| | | connectLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getConnectionsClosed() |
| | | { |
| | | disconnectLock.lock(); |
| | | |
| | | try |
| | | synchronized (disconnectLock) |
| | | { |
| | | return connectionsClosed; |
| | | } |
| | | finally |
| | | { |
| | | disconnectLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getBytesRead() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return bytesRead; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getBytesWritten() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return bytesWritten; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getMessagesRead() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return messagesRead; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getMessagesWritten() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return messagesWritten; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getOperationsInitiated() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return operationsInitiated; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getOperationsCompleted() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return operationsCompleted; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getOperationsAbandoned() |
| | | { |
| | | abandonLock.lock(); |
| | | |
| | | try |
| | | synchronized (abandonLock) |
| | | { |
| | | return operationsAbandoned; |
| | | } |
| | | finally |
| | | { |
| | | abandonLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getAbandonRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return abandonRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getAddRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return addRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getAddResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return addResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getBindRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return bindRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getBindResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return bindResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getCompareRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return compareRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getCompareResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return compareResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getDeleteRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return deleteRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getDeleteResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return deleteResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getExtendedRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return extendedRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getExtendedResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return extendedResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getModifyRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return modifyRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getModifyResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return modifyResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getModifyDNRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return modifyDNRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getModifyDNResponses() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return modifyDNResponses; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getSearchRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return searchRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getSearchResultEntries() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return searchResultEntries; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getSearchResultReferences() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return searchResultReferences; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getSearchResultsDone() |
| | | { |
| | | writeLock.lock(); |
| | | |
| | | try |
| | | synchronized (writeLock) |
| | | { |
| | | return searchResultsDone; |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public long getUnbindRequests() |
| | | { |
| | | readLock.lock(); |
| | | |
| | | try |
| | | synchronized (readLock) |
| | | { |
| | | return unbindRequests; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |