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