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