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