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 2015 ForgeRock AS
025 */
026package org.opends.server.tools;
027
028import java.io.File;
029import java.util.Collection;
030import java.util.LinkedList;
031import java.util.List;
032
033import org.forgerock.opendj.config.LDAPProfile;
034import org.forgerock.opendj.config.ManagedObjectDefinition;
035import org.forgerock.opendj.config.client.ManagementContext;
036import org.forgerock.opendj.config.client.ldap.LDAPManagementContext;
037import org.forgerock.opendj.ldap.DN;
038import org.forgerock.opendj.server.config.client.BackendCfgClient;
039import org.forgerock.opendj.server.config.client.BackendIndexCfgClient;
040import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient;
041import org.forgerock.opendj.server.config.client.RootCfgClient;
042import org.forgerock.opendj.server.config.meta.BackendCfgDefn.WritabilityMode;
043import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn;
044import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType;
045import org.forgerock.opendj.server.config.server.BackendCfg;
046import org.opends.guitools.controlpanel.util.Utilities;
047import org.opends.quicksetup.Installation;
048
049/** Utility class which can be used by tools to create a new backend with default indexes. */
050public class BackendCreationHelper
051{
052  /** Describes an attribute index which should be created during installation. */
053  public static final class DefaultIndex
054  {
055    static DefaultIndex withEqualityAndSubstring(final String name)
056    {
057      return new DefaultIndex(name, true);
058    }
059
060    static DefaultIndex withEquality(final String name)
061    {
062      return new DefaultIndex(name, false);
063    }
064
065    private final String name;
066    private final boolean shouldCreateSubstringIndex;
067
068    private DefaultIndex(final String name, final boolean substringIndex)
069    {
070      this.name = name;
071      this.shouldCreateSubstringIndex = substringIndex;
072    }
073
074    /**
075     * Return the name of this default index.
076     *
077     * @return The name of this default index
078     */
079    public String getName()
080    {
081      return name;
082    }
083
084    /**
085     * Return {@code true} if the substring index type should be enabled for
086     * this index.
087     *
088     * @return {@code true} if the substring index type should be enabled for
089     *         this index.
090     */
091    public boolean shouldCreateSubstringIndex()
092    {
093      return shouldCreateSubstringIndex;
094    }
095  }
096
097  /** Default indexes to add in a new backend. */
098  public static final DefaultIndex[] DEFAULT_INDEXES = {
099    DefaultIndex.withEqualityAndSubstring("cn"),
100    DefaultIndex.withEqualityAndSubstring("givenName"),
101    DefaultIndex.withEqualityAndSubstring("mail"),
102    DefaultIndex.withEqualityAndSubstring("sn"),
103    DefaultIndex.withEqualityAndSubstring("telephoneNumber"),
104    DefaultIndex.withEquality("member"),
105    DefaultIndex.withEquality("uid"),
106    DefaultIndex.withEquality("uniqueMember")
107  };
108
109  /**
110   * Add a new backend with the provided name in the config.ldif file.
111   *
112   * @param backendName
113   *          The new backend name
114   * @param baseDNs
115   *          The base dns to add in the new backend.
116   * @param backendType
117   *          The backend type
118   * @throws Exception
119   *           If any problems occurred
120   */
121  public static void createBackendOffline(String backendName, Collection<DN> baseDNs,
122      ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType) throws Exception
123  {
124    Utilities.initializeConfigurationFramework();
125    final File configFile = Installation.getLocal().getCurrentConfigurationFile();
126    final LDAPProfile ldapProfile = LDAPProfile.getInstance();
127    try (ManagementContext context = LDAPManagementContext.newLDIFManagementContext(configFile, ldapProfile))
128    {
129      createBackend(context.getRootConfiguration(), backendName, baseDNs, backendType);
130    }
131  }
132
133  /**
134   * Create a backend with the provided name using the provided
135   * {@code RootCfgClient}.
136   *
137   * @param rootConfiguration
138   *          The root configuration to use to create the new backend
139   * @param backendName
140   *          The new backend name
141   * @param baseDNs
142   *          The base dns to add in the new backend.
143   * @param backendType
144   *          The backend type
145   * @throws Exception
146   *           If any problems occurred
147   */
148  public static void createBackend(RootCfgClient rootConfiguration, String backendName, Collection<DN> baseDNs,
149      ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType) throws Exception
150  {
151      final BackendCfgClient backendCfgClient = rootConfiguration.createBackend(backendType, backendName, null);
152      backendCfgClient.setEnabled(true);
153      backendCfgClient.setBaseDN(baseDNs);
154      backendCfgClient.setWritabilityMode(WritabilityMode.ENABLED);
155      backendCfgClient.commit();
156
157      addBackendDefaultIndexes((PluggableBackendCfgClient) backendCfgClient);
158  }
159
160  private static void addBackendDefaultIndexes(PluggableBackendCfgClient backendCfgClient) throws Exception
161  {
162    for (DefaultIndex defaultIndex : DEFAULT_INDEXES)
163    {
164      final BackendIndexCfgClient index =
165          backendCfgClient.createBackendIndex(BackendIndexCfgDefn.getInstance(), defaultIndex.name, null);
166
167      final List<IndexType> indexTypes = new LinkedList<>();
168      indexTypes.add(IndexType.EQUALITY);
169      if (defaultIndex.shouldCreateSubstringIndex)
170      {
171        indexTypes.add(IndexType.SUBSTRING);
172      }
173      index.setIndexType(indexTypes);
174
175      index.commit();
176    }
177  }
178}