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