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-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.util;
018
019import static org.opends.messages.AdminToolMessages.*;
020
021import java.io.File;
022import java.net.InetAddress;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.Comparator;
026import java.util.List;
027import java.util.Set;
028import java.util.logging.Logger;
029
030import org.forgerock.i18n.LocalizableMessage;
031import org.forgerock.i18n.slf4j.LocalizedLogger;
032import org.forgerock.opendj.config.server.ConfigException;
033import org.forgerock.opendj.ldap.DN;
034import org.forgerock.opendj.server.config.meta.AdministrationConnectorCfgDefn;
035import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
036import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor;
037import org.opends.guitools.controlpanel.datamodel.VLVSortOrder;
038import org.opends.guitools.controlpanel.task.OfflineUpdateException;
039import org.opends.server.core.DirectoryServer;
040import org.opends.server.tools.tasks.TaskEntry;
041import org.opends.server.types.DirectoryEnvironmentConfig;
042import org.opends.server.types.DirectoryException;
043import org.opends.server.types.InitializationException;
044import org.opends.server.types.OpenDsException;
045import org.opends.server.types.Schema;
046
047/**
048 * An abstract class providing some common interface for the class that read
049 * the configuration (and if the server is running, the monitoring information).
050 */
051public abstract class ConfigReader
052{
053  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
054  /**
055   * The configuration file full path (-INSTANCE_ROOT-/config/config.ldif).
056   * of the installation of the control panel.
057   */
058  public static String configFile;
059
060  /** The error that occurred when setting the environment (null if no error occurred). */
061  protected static OpenDsException environmentSettingException;
062  static
063  {
064    // This allows testing of configuration components when the OpenDS.jar
065    // in the classpath does not necessarily point to the server's
066    // This is done here since both implementations of ConfigReader require it.
067    String installRoot = System.getProperty("org.opends.quicksetup.Root");
068    if (installRoot == null) {
069      installRoot = Utilities.getServerRootDirectory().getAbsolutePath();
070    }
071    String instanceRoot =
072      Utilities.getInstanceRootDirectory(installRoot).getAbsolutePath();
073    configFile = instanceRoot + File.separator + "config" + File.separator +
074    "config.ldif";
075    try
076    {
077      DirectoryEnvironmentConfig env = DirectoryServer.getEnvironmentConfig();
078      env.setServerRoot(new File(installRoot));
079      DirectoryServer instance = DirectoryServer.getInstance();
080      DirectoryServer.bootstrapClient();
081      DirectoryServer.initializeJMX();
082      // Initialize configuration framework without logging anything.
083      final Logger configFrameworkLogger = Logger.getLogger("com.forgerock.opendj.ldap.config.config");
084      configFrameworkLogger.setUseParentHandlers(false);
085      instance.initializeConfiguration(configFile);
086      configFrameworkLogger.setUseParentHandlers(true);
087      instance.initializeSchema();
088    }
089    catch (Throwable t)
090    {
091      environmentSettingException = new OfflineUpdateException(
092          ERR_CTRL_PANEL_SETTING_ENVIRONMENT.get(t.getMessage()), t);
093    }
094    logger.info(LocalizableMessage.raw("Environment initialized."));
095  }
096
097  /** The exceptions that occurred reading the configuration. */
098  protected List<Exception> exceptions = Collections.emptyList();
099
100  /** Whether the configuration has already been read or not. */
101  private boolean configRead;
102
103  /** The set of connection listeners. */
104  protected Set<ConnectionHandlerDescriptor> listeners = Collections.emptySet();
105  /** The administration connector. */
106  protected ConnectionHandlerDescriptor adminConnector;
107
108  /** The set of backend descriptors. */
109  protected Set<BackendDescriptor> backends = Collections.emptySet();
110  /** The set of administrative users. */
111  protected Set<DN> administrativeUsers = Collections.emptySet();
112
113  /** The replication serve port (-1 if the replication server port is not defined). */
114  protected int replicationPort = -1;
115  /** The java version used to run the server. */
116  protected String javaVersion;
117
118  /** The number of connections opened on the server. */
119  protected int numberConnections;
120
121  /** Whether the schema checking is enabled or not. */
122  protected boolean isSchemaEnabled;
123  /** The schema used by the server. */
124  protected Schema schema;
125
126  /** The task entries. */
127  protected Set<TaskEntry> taskEntries = Collections.emptySet();
128
129  /**
130   * Returns the Administrative User DNs found in the config.ldif.  The set
131   * must be unmodifiable (the inheriting classes must take care of this).
132   * @return the Administrative User DNs found in the config.ldif.
133   */
134  public Set<DN> getAdministrativeUsers()
135  {
136    return administrativeUsers;
137  }
138
139  /**
140   * Returns the backend descriptors found in the config.ldif.  The set
141   * must be unmodifiable (the inheriting classes must take care of this).
142   * @return the backend descriptors found in the config.ldif.
143   */
144  public Set<BackendDescriptor> getBackends()
145  {
146    return backends;
147  }
148
149  /**
150   * Returns the listener descriptors found in the config.ldif.  The set
151   * must be unmodifiable (the inheriting classes must take care of this).
152   * @return the listeners descriptors found in the config.ldif.
153   */
154  public Set<ConnectionHandlerDescriptor> getConnectionHandlers()
155  {
156    return listeners;
157  }
158
159  /**
160   * Returns the admin connector.
161   * @return the admin connector.
162   */
163  public ConnectionHandlerDescriptor getAdminConnector()
164  {
165    return adminConnector;
166  }
167
168  /**
169   * Returns the list of exceptions that were encountered reading the
170   * configuration.  The list must be unmodifiable (the inheriting classes must
171   * take care of this).
172   * @return the list of exceptions that were encountered reading the
173   * configuration.
174   */
175  public List<Exception> getExceptions()
176  {
177    return exceptions;
178  }
179
180  /**
181   * Returns <CODE>true</CODE> if the configuration has been read at least once
182   * and <CODE>false</CODE> otherwise.
183   * @return <CODE>true</CODE> if the configuration has been read at least once
184   * and <CODE>false</CODE> otherwise.
185   */
186  public boolean isConfigRead()
187  {
188    return configRead;
189  }
190
191  /**
192   * Returns the replication server port. -1 if no replication server port is
193   * defined.
194   * @return the replication server port. -1 if no replication server port is
195   * defined.
196   */
197  public int getReplicationPort()
198  {
199    return replicationPort;
200  }
201
202  /**
203   * Returns <CODE>true</CODE> if the schema check is enabled and
204   * <CODE>false</CODE> otherwise.
205   * @return <CODE>true</CODE> if the schema check is enabled and
206   * <CODE>false</CODE> otherwise.
207   */
208  public boolean isSchemaEnabled()
209  {
210    return isSchemaEnabled;
211  }
212
213  /**
214   * Returns the java version used to run the server. <CODE>null</CODE> if no
215   * java version is used (because the server is down).
216   * @return the java version used to run the server. <CODE>null</CODE> if no
217   * java version is used (because the server is down).
218   */
219  public String getJavaVersion()
220  {
221    return javaVersion;
222  }
223
224  /**
225   * Returns the number of open connections on the server.   -1 if the server
226   * is down.
227   * @return the number of open connections on the server.
228   */
229  public int getOpenConnections()
230  {
231    return numberConnections;
232  }
233
234  /**
235   * Returns the schema of the server.
236   * @return the schema of the server.
237   */
238  public Schema getSchema()
239  {
240    return schema;
241  }
242
243  /**
244   * Returns the task entries.
245   * @return the task entries.
246   */
247  public Set<TaskEntry> getTaskEntries()
248  {
249    return taskEntries;
250  }
251
252  /**
253   * Reads the schema from the files.
254   * @throws ConfigException if an error occurs reading the schema.
255   * @throws InitializationException if an error occurs initializing
256   * configuration to read schema.
257   * @throws DirectoryException if there is an error registering the minimal
258   * objectclasses.
259   */
260  protected void readSchema() throws ConfigException, InitializationException,
261  DirectoryException
262  {
263    SchemaLoader loader = new SchemaLoader();
264    loader.readSchema();
265    schema = loader.getSchema();
266  }
267
268  /**
269   * Method that transforms the VLV sort order value as it is defined in the
270   * schema to a list of VLVSortOrder objects.
271   * @param s the string in the configuration.
272   * @return  a list of VLVSortOrder objects.
273   */
274  protected List<VLVSortOrder> getVLVSortOrder(String s)
275  {
276    ArrayList<VLVSortOrder> sortOrder = new ArrayList<>();
277    if (s != null)
278    {
279      String[] attrNames = s.split(" ");
280      for (String attrName : attrNames)
281      {
282        if (attrName.startsWith("+"))
283        {
284          sortOrder.add(new VLVSortOrder(attrName.substring(1), true));
285        }
286        else if (attrName.startsWith("-"))
287        {
288          sortOrder.add(new VLVSortOrder(attrName.substring(1), false));
289        }
290        else
291        {
292          sortOrder.add(new VLVSortOrder(attrName, true));
293        }
294      }
295    }
296    return sortOrder;
297  }
298
299  /**
300   * Returns the comparator to be used to sort InetAddresses.
301   * @return the comparator to be used to sort InetAddresses.
302   */
303  protected Comparator<InetAddress> getInetAddressComparator()
304  {
305    return AdministrationConnectorCfgDefn.getInstance().
306    getListenAddressPropertyDefinition();
307  }
308
309  /**
310   * Returns <CODE>true</CODE> if the schema must be read and
311   * <CODE>false</CODE> otherwise.
312   * @return <CODE>true</CODE> if the schema must be read and
313   * <CODE>false</CODE> otherwise.
314   */
315  protected boolean mustReadSchema()
316  {
317    return true;
318  }
319}