mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gaetan Boismal
24.53.2015 688633f95faa52515b090ff00440b1eebdaad7d9
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
@@ -22,10 +22,16 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2014 ForgeRock AS
 *      Portions Copyright 2014-2015 ForgeRock AS
 */
package org.opends.guitools.controlpanel.datamodel;
import static org.opends.admin.ads.util.ConnectionUtils.*;
import static org.opends.guitools.controlpanel.util.Utilities.*;
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.util.OperatingSystem.*;
import java.io.File;
import java.net.InetAddress;
import java.util.Collection;
@@ -40,6 +46,8 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.ConfigurationFramework;
import org.forgerock.opendj.config.server.ConfigException;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.guitools.controlpanel.browser.IconPool;
@@ -64,12 +72,6 @@
import com.forgerock.opendj.cli.CliConstants;
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.util.OperatingSystem.*;
import static org.opends.admin.ads.util.ConnectionUtils.*;
import static org.opends.guitools.controlpanel.util.Utilities.*;
/**
 * This is the classes that is shared among all the different places in the
 * Control Panel.  It contains information about the server status and
@@ -1343,4 +1345,26 @@
    }
    return connectionWorks;
  }
  /**
   * Initialize the new configuration framework if needed.
   *
   * @throws org.opends.server.config.ConfigException
   *           If error occurred during the initialization
   */
  public void initializeConfigurationFramework() throws org.opends.server.config.ConfigException
  {
    if (!ConfigurationFramework.getInstance().isInitialized())
    {
      try
      {
        ConfigurationFramework.getInstance().initialize();
      }
      catch (ConfigException ce)
      {
        throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce);
      }
    }
  }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java
@@ -26,6 +26,7 @@
package org.opends.guitools.controlpanel.datamodel;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -33,7 +34,10 @@
import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
/** Defines the set of values for the index type. */
/**
 * Defines the set of values for the index type and provides adaptors to convert
 * from/to corresponding configuration classes.
 */
@RemoveOnceLocalDBBackendIsPluggable
public enum IndexTypeDescriptor
{
@@ -41,49 +45,64 @@
   * This index type is used to improve the efficiency of searches using
   * approximate matching search filters.
   */
  APPROXIMATE("approximate"),
  APPROXIMATE(LocalDBIndexCfgDefn.IndexType.APPROXIMATE, BackendIndexCfgDefn.IndexType.APPROXIMATE,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.APPROXIMATE,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.APPROXIMATE),
  /**
   * This index type is used to improve the efficiency of searches using
   * equality search filters.
   */
  EQUALITY("equality"),
  EQUALITY(LocalDBIndexCfgDefn.IndexType.EQUALITY, BackendIndexCfgDefn.IndexType.EQUALITY,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.EQUALITY,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.EQUALITY),
  /**
   * This index type is used to improve the efficiency of searches using
   * extensible matching search filters.
   */
  EXTENSIBLE("extensible"),
  EXTENSIBLE(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE, BackendIndexCfgDefn.IndexType.EXTENSIBLE,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.EXTENSIBLE,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.EXTENSIBLE),
  /**
   * This index type is used to improve the efficiency of searches using
   * "greater than or equal to" or "less then or equal to" search filters.
   */
  ORDERING("ordering"),
  ORDERING(LocalDBIndexCfgDefn.IndexType.ORDERING, BackendIndexCfgDefn.IndexType.ORDERING,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.ORDERING,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.ORDERING),
  /**
   * This index type is used to improve the efficiency of searches using the
   * presence search filters.
   */
  PRESENCE("presence"),
  PRESENCE(LocalDBIndexCfgDefn.IndexType.PRESENCE, BackendIndexCfgDefn.IndexType.PRESENCE,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.PRESENCE,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.PRESENCE),
  /**
   * This index type is used to improve the efficiency of searches using
   * substring search filters.
   */
  SUBSTRING("substring");
  SUBSTRING(LocalDBIndexCfgDefn.IndexType.SUBSTRING, BackendIndexCfgDefn.IndexType.SUBSTRING,
      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.SUBSTRING,
      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.SUBSTRING);
  private final String name;
  private final LocalDBIndexCfgDefn.IndexType oldConfigLocalDBIndexType;
  private final BackendIndexCfgDefn.IndexType oldConfigBackendIndexType;
  private final org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType localDBIndexType;
  private final org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType backendIndexType;
  private IndexTypeDescriptor(final String name)
  private IndexTypeDescriptor(final LocalDBIndexCfgDefn.IndexType oldConfigLocalDBIndexType,
      final BackendIndexCfgDefn.IndexType oldConfigBackendIndexType,
      final org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType localDBIndexType,
      final org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType backendIndexType)
  {
    this.name = name;
  }
  @Override
  public String toString()
  {
    return name;
    this.oldConfigLocalDBIndexType = oldConfigLocalDBIndexType;
    this.oldConfigBackendIndexType = oldConfigBackendIndexType;
    this.localDBIndexType = localDBIndexType;
    this.backendIndexType = backendIndexType;
  }
  /**
@@ -95,23 +114,7 @@
   */
  public BackendIndexCfgDefn.IndexType toBackendIndexType()
  {
    switch (this)
    {
    case APPROXIMATE:
      return BackendIndexCfgDefn.IndexType.APPROXIMATE;
    case EQUALITY:
      return BackendIndexCfgDefn.IndexType.EQUALITY;
    case EXTENSIBLE:
      return BackendIndexCfgDefn.IndexType.EXTENSIBLE;
    case ORDERING:
      return BackendIndexCfgDefn.IndexType.ORDERING;
    case PRESENCE:
      return BackendIndexCfgDefn.IndexType.PRESENCE;
    case SUBSTRING:
      return BackendIndexCfgDefn.IndexType.SUBSTRING;
    default:
      throw new IllegalArgumentException("No BackendIndexCfgDefn.IndexType corresponding to: " + this);
    }
    return oldConfigBackendIndexType;
  }
  /**
@@ -123,23 +126,7 @@
   */
  public LocalDBIndexCfgDefn.IndexType toLocalDBIndexType()
  {
    switch (this)
    {
    case APPROXIMATE:
      return LocalDBIndexCfgDefn.IndexType.APPROXIMATE;
    case EQUALITY:
      return LocalDBIndexCfgDefn.IndexType.EQUALITY;
    case EXTENSIBLE:
      return LocalDBIndexCfgDefn.IndexType.EXTENSIBLE;
    case ORDERING:
      return LocalDBIndexCfgDefn.IndexType.ORDERING;
    case PRESENCE:
      return LocalDBIndexCfgDefn.IndexType.PRESENCE;
    case SUBSTRING:
      return LocalDBIndexCfgDefn.IndexType.SUBSTRING;
    default:
      throw new IllegalArgumentException("No LocalDBIndexCfgDefn.IndexType corresponding to: " + this);
    }
    return oldConfigLocalDBIndexType;
  }
  private static IndexTypeDescriptor fromBackendIndexType(final BackendIndexCfgDefn.IndexType indexType)
@@ -262,4 +249,51 @@
    return indexTypes;
  }
  /**
   * Convert the provided {@code Set<IndexTypeDescriptor>} to a
   * {@code Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>}.
   *
   * @param indexTypeDescriptors
   *          A set of {@code Set<IndexTypeDescriptor>}
   * @return A set of
   *         {@code Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>}
   *         corresponding to the provided {@code Set<IndexTypeDescriptor>}
   */
  @RemoveOnceLocalDBBackendIsPluggable
  public static Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType> toNewConfigLocalDBIndexTypes(
      final Set<IndexTypeDescriptor> indexTypeDescriptors)
  {
    final Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType> newConfigIndexTypes =
        new HashSet<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>();
    for (IndexTypeDescriptor indexType : indexTypeDescriptors)
    {
      newConfigIndexTypes.add(indexType.localDBIndexType);
    }
    return newConfigIndexTypes;
  }
  /**
   * Convert the provided {@code Set<IndexTypeDescriptor>} to a
   * {@code Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>}.
   *
   * @param indexTypeDescriptors
   *          A set of {@code Set<IndexTypeDescriptor>}
   * @return A set of
   *         {@code Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>}
   *         corresponding to the provided {@code Set<IndexTypeDescriptor>}
   */
  public static Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType> toNewConfigBackendIndexTypes(
      final Set<IndexTypeDescriptor> indexTypeDescriptors)
  {
    final Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType> newConfigIndexTypes =
        new HashSet<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>();
    for (IndexTypeDescriptor indexType : indexTypeDescriptors)
    {
      newConfigIndexTypes.add(indexType.backendIndexType);
    }
    return newConfigIndexTypes;
  }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java
@@ -31,8 +31,10 @@
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -45,12 +47,27 @@
import javax.swing.JTextField;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.config.LDAPProfile;
import org.forgerock.opendj.config.PropertyException;
import org.forgerock.opendj.config.client.ManagementContext;
import org.forgerock.opendj.config.client.ldap.LDAPManagementContext;
import org.forgerock.opendj.server.config.client.BackendCfgClient;
import org.forgerock.opendj.server.config.client.BackendIndexCfgClient;
import org.forgerock.opendj.server.config.client.LocalDBBackendCfgClient;
import org.forgerock.opendj.server.config.client.LocalDBIndexCfgClient;
import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient;
import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn;
import org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn;
import org.opends.guitools.controlpanel.datamodel.IndexDescriptor;
import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor;
import org.opends.guitools.controlpanel.ui.components.TitlePanel;
import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.quicksetup.Installation;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.config.ConfigException;
import org.opends.server.types.AttributeType;
import org.opends.server.types.OpenDsException;
/**
 * Abstract class used to refactor some code between the classes that are used
@@ -353,4 +370,94 @@
    return errors;
  }
  void createIndexOffline(final String backendName, final String attributeName,
      final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit) throws OpenDsException
  {
    updateIndexOffline(backendName, null, attributeName, indexTypes, indexEntryLimit);
  }
  void modifyIndexOffline(final String backendName, final String attributeName, final IndexDescriptor indexToModify,
      final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit) throws OpenDsException
  {
    updateIndexOffline(backendName, indexToModify, attributeName, indexTypes, indexEntryLimit);
  }
  private void updateIndexOffline(final String backendName, final IndexDescriptor indexToModify,
      final String attributeName, final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit)
      throws OpenDsException
  {
    getInfo().initializeConfigurationFramework();
    try
    {
      final List<IOException> exceptions = new ArrayList<>();
      final ManagementContext context = LDAPManagementContext.newLDIFManagementContext(
              Installation.getLocal().getCurrentConfigurationFile(), LDAPProfile.getInstance(), exceptions);
      Utilities.throwFirstFrom(exceptions);
      final BackendCfgClient backend = context.getRootConfiguration().getBackend(backendName);
      if (backend instanceof LocalDBBackendCfgClient)
      {
        updateLocalDBIndexOffline(
            (LocalDBBackendCfgClient) backend, indexToModify, attributeName, indexTypes, indexEntryLimit);
      }
      else
      {
        updateBackendIndexOnline(
            (PluggableBackendCfgClient) backend, indexToModify, attributeName, indexTypes, indexEntryLimit);
      }
      context.close();
    }
    catch (final Exception e)
    {
      throw new ConfigException(LocalizableMessage.raw(e.getMessage(), e));
    }
  }
  private void updateBackendIndexOnline(final PluggableBackendCfgClient backend,
      final IndexDescriptor indexToModify, final String attributeName, final Set<IndexTypeDescriptor> indexTypes,
      final int indexEntryLimit) throws Exception
  {
    final boolean isCreation = indexToModify == null;
    final List<PropertyException> exceptions = new ArrayList<>();
    final BackendIndexCfgClient index = isCreation
        ? backend.createBackendIndex(BackendIndexCfgDefn.getInstance(), attributeName, exceptions)
        : backend.getBackendIndex(attributeName);
    if (isCreation || indexTypes.equals(indexToModify.getTypes()))
    {
      index.setIndexType(IndexTypeDescriptor.toNewConfigBackendIndexTypes(indexTypes));
    }
    if (indexEntryLimit != index.getIndexEntryLimit())
    {
      index.setIndexEntryLimit(indexEntryLimit);
    }
    index.commit();
    Utilities.throwFirstFrom(exceptions);
 }
  @RemoveOnceLocalDBBackendIsPluggable
  private void updateLocalDBIndexOffline(final LocalDBBackendCfgClient backend, final IndexDescriptor indexToModify,
      final String attributeName, final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit)
      throws Exception
  {
    final boolean isCreation = indexToModify == null;
    final List<PropertyException> exceptions = new ArrayList<>();
    final LocalDBIndexCfgClient index = isCreation
        ? backend.createLocalDBIndex(LocalDBIndexCfgDefn.getInstance(), attributeName, exceptions)
        : backend.getLocalDBIndex(attributeName);
    if (isCreation || indexTypes.equals(indexToModify.getTypes()))
    {
      index.setIndexType(IndexTypeDescriptor.toNewConfigLocalDBIndexTypes(indexTypes));
    }
    if (indexEntryLimit != index.getIndexEntryLimit())
    {
      index.setIndexEntryLimit(indexEntryLimit);
    }
    index.commit();
    Utilities.throwFirstFrom(exceptions);
  }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java
@@ -35,8 +35,6 @@
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -58,7 +56,7 @@
import javax.swing.event.DocumentListener;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor;
import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
import org.opends.guitools.controlpanel.datamodel.IndexDescriptor;
@@ -67,26 +65,22 @@
import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener;
import org.opends.guitools.controlpanel.task.DeleteIndexTask;
import org.opends.guitools.controlpanel.task.OfflineUpdateException;
import org.opends.guitools.controlpanel.task.Task;
import org.opends.guitools.controlpanel.util.ConfigReader;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.BackendCfgClient;
import org.opends.server.admin.std.client.BackendIndexCfgClient;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.LocalDBIndexCfgClient;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.client.PluggableBackendCfgClient;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.OpenDsException;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.ServerConstants;
import com.forgerock.opendj.cli.CommandBuilder;
/**
 * The panel that displays an existing index (it appears on the right of the
@@ -95,6 +89,8 @@
public class IndexPanel extends AbstractIndexPanel
{
  private static final long serialVersionUID = 1439500626486823366L;
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  private IndexDescriptor index;
  private ScrollPaneBorderListener scrollListener;
@@ -612,13 +608,11 @@
        if (isServerRunning())
        {
          // Create additional indexes and display the equivalent command.
          // Everything is done in the method createAdditionalIndexes
          modifyIndex(getInfo().getDirContext());
          modifyIndexOnline(getInfo().getDirContext());
        }
        else
        {
          modifyIndex();
          modifyIndexOffline(backendName, attributeName, indexToModify, indexTypes, entryLimitValue);
        }
        SwingUtilities.invokeLater(new Runnable()
@@ -641,66 +635,6 @@
    }
    /**
     * Returns the LDIF representation of the modified index.
     *
     * @return the LDIF representation of the modified index.
     */
    private String getIndexLDIF()
    {
      final String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName) + ",cn=Backends,cn=config";
      final List<String> lines = new ArrayList<String>();
      lines.add("dn: " + Utilities.getRDNString("ds-cfg-attribute", attributeName) + ",cn=Index,"+dn);
      lines.add("objectClass: ds-cfg-local-db-index");
      lines.add("objectClass: top");
      lines.add("ds-cfg-attribute: " + attributeName);
      lines.add("ds-cfg-index-entry-limit: " + entryLimitValue);
      for (IndexTypeDescriptor type : indexTypes)
      {
        lines.add("ds-cfg-index-type: " + type.toLocalDBIndexType());
      }
      final StringBuilder sb = new StringBuilder();
      for (final String line : lines)
      {
        sb.append(line)
          .append(ServerConstants.EOL);
      }
      return sb.toString();
    }
    private void modifyIndex() throws OpenDsException
    {
      LDIFImportConfig ldifImportConfig = null;
      try
      {
        String ldif = getIndexLDIF();
        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
        LDIFReader reader = new LDIFReader(ldifImportConfig);
        Entry newConfigEntry = reader.readEntry();
        Entry oldEntry = DirectoryServer.getConfigEntry(newConfigEntry.getName()).getEntry();
        DirectoryServer.getConfigHandler().replaceEntry(oldEntry, newConfigEntry, null);
        DirectoryServer.getConfigHandler().writeUpdatedConfig();
      }
      catch (IOException ioe)
      {
        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
      }
      catch (ConfigException ce)
      {
        throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce);
      }
      finally
      {
        if (ldifImportConfig != null)
        {
          ldifImportConfig.close();
        }
      }
    }
    /**
     * Modifies index using the provided connection.
     *
     * @param ctx
@@ -708,24 +642,42 @@
     * @throws OpenDsException
     *           if there is an error updating the server.
     */
    private void modifyIndex(InitialLdapContext ctx) throws OpenDsException
    private void modifyIndexOnline(final InitialLdapContext ctx) throws OpenDsException
    {
      final StringBuilder sb = new StringBuilder();
      sb.append(getConfigCommandLineName());
      Collection<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
      for (String arg : args)
      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      final BackendCfgClient backend = mCtx.getRootConfiguration().getBackend(backendName);
      if (backend instanceof LocalDBBackendCfgClient)
      {
        sb.append(" ").append(CommandBuilder.escapeValue(arg));
        modifyLocalDBIndexOnline((LocalDBBackendCfgClient) backend);
        return;
      }
      modifyBackendIndexOnline((PluggableBackendCfgClient) backend);
    }
    private void modifyBackendIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
    {
      final BackendIndexCfgClient index = backend.getBackendIndex(attributeName);
      if (!indexTypes.equals(indexToModify.getTypes()))
      {
        index.setIndexType(IndexTypeDescriptor.toBackendIndexTypes(indexTypes));
      }
      ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      LocalDBBackendCfgClient backend = (LocalDBBackendCfgClient) root.getBackend(backendName);
      LocalDBIndexCfgClient index = backend.getLocalDBIndex(attributeName);
      if (entryLimitValue != index.getIndexEntryLimit())
      {
        index.setIndexEntryLimit(entryLimitValue);
      }
      index.commit();
    }
    @RemoveOnceLocalDBBackendIsPluggable
    private void modifyLocalDBIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
    {
      final LocalDBIndexCfgClient index = backend.getLocalDBIndex(attributeName);
      if (!indexTypes.equals(indexToModify.getTypes()))
      {
        index.setIndexType(IndexTypeDescriptor.toLocalDBIndexTypes(indexTypes));
      }
      if (entryLimitValue != index.getIndexEntryLimit())
      {
        index.setIndexEntryLimit(entryLimitValue);
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java
@@ -32,8 +32,6 @@
import java.awt.GridBagConstraints;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -43,16 +41,12 @@
import java.util.SortedSet;
import java.util.TreeSet;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.InitialLdapContext;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.SwingUtilities;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -60,23 +54,26 @@
import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor;
import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
import org.opends.guitools.controlpanel.task.OfflineUpdateException;
import org.opends.guitools.controlpanel.task.OnlineUpdateException;
import org.opends.guitools.controlpanel.task.Task;
import org.opends.guitools.controlpanel.util.ConfigReader;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.BackendCfgClient;
import org.opends.server.admin.std.client.BackendIndexCfgClient;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.LocalDBIndexCfgClient;
import org.opends.server.admin.std.client.PluggableBackendCfgClient;
import org.opends.server.admin.std.meta.BackendIndexCfgDefn;
import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.Schema;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.ServerConstants;
import com.forgerock.opendj.cli.CommandBuilder;
/**
 * Panel that appears when the user defines a new index.
@@ -450,15 +447,14 @@
                INFO_CTRL_PANEL_CREATING_NEW_INDEX_PROGRESS.get(attributeName), ColorAndFontConstants.progressFont));
          }
        });
        if (isServerRunning())
        {
          // Create additional indexes and display the equivalent command.
          // Everything is done in the method createAdditionalIndexes
          createIndex(getInfo().getDirContext());
          createIndexOnline(getInfo().getDirContext());
        }
        else
        {
          createIndex();
          createIndexOffline(backendName.getText(), attributeName, indexTypes, entryLimitValue);
        }
        SwingUtilities.invokeLater(new Runnable()
        {
@@ -479,115 +475,45 @@
      }
    }
    /**
     * Returns the LDIF representation of the index to be created.
     *
     * @return the LDIF representation of the index to be created.
     */
    private String getIndexLDIF()
    private void createIndexOnline(final InitialLdapContext ctx) throws OpenDsException
    {
      String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName.getText()) + ",cn=Backends,cn=config";
      ArrayList<String> lines = new ArrayList<>();
      lines.add("dn: " + Utilities.getRDNString("ds-cfg-attribute", attributeName) + ",cn=Index," + dn);
      lines.add("objectClass: ds-cfg-local-db-index");
      lines.add("objectClass: top");
      lines.add("ds-cfg-attribute: " + attributeName);
      lines.add("ds-cfg-index-entry-limit: " + entryLimitValue);
      for (IndexTypeDescriptor type : indexTypes)
      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      final BackendCfgClient backend = mCtx.getRootConfiguration().getBackend(backendName.getText());
      if (backend instanceof LocalDBBackendCfgClient)
      {
        lines.add("ds-cfg-index-type: " + type.toLocalDBIndexType());
        createLocalDBIndexOnline((LocalDBBackendCfgClient) backend);
        return;
      }
      StringBuilder sb = new StringBuilder();
      for (String line : lines)
      {
        sb.append(line).append(ServerConstants.EOL);
      }
      return sb.toString();
      createBackendIndexOnline((PluggableBackendCfgClient) backend);
    }
    private void createIndex() throws OpenDsException
    private void createBackendIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
    {
      LDIFImportConfig ldifImportConfig = null;
      try
      final List<PropertyException> exceptions = new ArrayList<>();
      final BackendIndexCfgClient index = backend.createBackendIndex(
          BackendIndexCfgDefn.getInstance(), attributeName, exceptions);
      index.setIndexType(IndexTypeDescriptor.toBackendIndexTypes(indexTypes));
      if (entryLimitValue != index.getIndexEntryLimit())
      {
        String ldif = getIndexLDIF();
        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
        LDIFReader reader = new LDIFReader(ldifImportConfig);
        Entry backendConfigEntry;
        while ((backendConfigEntry = reader.readEntry()) != null)
        {
          DirectoryServer.getConfigHandler().addEntry(backendConfigEntry, null);
        }
        DirectoryServer.getConfigHandler().writeUpdatedConfig();
        index.setIndexEntryLimit(entryLimitValue);
      }
      catch (IOException ioe)
      {
        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
      }
      finally
      {
        if (ldifImportConfig != null)
        {
          ldifImportConfig.close();
        }
      }
      index.commit();
      Utilities.throwFirstFrom(exceptions);
    }
    private void createIndex(final InitialLdapContext ctx) throws OpenDsException
    @RemoveOnceLocalDBBackendIsPluggable
    private void createLocalDBIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
    {
      // Instead of adding indexes using management framework, use this approach
      // so that we have to define the additional indexes only in the method
      // getBackendLdif.
      String ldif = getIndexLDIF();
      LDIFImportConfig ldifImportConfig = null;
      try
      final List<PropertyException> exceptions = new ArrayList<>();
      final LocalDBIndexCfgClient index = backend.createLocalDBIndex(
          LocalDBIndexCfgDefn.getInstance(), backendName.getText(), exceptions);
      index.setIndexType(IndexTypeDescriptor.toLocalDBIndexTypes(indexTypes));
      if (entryLimitValue != index.getIndexEntryLimit())
      {
        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
        LDIFReader reader = new LDIFReader(ldifImportConfig);
        Entry indexEntry = reader.readEntry();
        Attributes attrs = new BasicAttributes();
        BasicAttribute oc = new BasicAttribute("objectClass");
        for (ByteString bs : indexEntry.getObjectClassAttribute())
        {
          oc.add(bs.toString());
        }
        attrs.put(oc);
        List<Attribute> odsAttrs = indexEntry.getAttributes();
        for (Attribute odsAttr : odsAttrs)
        {
          String attrName = odsAttr.getName();
          BasicAttribute attr = new BasicAttribute(attrName);
          for (ByteString bs : odsAttr)
          {
            attr.add(bs.toString());
          }
          attrs.put(attr);
        }
        final StringBuilder sb = new StringBuilder();
        sb.append(getConfigCommandLineName());
        Collection<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
        for (String arg : args)
        {
          sb.append(" ").append(CommandBuilder.escapeValue(arg));
        }
        ctx.createSubcontext(indexEntry.getName().toString(), attrs);
        index.setIndexEntryLimit(entryLimitValue);
      }
      catch (Throwable t)
      {
        throw new OnlineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(t), t);
      }
      finally
      {
        if (ldifImportConfig != null)
        {
          ldifImportConfig.close();
        }
      }
      index.commit();
      Utilities.throwFirstFrom(exceptions);
    }
    @Override
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
@@ -2891,4 +2891,23 @@
    return null;
  }
  /**
   * Throw the first exception of the list (if any).
   *
   * @param <E>
   *          The exception type
   * @param exceptions
   *          A list of exceptions.
   * @throws E
   *           The first element of the provided list (if the list is not
   *           empty).
   */
  public static <E extends Exception> void throwFirstFrom(List<? extends E> exceptions) throws E
  {
    if (!exceptions.isEmpty())
    {
      throw exceptions.get(0);
    }
  }
}