/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2011 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS. */ package org.opends.guitools.controlpanel.util; import static org.opends.messages.AdminToolMessages.*; import static org.opends.server.backends.pluggable.SuffixContainer.*; import java.net.InetAddress; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TimeZone; import java.util.TreeSet; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapName; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigException; import org.opends.admin.ads.util.ConnectionUtils; import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor; import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; import org.opends.guitools.controlpanel.datamodel.VLVSortOrder; import org.opends.guitools.controlpanel.task.OnlineUpdateException; import org.opends.server.admin.client.AuthorizationException; import org.opends.server.admin.client.CommunicationException; import org.opends.server.admin.client.ConcurrentModificationException; import org.opends.server.admin.client.ManagementContext; import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor; import org.opends.server.admin.client.ldap.LDAPManagementContext; import org.opends.server.admin.std.client.AdministrationConnectorCfgClient; import org.opends.server.admin.std.client.BackendCfgClient; import org.opends.server.admin.std.client.BackendIndexCfgClient; import org.opends.server.admin.std.client.BackendVLVIndexCfgClient; import org.opends.server.admin.std.client.BackupBackendCfgClient; import org.opends.server.admin.std.client.ConnectionHandlerCfgClient; import org.opends.server.admin.std.client.HTTPConnectionHandlerCfgClient; import org.opends.server.admin.std.client.JMXConnectionHandlerCfgClient; import org.opends.server.admin.std.client.LDAPConnectionHandlerCfgClient; import org.opends.server.admin.std.client.LDIFBackendCfgClient; import org.opends.server.admin.std.client.LDIFConnectionHandlerCfgClient; import org.opends.server.admin.std.client.MemoryBackendCfgClient; import org.opends.server.admin.std.client.MonitorBackendCfgClient; import org.opends.server.admin.std.client.PluggableBackendCfgClient; import org.opends.server.admin.std.client.ReplicationDomainCfgClient; import org.opends.server.admin.std.client.ReplicationServerCfgClient; import org.opends.server.admin.std.client.ReplicationSynchronizationProviderCfgClient; import org.opends.server.admin.std.client.RootCfgClient; import org.opends.server.admin.std.client.RootDNCfgClient; import org.opends.server.admin.std.client.RootDNUserCfgClient; import org.opends.server.admin.std.client.SNMPConnectionHandlerCfgClient; import org.opends.server.admin.std.client.TaskBackendCfgClient; import org.opends.server.config.ConfigConstants; import org.opends.server.core.DirectoryServer; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.DN; import org.opends.server.types.OpenDsException; import org.opends.server.util.ServerConstants; /** * A class that reads the configuration and monitoring information using a * DirContext through LDAP. */ public class ConfigFromDirContext extends ConfigReader { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private static final String DATABASE_JE_MONITORING_ENTRY_SUFFIX = " JE Database"; private static final String DATABASE_PDB_MONITORING_ENTRY_SUFFIX = " PDB Database"; private static final String SYNC_PROVIDER_NAME = "Multimaster Synchronization"; private CustomSearchResult rootMonitor; private CustomSearchResult jvmMemoryUsage; private CustomSearchResult systemInformation; private CustomSearchResult entryCaches; private CustomSearchResult workQueue; private CustomSearchResult versionMonitor; private boolean isLocal = true; private final Map<String, CustomSearchResult> hmConnectionHandlersMonitor = new HashMap<>(); /** The monitor root entry DN. */ protected DN monitorDN = DN.rootDN(); /** The JVM memory usage monitoring entry DN. */ protected DN jvmMemoryUsageDN = DN.rootDN(); /** The system information monitoring entry DN. */ protected DN systemInformationDN = DN.rootDN(); /**The entry cache monitoring entry DN. */ protected DN entryCachesDN = DN.rootDN(); /** The work queue monitoring entry DN. */ protected DN workQueueDN = DN.rootDN(); /** The version monitoring entry DN. */ protected DN versionDN = DN.rootDN(); { try { monitorDN = DN.valueOf("cn=monitor"); jvmMemoryUsageDN = DN.valueOf("cn=JVM Memory Usage,cn=monitor"); systemInformationDN = DN.valueOf("cn=System Information,cn=monitor"); entryCachesDN = DN.valueOf("cn=Entry Caches,cn=monitor"); workQueueDN = DN.valueOf("cn=Work Queue,cn=monitor"); versionDN = DN.valueOf("cn=Version,cn=monitor"); } catch (Throwable t) { throw new RuntimeException("Could not decode DNs: "+t, t); } } /** The date formatter to be used to parse GMT dates. */ public static final SimpleDateFormat utcParser = new SimpleDateFormat(ServerConstants.DATE_FORMAT_GMT_TIME); { utcParser.setTimeZone(TimeZone.getTimeZone("UTC")); } /** The date formatter to be used to format dates. */ public static final DateFormat formatter = DateFormat.getDateTimeInstance(); /** * Returns the monitoring entry for the entry caches. * * @return the monitoring entry for the entry caches. */ public CustomSearchResult getEntryCaches() { return entryCaches; } /** * Returns the monitoring entry for the JVM memory usage. * * @return the monitoring entry for the JVM memory usage. */ public CustomSearchResult getJvmMemoryUsage() { return jvmMemoryUsage; } /** * Returns the root entry of the monitoring tree. * * @return the root entry of the monitoring tree. */ public CustomSearchResult getRootMonitor() { return rootMonitor; } /** * Returns the version entry of the monitoring tree. * * @return the version entry of the monitoring tree. */ public CustomSearchResult getVersionMonitor() { return versionMonitor; } /** * Returns the monitoring entry for the system information. * * @return the monitoring entry for the system information. */ public CustomSearchResult getSystemInformation() { return systemInformation; } /** * Returns the monitoring entry for the work queue. * * @return the monitoring entry for the work queue. */ public CustomSearchResult getWorkQueue() { return workQueue; } /** * Sets whether this server represents the local instance or a remote server. * * @param isLocal * whether this server represents the local instance or a remote * server (in another machine or in another installation on the same * machine). */ public void setIsLocal(boolean isLocal) { this.isLocal = isLocal; } /** * Returns <CODE>true</CODE> if we are trying to manage the local host and * <CODE>false</CODE> otherwise. * * @return <CODE>true</CODE> if we are trying to manage the local host and * <CODE>false</CODE> otherwise. */ public boolean isLocal() { return isLocal; } /** * Reads configuration and monitoring information using the provided * connection. * * @param context * the connection to be used to read the information. */ public void readConfiguration(final InitialLdapContext context) { final List<OpenDsException> errors = new ArrayList<>(); final Set<ConnectionHandlerDescriptor> connectionHandlers = new HashSet<>(); final Set<BackendDescriptor> backendDescriptors = new HashSet<>(); final Set<DN> as = new HashSet<>(); final Set<TaskEntry> tasks = new HashSet<>(); rootMonitor = null; jvmMemoryUsage = null; systemInformation = null; entryCaches = null; workQueue = null; versionMonitor = null; hmConnectionHandlersMonitor.clear(); readSchemaIfNeeded(context, errors); try { readConfig(context, connectionHandlers, backendDescriptors, as, errors); } catch (final Throwable t) { errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); } for (OpenDsException oe : errors) { logger.warn(LocalizableMessage.raw("Error reading configuration: " + oe, oe)); } administrativeUsers = Collections.unmodifiableSet(as); listeners = Collections.unmodifiableSet(connectionHandlers); backends = Collections.unmodifiableSet(backendDescriptors); try { updateMonitorInformation(context, errors); } catch (Throwable t) { logger.warn(LocalizableMessage.raw("Error reading monitoring: " + t, t)); errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); } try { updateTaskInformation(context, errors, tasks); } catch (Throwable t) { logger.warn(LocalizableMessage.raw("Error reading task information: " + t, t)); errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); } taskEntries = Collections.unmodifiableSet(tasks); for (ConnectionHandlerDescriptor ch : getConnectionHandlers()) { ch.setMonitoringEntries(getMonitoringEntries(ch)); } if (adminConnector != null) { adminConnector.setMonitoringEntries(getMonitoringEntries(adminConnector)); } exceptions = Collections.unmodifiableList(errors); } private void readSchemaIfNeeded(final InitialLdapContext context, final List<OpenDsException> errors) { if (mustReadSchema()) { try { readSchema(context); if (getSchema() != null) { // Update the schema: so that when we call the server code the // latest schema read on the server we are managing is used. DirectoryServer.setSchema(getSchema()); } } catch (OpenDsException oe) { errors.add(oe); } } } private void readConfig(final InitialLdapContext context, final Set<ConnectionHandlerDescriptor> connectionHandlers, final Set<BackendDescriptor> backendDescriptors, final Set<DN> alternateBindDNs, final List<OpenDsException> errors) throws Exception { // Get the Directory Server configuration handler and use it. ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(context)); final RootCfgClient root = mCtx.getRootConfiguration(); readAdminConnector(root, errors); readConnectionHandlers(connectionHandlers, root, errors); isSchemaEnabled = root.getGlobalConfiguration().isCheckSchema(); readBackendConfiguration(backendDescriptors, root, errors); boolean isReplicationSecure = readIfReplicationIsSecure(root, errors); final ReplicationSynchronizationProviderCfgClient sync = readSyncProviderIfExists(root); if (sync != null) { readReplicationConfig(connectionHandlers, backendDescriptors, sync, isReplicationSecure, errors); } readAlternateBindDNs(alternateBindDNs, root, errors); } private void readAdminConnector(final RootCfgClient root, final List<OpenDsException> errors) { try { AdministrationConnectorCfgClient adminConnector = root.getAdministrationConnector(); this.adminConnector = getConnectionHandler(adminConnector); } catch (OpenDsException oe) { errors.add(oe); } } private void readConnectionHandlers(final Set<ConnectionHandlerDescriptor> connectionHandlers, RootCfgClient root, final List<OpenDsException> errors) throws ConcurrentModificationException, AuthorizationException, CommunicationException { for (String connHandler : root.listConnectionHandlers()) { try { ConnectionHandlerCfgClient connectionHandler = root.getConnectionHandler(connHandler); connectionHandlers.add(getConnectionHandler(connectionHandler, connHandler)); } catch (OpenDsException oe) { errors.add(oe); } } } private void readBackendConfiguration(final Set<BackendDescriptor> backendDescriptors, final RootCfgClient root, final List<OpenDsException> errors) throws Exception { for (final String backendName : root.listBackends()) { try { BackendCfgClient backend = root.getBackend(backendName); Set<BaseDNDescriptor> baseDNs = new HashSet<>(); for (DN dn : backend.getBaseDN()) { BaseDNDescriptor baseDN = new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED, dn, null, -1, -1, -1); baseDNs.add(baseDN); } Set<IndexDescriptor> indexes = new HashSet<>(); Set<VLVIndexDescriptor> vlvIndexes = new HashSet<>(); BackendDescriptor.Type type = getBackendType(backend); if (type == BackendDescriptor.Type.PLUGGABLE) { refreshBackendConfig(indexes, vlvIndexes, backend, errors); } BackendDescriptor desc = new BackendDescriptor( backend.getBackendId(), baseDNs, indexes, vlvIndexes, -1, backend.isEnabled(), type); for (AbstractIndexDescriptor index: indexes) { index.setBackend(desc); } for (AbstractIndexDescriptor index: vlvIndexes) { index.setBackend(desc); } for (BaseDNDescriptor baseDN : baseDNs) { baseDN.setBackend(desc); } backendDescriptors.add(desc); } catch (OpenDsException oe) { errors.add(oe); } } } private BackendDescriptor.Type getBackendType(BackendCfgClient backend) { if (backend instanceof PluggableBackendCfgClient) { return BackendDescriptor.Type.PLUGGABLE; } else if (backend instanceof LDIFBackendCfgClient) { return BackendDescriptor.Type.LDIF; } else if (backend instanceof MemoryBackendCfgClient) { return BackendDescriptor.Type.MEMORY; } else if (backend instanceof BackupBackendCfgClient) { return BackendDescriptor.Type.BACKUP; } else if (backend instanceof MonitorBackendCfgClient) { return BackendDescriptor.Type.MONITOR; } else if (backend instanceof TaskBackendCfgClient) { return BackendDescriptor.Type.TASK; } else { return BackendDescriptor.Type.OTHER; } } private void refreshBackendConfig(final Set<IndexDescriptor> indexes, final Set<VLVIndexDescriptor> vlvIndexes, final BackendCfgClient backend, final List<OpenDsException> errors) { final PluggableBackendCfgClient db = (PluggableBackendCfgClient) backend; readBackendIndexes(indexes, errors, db); readBackendVLVIndexes(vlvIndexes, errors, db); } private void readBackendIndexes(final Set<IndexDescriptor> indexes, final List<OpenDsException> errors, final PluggableBackendCfgClient db) { indexes.add(new IndexDescriptor(DN2ID_INDEX_NAME)); indexes.add(new IndexDescriptor(ID2CHILDREN_COUNT_NAME)); try { for (final String indexName : db.listBackendIndexes()) { final BackendIndexCfgClient index = db.getBackendIndex(indexName); indexes.add(new IndexDescriptor( index.getAttribute().getNameOrOID(), index.getAttribute(), null, IndexTypeDescriptor.fromBackendIndexTypes(index.getIndexType()), index.getIndexEntryLimit())); } } catch (OpenDsException oe) { errors.add(oe); } } private void readBackendVLVIndexes(final Set<VLVIndexDescriptor> vlvIndexes, final List<OpenDsException> errors, final PluggableBackendCfgClient db) { try { for (final String vlvIndexName : db.listBackendVLVIndexes()) { final BackendVLVIndexCfgClient index = db.getBackendVLVIndex(vlvIndexName); final List<VLVSortOrder> sortOrder = getVLVSortOrder(index.getSortOrder()); vlvIndexes.add(new VLVIndexDescriptor( index.getName(), null, index.getBaseDN(), VLVIndexDescriptor.toSearchScope(index.getScope()), index.getFilter(), sortOrder)); } } catch (OpenDsException oe) { errors.add(oe); } } private boolean readIfReplicationIsSecure(final RootCfgClient root, final List<OpenDsException> errors) { try { return root.getCryptoManager().isSSLEncryption(); } catch (OpenDsException oe) { errors.add(oe); return false; } } private ReplicationSynchronizationProviderCfgClient readSyncProviderIfExists(final RootCfgClient root) { try { return (ReplicationSynchronizationProviderCfgClient) root.getSynchronizationProvider(SYNC_PROVIDER_NAME); } catch (OpenDsException oe) { return null; } } private void readReplicationConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, final Set<BackendDescriptor> backendDescriptors, final ReplicationSynchronizationProviderCfgClient sync, boolean isReplicationSecure, final List<OpenDsException> errors) { replicationPort = -1; try { if (sync.isEnabled() && sync.hasReplicationServer()) { ReplicationServerCfgClient replicationServer = sync.getReplicationServer(); if (replicationServer != null) { replicationPort = replicationServer.getReplicationPort(); ConnectionHandlerDescriptor.Protocol protocol = isReplicationSecure ? ConnectionHandlerDescriptor.Protocol.REPLICATION_SECURE : ConnectionHandlerDescriptor.Protocol.REPLICATION; Set<CustomSearchResult> emptySet = Collections.emptySet(); ConnectionHandlerDescriptor connHandler = new ConnectionHandlerDescriptor( new HashSet<InetAddress>(), replicationPort, protocol, ConnectionHandlerDescriptor.State.ENABLED, SYNC_PROVIDER_NAME, emptySet); connectionHandlers.add(connHandler); } } String[] domains = sync.listReplicationDomains(); if (domains != null) { for (String domain2 : domains) { ReplicationDomainCfgClient domain = sync.getReplicationDomain(domain2); DN dn = domain.getBaseDN(); for (BackendDescriptor backend : backendDescriptors) { for (BaseDNDescriptor baseDN : backend.getBaseDns()) { if (baseDN.getDn().equals(dn)) { baseDN.setType(sync.isEnabled() ? BaseDNDescriptor.Type.REPLICATED : BaseDNDescriptor.Type.DISABLED); baseDN.setReplicaID(domain.getServerId()); } } } } } } catch (OpenDsException oe) { errors.add(oe); } } private void readAlternateBindDNs(final Set<DN> alternateBindDNs, final RootCfgClient root, final List<OpenDsException> errors) { try { RootDNCfgClient rootDN = root.getRootDN(); String[] rootUsers = rootDN.listRootDNUsers(); if (rootUsers != null) { for (String rootUser2 : rootUsers) { RootDNUserCfgClient rootUser = rootDN.getRootDNUser(rootUser2); alternateBindDNs.addAll(rootUser.getAlternateBindDN()); } } } catch (OpenDsException oe) { errors.add(oe); } } /** * Returns an array of monitoring attributes to be returned in the request. * * @return an array of monitoring attributes to be returned in the request. */ protected String[] getMonitoringAttributes() { return new String[] {"*"}; } /** * Reads the schema from the files. * * @param ctx * the connection to be used to load the schema. * @throws OpenDsException * if an error occurs reading the schema. */ private void readSchema(InitialLdapContext ctx) throws OpenDsException { try { if (isLocal) { super.readSchema(); } else { RemoteSchemaLoader loader = new RemoteSchemaLoader(); loader.readSchema(ctx); schema = loader.getSchema(); } } catch (NamingException ne) { throw new OnlineUpdateException(ERR_READING_SCHEMA_LDAP.get(ne), ne); } catch (ConfigException ce) { throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce); } } /** * Takes the provided search result and updates the monitoring information * accordingly. * * @param sr * the search result. * @param searchBaseDN * the base search. * @throws NamingException * if there is an error retrieving the values of the search result. */ protected void handleMonitoringSearchResult(SearchResult sr, String searchBaseDN) throws NamingException { if (javaVersion == null) { javaVersion = ConnectionUtils.getFirstValue(sr, "javaVersion"); } if (numberConnections == -1) { String v = ConnectionUtils.getFirstValue(sr, "currentConnections"); if (v != null) { numberConnections = Integer.parseInt(v); } } String dn = ConnectionUtils.getFirstValue(sr, "domain-name"); String replicaId = ConnectionUtils.getFirstValue(sr, "server-id"); String missingChanges = ConnectionUtils.getFirstValue(sr, "missing-changes"); if (dn != null && replicaId != null && missingChanges != null) { for (BackendDescriptor backend : backends) { for (BaseDNDescriptor baseDN : backend.getBaseDns()) { try { if (baseDN.getDn().equals(DN.valueOf(dn)) && Integer.toString(baseDN.getReplicaID()).equals(replicaId)) { try { baseDN.setAgeOfOldestMissingChange( Long.valueOf(ConnectionUtils.getFirstValue(sr, "approx-older-change-not-synchronized-millis"))); } catch (Throwable ignored) { } try { baseDN.setMissingChanges(Integer.valueOf(missingChanges)); } catch (Throwable ignored) { } } } catch (Throwable ignored) { } } } } else { CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN); String backendID = ConnectionUtils.getFirstValue(sr, "ds-backend-id"); String entryCount = ConnectionUtils.getFirstValue(sr, "ds-backend-entry-count"); Set<String> baseDnEntries = ConnectionUtils.getValues(sr, "ds-base-dn-entry-count"); if (backendID != null && (entryCount != null || baseDnEntries != null)) { for (BackendDescriptor backend : backends) { if (backend.getBackendID().equalsIgnoreCase(backendID)) { if (entryCount != null) { backend.setEntries(Integer.parseInt(entryCount)); } if (baseDnEntries != null) { for (String s : baseDnEntries) { int index = s.indexOf(" "); if (index != -1) { for (BaseDNDescriptor baseDN : backend.getBaseDns()) { dn = s.substring(index +1); if (Utilities.areDnsEqual(dn, baseDN.getDn().toString())) { try { baseDN.setEntries( Integer.parseInt(s.substring(0, index))); } catch (Throwable t) { /* Ignore */ } break; } } } } } } } } else { // Check if it is the DB monitor entry String cn = ConnectionUtils.getFirstValue(sr, "cn"); String monitorBackendID = null; BackendDescriptor.PluggableType pluggableType = BackendDescriptor.PluggableType.UNKNOWN; if (cn != null && cn.endsWith(DATABASE_JE_MONITORING_ENTRY_SUFFIX)) { pluggableType = BackendDescriptor.PluggableType.JE; monitorBackendID = cn.substring(0, cn.length() - DATABASE_JE_MONITORING_ENTRY_SUFFIX.length()); } if (cn != null && cn.endsWith(DATABASE_PDB_MONITORING_ENTRY_SUFFIX)) { pluggableType = BackendDescriptor.PluggableType.PDB; monitorBackendID = cn.substring(0, cn.length() - DATABASE_PDB_MONITORING_ENTRY_SUFFIX.length()); } if (monitorBackendID != null) { for (BackendDescriptor backend : backends) { if (backend.getBackendID().equalsIgnoreCase(monitorBackendID)) { backend.setPluggableType(pluggableType); backend.setMonitoringEntry(csr); } } } } try { if (rootMonitor == null && isRootMonitor(csr)) { rootMonitor = csr; } else if (entryCaches == null && isEntryCaches(csr)) { entryCaches = csr; } else if (workQueue == null && isWorkQueue(csr)) { workQueue = csr; } else if (jvmMemoryUsage == null && isJvmMemoryUsage(csr)) { jvmMemoryUsage = csr; } else if (systemInformation == null && isSystemInformation(csr)) { systemInformation = csr; } else if (versionMonitor == null && isVersionMonitor(csr)) { versionMonitor = csr; } else if (isConnectionHandler(csr)) { String statistics = " Statistics"; String cn = ConnectionUtils.getFirstValue(sr, "cn"); if (cn.endsWith(statistics)) { // Assume it is a connection handler String name = cn.substring(0, cn.length() - statistics.length()); hmConnectionHandlersMonitor.put(getKey(name), csr); } } } catch (OpenDsException ode) { exceptions.add(ode); } } } /** * Takes the provided search result and updates the task information * accordingly. * * @param sr * the search result. * @param searchBaseDN * the base search. * @param taskEntries * the collection of TaskEntries to be updated. * @param ex * the list of exceptions to be updated if an error occurs. * @throws NamingException * if there is an error retrieving the values of the search result. */ private void handleTaskSearchResult(SearchResult sr, String searchBaseDN, Collection<TaskEntry> taskEntries, List<OpenDsException> ex) throws NamingException { CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN); try { if (isTaskEntry(csr)) { taskEntries.add(new TaskEntry(csr.getEntry())); } } catch (OpenDsException ode) { ex.add(ode); } } private void updateMonitorInformation(InitialLdapContext ctx, List<OpenDsException> ex) { // Read monitoring information: since it is computed, it is faster // to get everything in just one request. SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes(getMonitoringAttributes()); String filter = "(objectclass=*)"; try { LdapName jndiName = new LdapName("cn=monitor"); NamingEnumeration<SearchResult> monitorEntries = ctx.search(jndiName, filter, ctls); javaVersion = null; numberConnections = -1; try { while (monitorEntries.hasMore()) { SearchResult sr = monitorEntries.next(); handleMonitoringSearchResult(sr, "cn=monitor"); } } finally { monitorEntries.close(); } } catch (NamingException ne) { ex.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(ne.getMessage()), ne)); } } /** * Updates the provided list of TaskEntry with the task entries found in a * server. * * @param ctx * the connection to the server. * @param ex * the list of exceptions encountered while retrieving the task * entries. * @param ts * the list of task entries to be updated. */ public void updateTaskInformation(InitialLdapContext ctx, List<OpenDsException> ex, Collection<TaskEntry> ts) { // Read monitoring information: since it is computed, it is faster // to get everything in just one request. SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes(getMonitoringAttributes()); String filter = "(objectclass=ds-task)"; try { LdapName jndiName = new LdapName(ConfigConstants.DN_TASK_ROOT); NamingEnumeration<SearchResult> taskEntries = ctx.search(jndiName, filter, ctls); try { while (taskEntries.hasMore()) { SearchResult sr = taskEntries.next(); handleTaskSearchResult(sr, ConfigConstants.DN_TASK_ROOT, ts, ex); } } finally { taskEntries.close(); } } catch (NamingException ne) { ex.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(ne.getMessage()), ne)); } } private ConnectionHandlerDescriptor getConnectionHandler(ConnectionHandlerCfgClient connHandler, String name) throws OpenDsException { SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); ConnectionHandlerDescriptor.State state = connHandler.isEnabled() ? ConnectionHandlerDescriptor.State.ENABLED : ConnectionHandlerDescriptor.State.DISABLED; ConnectionHandlerDescriptor.Protocol protocol; int port; if (connHandler instanceof LDAPConnectionHandlerCfgClient) { LDAPConnectionHandlerCfgClient ldap = (LDAPConnectionHandlerCfgClient)connHandler; if (ldap.isUseSSL()) { protocol = ConnectionHandlerDescriptor.Protocol.LDAPS; } else if (ldap.isAllowStartTLS()) { protocol = ConnectionHandlerDescriptor.Protocol.LDAP_STARTTLS; } else { protocol = ConnectionHandlerDescriptor.Protocol.LDAP; } addAll(addresses, ldap.getListenAddress()); port = ldap.getListenPort(); } else if (connHandler instanceof HTTPConnectionHandlerCfgClient) { HTTPConnectionHandlerCfgClient http = (HTTPConnectionHandlerCfgClient) connHandler; if (http.isUseSSL()) { protocol = ConnectionHandlerDescriptor.Protocol.HTTPS; } else { protocol = ConnectionHandlerDescriptor.Protocol.HTTP; } addAll(addresses, http.getListenAddress()); port = http.getListenPort(); } else if (connHandler instanceof JMXConnectionHandlerCfgClient) { JMXConnectionHandlerCfgClient jmx = (JMXConnectionHandlerCfgClient)connHandler; if (jmx.isUseSSL()) { protocol = ConnectionHandlerDescriptor.Protocol.JMXS; } else { protocol = ConnectionHandlerDescriptor.Protocol.JMX; } addresses.add(jmx.getListenAddress()); port = jmx.getListenPort(); } else if (connHandler instanceof LDIFConnectionHandlerCfgClient) { protocol = ConnectionHandlerDescriptor.Protocol.LDIF; port = -1; } else if (connHandler instanceof SNMPConnectionHandlerCfgClient) { protocol = ConnectionHandlerDescriptor.Protocol.SNMP; SNMPConnectionHandlerCfgClient snmp = (SNMPConnectionHandlerCfgClient)connHandler; addAll(addresses, snmp.getListenAddress()); port = snmp.getListenPort(); } else { protocol = ConnectionHandlerDescriptor.Protocol.OTHER; port = -1; } Set<CustomSearchResult> emptySet = Collections.emptySet(); return new ConnectionHandlerDescriptor(addresses, port, protocol, state, name, emptySet); } private <T> void addAll(Collection<T> target, Collection<T> source) { if (source != null) { target.addAll(source); } } private ConnectionHandlerDescriptor getConnectionHandler(AdministrationConnectorCfgClient adminConnector) throws OpenDsException { SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); ConnectionHandlerDescriptor.Protocol protocol = ConnectionHandlerDescriptor.Protocol.ADMINISTRATION_CONNECTOR; ConnectionHandlerDescriptor.State state = ConnectionHandlerDescriptor.State.ENABLED; addAll(addresses, adminConnector.getListenAddress()); int port = adminConnector.getListenPort(); Set<CustomSearchResult> emptySet = Collections.emptySet(); return new ConnectionHandlerDescriptor( addresses, port, protocol, state, INFO_CTRL_PANEL_CONN_HANDLER_ADMINISTRATION.get().toString(), emptySet); } private boolean isRootMonitor(CustomSearchResult csr) throws OpenDsException { return monitorDN.equals(DN.valueOf(csr.getDN())); } private boolean isVersionMonitor(CustomSearchResult csr) throws OpenDsException { return versionDN.equals(DN.valueOf(csr.getDN())); } private boolean isSystemInformation(CustomSearchResult csr) throws OpenDsException { return systemInformationDN.equals(DN.valueOf(csr.getDN())); } private boolean isJvmMemoryUsage(CustomSearchResult csr) throws OpenDsException { return jvmMemoryUsageDN.equals(DN.valueOf(csr.getDN())); } private boolean isWorkQueue(CustomSearchResult csr) throws OpenDsException { return workQueueDN.equals(DN.valueOf(csr.getDN())); } private boolean isEntryCaches(CustomSearchResult csr) throws OpenDsException { return entryCachesDN.equals(DN.valueOf(csr.getDN())); } private boolean isConnectionHandler(CustomSearchResult csr) throws OpenDsException { DN dn = DN.valueOf(csr.getDN()); DN parent = dn.parent(); if (parent != null && parent.equals(monitorDN)) { List<?> vs = csr.getAttributeValues("cn"); if (vs != null && !vs.isEmpty()) { String cn = (String) vs.iterator().next(); String statistics = " Statistics"; if (cn.endsWith(statistics)) { return true; } } } return false; } private static boolean isTaskEntry(CustomSearchResult csr) throws OpenDsException { List<Object> vs = csr.getAttributeValues("objectclass"); if (vs != null && !vs.isEmpty()) { for (Object oc : vs) { if (oc.toString().equalsIgnoreCase("ds-task")) { return true; } } } return false; } /** * Commodity method to get the string representation to be used in the hash * maps as key. * * @param value * the value to be transformed into a key for a hash map. * @return the string representation to be used in the hash maps as key. */ private String getKey(String value) { return value.toLowerCase(); } private Set<CustomSearchResult>getMonitoringEntries(ConnectionHandlerDescriptor ch) { Set<CustomSearchResult> monitorEntries = new HashSet<>(); if (ch.getState() == ConnectionHandlerDescriptor.State.ENABLED) { for (String key : hmConnectionHandlersMonitor.keySet()) { // The name of the connection handler does not appear necessarily in the // key (which is based on the DN of the monitoring entry). In general // the DN contains the String specified in // LDAPConnectionHandler.DEFAULT_FRIENDLY_NAME, so we have to check that // this connection handler is the right one. // See org.opends.server.protocols.ldap.LDAPConnectionHandler to see // how the DN of the monitoring entry is generated. if (key.contains(getKey("port " + ch.getPort())) && hasAllAddresses(ch, key)) { monitorEntries.add(hmConnectionHandlersMonitor.get(key)); } } } return monitorEntries; } private boolean hasAllAddresses(ConnectionHandlerDescriptor ch, String key) { for (InetAddress a : ch.getAddresses()) { if (!key.contains(getKey(a.getHostAddress()))) { return false; } } return true; } }