opendj-sdk/opendj3-server-dev/src/server/org/opends/server/admin/AdministrationConnector.java
@@ -22,7 +22,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2014 ForgeRock AS * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.server.admin; @@ -32,41 +32,38 @@ import java.io.FileWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.naming.ldap.Rdn; import org.forgerock.opendj.ldap.AddressMask; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.opendj.ldap.AddressMask; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.server.ServerManagementContext; import org.opends.server.admin.std.meta.LDAPConnectionHandlerCfgDefn. SSLClientAuthPolicy; import org.opends.server.admin.std.meta.LDAPConnectionHandlerCfgDefn.SSLClientAuthPolicy; import org.opends.server.admin.std.server.AdministrationConnectorCfg; import org.opends.server.admin.std.server.ConnectionHandlerCfg; import org.opends.server.admin.std.server.KeyManagerProviderCfg; import org.opends.server.admin.std.server.FileBasedKeyManagerProviderCfg; import org.opends.server.admin.std.server.FileBasedTrustManagerProviderCfg; import org.opends.server.admin.std.server.KeyManagerProviderCfg; import org.opends.server.admin.std.server.LDAPConnectionHandlerCfg; import org.opends.server.admin.std.server.RootCfg; import org.forgerock.opendj.config.server.ConfigException; import org.opends.server.admin.std.server.TrustManagerProviderCfg; import org.opends.server.core.DirectoryServer; import org.opends.server.core.ServerContext; import org.opends.server.core.SynchronousStrategy; import org.opends.server.protocols.ldap.LDAPConnectionHandler; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DN; import org.opends.server.types.InitializationException; import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.util.CertificateManager; import org.opends.server.util.SetupUtils; import org.opends.server.admin.std.server.TrustManagerProviderCfg; import org.opends.server.core.DirectoryServer; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.opends.server.types.DirectoryException; import org.opends.server.types.FilePermission; import org.opends.server.types.InitializationException; import org.opends.server.util.CertificateManager; import org.opends.server.util.SetupUtils; /** * This class is a wrapper on top of LDAPConnectionHandler to manage @@ -77,74 +74,47 @@ ConfigurationChangeListener<AdministrationConnectorCfg> { /** * Default Administration Connector port. */ /** Default Administration Connector port. */ public static final int DEFAULT_ADMINISTRATION_CONNECTOR_PORT = 4444; /** * Validity (in days) of the generated certificate. */ /** Validity (in days) of the generated certificate. */ public static final int ADMIN_CERT_VALIDITY = 20 * 365; // Friendly name of the administration connector /** Friendly name of the administration connector. */ private static final String FRIENDLY_NAME = "Administration Connector"; private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private LDAPConnectionHandler adminConnectionHandler; private AdministrationConnectorCfg config; private AdministrationConnectorCfg config; // // Predefined values for Administration Connector configuration // /** Predefined values for Administration Connector configuration. */ private static final String ADMIN_CLASS_NAME = "org.opends.server.protocols.ldap.LDAPConnectionHandler"; private static final boolean ADMIN_ALLOW_LDAP_V2 = false; private static final boolean ADMIN_ALLOW_START_TLS = false; private static final SortedSet<AddressMask> ADMIN_ALLOWED_CLIENT = new TreeSet<AddressMask>(); private static final SortedSet<AddressMask> ADMIN_DENIED_CLIENT = new TreeSet<AddressMask>(); private static final SortedSet<AddressMask> ADMIN_ALLOWED_CLIENT = new TreeSet<AddressMask>(); private static final SortedSet<AddressMask> ADMIN_DENIED_CLIENT = new TreeSet<AddressMask>(); private static final boolean ADMIN_ENABLED = true; private static final boolean ADMIN_KEEP_STATS = true; private static final boolean ADMIN_USE_SSL = true; private static final int ADMIN_ACCEPT_BACKLOG = 128; private static final boolean ADMIN_ALLOW_TCP_REUSE_ADDRESS = true; private static final long ADMIN_MAX_BLOCKED_WRITE_TIME_LIMIT = 120000; // 2mn private static final int ADMIN_MAX_REQUEST_SIZE = 5000000; // 5 Mb /** 2mn. */ private static final long ADMIN_MAX_BLOCKED_WRITE_TIME_LIMIT = 120000; /** 5 Mb. */ private static final int ADMIN_MAX_REQUEST_SIZE = 5000000; private static final int ADMIN_WRITE_BUFFER_SIZE = 4096; private static final int ADMIN_NUM_REQUEST_HANDLERS = 1; private static final boolean ADMIN_SEND_REJECTION_NOTICE = true; private static final boolean ADMIN_USE_TCP_KEEP_ALIVE = true; private static final boolean ADMIN_USE_TCP_NO_DELAY = true; private static final SSLClientAuthPolicy ADMIN_SSL_CLIENT_AUTH_POLICY = SSLClientAuthPolicy.DISABLED; private static final SortedSet<String> ADMIN_SSL_CIPHER_SUITE = new TreeSet<String>(); private static final SortedSet<String> ADMIN_SSL_PROTOCOL = new TreeSet<String>(); /** * Initializes this administration connector provider based on the * information in the provided administration connector @@ -172,8 +142,7 @@ LDAPConnectionHandlerCfg ldapConnectionHandlerCfg = new FakeLDAPConnectionHandlerCfg(config); // Administration Connector uses the LDAP connection handler // implementation // Administration Connector uses the LDAP connection handler implementation adminConnectionHandler = new LDAPConnectionHandler( new SynchronousStrategy(), FRIENDLY_NAME); adminConnectionHandler @@ -185,34 +154,24 @@ } /** * Create an instance of the administration connector. */ /** Create an instance of the administration connector. */ public AdministrationConnector() { // Do nothing. } /** * Retrieves the connection handler linked to this administration * connector. * Retrieves the connection handler linked to this administration connector. * * @return The connection handler linked to this administration * connector. * @return The connection handler linked to this administration connector. */ public LDAPConnectionHandler getConnectionHandler() { return adminConnectionHandler; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationChangeAcceptable( AdministrationConnectorCfg configuration, List<LocalizableMessage> unacceptableReasons) @@ -223,367 +182,260 @@ unacceptableReasons); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationChange( AdministrationConnectorCfg configuration) { return new ConfigChangeResult(ResultCode.SUCCESS, true, new ArrayList<LocalizableMessage>()); return new ConfigChangeResult(); } /** * This private class implements a fake LDAP connection Handler * configuration. This allows to re-use the LDAPConnectionHandler as * it is. * This private class implements a fake LDAP connection Handler configuration. * This allows to re-use the LDAPConnectionHandler as it is. */ private static class FakeLDAPConnectionHandlerCfg implements LDAPConnectionHandlerCfg { private final AdministrationConnectorCfg config; public FakeLDAPConnectionHandlerCfg(AdministrationConnectorCfg config) { this.config = config; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Class<? extends LDAPConnectionHandlerCfg> configurationClass() { return LDAPConnectionHandlerCfg.class; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void addLDAPChangeListener( ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener) { // do nothing. change listener already added. } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void removeLDAPChangeListener( ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener) { // do nothing. change listener already added. } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public int getAcceptBacklog() { return ADMIN_ACCEPT_BACKLOG; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isAllowLDAPV2() { return ADMIN_ALLOW_LDAP_V2; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isAllowStartTLS() { return ADMIN_ALLOW_START_TLS; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isAllowTCPReuseAddress() { return ADMIN_ALLOW_TCP_REUSE_ADDRESS; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String getJavaClass() { return ADMIN_CLASS_NAME; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isKeepStats() { return ADMIN_KEEP_STATS; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String getKeyManagerProvider() { return config.getKeyManagerProvider(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public DN getKeyManagerProviderDN() { return config.getKeyManagerProviderDN(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SortedSet<InetAddress> getListenAddress() { return config.getListenAddress(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public int getListenPort() { return config.getListenPort(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public long getMaxBlockedWriteTimeLimit() { return ADMIN_MAX_BLOCKED_WRITE_TIME_LIMIT; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public long getMaxRequestSize() { return ADMIN_MAX_REQUEST_SIZE; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public long getBufferSize() { return ADMIN_WRITE_BUFFER_SIZE; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Integer getNumRequestHandlers() { return ADMIN_NUM_REQUEST_HANDLERS; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isSendRejectionNotice() { return ADMIN_SEND_REJECTION_NOTICE; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String getSSLCertNickname() { return config.getSSLCertNickname(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SortedSet<String> getSSLCipherSuite() { return config.getSSLCipherSuite(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SSLClientAuthPolicy getSSLClientAuthPolicy() { return ADMIN_SSL_CLIENT_AUTH_POLICY; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SortedSet<String> getSSLProtocol() { return config.getSSLProtocol(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String getTrustManagerProvider() { return config.getTrustManagerProvider(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public DN getTrustManagerProviderDN() { return config.getTrustManagerProviderDN(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isUseSSL() { return ADMIN_USE_SSL; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isUseTCPKeepAlive() { return ADMIN_USE_TCP_KEEP_ALIVE; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isUseTCPNoDelay() { return ADMIN_USE_TCP_NO_DELAY; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void addChangeListener( ConfigurationChangeListener<ConnectionHandlerCfg> listener) { // do nothing. change listener already added. } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void removeChangeListener( ConfigurationChangeListener<ConnectionHandlerCfg> listener) { // do nothing. change listener already added. } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SortedSet<AddressMask> getAllowedClient() { return ADMIN_ALLOWED_CLIENT; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public SortedSet<AddressMask> getDeniedClient() { return ADMIN_DENIED_CLIENT; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isEnabled() { return ADMIN_ENABLED; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public DN dn() { return config.dn(); @@ -768,17 +620,17 @@ KeyManagerProviderCfg keyConfig, TrustManagerProviderCfg trustConfig) { if (keyConfig.isEnabled() && (keyConfig instanceof FileBasedKeyManagerProviderCfg) && keyConfig instanceof FileBasedKeyManagerProviderCfg && trustConfig.isEnabled() && (trustConfig instanceof FileBasedTrustManagerProviderCfg)) && trustConfig instanceof FileBasedTrustManagerProviderCfg) { FileBasedKeyManagerProviderCfg fileKeyConfig = (FileBasedKeyManagerProviderCfg) keyConfig; boolean pinIsProvidedByFileOnly = (fileKeyConfig.getKeyStorePinFile() != null) && (fileKeyConfig.getKeyStorePin() == null) && (fileKeyConfig.getKeyStorePinEnvironmentVariable() == null) && (fileKeyConfig.getKeyStorePinProperty() == null); fileKeyConfig.getKeyStorePinFile() != null && fileKeyConfig.getKeyStorePin() == null && fileKeyConfig.getKeyStorePinEnvironmentVariable() == null && fileKeyConfig.getKeyStorePinProperty() == null; return !pinIsProvidedByFileOnly; } return true; opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FIFOEntryCache.java
@@ -22,10 +22,12 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2011-2014 ForgeRock AS * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.server.extensions; import static org.opends.messages.ExtensionMessages.*; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; @@ -33,14 +35,15 @@ import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.util.Utils; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.server.EntryCacheCfg; import org.opends.server.admin.std.server.FIFOEntryCacheCfg; import org.opends.server.api.Backend; import org.opends.server.api.EntryCache; import org.forgerock.opendj.config.server.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.types.Attribute; import org.opends.server.types.CacheEntry; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DN; @@ -48,11 +51,8 @@ import org.opends.server.types.InitializationException; import org.opends.server.types.LockManager; import org.opends.server.types.SearchFilter; import org.opends.server.types.Attribute; import org.opends.server.util.ServerConstants; import static org.opends.messages.ExtensionMessages.*; /** * This class defines a Directory Server entry cache that uses a FIFO to keep * track of the entries. Entries that have been in the cache the longest are @@ -90,61 +90,52 @@ */ private static final Runtime runtime = Runtime.getRuntime(); // The mapping between entry backends/IDs and entries. private HashMap<Backend,HashMap<Long,CacheEntry>> idMap; /** The mapping between entry backends/IDs and entries. */ private HashMap<Backend<?>, HashMap<Long, CacheEntry>> idMap; // The mapping between DNs and entries. /** The mapping between DNs and entries. */ private LinkedHashMap<DN,CacheEntry> dnMap; // The lock used to provide threadsafe access when changing the contents of // the cache. /** * The lock used to provide threadsafe access when changing the contents of * the cache. */ private ReentrantReadWriteLock cacheLock; private Lock cacheWriteLock; private Lock cacheReadLock; // The maximum amount of memory in bytes that the JVM will be allowed to use // before we need to start purging entries. /** * The maximum amount of memory in bytes that the JVM will be allowed to use * before we need to start purging entries. */ private long maxAllowedMemory; // The maximum number of entries that may be held in the cache. /** The maximum number of entries that may be held in the cache. */ private long maxEntries; // Currently registered configuration object. /** Currently registered configuration object. */ private FIFOEntryCacheCfg registeredConfiguration; // The maximum length of time to try to obtain a lock before giving // up. /** The maximum length of time to try to obtain a lock before giving up. */ private long lockTimeout = LockManager.DEFAULT_TIMEOUT; /** * Creates a new instance of this FIFO entry cache. */ /** Creates a new instance of this FIFO entry cache. */ public FIFOEntryCache() { super(); // All initialization should be performed in the initializeEntryCache. } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void initializeEntryCache( FIFOEntryCacheCfg configuration ) public void initializeEntryCache(FIFOEntryCacheCfg configuration) throws ConfigException, InitializationException { registeredConfiguration = configuration; configuration.addFIFOChangeListener (this); // Initialize the cache structures. idMap = new HashMap<Backend,HashMap<Long,CacheEntry>>(); idMap = new HashMap<Backend<?>, HashMap<Long, CacheEntry>>(); dnMap = new LinkedHashMap<DN,CacheEntry>(); // Initialize locks. @@ -165,11 +156,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void finalizeEntryCache() { @@ -191,11 +178,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean containsEntry(DN entryDN) { @@ -212,11 +195,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Entry getEntry(DN entryDN) { @@ -238,11 +217,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public long getEntryID(DN entryDN) { @@ -250,21 +225,13 @@ cacheReadLock.lock(); try { CacheEntry e = dnMap.get(entryDN); if (e == null) { return -1; } else { return e.getEntryID(); } return e != null ? e.getEntryID() : -1; } finally { cacheReadLock.unlock(); } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public DN getEntryDN(Backend backend, long entryID) { @@ -284,11 +251,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void putEntry(Entry entry, Backend backend, long entryID) { @@ -379,10 +342,10 @@ // cache. If so, then see if we have exceeded it and we need to purge // entries until we're within the limit. int entryCount = dnMap.size(); if ((maxEntries > 0) && (entryCount > maxEntries)) if (maxEntries > 0 && entryCount > maxEntries) { Iterator<CacheEntry> iterator = dnMap.values().iterator(); while (iterator.hasNext() && (entryCount > maxEntries)) while (iterator.hasNext() && entryCount > maxEntries) { CacheEntry ce = iterator.next(); iterator.remove(); @@ -408,11 +371,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean putEntryIfAbsent(Entry entry, Backend backend, long entryID) { @@ -492,10 +451,10 @@ // cache. If so, then see if we have exceeded it and we need to purge // entries until we're within the limit. int entryCount = dnMap.size(); if ((maxEntries > 0) && (entryCount > maxEntries)) if (maxEntries > 0 && entryCount > maxEntries) { Iterator<CacheEntry> iterator = dnMap.values().iterator(); while (iterator.hasNext() && (entryCount > maxEntries)) while (iterator.hasNext() && entryCount > maxEntries) { CacheEntry ce = iterator.next(); iterator.remove(); @@ -529,11 +488,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void removeEntry(DN entryDN) { @@ -588,11 +543,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clear() { @@ -623,11 +574,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clearBackend(Backend backend) { @@ -682,11 +629,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clearSubtree(DN baseDN) { @@ -793,11 +736,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void handleLowMemory() { @@ -821,7 +760,7 @@ { int numToDrop = numEntries / 10; Iterator<CacheEntry> iterator = dnMap.values().iterator(); while (iterator.hasNext() && (numToDrop > 0)) while (iterator.hasNext() && numToDrop > 0) { CacheEntry entry = iterator.next(); iterator.remove(); @@ -848,12 +787,8 @@ } } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public boolean isConfigurationAcceptable(EntryCacheCfg configuration, List<LocalizableMessage> unacceptableReasons) { @@ -861,11 +796,7 @@ return isConfigurationChangeAcceptable(config, unacceptableReasons); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationChangeAcceptable( FIFOEntryCacheCfg configuration, @@ -884,15 +815,9 @@ return errorHandler.getIsAcceptable(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationChange( FIFOEntryCacheCfg configuration ) public ConfigChangeResult applyConfigurationChange( FIFOEntryCacheCfg configuration ) { boolean applyChanges = true; ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>(); @@ -906,13 +831,10 @@ processEntryCacheConfig (configuration, applyChanges, errorHandler); } boolean adminActionRequired = errorHandler.getIsAdminActionRequired(); ConfigChangeResult changeResult = new ConfigChangeResult( errorHandler.getResultCode(), adminActionRequired, errorHandler.getErrorMessages() ); final ConfigChangeResult changeResult = new ConfigChangeResult(); changeResult.setResultCode(errorHandler.getResultCode()); changeResult.setAdminActionRequired(errorHandler.getIsAdminActionRequired()); changeResult.getMessages().addAll(errorHandler.getErrorMessages()); return changeResult; } @@ -935,23 +857,18 @@ ) { // Local variables to read configuration. DN newConfigEntryDN; long newLockTimeout; long newMaxEntries; int newMaxMemoryPercent; long newMaxAllowedMemory; HashSet<SearchFilter> newIncludeFilters = null; HashSet<SearchFilter> newExcludeFilters = null; // Read configuration. newConfigEntryDN = configuration.dn(); newLockTimeout = configuration.getLockTimeout(); newMaxEntries = configuration.getMaxEntries(); DN newConfigEntryDN = configuration.dn(); long newLockTimeout = configuration.getLockTimeout(); long newMaxEntries = configuration.getMaxEntries(); // Maximum memory the cache can use. newMaxMemoryPercent = configuration.getMaxMemoryPercent(); long maxJvmHeapSize = Runtime.getRuntime().maxMemory(); newMaxAllowedMemory = (maxJvmHeapSize / 100) * newMaxMemoryPercent; int newMaxMemoryPercent = configuration.getMaxMemoryPercent(); long maxJvmHeapSize = Runtime.getRuntime().maxMemory(); long newMaxAllowedMemory = (maxJvmHeapSize / 100) * newMaxMemoryPercent; // Get include and exclude filters. switch (errorHandler.getConfigPhase()) @@ -987,11 +904,7 @@ return errorHandler.getIsAcceptable(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ArrayList<Attribute> getMonitorData() { @@ -999,16 +912,15 @@ try { attrs = EntryCacheCommon.getGenericMonitorData( new Long(cacheHits.longValue()), Long.valueOf(cacheHits.longValue()), // If cache misses is maintained by default cache // get it from there and if not point to itself. DirectoryServer.getEntryCache().getCacheMisses(), null, new Long(maxAllowedMemory), new Long(dnMap.size()), (((maxEntries != Integer.MAX_VALUE) && (maxEntries != Long.MAX_VALUE)) ? new Long(maxEntries) : new Long(0)) Long.valueOf(maxAllowedMemory), Long.valueOf(dnMap.size()), Long.valueOf( (maxEntries != Integer.MAX_VALUE && maxEntries != Long.MAX_VALUE) ? maxEntries : 0) ); } catch (Exception e) { logger.traceException(e); @@ -1017,29 +929,21 @@ return attrs; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Long getCacheCount() { return new Long(dnMap.size()); return Long.valueOf(dnMap.size()); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String toVerboseString() { StringBuilder sb = new StringBuilder(); Map<DN,CacheEntry> dnMapCopy; Map<Backend,HashMap<Long,CacheEntry>> idMapCopy; Map<Backend<?>, HashMap<Long, CacheEntry>> idMapCopy; // Grab cache lock to prevent any modifications // to the cache maps until a snapshot is taken. @@ -1049,26 +953,27 @@ // modifications in case of any access order maps, make copies // instead. dnMapCopy = new LinkedHashMap<DN,CacheEntry>(dnMap); idMapCopy = new HashMap<Backend,HashMap<Long,CacheEntry>>(idMap); idMapCopy = new HashMap<Backend<?>, HashMap<Long, CacheEntry>>(idMap); } finally { cacheWriteLock.unlock(); } // Check dnMap first. for (DN dn : dnMapCopy.keySet()) { sb.append(dn.toString()); final CacheEntry cacheEntry = dnMapCopy.get(dn); sb.append(dn); sb.append(":"); sb.append((dnMapCopy.get(dn) != null ? Long.toString(dnMapCopy.get(dn).getEntryID()) : null)); sb.append(cacheEntry != null ? Long.toString(cacheEntry.getEntryID()) : null); sb.append(":"); sb.append((dnMapCopy.get(dn) != null ? dnMapCopy.get(dn).getBackend().getBackendID() : null)); sb.append(cacheEntry != null ? cacheEntry.getBackend().getBackendID() : null); sb.append(ServerConstants.EOL); } // See if there is anything on idMap that is not reflected on // dnMap in case maps went out of sync. for (Backend backend : idMapCopy.keySet()) { for (Backend<?> backend : idMapCopy.keySet()) { for (Long id : idMapCopy.get(backend).keySet()) { final CacheEntry cacheEntry = idMapCopy.get(backend).get(id); if (cacheEntry == null || !dnMapCopy.containsKey(cacheEntry.getDN())) { @@ -1083,9 +988,6 @@ } String verboseString = sb.toString(); return (verboseString.length() > 0 ? verboseString : null); return verboseString.length() > 0 ? verboseString : null; } } opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java
@@ -22,10 +22,12 @@ * * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2011-2014 ForgeRock AS * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.server.extensions; import static org.opends.messages.ExtensionMessages.*; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.ArrayList; @@ -35,6 +37,7 @@ import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.util.Utils; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.server.EntryCacheCfg; @@ -42,7 +45,6 @@ import org.opends.server.api.Backend; import org.opends.server.api.DirectoryThread; import org.opends.server.api.EntryCache; import org.forgerock.opendj.config.server.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.types.Attribute; import org.opends.server.types.CacheEntry; @@ -53,8 +55,6 @@ import org.opends.server.types.SearchFilter; import org.opends.server.util.ServerConstants; import static org.opends.messages.ExtensionMessages.*; /** * This class defines a Directory Server entry cache that uses soft references * to manage objects in a way that will allow them to be freed if the JVM is @@ -68,23 +68,24 @@ { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); // The mapping between entry DNs and their corresponding entries. /** The mapping between entry DNs and their corresponding entries. */ private ConcurrentHashMap<DN,SoftReference<CacheEntry>> dnMap; // The mapping between backend+ID and their corresponding entries. /** The mapping between backend+ID and their corresponding entries. */ private ConcurrentHashMap<Backend, ConcurrentHashMap<Long,SoftReference<CacheEntry>>> idMap; // The reference queue that will be used to notify us whenever a soft // reference is freed. /** * The reference queue that will be used to notify us whenever a soft * reference is freed. */ private ReferenceQueue<CacheEntry> referenceQueue; // Currently registered configuration object. /** Currently registered configuration object. */ private SoftReferenceEntryCacheCfg registeredConfiguration; private Thread cleanerThread; private volatile boolean shutdown = false; private volatile boolean shutdown; @@ -106,11 +107,7 @@ referenceQueue = new ReferenceQueue<CacheEntry>(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void initializeEntryCache( SoftReferenceEntryCacheCfg configuration @@ -141,11 +138,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public synchronized void finalizeEntryCache() { @@ -156,7 +149,7 @@ dnMap.clear(); idMap.clear(); if (cleanerThread != null) { for (int i = 0; cleanerThread.isAlive() && (i < 5); i++) { for (int i = 0; cleanerThread.isAlive() && i < 5; i++) { cleanerThread.interrupt(); try { cleanerThread.join(10); @@ -168,27 +161,14 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean containsEntry(DN entryDN) { if (entryDN == null) { return false; } // Indicate whether the DN map contains the specified DN. return dnMap.containsKey(entryDN); return entryDN != null && dnMap.containsKey(entryDN); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Entry getEntry(DN entryDN) { @@ -217,38 +197,20 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public long getEntryID(DN entryDN) { SoftReference<CacheEntry> ref = dnMap.get(entryDN); if (ref == null) { return -1; } else if (ref != null) { CacheEntry cacheEntry = ref.get(); if (cacheEntry == null) { return -1; } else { return cacheEntry.getEntryID(); } return cacheEntry != null ? cacheEntry.getEntryID() : -1; } return -1; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public DN getEntryDN(Backend backend, long entryID) { @@ -267,11 +229,7 @@ return null; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void putEntry(Entry entry, Backend backend, long entryID) { @@ -303,11 +261,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean putEntryIfAbsent(Entry entry, Backend backend, long entryID) @@ -341,11 +295,7 @@ return true; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void removeEntry(DN entryDN) { @@ -357,7 +307,7 @@ CacheEntry cacheEntry = ref.get(); if (cacheEntry != null) { Backend backend = cacheEntry.getBackend(); Backend<?> backend = cacheEntry.getBackend(); ConcurrentHashMap<Long,SoftReference<CacheEntry>> map = idMap.get(backend); @@ -379,11 +329,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clear() { @@ -391,11 +337,7 @@ idMap.clear(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clearBackend(Backend backend) { @@ -419,16 +361,12 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void clearSubtree(DN baseDN) { // Determine the backend used to hold the specified base DN and clear it. Backend backend = DirectoryServer.getBackend(baseDN); Backend<?> backend = DirectoryServer.getBackend(baseDN); if (backend == null) { // FIXME -- Should we clear everything just to be safe? @@ -439,11 +377,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public void handleLowMemory() { @@ -452,12 +386,8 @@ // FIXME -- Do we need to do anything at all here? } /** * {@inheritDoc} */ @Override() /** {@inheritDoc} */ @Override public boolean isConfigurationAcceptable(EntryCacheCfg configuration, List<LocalizableMessage> unacceptableReasons) { @@ -466,11 +396,7 @@ return isConfigurationChangeAcceptable(config, unacceptableReasons); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationChangeAcceptable( SoftReferenceEntryCacheCfg configuration, @@ -488,15 +414,9 @@ return errorHandler.getIsAcceptable(); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationChange( SoftReferenceEntryCacheCfg configuration ) public ConfigChangeResult applyConfigurationChange(SoftReferenceEntryCacheCfg configuration) { boolean applyChanges = true; ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>(); @@ -509,12 +429,10 @@ processEntryCacheConfig (configuration, applyChanges, errorHandler); } boolean adminActionRequired = errorHandler.getIsAdminActionRequired(); ConfigChangeResult changeResult = new ConfigChangeResult( errorHandler.getResultCode(), adminActionRequired, errorHandler.getErrorMessages() ); final ConfigChangeResult changeResult = new ConfigChangeResult(); changeResult.setResultCode(errorHandler.getResultCode()); changeResult.setAdminActionRequired(errorHandler.getIsAdminActionRequired()); changeResult.getMessages().addAll(errorHandler.getErrorMessages()); return changeResult; } @@ -576,9 +494,6 @@ return errorHandler.getIsAcceptable(); } /** * Operate in a loop, receiving notification of soft references that have been * freed and removing the corresponding entries from the cache. @@ -609,7 +524,7 @@ { ref.clear(); Backend backend = freedEntry.getBackend(); Backend<?> backend = freedEntry.getBackend(); ConcurrentHashMap<Long,SoftReference<CacheEntry>> map = idMap.get(backend); if (map != null) @@ -636,11 +551,7 @@ } } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ArrayList<Attribute> getMonitorData() { @@ -648,13 +559,13 @@ try { attrs = EntryCacheCommon.getGenericMonitorData( new Long(cacheHits.longValue()), Long.valueOf(cacheHits.longValue()), // If cache misses is maintained by default cache // get it from there and if not point to itself. DirectoryServer.getEntryCache().getCacheMisses(), null, null, new Long(dnMap.size()), Long.valueOf(dnMap.size()), null ); } catch (Exception e) { @@ -664,30 +575,22 @@ return attrs; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public Long getCacheCount() { return new Long(dnMap.size()); return Long.valueOf(dnMap.size()); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public String toVerboseString() { StringBuilder sb = new StringBuilder(); // There're no locks in this cache to keep dnMap and idMap in // sync. Examine dnMap only since its more likely to be up to // date than idMap. Dont bother with copies either since this // There're no locks in this cache to keep dnMap and idMap in sync. // Examine dnMap only since its more likely to be up to date than idMap. // Do not bother with copies either since this // is SoftReference based implementation. for(SoftReference<CacheEntry> ce : dnMap.values()) { sb.append(ce.get().getDN()); @@ -699,8 +602,6 @@ } String verboseString = sb.toString(); return (verboseString.length() > 0 ? verboseString : null); return verboseString.length() > 0 ? verboseString : null; } } opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/ConfigChangeResult.java
@@ -22,7 +22,7 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2014 ForgeRock AS * Portions Copyright 2014-2015 ForgeRock AS */ package org.opends.server.types; @@ -48,7 +48,7 @@ * A set of messages describing the changes that were made, any action that * may be required, or any problems that were encountered. */ private final List<LocalizableMessage> messages; private final List<LocalizableMessage> messages = new ArrayList<LocalizableMessage>(); /** * Indicates whether one or more of the changes requires administrative action @@ -57,34 +57,12 @@ private boolean adminActionRequired; /** The result code to return to the client from this configuration change. */ private ResultCode resultCode; private ResultCode resultCode = ResultCode.SUCCESS; /** Creates a new mutable config change result object. */ public ConfigChangeResult() { this(ResultCode.SUCCESS, false, new ArrayList<LocalizableMessage>()); } /** * Creates a new config change result object with the provided * information. * * @param resultCode The result code for this config * change result. * @param adminActionRequired Indicates whether administrative * action is required for one or more * of the changes to take effect. * @param messages A set of messages that provide * additional information about the * change processing. */ public ConfigChangeResult(ResultCode resultCode, boolean adminActionRequired, List<LocalizableMessage> messages) { this.resultCode = resultCode; this.adminActionRequired = adminActionRequired; this.messages = messages; super(); } /**