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