001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2011 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.util; 018 019import static org.opends.messages.AdminToolMessages.*; 020import static org.opends.server.backends.pluggable.SuffixContainer.*; 021 022import java.net.InetAddress; 023import java.text.DateFormat; 024import java.text.SimpleDateFormat; 025import java.util.ArrayList; 026import java.util.Collection; 027import java.util.Collections; 028import java.util.HashMap; 029import java.util.HashSet; 030import java.util.List; 031import java.util.Map; 032import java.util.Set; 033import java.util.SortedSet; 034import java.util.TimeZone; 035import java.util.TreeSet; 036 037import javax.naming.NamingEnumeration; 038import javax.naming.NamingException; 039import javax.naming.directory.SearchControls; 040import javax.naming.directory.SearchResult; 041import javax.naming.ldap.InitialLdapContext; 042import javax.naming.ldap.LdapName; 043 044import org.forgerock.i18n.LocalizableMessage; 045import org.forgerock.i18n.slf4j.LocalizedLogger; 046import org.forgerock.opendj.config.server.ConfigException; 047import org.opends.admin.ads.util.ConnectionUtils; 048import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 049import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 050import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; 051import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; 052import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 053import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; 054import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor; 055import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 056import org.opends.guitools.controlpanel.datamodel.VLVSortOrder; 057import org.opends.guitools.controlpanel.task.OnlineUpdateException; 058import org.opends.server.admin.client.AuthorizationException; 059import org.opends.server.admin.client.CommunicationException; 060import org.opends.server.admin.client.ConcurrentModificationException; 061import org.opends.server.admin.client.ManagementContext; 062import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor; 063import org.opends.server.admin.client.ldap.LDAPManagementContext; 064import org.opends.server.admin.std.client.AdministrationConnectorCfgClient; 065import org.opends.server.admin.std.client.BackendCfgClient; 066import org.opends.server.admin.std.client.BackendIndexCfgClient; 067import org.opends.server.admin.std.client.BackendVLVIndexCfgClient; 068import org.opends.server.admin.std.client.BackupBackendCfgClient; 069import org.opends.server.admin.std.client.ConnectionHandlerCfgClient; 070import org.opends.server.admin.std.client.HTTPConnectionHandlerCfgClient; 071import org.opends.server.admin.std.client.JMXConnectionHandlerCfgClient; 072import org.opends.server.admin.std.client.LDAPConnectionHandlerCfgClient; 073import org.opends.server.admin.std.client.LDIFBackendCfgClient; 074import org.opends.server.admin.std.client.LDIFConnectionHandlerCfgClient; 075import org.opends.server.admin.std.client.MemoryBackendCfgClient; 076import org.opends.server.admin.std.client.MonitorBackendCfgClient; 077import org.opends.server.admin.std.client.PluggableBackendCfgClient; 078import org.opends.server.admin.std.client.ReplicationDomainCfgClient; 079import org.opends.server.admin.std.client.ReplicationServerCfgClient; 080import org.opends.server.admin.std.client.ReplicationSynchronizationProviderCfgClient; 081import org.opends.server.admin.std.client.RootCfgClient; 082import org.opends.server.admin.std.client.RootDNCfgClient; 083import org.opends.server.admin.std.client.RootDNUserCfgClient; 084import org.opends.server.admin.std.client.SNMPConnectionHandlerCfgClient; 085import org.opends.server.admin.std.client.TaskBackendCfgClient; 086import org.opends.server.config.ConfigConstants; 087import org.opends.server.core.DirectoryServer; 088import org.opends.server.tools.tasks.TaskEntry; 089import org.forgerock.opendj.ldap.DN; 090import org.opends.server.types.OpenDsException; 091import org.opends.server.util.ServerConstants; 092 093/** 094 * A class that reads the configuration and monitoring information using a 095 * DirContext through LDAP. 096 */ 097public class ConfigFromDirContext extends ConfigReader 098{ 099 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 100 101 private static final String DATABASE_JE_MONITORING_ENTRY_SUFFIX = " JE Database"; 102 private static final String DATABASE_PDB_MONITORING_ENTRY_SUFFIX = " PDB Database"; 103 private static final String SYNC_PROVIDER_NAME = "Multimaster Synchronization"; 104 105 private CustomSearchResult rootMonitor; 106 private CustomSearchResult jvmMemoryUsage; 107 private CustomSearchResult systemInformation; 108 private CustomSearchResult entryCaches; 109 private CustomSearchResult workQueue; 110 private CustomSearchResult versionMonitor; 111 112 private boolean isLocal = true; 113 114 private final Map<String, CustomSearchResult> hmConnectionHandlersMonitor = new HashMap<>(); 115 116 /** The monitor root entry DN. */ 117 protected DN monitorDN = DN.rootDN(); 118 /** The JVM memory usage monitoring entry DN. */ 119 protected DN jvmMemoryUsageDN = DN.rootDN(); 120 /** The system information monitoring entry DN. */ 121 protected DN systemInformationDN = DN.rootDN(); 122 /**The entry cache monitoring entry DN. */ 123 protected DN entryCachesDN = DN.rootDN(); 124 /** The work queue monitoring entry DN. */ 125 protected DN workQueueDN = DN.rootDN(); 126 /** The version monitoring entry DN. */ 127 protected DN versionDN = DN.rootDN(); 128 129 { 130 try 131 { 132 monitorDN = DN.valueOf("cn=monitor"); 133 jvmMemoryUsageDN = DN.valueOf("cn=JVM Memory Usage,cn=monitor"); 134 systemInformationDN = DN.valueOf("cn=System Information,cn=monitor"); 135 entryCachesDN = DN.valueOf("cn=Entry Caches,cn=monitor"); 136 workQueueDN = DN.valueOf("cn=Work Queue,cn=monitor"); 137 versionDN = DN.valueOf("cn=Version,cn=monitor"); 138 } 139 catch (Throwable t) 140 { 141 throw new RuntimeException("Could not decode DNs: "+t, t); 142 } 143 } 144 145 /** The date formatter to be used to parse GMT dates. */ 146 public static final SimpleDateFormat utcParser = new SimpleDateFormat(ServerConstants.DATE_FORMAT_GMT_TIME); 147 { 148 utcParser.setTimeZone(TimeZone.getTimeZone("UTC")); 149 } 150 151 /** The date formatter to be used to format dates. */ 152 public static final DateFormat formatter = DateFormat.getDateTimeInstance(); 153 154 /** 155 * Returns the monitoring entry for the entry caches. 156 * 157 * @return the monitoring entry for the entry caches. 158 */ 159 public CustomSearchResult getEntryCaches() 160 { 161 return entryCaches; 162 } 163 164 /** 165 * Returns the monitoring entry for the JVM memory usage. 166 * 167 * @return the monitoring entry for the JVM memory usage. 168 */ 169 public CustomSearchResult getJvmMemoryUsage() 170 { 171 return jvmMemoryUsage; 172 } 173 174 /** 175 * Returns the root entry of the monitoring tree. 176 * 177 * @return the root entry of the monitoring tree. 178 */ 179 public CustomSearchResult getRootMonitor() 180 { 181 return rootMonitor; 182 } 183 184 /** 185 * Returns the version entry of the monitoring tree. 186 * 187 * @return the version entry of the monitoring tree. 188 */ 189 public CustomSearchResult getVersionMonitor() 190 { 191 return versionMonitor; 192 } 193 194 /** 195 * Returns the monitoring entry for the system information. 196 * 197 * @return the monitoring entry for the system information. 198 */ 199 public CustomSearchResult getSystemInformation() 200 { 201 return systemInformation; 202 } 203 204 /** 205 * Returns the monitoring entry for the work queue. 206 * 207 * @return the monitoring entry for the work queue. 208 */ 209 public CustomSearchResult getWorkQueue() 210 { 211 return workQueue; 212 } 213 214 /** 215 * Sets whether this server represents the local instance or a remote server. 216 * 217 * @param isLocal 218 * whether this server represents the local instance or a remote 219 * server (in another machine or in another installation on the same 220 * machine). 221 */ 222 public void setIsLocal(boolean isLocal) 223 { 224 this.isLocal = isLocal; 225 } 226 227 /** 228 * Returns <CODE>true</CODE> if we are trying to manage the local host and 229 * <CODE>false</CODE> otherwise. 230 * 231 * @return <CODE>true</CODE> if we are trying to manage the local host and 232 * <CODE>false</CODE> otherwise. 233 */ 234 public boolean isLocal() 235 { 236 return isLocal; 237 } 238 239 /** 240 * Reads configuration and monitoring information using the provided 241 * connection. 242 * 243 * @param context 244 * the connection to be used to read the information. 245 */ 246 public void readConfiguration(final InitialLdapContext context) 247 { 248 final List<OpenDsException> errors = new ArrayList<>(); 249 final Set<ConnectionHandlerDescriptor> connectionHandlers = new HashSet<>(); 250 final Set<BackendDescriptor> backendDescriptors = new HashSet<>(); 251 final Set<DN> as = new HashSet<>(); 252 final Set<TaskEntry> tasks = new HashSet<>(); 253 254 rootMonitor = null; 255 jvmMemoryUsage = null; 256 systemInformation = null; 257 entryCaches = null; 258 workQueue = null; 259 versionMonitor = null; 260 261 hmConnectionHandlersMonitor.clear(); 262 263 readSchemaIfNeeded(context, errors); 264 265 try 266 { 267 readConfig(context, connectionHandlers, backendDescriptors, as, errors); 268 } 269 catch (final Throwable t) 270 { 271 errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); 272 } 273 274 for (OpenDsException oe : errors) 275 { 276 logger.warn(LocalizableMessage.raw("Error reading configuration: " + oe, oe)); 277 } 278 administrativeUsers = Collections.unmodifiableSet(as); 279 listeners = Collections.unmodifiableSet(connectionHandlers); 280 backends = Collections.unmodifiableSet(backendDescriptors); 281 try 282 { 283 updateMonitorInformation(context, errors); 284 } 285 catch (Throwable t) 286 { 287 logger.warn(LocalizableMessage.raw("Error reading monitoring: " + t, t)); 288 errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); 289 } 290 291 try 292 { 293 updateTaskInformation(context, errors, tasks); 294 } 295 catch (Throwable t) 296 { 297 logger.warn(LocalizableMessage.raw("Error reading task information: " + t, t)); 298 errors.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(t), t)); 299 } 300 301 taskEntries = Collections.unmodifiableSet(tasks); 302 for (ConnectionHandlerDescriptor ch : getConnectionHandlers()) 303 { 304 ch.setMonitoringEntries(getMonitoringEntries(ch)); 305 } 306 307 if (adminConnector != null) 308 { 309 adminConnector.setMonitoringEntries(getMonitoringEntries(adminConnector)); 310 } 311 exceptions = Collections.unmodifiableList(errors); 312 } 313 314 private void readSchemaIfNeeded(final InitialLdapContext context, final List<OpenDsException> errors) 315 { 316 if (mustReadSchema()) 317 { 318 try 319 { 320 readSchema(context); 321 if (getSchema() != null) 322 { 323 // Update the schema: so that when we call the server code the 324 // latest schema read on the server we are managing is used. 325 DirectoryServer.setSchema(getSchema()); 326 } 327 } 328 catch (OpenDsException oe) 329 { 330 errors.add(oe); 331 } 332 } 333 } 334 335 private void readConfig(final InitialLdapContext context, 336 final Set<ConnectionHandlerDescriptor> connectionHandlers, final Set<BackendDescriptor> backendDescriptors, 337 final Set<DN> alternateBindDNs, final List<OpenDsException> errors) throws Exception 338 { 339 // Get the Directory Server configuration handler and use it. 340 ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(context)); 341 final RootCfgClient root = mCtx.getRootConfiguration(); 342 343 readAdminConnector(root, errors); 344 readConnectionHandlers(connectionHandlers, root, errors); 345 isSchemaEnabled = root.getGlobalConfiguration().isCheckSchema(); 346 347 readBackendConfiguration(backendDescriptors, root, errors); 348 349 boolean isReplicationSecure = readIfReplicationIsSecure(root, errors); 350 351 final ReplicationSynchronizationProviderCfgClient sync = readSyncProviderIfExists(root); 352 if (sync != null) 353 { 354 readReplicationConfig(connectionHandlers, backendDescriptors, sync, isReplicationSecure, errors); 355 } 356 357 readAlternateBindDNs(alternateBindDNs, root, errors); 358 } 359 360 private void readAdminConnector(final RootCfgClient root, final List<OpenDsException> errors) 361 { 362 try 363 { 364 AdministrationConnectorCfgClient adminConnector = root.getAdministrationConnector(); 365 this.adminConnector = getConnectionHandler(adminConnector); 366 } 367 catch (OpenDsException oe) 368 { 369 errors.add(oe); 370 } 371 } 372 373 private void readConnectionHandlers(final Set<ConnectionHandlerDescriptor> connectionHandlers, 374 RootCfgClient root, final List<OpenDsException> errors) throws ConcurrentModificationException, 375 AuthorizationException, CommunicationException 376 { 377 for (String connHandler : root.listConnectionHandlers()) 378 { 379 try 380 { 381 ConnectionHandlerCfgClient connectionHandler = root.getConnectionHandler(connHandler); 382 connectionHandlers.add(getConnectionHandler(connectionHandler, connHandler)); 383 } 384 catch (OpenDsException oe) 385 { 386 errors.add(oe); 387 } 388 } 389 } 390 391 private void readBackendConfiguration(final Set<BackendDescriptor> backendDescriptors, 392 final RootCfgClient root, final List<OpenDsException> errors) throws Exception 393 { 394 for (final String backendName : root.listBackends()) 395 { 396 try 397 { 398 BackendCfgClient backend = root.getBackend(backendName); 399 Set<BaseDNDescriptor> baseDNs = new HashSet<>(); 400 for (DN dn : backend.getBaseDN()) 401 { 402 BaseDNDescriptor baseDN = new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED, dn, null, -1, -1, -1); 403 baseDNs.add(baseDN); 404 } 405 Set<IndexDescriptor> indexes = new HashSet<>(); 406 Set<VLVIndexDescriptor> vlvIndexes = new HashSet<>(); 407 BackendDescriptor.Type type = getBackendType(backend); 408 if (type == BackendDescriptor.Type.PLUGGABLE) 409 { 410 refreshBackendConfig(indexes, vlvIndexes, backend, errors); 411 } 412 413 BackendDescriptor desc = new BackendDescriptor( 414 backend.getBackendId(), baseDNs, indexes, vlvIndexes, -1, backend.isEnabled(), type); 415 for (AbstractIndexDescriptor index: indexes) 416 { 417 index.setBackend(desc); 418 } 419 for (AbstractIndexDescriptor index: vlvIndexes) 420 { 421 index.setBackend(desc); 422 } 423 for (BaseDNDescriptor baseDN : baseDNs) 424 { 425 baseDN.setBackend(desc); 426 } 427 backendDescriptors.add(desc); 428 } 429 catch (OpenDsException oe) 430 { 431 errors.add(oe); 432 } 433 } 434 } 435 436 private BackendDescriptor.Type getBackendType(BackendCfgClient backend) 437 { 438 if (backend instanceof PluggableBackendCfgClient) 439 { 440 return BackendDescriptor.Type.PLUGGABLE; 441 } 442 else if (backend instanceof LDIFBackendCfgClient) 443 { 444 return BackendDescriptor.Type.LDIF; 445 } 446 else if (backend instanceof MemoryBackendCfgClient) 447 { 448 return BackendDescriptor.Type.MEMORY; 449 } 450 else if (backend instanceof BackupBackendCfgClient) 451 { 452 return BackendDescriptor.Type.BACKUP; 453 } 454 else if (backend instanceof MonitorBackendCfgClient) 455 { 456 return BackendDescriptor.Type.MONITOR; 457 } 458 else if (backend instanceof TaskBackendCfgClient) 459 { 460 return BackendDescriptor.Type.TASK; 461 } 462 else 463 { 464 return BackendDescriptor.Type.OTHER; 465 } 466 } 467 468 private void refreshBackendConfig(final Set<IndexDescriptor> indexes, 469 final Set<VLVIndexDescriptor> vlvIndexes, final BackendCfgClient backend, final List<OpenDsException> errors) 470 { 471 final PluggableBackendCfgClient db = (PluggableBackendCfgClient) backend; 472 readBackendIndexes(indexes, errors, db); 473 readBackendVLVIndexes(vlvIndexes, errors, db); 474 } 475 476 private void readBackendIndexes(final Set<IndexDescriptor> indexes, final List<OpenDsException> errors, 477 final PluggableBackendCfgClient db) 478 { 479 indexes.add(new IndexDescriptor(DN2ID_INDEX_NAME)); 480 indexes.add(new IndexDescriptor(ID2CHILDREN_COUNT_NAME)); 481 try 482 { 483 for (final String indexName : db.listBackendIndexes()) 484 { 485 final BackendIndexCfgClient index = db.getBackendIndex(indexName); 486 indexes.add(new IndexDescriptor( 487 index.getAttribute().getNameOrOID(), index.getAttribute(), 488 null, IndexTypeDescriptor.fromBackendIndexTypes(index.getIndexType()), index.getIndexEntryLimit())); 489 } 490 } 491 catch (OpenDsException oe) 492 { 493 errors.add(oe); 494 } 495 } 496 497 private void readBackendVLVIndexes(final Set<VLVIndexDescriptor> vlvIndexes, 498 final List<OpenDsException> errors, final PluggableBackendCfgClient db) 499 { 500 try 501 { 502 for (final String vlvIndexName : db.listBackendVLVIndexes()) 503 { 504 final BackendVLVIndexCfgClient index = db.getBackendVLVIndex(vlvIndexName); 505 final List<VLVSortOrder> sortOrder = getVLVSortOrder(index.getSortOrder()); 506 vlvIndexes.add(new VLVIndexDescriptor( 507 index.getName(), null, index.getBaseDN(), VLVIndexDescriptor.toSearchScope(index.getScope()), 508 index.getFilter(), sortOrder)); 509 } 510 } 511 catch (OpenDsException oe) 512 { 513 errors.add(oe); 514 } 515 } 516 517 private boolean readIfReplicationIsSecure(final RootCfgClient root, final List<OpenDsException> errors) 518 { 519 try 520 { 521 return root.getCryptoManager().isSSLEncryption(); 522 } 523 catch (OpenDsException oe) 524 { 525 errors.add(oe); 526 return false; 527 } 528 } 529 530 private ReplicationSynchronizationProviderCfgClient readSyncProviderIfExists(final RootCfgClient root) 531 { 532 try 533 { 534 return (ReplicationSynchronizationProviderCfgClient) root.getSynchronizationProvider(SYNC_PROVIDER_NAME); 535 } 536 catch (OpenDsException oe) 537 { 538 return null; 539 } 540 } 541 542 private void readReplicationConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, 543 final Set<BackendDescriptor> backendDescriptors, final ReplicationSynchronizationProviderCfgClient sync, 544 boolean isReplicationSecure, final List<OpenDsException> errors) 545 { 546 replicationPort = -1; 547 try 548 { 549 if (sync.isEnabled() && sync.hasReplicationServer()) 550 { 551 ReplicationServerCfgClient replicationServer = sync.getReplicationServer(); 552 if (replicationServer != null) 553 { 554 replicationPort = replicationServer.getReplicationPort(); 555 ConnectionHandlerDescriptor.Protocol protocol = 556 isReplicationSecure ? ConnectionHandlerDescriptor.Protocol.REPLICATION_SECURE 557 : ConnectionHandlerDescriptor.Protocol.REPLICATION; 558 Set<CustomSearchResult> emptySet = Collections.emptySet(); 559 ConnectionHandlerDescriptor connHandler = new ConnectionHandlerDescriptor( 560 new HashSet<InetAddress>(), replicationPort, protocol, ConnectionHandlerDescriptor.State.ENABLED, 561 SYNC_PROVIDER_NAME, emptySet); 562 connectionHandlers.add(connHandler); 563 } 564 } 565 566 String[] domains = sync.listReplicationDomains(); 567 if (domains != null) 568 { 569 for (String domain2 : domains) 570 { 571 ReplicationDomainCfgClient domain = sync.getReplicationDomain(domain2); 572 DN dn = domain.getBaseDN(); 573 for (BackendDescriptor backend : backendDescriptors) 574 { 575 for (BaseDNDescriptor baseDN : backend.getBaseDns()) 576 { 577 if (baseDN.getDn().equals(dn)) 578 { 579 baseDN.setType(sync.isEnabled() ? BaseDNDescriptor.Type.REPLICATED 580 : BaseDNDescriptor.Type.DISABLED); 581 baseDN.setReplicaID(domain.getServerId()); 582 } 583 } 584 } 585 } 586 } 587 } 588 catch (OpenDsException oe) 589 { 590 errors.add(oe); 591 } 592 } 593 594 private void readAlternateBindDNs(final Set<DN> alternateBindDNs, final RootCfgClient root, 595 final List<OpenDsException> errors) 596 { 597 try 598 { 599 RootDNCfgClient rootDN = root.getRootDN(); 600 String[] rootUsers = rootDN.listRootDNUsers(); 601 if (rootUsers != null) 602 { 603 for (String rootUser2 : rootUsers) 604 { 605 RootDNUserCfgClient rootUser = rootDN.getRootDNUser(rootUser2); 606 alternateBindDNs.addAll(rootUser.getAlternateBindDN()); 607 } 608 } 609 } 610 catch (OpenDsException oe) 611 { 612 errors.add(oe); 613 } 614 } 615 616 /** 617 * Returns an array of monitoring attributes to be returned in the request. 618 * 619 * @return an array of monitoring attributes to be returned in the request. 620 */ 621 protected String[] getMonitoringAttributes() 622 { 623 return new String[] {"*"}; 624 } 625 626 /** 627 * Reads the schema from the files. 628 * 629 * @param ctx 630 * the connection to be used to load the schema. 631 * @throws OpenDsException 632 * if an error occurs reading the schema. 633 */ 634 private void readSchema(InitialLdapContext ctx) throws OpenDsException 635 { 636 try 637 { 638 if (isLocal) 639 { 640 super.readSchema(); 641 } 642 else 643 { 644 RemoteSchemaLoader loader = new RemoteSchemaLoader(); 645 loader.readSchema(ctx); 646 schema = loader.getSchema(); 647 } 648 } 649 catch (NamingException ne) 650 { 651 throw new OnlineUpdateException(ERR_READING_SCHEMA_LDAP.get(ne), ne); 652 } 653 catch (ConfigException ce) 654 { 655 throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce); 656 } 657 } 658 659 /** 660 * Takes the provided search result and updates the monitoring information 661 * accordingly. 662 * 663 * @param sr 664 * the search result. 665 * @param searchBaseDN 666 * the base search. 667 * @throws NamingException 668 * if there is an error retrieving the values of the search result. 669 */ 670 protected void handleMonitoringSearchResult(SearchResult sr, 671 String searchBaseDN) 672 throws NamingException 673 { 674 if (javaVersion == null) 675 { 676 javaVersion = ConnectionUtils.getFirstValue(sr, "javaVersion"); 677 } 678 679 if (numberConnections == -1) 680 { 681 String v = ConnectionUtils.getFirstValue(sr, "currentConnections"); 682 if (v != null) 683 { 684 numberConnections = Integer.parseInt(v); 685 } 686 } 687 688 String dn = ConnectionUtils.getFirstValue(sr, "domain-name"); 689 String replicaId = ConnectionUtils.getFirstValue(sr, "server-id"); 690 String missingChanges = ConnectionUtils.getFirstValue(sr, "missing-changes"); 691 692 if (dn != null && replicaId != null && missingChanges != null) 693 { 694 for (BackendDescriptor backend : backends) 695 { 696 for (BaseDNDescriptor baseDN : backend.getBaseDns()) 697 { 698 try 699 { 700 if (baseDN.getDn().equals(DN.valueOf(dn)) && 701 Integer.toString(baseDN.getReplicaID()).equals(replicaId)) 702 { 703 try 704 { 705 baseDN.setAgeOfOldestMissingChange( 706 Long.valueOf(ConnectionUtils.getFirstValue(sr, "approx-older-change-not-synchronized-millis"))); 707 } 708 catch (Throwable ignored) 709 { 710 } 711 try 712 { 713 baseDN.setMissingChanges(Integer.valueOf(missingChanges)); 714 } 715 catch (Throwable ignored) 716 { 717 } 718 } 719 } 720 catch (Throwable ignored) 721 { 722 } 723 } 724 } 725 } 726 else 727 { 728 CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN); 729 String backendID = ConnectionUtils.getFirstValue(sr, "ds-backend-id"); 730 String entryCount = ConnectionUtils.getFirstValue(sr, "ds-backend-entry-count"); 731 Set<String> baseDnEntries = ConnectionUtils.getValues(sr, "ds-base-dn-entry-count"); 732 if (backendID != null && (entryCount != null || baseDnEntries != null)) 733 { 734 for (BackendDescriptor backend : backends) 735 { 736 if (backend.getBackendID().equalsIgnoreCase(backendID)) 737 { 738 if (entryCount != null) 739 { 740 backend.setEntries(Integer.parseInt(entryCount)); 741 } 742 if (baseDnEntries != null) 743 { 744 for (String s : baseDnEntries) 745 { 746 int index = s.indexOf(" "); 747 if (index != -1) 748 { 749 for (BaseDNDescriptor baseDN : backend.getBaseDns()) 750 { 751 dn = s.substring(index +1); 752 753 if (Utilities.areDnsEqual(dn, 754 baseDN.getDn().toString())) 755 { 756 try 757 { 758 baseDN.setEntries( 759 Integer.parseInt(s.substring(0, index))); 760 } 761 catch (Throwable t) 762 { 763 /* Ignore */ 764 } 765 break; 766 } 767 } 768 } 769 } 770 } 771 } 772 } 773 } 774 else 775 { 776 // Check if it is the DB monitor entry 777 String cn = ConnectionUtils.getFirstValue(sr, "cn"); 778 String monitorBackendID = null; 779 BackendDescriptor.PluggableType pluggableType = BackendDescriptor.PluggableType.UNKNOWN; 780 if (cn != null && cn.endsWith(DATABASE_JE_MONITORING_ENTRY_SUFFIX)) 781 { 782 pluggableType = BackendDescriptor.PluggableType.JE; 783 monitorBackendID = cn.substring(0, cn.length() - DATABASE_JE_MONITORING_ENTRY_SUFFIX.length()); 784 } 785 if (cn != null && cn.endsWith(DATABASE_PDB_MONITORING_ENTRY_SUFFIX)) 786 { 787 pluggableType = BackendDescriptor.PluggableType.PDB; 788 monitorBackendID = cn.substring(0, cn.length() - DATABASE_PDB_MONITORING_ENTRY_SUFFIX.length()); 789 } 790 if (monitorBackendID != null) 791 { 792 for (BackendDescriptor backend : backends) 793 { 794 if (backend.getBackendID().equalsIgnoreCase(monitorBackendID)) 795 { 796 backend.setPluggableType(pluggableType); 797 backend.setMonitoringEntry(csr); 798 } 799 } 800 } 801 } 802 try 803 { 804 if (rootMonitor == null && isRootMonitor(csr)) 805 { 806 rootMonitor = csr; 807 } 808 else if (entryCaches == null && isEntryCaches(csr)) 809 { 810 entryCaches = csr; 811 } 812 else if (workQueue == null && isWorkQueue(csr)) 813 { 814 workQueue = csr; 815 } 816 else if (jvmMemoryUsage == null && isJvmMemoryUsage(csr)) 817 { 818 jvmMemoryUsage = csr; 819 } 820 else if (systemInformation == null && isSystemInformation(csr)) 821 { 822 systemInformation = csr; 823 } 824 else if (versionMonitor == null && isVersionMonitor(csr)) 825 { 826 versionMonitor = csr; 827 } 828 else if (isConnectionHandler(csr)) 829 { 830 String statistics = " Statistics"; 831 String cn = ConnectionUtils.getFirstValue(sr, "cn"); 832 if (cn.endsWith(statistics)) 833 { 834 // Assume it is a connection handler 835 String name = cn.substring(0, cn.length() - statistics.length()); 836 hmConnectionHandlersMonitor.put(getKey(name), csr); 837 } 838 } 839 } 840 catch (OpenDsException ode) 841 { 842 exceptions.add(ode); 843 } 844 } 845 } 846 847 /** 848 * Takes the provided search result and updates the task information 849 * accordingly. 850 * 851 * @param sr 852 * the search result. 853 * @param searchBaseDN 854 * the base search. 855 * @param taskEntries 856 * the collection of TaskEntries to be updated. 857 * @param ex 858 * the list of exceptions to be updated if an error occurs. 859 * @throws NamingException 860 * if there is an error retrieving the values of the search result. 861 */ 862 private void handleTaskSearchResult(SearchResult sr, String searchBaseDN, Collection<TaskEntry> taskEntries, 863 List<OpenDsException> ex) throws NamingException 864 { 865 CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN); 866 try 867 { 868 if (isTaskEntry(csr)) 869 { 870 taskEntries.add(new TaskEntry(csr.getEntry())); 871 } 872 } 873 catch (OpenDsException ode) 874 { 875 ex.add(ode); 876 } 877 } 878 879 private void updateMonitorInformation(InitialLdapContext ctx, 880 List<OpenDsException> ex) 881 { 882 // Read monitoring information: since it is computed, it is faster 883 // to get everything in just one request. 884 SearchControls ctls = new SearchControls(); 885 ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); 886 ctls.setReturningAttributes(getMonitoringAttributes()); 887 String filter = "(objectclass=*)"; 888 889 try 890 { 891 LdapName jndiName = new LdapName("cn=monitor"); 892 NamingEnumeration<SearchResult> monitorEntries = ctx.search(jndiName, filter, ctls); 893 javaVersion = null; 894 numberConnections = -1; 895 896 try 897 { 898 while (monitorEntries.hasMore()) 899 { 900 SearchResult sr = monitorEntries.next(); 901 handleMonitoringSearchResult(sr, "cn=monitor"); 902 } 903 } 904 finally 905 { 906 monitorEntries.close(); 907 } 908 } 909 catch (NamingException ne) 910 { 911 ex.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(ne.getMessage()), ne)); 912 } 913 } 914 915 /** 916 * Updates the provided list of TaskEntry with the task entries found in a 917 * server. 918 * 919 * @param ctx 920 * the connection to the server. 921 * @param ex 922 * the list of exceptions encountered while retrieving the task 923 * entries. 924 * @param ts 925 * the list of task entries to be updated. 926 */ 927 public void updateTaskInformation(InitialLdapContext ctx, List<OpenDsException> ex, Collection<TaskEntry> ts) 928 { 929 // Read monitoring information: since it is computed, it is faster 930 // to get everything in just one request. 931 SearchControls ctls = new SearchControls(); 932 ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); 933 ctls.setReturningAttributes(getMonitoringAttributes()); 934 String filter = "(objectclass=ds-task)"; 935 936 try 937 { 938 LdapName jndiName = new LdapName(ConfigConstants.DN_TASK_ROOT); 939 NamingEnumeration<SearchResult> taskEntries = ctx.search(jndiName, filter, ctls); 940 try 941 { 942 while (taskEntries.hasMore()) 943 { 944 SearchResult sr = taskEntries.next(); 945 handleTaskSearchResult(sr, ConfigConstants.DN_TASK_ROOT, ts, ex); 946 } 947 } 948 finally 949 { 950 taskEntries.close(); 951 } 952 } 953 catch (NamingException ne) 954 { 955 ex.add(new OnlineUpdateException(ERR_READING_CONFIG_LDAP.get(ne.getMessage()), ne)); 956 } 957 } 958 959 private ConnectionHandlerDescriptor getConnectionHandler(ConnectionHandlerCfgClient connHandler, String name) 960 throws OpenDsException 961 { 962 SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 963 ConnectionHandlerDescriptor.State state = connHandler.isEnabled() ? ConnectionHandlerDescriptor.State.ENABLED 964 : ConnectionHandlerDescriptor.State.DISABLED; 965 966 ConnectionHandlerDescriptor.Protocol protocol; 967 int port; 968 if (connHandler instanceof LDAPConnectionHandlerCfgClient) 969 { 970 LDAPConnectionHandlerCfgClient ldap = (LDAPConnectionHandlerCfgClient)connHandler; 971 if (ldap.isUseSSL()) 972 { 973 protocol = ConnectionHandlerDescriptor.Protocol.LDAPS; 974 } 975 else if (ldap.isAllowStartTLS()) 976 { 977 protocol = ConnectionHandlerDescriptor.Protocol.LDAP_STARTTLS; 978 } 979 else 980 { 981 protocol = ConnectionHandlerDescriptor.Protocol.LDAP; 982 } 983 addAll(addresses, ldap.getListenAddress()); 984 port = ldap.getListenPort(); 985 } 986 else if (connHandler instanceof HTTPConnectionHandlerCfgClient) 987 { 988 HTTPConnectionHandlerCfgClient http = (HTTPConnectionHandlerCfgClient) connHandler; 989 if (http.isUseSSL()) 990 { 991 protocol = ConnectionHandlerDescriptor.Protocol.HTTPS; 992 } 993 else 994 { 995 protocol = ConnectionHandlerDescriptor.Protocol.HTTP; 996 } 997 addAll(addresses, http.getListenAddress()); 998 port = http.getListenPort(); 999 } 1000 else if (connHandler instanceof JMXConnectionHandlerCfgClient) 1001 { 1002 JMXConnectionHandlerCfgClient jmx = (JMXConnectionHandlerCfgClient)connHandler; 1003 if (jmx.isUseSSL()) 1004 { 1005 protocol = ConnectionHandlerDescriptor.Protocol.JMXS; 1006 } 1007 else 1008 { 1009 protocol = ConnectionHandlerDescriptor.Protocol.JMX; 1010 } 1011 addresses.add(jmx.getListenAddress()); 1012 port = jmx.getListenPort(); 1013 } 1014 else if (connHandler instanceof LDIFConnectionHandlerCfgClient) 1015 { 1016 protocol = ConnectionHandlerDescriptor.Protocol.LDIF; 1017 port = -1; 1018 } 1019 else if (connHandler instanceof SNMPConnectionHandlerCfgClient) 1020 { 1021 protocol = ConnectionHandlerDescriptor.Protocol.SNMP; 1022 SNMPConnectionHandlerCfgClient snmp = (SNMPConnectionHandlerCfgClient)connHandler; 1023 addAll(addresses, snmp.getListenAddress()); 1024 port = snmp.getListenPort(); 1025 } 1026 else 1027 { 1028 protocol = ConnectionHandlerDescriptor.Protocol.OTHER; 1029 port = -1; 1030 } 1031 Set<CustomSearchResult> emptySet = Collections.emptySet(); 1032 return new ConnectionHandlerDescriptor(addresses, port, protocol, state, name, emptySet); 1033 } 1034 1035 private <T> void addAll(Collection<T> target, Collection<T> source) 1036 { 1037 if (source != null) 1038 { 1039 target.addAll(source); 1040 } 1041 } 1042 1043 private ConnectionHandlerDescriptor getConnectionHandler(AdministrationConnectorCfgClient adminConnector) 1044 throws OpenDsException 1045 { 1046 SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 1047 1048 ConnectionHandlerDescriptor.Protocol protocol = ConnectionHandlerDescriptor.Protocol.ADMINISTRATION_CONNECTOR; 1049 ConnectionHandlerDescriptor.State state = ConnectionHandlerDescriptor.State.ENABLED; 1050 1051 addAll(addresses, adminConnector.getListenAddress()); 1052 int port = adminConnector.getListenPort(); 1053 1054 Set<CustomSearchResult> emptySet = Collections.emptySet(); 1055 return new ConnectionHandlerDescriptor( 1056 addresses, port, protocol, state, INFO_CTRL_PANEL_CONN_HANDLER_ADMINISTRATION.get().toString(), emptySet); 1057 } 1058 1059 private boolean isRootMonitor(CustomSearchResult csr) throws OpenDsException 1060 { 1061 return monitorDN.equals(DN.valueOf(csr.getDN())); 1062 } 1063 1064 private boolean isVersionMonitor(CustomSearchResult csr) throws OpenDsException 1065 { 1066 return versionDN.equals(DN.valueOf(csr.getDN())); 1067 } 1068 1069 private boolean isSystemInformation(CustomSearchResult csr) throws OpenDsException 1070 { 1071 return systemInformationDN.equals(DN.valueOf(csr.getDN())); 1072 } 1073 1074 private boolean isJvmMemoryUsage(CustomSearchResult csr) throws OpenDsException 1075 { 1076 return jvmMemoryUsageDN.equals(DN.valueOf(csr.getDN())); 1077 } 1078 1079 private boolean isWorkQueue(CustomSearchResult csr) throws OpenDsException 1080 { 1081 return workQueueDN.equals(DN.valueOf(csr.getDN())); 1082 } 1083 1084 private boolean isEntryCaches(CustomSearchResult csr) throws OpenDsException 1085 { 1086 return entryCachesDN.equals(DN.valueOf(csr.getDN())); 1087 } 1088 1089 private boolean isConnectionHandler(CustomSearchResult csr) throws OpenDsException 1090 { 1091 DN dn = DN.valueOf(csr.getDN()); 1092 DN parent = dn.parent(); 1093 if (parent != null && parent.equals(monitorDN)) 1094 { 1095 List<?> vs = csr.getAttributeValues("cn"); 1096 if (vs != null && !vs.isEmpty()) 1097 { 1098 String cn = (String) vs.iterator().next(); 1099 String statistics = " Statistics"; 1100 if (cn.endsWith(statistics)) 1101 { 1102 return true; 1103 } 1104 } 1105 } 1106 return false; 1107 } 1108 1109 private static boolean isTaskEntry(CustomSearchResult csr) throws OpenDsException 1110 { 1111 List<Object> vs = csr.getAttributeValues("objectclass"); 1112 if (vs != null && !vs.isEmpty()) 1113 { 1114 for (Object oc : vs) 1115 { 1116 if (oc.toString().equalsIgnoreCase("ds-task")) 1117 { 1118 return true; 1119 } 1120 } 1121 } 1122 return false; 1123 } 1124 1125 /** 1126 * Commodity method to get the string representation to be used in the hash 1127 * maps as key. 1128 * 1129 * @param value 1130 * the value to be transformed into a key for a hash map. 1131 * @return the string representation to be used in the hash maps as key. 1132 */ 1133 private String getKey(String value) 1134 { 1135 return value.toLowerCase(); 1136 } 1137 1138 private Set<CustomSearchResult>getMonitoringEntries(ConnectionHandlerDescriptor ch) 1139 { 1140 Set<CustomSearchResult> monitorEntries = new HashSet<>(); 1141 if (ch.getState() == ConnectionHandlerDescriptor.State.ENABLED) 1142 { 1143 for (String key : hmConnectionHandlersMonitor.keySet()) 1144 { 1145 // The name of the connection handler does not appear necessarily in the 1146 // key (which is based on the DN of the monitoring entry). In general 1147 // the DN contains the String specified in 1148 // LDAPConnectionHandler.DEFAULT_FRIENDLY_NAME, so we have to check that 1149 // this connection handler is the right one. 1150 // See org.opends.server.protocols.ldap.LDAPConnectionHandler to see 1151 // how the DN of the monitoring entry is generated. 1152 if (key.contains(getKey("port " + ch.getPort())) 1153 && hasAllAddresses(ch, key)) 1154 { 1155 monitorEntries.add(hmConnectionHandlersMonitor.get(key)); 1156 } 1157 } 1158 } 1159 1160 return monitorEntries; 1161 } 1162 1163 private boolean hasAllAddresses(ConnectionHandlerDescriptor ch, String key) 1164 { 1165 for (InetAddress a : ch.getAddresses()) 1166 { 1167 if (!key.contains(getKey(a.getHostAddress()))) 1168 { 1169 return false; 1170 } 1171 } 1172 return true; 1173 } 1174}