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 2006-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.backends;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.forgerock.opendj.ldap.DN;
023
024/** Configuration for the indexType rebuild process. */
025public class RebuildConfig
026{
027  /** Identifies how indexes will be selected for rebuild. */
028  public static enum RebuildMode
029  {
030    /** Rebuild all indexes, including system indexes. */
031    ALL,
032    /** Rebuild all degraded indexes, including system indexes. */
033    DEGRADED,
034    /** Rebuild used defined list of indexes. */
035    USER_DEFINED;
036  }
037
038  /** The base DN to rebuild. */
039  private DN baseDN;
040  private RebuildMode rebuildMode = RebuildMode.USER_DEFINED;
041  /** The names of indexes to rebuild. */
042  private final List<String> rebuildList = new ArrayList<>();
043  private String tmpDirectory;
044  private boolean isClearDegradedState;
045
046  /**
047   * Get the base DN to rebuild.
048   *
049   * @return The base DN to rebuild.
050   */
051  public DN getBaseDN()
052  {
053    return baseDN;
054  }
055
056  /**
057   * Set the base DN to rebuild.
058   *
059   * @param baseDN
060   *          The base DN to rebuild.
061   */
062  public void setBaseDN(DN baseDN)
063  {
064    this.baseDN = baseDN;
065  }
066
067  /**
068   * Get the list of indexes to rebuild in this configuration.
069   *
070   * @return The list of indexes to rebuild.
071   */
072  public List<String> getRebuildList()
073  {
074    return rebuildList;
075  }
076
077  /**
078   * Add an index to be rebuilt into the configuration. Duplicate index names
079   * will be ignored. Adding an index that causes a mix of complete and partial
080   * rebuild for the same attribute index in the configuration will remove the
081   * partial and just keep the complete attribute index name. (ie. uid and
082   * uid.presence).
083   *
084   * @param index
085   *          The index to add.
086   */
087  public void addRebuildIndex(String index)
088  {
089    final String[] newIndexParts = index.split("\\.");
090    for (String s : new ArrayList<String>(rebuildList))
091    {
092      final String[] existingIndexParts = s.split("\\.");
093      if (newIndexParts[0].equalsIgnoreCase(existingIndexParts[0]))
094      {
095        if (newIndexParts.length == 1 && existingIndexParts.length > 1)
096        {
097          rebuildList.remove(s);
098        }
099        else if ((newIndexParts.length == 1 && existingIndexParts.length == 1)
100            || (newIndexParts.length > 1 && existingIndexParts.length == 1)
101            || newIndexParts[1].equalsIgnoreCase(existingIndexParts[1]))
102        {
103          return;
104        }
105      }
106    }
107
108    this.rebuildList.add(index);
109  }
110
111  /**
112   * Check the given config for conflicts with this config. A conflict is
113   * detected if both configs specify the same indexType/database to be rebuilt.
114   *
115   * @param config
116   *          The rebuild config to check against.
117   * @return the name of the indexType causing the conflict or null if no
118   *         conflict is detected.
119   */
120  public String checkConflicts(RebuildConfig config)
121  {
122    //If they specify different base DNs, no conflicts can occur.
123    if (this.baseDN.equals(config.baseDN))
124    {
125      for (String thisIndex : this.rebuildList)
126      {
127        for (String thatIndex : config.rebuildList)
128        {
129          String[] existingIndexParts = thisIndex.split("\\.");
130          String[] newIndexParts = thatIndex.split("\\.");
131          if (newIndexParts[0].equalsIgnoreCase(existingIndexParts[0]))
132          {
133            if ((newIndexParts.length == 1 && existingIndexParts.length >= 1)
134                || (newIndexParts.length > 1 && existingIndexParts.length == 1)
135                || newIndexParts[1].equalsIgnoreCase(existingIndexParts[1]))
136            {
137              return thatIndex;
138            }
139          }
140        }
141      }
142    }
143
144    return null;
145  }
146
147  /**
148   * Test if this rebuild config includes any system indexes to rebuild.
149   *
150   * @return True if rebuilding of system indexes are included. False otherwise.
151   */
152  public boolean includesSystemIndex()
153  {
154    for (String index : rebuildList)
155    {
156      // id2entry is not A system index, it is THE primary system index.
157      // It cannot be rebuilt.
158      if ("dn2id".equalsIgnoreCase(index) || "dn2uri".equalsIgnoreCase(index))
159      {
160        return true;
161      }
162    }
163    return false;
164  }
165
166  /**
167   * Set the temporary directory to the specified path.
168   *
169   * @param path
170   *          The path to set the temporary directory to.
171   */
172  public void setTmpDirectory(String path)
173  {
174    tmpDirectory = path;
175  }
176
177  /**
178   * Return the temporary directory path.
179   *
180   * @return The temporary directory string.
181   */
182  public String getTmpDirectory()
183  {
184    return tmpDirectory;
185  }
186
187  /**
188   * Sets the rebuild mode.
189   *
190   * @param mode
191   *          The new rebuild mode.
192   */
193  public void setRebuildMode(RebuildMode mode)
194  {
195    rebuildMode = mode;
196  }
197
198  /**
199   * Returns the rebuild mode.
200   *
201   * @return The rebuild mode.
202   */
203  public RebuildMode getRebuildMode()
204  {
205    return rebuildMode;
206  }
207
208  /**
209   * Returns {@code true} if indexes should be forcefully marked as valid even
210   * if they are currently degraded.
211   *
212   * @return {@code true} if index should be forcefully marked as valid.
213   */
214  public boolean isClearDegradedState()
215  {
216    return isClearDegradedState;
217  }
218
219  /**
220   * Sets the 'clear degraded index' status.
221   *
222   * @param isClearDegradedState
223   *          {@code true} if indexes should be forcefully marked as valid even
224   *          if they are currently degraded.
225   */
226  public void isClearDegradedState(boolean isClearDegradedState)
227  {
228    this.isClearDegradedState = isClearDegradedState;
229  }
230
231}