001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2008-2011 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS. 026 */ 027package org.opends.guitools.controlpanel.util; 028 029import static org.opends.messages.AdminToolMessages.*; 030import static org.opends.server.backends.pluggable.SuffixContainer.*; 031 032import java.net.InetAddress; 033import java.util.ArrayList; 034import java.util.Collection; 035import java.util.Collections; 036import java.util.HashSet; 037import java.util.List; 038import java.util.Set; 039import java.util.SortedSet; 040import java.util.TreeSet; 041 042import org.forgerock.i18n.LocalizableMessage; 043import org.forgerock.i18n.slf4j.LocalizedLogger; 044import org.forgerock.opendj.config.server.ConfigException; 045import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 046import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 047import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; 048import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; 049import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 050import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; 051import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor; 052import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 053import org.opends.guitools.controlpanel.datamodel.VLVSortOrder; 054import org.opends.guitools.controlpanel.task.OfflineUpdateException; 055import org.opends.server.admin.server.ServerManagementContext; 056import org.opends.server.admin.std.server.AdministrationConnectorCfg; 057import org.opends.server.admin.std.server.BackendCfg; 058import org.opends.server.admin.std.server.BackendIndexCfg; 059import org.opends.server.admin.std.server.BackendVLVIndexCfg; 060import org.opends.server.admin.std.server.BackupBackendCfg; 061import org.opends.server.admin.std.server.ConnectionHandlerCfg; 062import org.opends.server.admin.std.server.HTTPConnectionHandlerCfg; 063import org.opends.server.admin.std.server.JMXConnectionHandlerCfg; 064import org.opends.server.admin.std.server.LDAPConnectionHandlerCfg; 065import org.opends.server.admin.std.server.LDIFBackendCfg; 066import org.opends.server.admin.std.server.LDIFConnectionHandlerCfg; 067import org.opends.server.admin.std.server.MemoryBackendCfg; 068import org.opends.server.admin.std.server.MonitorBackendCfg; 069import org.opends.server.admin.std.server.PluggableBackendCfg; 070import org.opends.server.admin.std.server.ReplicationDomainCfg; 071import org.opends.server.admin.std.server.ReplicationServerCfg; 072import org.opends.server.admin.std.server.ReplicationSynchronizationProviderCfg; 073import org.opends.server.admin.std.server.RootCfg; 074import org.opends.server.admin.std.server.RootDNCfg; 075import org.opends.server.admin.std.server.RootDNUserCfg; 076import org.opends.server.admin.std.server.SNMPConnectionHandlerCfg; 077import org.opends.server.admin.std.server.TaskBackendCfg; 078import org.opends.server.core.DirectoryServer; 079import org.opends.server.types.DN; 080import org.opends.server.types.OpenDsException; 081 082/** 083 * A class that reads the configuration information from the files. 084 */ 085public class ConfigFromFile extends ConfigReader 086{ 087 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 088 089 /** 090 * Creates a new instance of this config file handler. No initialization 091 * should be performed here, as all of that work should be done in the 092 * <CODE>initializeConfigHandler</CODE> method. 093 */ 094 public ConfigFromFile() 095 { 096 super(); 097 } 098 099 /** 100 * Reads configuration information from the configuration files. 101 */ 102 public void readConfiguration() 103 { 104 final List<OpenDsException> errors = new ArrayList<>(); 105 final Set<ConnectionHandlerDescriptor> connectionHandlers = new HashSet<>(); 106 final Set<BackendDescriptor> backendDescriptors = new HashSet<>(); 107 final Set<DN> alternateBindDNs = new HashSet<>(); 108 try 109 { 110 DirectoryServer.getInstance().initializeConfiguration(); 111 112 readSchemaIfNeeded(errors); 113 readConfig(connectionHandlers, backendDescriptors, alternateBindDNs, errors); 114 } 115 catch (final OpenDsException oe) 116 { 117 errors.add(oe); 118 } 119 catch (final Throwable t) 120 { 121 logger.warn(LocalizableMessage.raw("Error reading configuration: " + t, t)); 122 errors.add(new OfflineUpdateException(ERR_READING_CONFIG_LDAP.get(t.getMessage()), t)); 123 } 124 125 if (!errors.isEmpty() && environmentSettingException != null) 126 { 127 errors.add(0, environmentSettingException); 128 } 129 130 for (final OpenDsException oe : errors) 131 { 132 logger.warn(LocalizableMessage.raw("Error reading configuration: " + oe, oe)); 133 } 134 exceptions = Collections.unmodifiableList(errors); 135 administrativeUsers = Collections.unmodifiableSet(alternateBindDNs); 136 listeners = Collections.unmodifiableSet(connectionHandlers); 137 backends = Collections.unmodifiableSet(backendDescriptors); 138 } 139 140 private void readSchemaIfNeeded(final List<OpenDsException> errors) throws ConfigException 141 { 142 if (mustReadSchema()) 143 { 144 try 145 { 146 readSchema(); 147 if (getSchema() != null) 148 { 149 // Update the schema: so that when we call the server code the 150 // latest schema read on the server we are managing is used. 151 DirectoryServer.setSchema(getSchema()); 152 } 153 } 154 catch (final OpenDsException oe) 155 { 156 errors.add(oe); 157 } 158 } 159 } 160 161 private void readConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, 162 final Set<BackendDescriptor> backendDescriptors, final Set<DN> alternateBindDNs, 163 final List<OpenDsException> errors) throws OpenDsException, ConfigException 164 { 165 // Get the Directory Server configuration handler and use it. 166 final RootCfg root = ServerManagementContext.getInstance().getRootConfiguration(); 167 readAdminConnector(root, errors); 168 readConnectionHandlers(connectionHandlers, root, errors); 169 isSchemaEnabled = root.getGlobalConfiguration().isCheckSchema(); 170 171 readBackendConfiguration(backendDescriptors, root, errors); 172 boolean isReplicationSecure = readIfReplicationIsSecure(root, errors); 173 ReplicationSynchronizationProviderCfg sync = readSyncProviderIfExists(root); 174 if (sync != null) 175 { 176 readReplicationConfig(connectionHandlers, backendDescriptors, sync, isReplicationSecure, errors); 177 } 178 readAlternateBindDNs(alternateBindDNs, root, errors); 179 } 180 181 private void readAdminConnector(final RootCfg root, final List<OpenDsException> errors) throws OpenDsException 182 { 183 try 184 { 185 final AdministrationConnectorCfg adminConnector = root.getAdministrationConnector(); 186 this.adminConnector = getConnectionHandler(adminConnector); 187 } 188 catch (final ConfigException ce) 189 { 190 errors.add(toConfigException(ce)); 191 } 192 } 193 194 private void readConnectionHandlers(final Set<ConnectionHandlerDescriptor> connectionHandlers, final RootCfg root, 195 final List<OpenDsException> errors) throws ConfigException 196 { 197 for (final String connHandler : root.listConnectionHandlers()) 198 { 199 try 200 { 201 final ConnectionHandlerCfg connectionHandler = root.getConnectionHandler(connHandler); 202 connectionHandlers.add(getConnectionHandler(connectionHandler, connHandler)); 203 } 204 catch (final OpenDsException oe) 205 { 206 errors.add(oe); 207 } 208 } 209 } 210 211 private void readBackendConfiguration(final Set<BackendDescriptor> backendDescriptors, final RootCfg root, 212 final List<OpenDsException> errors) 213 { 214 for (final String backendName : root.listBackends()) 215 { 216 try 217 { 218 final BackendCfg backend = root.getBackend(backendName); 219 final Set<BaseDNDescriptor> baseDNs = new HashSet<>(); 220 for (final DN dn : backend.getBaseDN()) 221 { 222 final BaseDNDescriptor baseDN = 223 new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED, dn, null, -1, -1, -1); 224 baseDNs.add(baseDN); 225 } 226 final Set<IndexDescriptor> indexes = new HashSet<>(); 227 final Set<VLVIndexDescriptor> vlvIndexes = new HashSet<>(); 228 BackendDescriptor.Type type = getBackendType(backend); 229 if (type == BackendDescriptor.Type.PLUGGABLE) 230 { 231 refreshBackendConfig(indexes, vlvIndexes, backend, errors); 232 } 233 234 final BackendDescriptor desc = 235 new BackendDescriptor(backend.getBackendId(), baseDNs, indexes, vlvIndexes, -1, backend.isEnabled(), type); 236 for (final AbstractIndexDescriptor index : indexes) 237 { 238 index.setBackend(desc); 239 } 240 for (final AbstractIndexDescriptor index : vlvIndexes) 241 { 242 index.setBackend(desc); 243 } 244 245 backendDescriptors.add(desc); 246 } 247 catch (final ConfigException ce) 248 { 249 errors.add(toConfigException(ce)); 250 } 251 } 252 } 253 254 private BackendDescriptor.Type getBackendType(final BackendCfg backend) 255 { 256 if (backend instanceof PluggableBackendCfg) 257 { 258 return BackendDescriptor.Type.PLUGGABLE; 259 } 260 else if (backend instanceof LDIFBackendCfg) 261 { 262 return BackendDescriptor.Type.LDIF; 263 } 264 else if (backend instanceof MemoryBackendCfg) 265 { 266 return BackendDescriptor.Type.MEMORY; 267 } 268 else if (backend instanceof BackupBackendCfg) 269 { 270 return BackendDescriptor.Type.BACKUP; 271 } 272 else if (backend instanceof MonitorBackendCfg) 273 { 274 return BackendDescriptor.Type.MONITOR; 275 } 276 else if (backend instanceof TaskBackendCfg) 277 { 278 return BackendDescriptor.Type.TASK; 279 } 280 else 281 { 282 return BackendDescriptor.Type.OTHER; 283 } 284 } 285 286 private void refreshBackendConfig(final Set<IndexDescriptor> indexes, 287 final Set<VLVIndexDescriptor> vlvIndexes, final BackendCfg backend, final List<OpenDsException> errors) 288 { 289 final PluggableBackendCfg db = (PluggableBackendCfg) backend; 290 readBackendIndexes(indexes, errors, db); 291 readBackendVLVIndexes(vlvIndexes, errors, db); 292 } 293 294 private void readBackendIndexes(final Set<IndexDescriptor> indexes, final List<OpenDsException> errors, 295 final PluggableBackendCfg db) 296 { 297 indexes.add(new IndexDescriptor(DN2ID_INDEX_NAME)); 298 indexes.add(new IndexDescriptor(ID2CHILDREN_COUNT_NAME)); 299 try 300 { 301 for (final String indexName : db.listBackendIndexes()) 302 { 303 final BackendIndexCfg index = db.getBackendIndex(indexName); 304 indexes.add(new IndexDescriptor( 305 index.getAttribute().getNameOrOID(), index.getAttribute(), 306 null, IndexTypeDescriptor.fromBackendIndexTypes(index.getIndexType()), index.getIndexEntryLimit())); 307 } 308 } 309 catch (ConfigException ce) 310 { 311 errors.add(toConfigException(ce)); 312 } 313 } 314 315 private void readBackendVLVIndexes(final Set<VLVIndexDescriptor> vlvIndexes, 316 final List<OpenDsException> errors, final PluggableBackendCfg db) 317 { 318 try 319 { 320 for (final String vlvIndexName : db.listBackendVLVIndexes()) 321 { 322 final BackendVLVIndexCfg index = db.getBackendVLVIndex(vlvIndexName); 323 final List<VLVSortOrder> sortOrder = getVLVSortOrder(index.getSortOrder()); 324 vlvIndexes.add(new VLVIndexDescriptor( 325 index.getName(), null, index.getBaseDN(), VLVIndexDescriptor.toSearchScope(index.getScope()), 326 index.getFilter(), sortOrder)); 327 } 328 } 329 catch (ConfigException ce) 330 { 331 errors.add(toConfigException(ce)); 332 } 333 } 334 335 private boolean readIfReplicationIsSecure(final RootCfg root, final List<OpenDsException> errors) 336 { 337 try 338 { 339 return root.getCryptoManager().isSSLEncryption(); 340 } 341 catch (final ConfigException ce) 342 { 343 errors.add(toConfigException(ce)); 344 return false; 345 } 346 } 347 348 private ReplicationSynchronizationProviderCfg readSyncProviderIfExists(final RootCfg root) 349 { 350 replicationPort = -1; 351 try 352 { 353 return (ReplicationSynchronizationProviderCfg) root.getSynchronizationProvider("Multimaster Synchronization"); 354 } 355 catch (final ConfigException ce) 356 { 357 // Ignore this one 358 return null; 359 } 360 } 361 362 private void readReplicationConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, 363 final Set<BackendDescriptor> backendDescriptors, ReplicationSynchronizationProviderCfg sync, 364 boolean isReplicationSecure, final List<OpenDsException> errors) 365 { 366 try 367 { 368 if (sync.isEnabled() && sync.hasReplicationServer()) 369 { 370 final ReplicationServerCfg replicationServer = sync.getReplicationServer(); 371 if (replicationServer != null) 372 { 373 replicationPort = replicationServer.getReplicationPort(); 374 final ConnectionHandlerDescriptor.Protocol protocol = 375 isReplicationSecure ? ConnectionHandlerDescriptor.Protocol.REPLICATION_SECURE 376 : ConnectionHandlerDescriptor.Protocol.REPLICATION; 377 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 378 final ConnectionHandlerDescriptor connHandler = 379 new ConnectionHandlerDescriptor(new HashSet<InetAddress>(), replicationPort, protocol, 380 ConnectionHandlerDescriptor.State.ENABLED, "Multimaster Synchronization", emptySet); 381 connectionHandlers.add(connHandler); 382 } 383 } 384 final String[] domains = sync.listReplicationDomains(); 385 if (domains != null) 386 { 387 for (final String domain2 : domains) 388 { 389 final ReplicationDomainCfg domain = sync.getReplicationDomain(domain2); 390 final DN dn = domain.getBaseDN(); 391 for (final BackendDescriptor backend : backendDescriptors) 392 { 393 for (final BaseDNDescriptor baseDN : backend.getBaseDns()) 394 { 395 if (baseDN.getDn().equals(dn)) 396 { 397 baseDN 398 .setType(sync.isEnabled() ? BaseDNDescriptor.Type.REPLICATED : BaseDNDescriptor.Type.DISABLED); 399 baseDN.setReplicaID(domain.getServerId()); 400 } 401 } 402 } 403 } 404 } 405 } 406 catch (final ConfigException ce) 407 { 408 errors.add(toConfigException(ce)); 409 } 410 } 411 412 private void readAlternateBindDNs(final Set<DN> dns, final RootCfg root, final List<OpenDsException> errors) 413 { 414 try 415 { 416 final RootDNCfg rootDN = root.getRootDN(); 417 final String[] rootUsers = rootDN.listRootDNUsers(); 418 dns.clear(); 419 if (rootUsers != null) 420 { 421 for (final String rootUser2 : rootUsers) 422 { 423 final RootDNUserCfg rootUser = rootDN.getRootDNUser(rootUser2); 424 dns.addAll(rootUser.getAlternateBindDN()); 425 } 426 } 427 } 428 catch (final ConfigException ce) 429 { 430 errors.add(toConfigException(ce)); 431 } 432 } 433 434 private org.opends.server.config.ConfigException toConfigException(final ConfigException ce) 435 { 436 return new org.opends.server.config.ConfigException(ce.getMessageObject(), ce); 437 } 438 439 private ConnectionHandlerDescriptor getConnectionHandler(final ConnectionHandlerCfg connHandler, final String name) 440 throws OpenDsException 441 { 442 final SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 443 444 final ConnectionHandlerDescriptor.State state = 445 connHandler.isEnabled() ? ConnectionHandlerDescriptor.State.ENABLED 446 : ConnectionHandlerDescriptor.State.DISABLED; 447 448 ConnectionHandlerDescriptor.Protocol protocol; 449 int port; 450 if (connHandler instanceof LDAPConnectionHandlerCfg) 451 { 452 final LDAPConnectionHandlerCfg ldap = (LDAPConnectionHandlerCfg) connHandler; 453 if (ldap.isUseSSL()) 454 { 455 protocol = ConnectionHandlerDescriptor.Protocol.LDAPS; 456 } 457 else if (ldap.isAllowStartTLS()) 458 { 459 protocol = ConnectionHandlerDescriptor.Protocol.LDAP_STARTTLS; 460 } 461 else 462 { 463 protocol = ConnectionHandlerDescriptor.Protocol.LDAP; 464 } 465 addAll(addresses, ldap.getListenAddress()); 466 port = ldap.getListenPort(); 467 } 468 else if (connHandler instanceof HTTPConnectionHandlerCfg) 469 { 470 final HTTPConnectionHandlerCfg http = (HTTPConnectionHandlerCfg) connHandler; 471 if (http.isUseSSL()) 472 { 473 protocol = ConnectionHandlerDescriptor.Protocol.HTTPS; 474 } 475 else 476 { 477 protocol = ConnectionHandlerDescriptor.Protocol.HTTP; 478 } 479 addAll(addresses, http.getListenAddress()); 480 port = http.getListenPort(); 481 } 482 else if (connHandler instanceof JMXConnectionHandlerCfg) 483 { 484 final JMXConnectionHandlerCfg jmx = (JMXConnectionHandlerCfg) connHandler; 485 if (jmx.isUseSSL()) 486 { 487 protocol = ConnectionHandlerDescriptor.Protocol.JMXS; 488 } 489 else 490 { 491 protocol = ConnectionHandlerDescriptor.Protocol.JMX; 492 } 493 addresses.add(jmx.getListenAddress()); 494 port = jmx.getListenPort(); 495 } 496 else if (connHandler instanceof LDIFConnectionHandlerCfg) 497 { 498 protocol = ConnectionHandlerDescriptor.Protocol.LDIF; 499 port = -1; 500 } 501 else if (connHandler instanceof SNMPConnectionHandlerCfg) 502 { 503 protocol = ConnectionHandlerDescriptor.Protocol.SNMP; 504 final SNMPConnectionHandlerCfg snmp = (SNMPConnectionHandlerCfg) connHandler; 505 addAll(addresses, snmp.getListenAddress()); 506 port = snmp.getListenPort(); 507 } 508 else 509 { 510 protocol = ConnectionHandlerDescriptor.Protocol.OTHER; 511 port = -1; 512 } 513 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 514 return new ConnectionHandlerDescriptor(addresses, port, protocol, state, name, emptySet); 515 } 516 517 private <T> void addAll(final Collection<T> target, final Collection<T> source) 518 { 519 if (source != null) 520 { 521 target.addAll(source); 522 } 523 } 524 525 private ConnectionHandlerDescriptor getConnectionHandler(final AdministrationConnectorCfg adminConnector) 526 throws OpenDsException 527 { 528 final SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 529 530 final ConnectionHandlerDescriptor.Protocol protocol = ConnectionHandlerDescriptor.Protocol.ADMINISTRATION_CONNECTOR; 531 final ConnectionHandlerDescriptor.State state = ConnectionHandlerDescriptor.State.ENABLED; 532 533 addAll(addresses, adminConnector.getListenAddress()); 534 final int port = adminConnector.getListenPort(); 535 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 536 return new ConnectionHandlerDescriptor(addresses, port, protocol, state, 537 INFO_CTRL_PANEL_CONN_HANDLER_ADMINISTRATION.get().toString(), emptySet); 538 } 539}