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 2008-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2012-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.task; 018 019import static org.opends.messages.AdminToolMessages.*; 020 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.HashSet; 024import java.util.List; 025import java.util.Set; 026import java.util.SortedSet; 027import java.util.TreeSet; 028 029import javax.swing.SwingUtilities; 030 031import org.forgerock.i18n.LocalizableMessage; 032import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 033import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 034import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 035import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; 036import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 037import org.opends.guitools.controlpanel.ui.ProgressDialog; 038import org.opends.guitools.controlpanel.util.Utilities; 039import org.opends.server.backends.pluggable.SuffixContainer; 040import org.opends.server.tools.RebuildIndex; 041 042/** 043 * The class that is used when a set of indexes must be rebuilt. 044 */ 045public class RebuildIndexTask extends IndexTask 046{ 047 private final SortedSet<AbstractIndexDescriptor> indexes = new TreeSet<>(); 048 049 /** 050 * The indexes that must not be specified in the command-line. 051 */ 052 public static final String[] INDEXES_NOT_TO_SPECIFY = { SuffixContainer.ID2CHILDREN_INDEX_NAME, 053 SuffixContainer.ID2SUBTREE_INDEX_NAME, SuffixContainer.ID2CHILDREN_COUNT_NAME }; 054 055 /** 056 * Constructor of the task. 057 * 058 * @param info 059 * the control panel information. 060 * @param dlg 061 * the progress dialog where the task progress will be displayed. 062 * @param baseDNs 063 * the baseDNs corresponding to the indexes. 064 * @param indexes 065 * the indexes. 066 */ 067 public RebuildIndexTask(ControlPanelInfo info, ProgressDialog dlg, Collection<String> baseDNs, 068 SortedSet<AbstractIndexDescriptor> indexes) 069 { 070 super(info, dlg, baseDNs); 071 this.indexes.addAll(indexes); 072 } 073 074 @Override 075 public Type getType() 076 { 077 return Type.REBUILD_INDEXES; 078 } 079 080 @Override 081 public LocalizableMessage getTaskDescription() 082 { 083 if (baseDNs.size() == 1) 084 { 085 return INFO_CTRL_PANEL_REBUILD_INDEX_TASK_DESCRIPTION.get(baseDNs.iterator().next()); 086 } 087 else 088 { 089 // Assume is in a backend 090 return INFO_CTRL_PANEL_REBUILD_INDEX_TASK_DESCRIPTION.get(backendSet.iterator().next()); 091 } 092 } 093 094 @Override 095 public boolean canLaunch(Task taskToBeLaunched, Collection<LocalizableMessage> incompatibilityReasons) 096 { 097 boolean canLaunch = true; 098 if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched)) 099 { 100 // All the operations are incompatible if they apply to this backend. 101 Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends()); 102 backends.retainAll(getBackends()); 103 if (!backends.isEmpty()) 104 { 105 incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); 106 canLaunch = false; 107 } 108 } 109 return canLaunch; 110 } 111 112 @Override 113 public void runTask() 114 { 115 state = State.RUNNING; 116 lastException = null; 117 try 118 { 119 boolean isLocal = getInfo().getServerDescriptor().isLocal(); 120 121 for (final String baseDN : baseDNs) 122 { 123 List<String> arguments = getCommandLineArguments(baseDN); 124 String[] args = arguments.toArray(new String[arguments.size()]); 125 126 final List<String> displayArgs = getObfuscatedCommandLineArguments(getCommandLineArguments(baseDN)); 127 displayArgs.removeAll(getConfigCommandLineArguments()); 128 129 SwingUtilities.invokeLater(new Runnable() 130 { 131 @Override 132 public void run() 133 { 134 printEquivalentCommandLine(getCommandLinePath("rebuild-index"), displayArgs, 135 INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_REBUILD_INDEX.get(baseDN)); 136 } 137 }); 138 139 if (isLocal && !isServerRunning()) 140 { 141 returnCode = executeCommandLine(getCommandLinePath("rebuild-index"), args); 142 } 143 else 144 { 145 returnCode = RebuildIndex.mainRebuildIndex(args, false, outPrintStream, errorPrintStream); 146 } 147 148 if (returnCode != 0) 149 { 150 break; 151 } 152 } 153 154 if (returnCode != 0) 155 { 156 state = State.FINISHED_WITH_ERROR; 157 } 158 else 159 { 160 for (AbstractIndexDescriptor index : indexes) 161 { 162 getInfo().unregisterModifiedIndex(index); 163 } 164 165 state = State.FINISHED_SUCCESSFULLY; 166 } 167 } 168 catch (Throwable t) 169 { 170 lastException = t; 171 state = State.FINISHED_WITH_ERROR; 172 } 173 } 174 175 @Override 176 protected List<String> getCommandLineArguments() 177 { 178 return new ArrayList<>(); 179 } 180 181 /** 182 * Returns the command line arguments required to rebuild the indexes in the 183 * specified base DN. 184 * 185 * @param baseDN 186 * the base DN. 187 * @return the command line arguments required to rebuild the indexes in the 188 * specified base DN. 189 */ 190 private List<String> getCommandLineArguments(String baseDN) 191 { 192 List<String> args = new ArrayList<>(); 193 194 args.add("--baseDN"); 195 args.add(baseDN); 196 197 if (rebuildAll()) 198 { 199 args.add("--rebuildAll"); 200 } 201 else 202 { 203 for (AbstractIndexDescriptor index : indexes) 204 { 205 args.add("--index"); 206 if (index instanceof VLVIndexDescriptor) 207 { 208 args.add(Utilities.getVLVNameInCommandLine((VLVIndexDescriptor) index)); 209 } 210 else 211 { 212 args.add(index.getName()); 213 } 214 } 215 } 216 217 boolean isLocal = getInfo().getServerDescriptor().isLocal(); 218 if (isLocal && isServerRunning()) 219 { 220 args.addAll(getConnectionCommandLineArguments()); 221 args.addAll(getConfigCommandLineArguments()); 222 } 223 224 return args; 225 } 226 227 @Override 228 protected String getCommandLinePath() 229 { 230 return null; 231 } 232 233 private boolean rebuildAll() 234 { 235 Set<BackendDescriptor> backends = new HashSet<>(); 236 for (AbstractIndexDescriptor index : indexes) 237 { 238 backends.add(index.getBackend()); 239 } 240 for (BackendDescriptor backend : backends) 241 { 242 Set<AbstractIndexDescriptor> allIndexes = new HashSet<>(); 243 allIndexes.addAll(backend.getIndexes()); 244 allIndexes.addAll(backend.getVLVIndexes()); 245 for (AbstractIndexDescriptor index : allIndexes) 246 { 247 if (!ignoreIndex(index) && !indexes.contains(index)) 248 { 249 return false; 250 } 251 } 252 } 253 return true; 254 } 255 256 private boolean ignoreIndex(AbstractIndexDescriptor index) 257 { 258 if (index instanceof IndexDescriptor) 259 { 260 for (String name : INDEXES_NOT_TO_SPECIFY) 261 { 262 if (name.equalsIgnoreCase(index.getName())) 263 { 264 return true; 265 } 266 } 267 } 268 return false; 269 } 270}