1 package autotest.afe; 2 3 import autotest.afe.create.CreateJobViewPresenter.JobCreateListener; 4 import autotest.common.JSONArrayList; 5 import autotest.common.JsonRpcCallback; 6 import autotest.common.JsonRpcProxy; 7 import autotest.common.SimpleCallback; 8 import autotest.common.StaticDataRepository; 9 import autotest.common.Utils; 10 import autotest.common.table.JSONObjectSet; 11 import autotest.common.ui.NotifyManager; 12 import autotest.common.ui.SimplifiedList; 13 14 import com.google.gwt.json.client.JSONArray; 15 import com.google.gwt.json.client.JSONBoolean; 16 import com.google.gwt.json.client.JSONObject; 17 import com.google.gwt.json.client.JSONString; 18 import com.google.gwt.json.client.JSONValue; 19 import com.google.gwt.user.client.DOM; 20 import com.google.gwt.user.client.Element; 21 import com.google.gwt.user.client.ui.ListBox; 22 23 import java.util.ArrayList; 24 import java.util.Collection; 25 import java.util.Iterator; 26 import java.util.List; 27 import java.util.Set; 28 29 /** 30 * Utility methods. 31 */ 32 public class AfeUtils { 33 public static final String PLATFORM_SUFFIX = " (platform)"; 34 public static final String ATOMIC_GROUP_SUFFIX = " (atomic group)"; 35 public static final String REINSTALL_TEST_NAME = "autoupdate:repair"; 36 37 public static final ClassFactory factory = new SiteClassFactory(); 38 39 private static StaticDataRepository staticData = StaticDataRepository.getRepository(); 40 formatStatusCounts(JSONObject counts, String joinWith)41 public static String formatStatusCounts(JSONObject counts, String joinWith) { 42 StringBuilder result = new StringBuilder(); 43 Set<String> statusSet = counts.keySet(); 44 for (Iterator<String> i = statusSet.iterator(); i.hasNext();) { 45 String status = i.next(); 46 int count = (int) counts.get(status).isNumber().doubleValue(); 47 result.append(Integer.toString(count)); 48 result.append(" "); 49 result.append(status); 50 if (i.hasNext()) { 51 result.append(joinWith); 52 } 53 } 54 return result.toString(); 55 } 56 getLabelStrings()57 public static String[] getLabelStrings() { 58 return getFilteredLabelStrings(false, false); 59 } 60 getFilteredLabelStrings(boolean onlyPlatforms, boolean onlyNonPlatforms)61 protected static String[] getFilteredLabelStrings(boolean onlyPlatforms, 62 boolean onlyNonPlatforms) { 63 assert !(onlyPlatforms && onlyNonPlatforms); 64 JSONArray labels = staticData.getData("labels").isArray(); 65 List<String> result = new ArrayList<String>(); 66 for (int i = 0; i < labels.size(); i++) { 67 JSONObject label = labels.get(i).isObject(); 68 String name = label.get("name").isString().stringValue(); 69 boolean labelIsPlatform = label.get("platform").isBoolean().booleanValue(); 70 JSONObject atomicGroup = label.get("atomic_group").isObject(); 71 if (atomicGroup != null) { 72 name += ATOMIC_GROUP_SUFFIX; 73 } 74 if (onlyPlatforms && labelIsPlatform || 75 onlyNonPlatforms && !labelIsPlatform) { 76 result.add(name); 77 } else if (!onlyPlatforms && !onlyNonPlatforms) { 78 if (labelIsPlatform) { 79 name += PLATFORM_SUFFIX; 80 } 81 result.add(name); 82 } 83 } 84 return result.toArray(new String[result.size()]); 85 } 86 getPlatformStrings()87 public static String[] getPlatformStrings() { 88 return getFilteredLabelStrings(true, false); 89 } 90 getNonPlatformLabelStrings()91 public static String[] getNonPlatformLabelStrings() { 92 return getFilteredLabelStrings(false, true); 93 } 94 decodeLabelName(String labelName)95 public static String decodeLabelName(String labelName) { 96 String name = labelName; 97 if (name.endsWith(PLATFORM_SUFFIX)) { 98 int nameLength = name.length() - PLATFORM_SUFFIX.length(); 99 name = name.substring(0, nameLength); 100 } 101 if (name.endsWith(ATOMIC_GROUP_SUFFIX)) { 102 int nameLength = name.length() - ATOMIC_GROUP_SUFFIX.length(); 103 name = name.substring(0, nameLength); 104 } 105 return name; 106 } 107 getLockedText(JSONObject host)108 public static JSONString getLockedText(JSONObject host) { 109 boolean locked = host.get("locked").isBoolean().booleanValue(); 110 return new JSONString(locked ? "Yes" : "No"); 111 } 112 abortHostQueueEntries(Collection<JSONObject> entries, final SimpleCallback onSuccess)113 public static void abortHostQueueEntries(Collection<JSONObject> entries, 114 final SimpleCallback onSuccess) { 115 if (entries.isEmpty()) { 116 NotifyManager.getInstance().showError("No entries selected to abort"); 117 return; 118 } 119 120 final JSONArray asynchronousEntryIds = new JSONArray(); 121 Set<JSONObject> synchronousEntries = new JSONObjectSet<JSONObject>(); 122 for (JSONObject entry : entries) { 123 JSONObject job = entry.get("job").isObject(); 124 int synchCount = (int) job.get("synch_count").isNumber().doubleValue(); 125 boolean hasExecutionSubdir = 126 entry.containsKey("execution_subdir") && 127 !Utils.jsonToString(entry.get("execution_subdir")).equals(""); 128 if (synchCount > 1 && hasExecutionSubdir) { 129 synchronousEntries.add(entry); 130 continue; 131 } 132 133 JSONValue idListValue = entry.get("id_list"); 134 if (idListValue != null) { 135 // metahost row 136 extendJsonArray(asynchronousEntryIds, idListValue.isArray()); 137 } else { 138 JSONValue id = entry.get("id"); 139 if (entry.containsKey("oid")) 140 id = entry.get("oid"); 141 asynchronousEntryIds.set(asynchronousEntryIds.size(), id); 142 } 143 } 144 145 SimpleCallback abortAsynchronousEntries = new SimpleCallback() { 146 public void doCallback(Object source) { 147 JSONObject params = new JSONObject(); 148 params.put("id__in", asynchronousEntryIds); 149 AfeUtils.callAbort(params, onSuccess); 150 } 151 }; 152 153 if (synchronousEntries.size() == 0) { 154 abortAsynchronousEntries.doCallback(null); 155 } else { 156 AbortSynchronousDialog dialog = new AbortSynchronousDialog( 157 abortAsynchronousEntries, synchronousEntries, asynchronousEntryIds.size() != 0); 158 dialog.center(); 159 } 160 } 161 abortSpecialTasks(final JSONArray specialTaskIds, final SimpleCallback onSuccess)162 public static void abortSpecialTasks(final JSONArray specialTaskIds, 163 final SimpleCallback onSuccess) { 164 if (specialTaskIds.size() == 0) { 165 NotifyManager.getInstance().showError("No entries selected to abort"); 166 return; 167 } 168 169 SimpleCallback abortSpecialTasks = new SimpleCallback() { 170 public void doCallback(Object source) { 171 JSONObject params = new JSONObject(); 172 params.put("id__in", specialTaskIds); 173 AfeUtils.callAbortSpecialTasks(params, onSuccess); 174 } 175 }; 176 177 abortSpecialTasks.doCallback(null); 178 } 179 extendJsonArray(JSONArray array, JSONArray newValues)180 private static void extendJsonArray(JSONArray array, JSONArray newValues) { 181 for (JSONValue value : new JSONArrayList<JSONValue>(newValues)) { 182 array.set(array.size(), value); 183 } 184 } 185 callAbort(JSONObject params, final SimpleCallback onSuccess, final boolean showMessage)186 public static void callAbort(JSONObject params, final SimpleCallback onSuccess, 187 final boolean showMessage) { 188 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 189 rpcProxy.rpcCall("abort_host_queue_entries", params, new JsonRpcCallback() { 190 @Override 191 public void onSuccess(JSONValue result) { 192 if (showMessage) { 193 NotifyManager.getInstance().showMessage("Jobs aborted"); 194 } 195 if (onSuccess != null) { 196 onSuccess.doCallback(null); 197 } 198 } 199 }); 200 } 201 callAbort(JSONObject params, final SimpleCallback onSuccess)202 public static void callAbort(JSONObject params, final SimpleCallback onSuccess) { 203 callAbort(params, onSuccess, true); 204 } 205 callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess, final boolean showMessage)206 public static void callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess, 207 final boolean showMessage) { 208 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 209 rpcProxy.rpcCall("abort_special_tasks", params, new JsonRpcCallback() { 210 @Override 211 public void onSuccess(JSONValue result) { 212 if (showMessage) { 213 NotifyManager.getInstance().showMessage("Special tasks aborted"); 214 } 215 if (onSuccess != null) { 216 onSuccess.doCallback(null); 217 } 218 } 219 }); 220 } 221 callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess)222 public static void callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess) { 223 callAbortSpecialTasks(params, onSuccess, true); 224 } 225 callReverify(JSONObject params, final SimpleCallback onSuccess, final String messagePrefix)226 public static void callReverify(JSONObject params, final SimpleCallback onSuccess, 227 final String messagePrefix) { 228 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 229 rpcProxy.rpcCall("reverify_hosts", params, new JsonRpcCallback() { 230 @Override 231 public void onSuccess(JSONValue result) { 232 233 NotifyManager.getInstance().showMessage( 234 messagePrefix + " scheduled for reverification"); 235 236 if (onSuccess != null) { 237 onSuccess.doCallback(null); 238 } 239 } 240 }); 241 } 242 callRepair(JSONObject params, final SimpleCallback onSuccess, final String messagePrefix)243 public static void callRepair(JSONObject params, final SimpleCallback onSuccess, 244 final String messagePrefix) { 245 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 246 rpcProxy.rpcCall("repair_hosts", params, new JsonRpcCallback() { 247 @Override 248 public void onSuccess(JSONValue result) { 249 250 NotifyManager.getInstance().showMessage( 251 messagePrefix + " scheduled for repair"); 252 253 if (onSuccess != null) { 254 onSuccess.doCallback(null); 255 } 256 } 257 }); 258 } 259 scheduleReinstallHelper(JSONArray hosts, JSONObject controlInfo, final String messagePrefix, final JobCreateListener listener)260 private static void scheduleReinstallHelper(JSONArray hosts, JSONObject controlInfo, 261 final String messagePrefix, 262 final JobCreateListener listener) { 263 String name = "reinstall_" + hosts.get(0).isString().stringValue(); 264 if (hosts.size() > 1) { 265 name += "_etc"; 266 } 267 268 // Get the option for "Never" 269 JSONValue rebootBefore = staticData.getData("reboot_before_options").isArray().get(0); 270 JSONValue rebootAfter = staticData.getData("reboot_after_options").isArray().get(0); 271 272 JSONObject args = new JSONObject(); 273 args.put("name", new JSONString(name)); 274 args.put("priority", staticData.getData("default_priority")); 275 args.put("control_file", controlInfo.get("control_file")); 276 args.put("control_type", new JSONString(TestSelector.SERVER_TYPE)); 277 args.put("synch_count", controlInfo.get("synch_count")); 278 args.put("timeout_mins", staticData.getData("job_timeout_mins_default")); 279 args.put("max_runtime_mins", staticData.getData("job_max_runtime_mins_default")); 280 args.put("run_verify", JSONBoolean.getInstance(false)); 281 args.put("parse_failed_repair", JSONBoolean.getInstance(true)); 282 args.put("reboot_before", rebootBefore); 283 args.put("reboot_after", rebootAfter); 284 args.put("hosts", hosts); 285 286 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 287 rpcProxy.rpcCall("create_job", args, new JsonRpcCallback() { 288 @Override 289 public void onSuccess(JSONValue result) { 290 NotifyManager.getInstance().showMessage(messagePrefix + " scheduled for reinstall"); 291 if (listener != null) { 292 listener.onJobCreated((int) result.isNumber().doubleValue()); 293 } 294 } 295 }); 296 } 297 scheduleReinstall(final JSONArray hosts, final String messagePrefix, final JobCreateListener listener)298 public static void scheduleReinstall(final JSONArray hosts, final String messagePrefix, 299 final JobCreateListener listener) { 300 // Find the test 301 JSONArray tests = staticData.getData("tests").isArray(); 302 JSONObject reinstallTest = null; 303 for (int i = 0; i < tests.size(); i++) { 304 JSONObject test = tests.get(i).isObject(); 305 if (test.get("name").isString().stringValue().equals(REINSTALL_TEST_NAME)) { 306 reinstallTest = test; 307 break; 308 } 309 } 310 311 if (reinstallTest == null) { 312 NotifyManager.getInstance().showError("No test found: " + REINSTALL_TEST_NAME); 313 return; 314 } 315 316 JSONObject params = new JSONObject(); 317 JSONArray array = new JSONArray(); 318 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 319 320 array.set(0, reinstallTest.get("id")); 321 params.put("tests", array); 322 rpcProxy.rpcCall("generate_control_file", params, new JsonRpcCallback() { 323 @Override 324 public void onSuccess(JSONValue controlInfo) { 325 scheduleReinstallHelper(hosts, controlInfo.isObject(), 326 messagePrefix, listener); 327 } 328 }); 329 } 330 callModifyHosts(JSONObject params, final SimpleCallback onSuccess)331 public static void callModifyHosts(JSONObject params, final SimpleCallback onSuccess) { 332 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 333 rpcProxy.rpcCall("modify_hosts", params, new JsonRpcCallback() { 334 @Override 335 public void onSuccess(JSONValue result) { 336 if (onSuccess != null) { 337 onSuccess.doCallback(null); 338 } 339 } 340 }); 341 } 342 changeHostLocks(JSONArray hostIds, final boolean lock, String lockReason, final String messagePrefix, final SimpleCallback callback)343 public static void changeHostLocks(JSONArray hostIds, final boolean lock, 344 String lockReason, final String messagePrefix, 345 final SimpleCallback callback) { 346 JSONObject hostFilterData = new JSONObject(); 347 JSONObject updateData = new JSONObject(); 348 JSONObject params = new JSONObject(); 349 350 hostFilterData.put("id__in", hostIds); 351 updateData.put("locked", JSONBoolean.getInstance(lock)); 352 updateData.put("lock_reason", new JSONString("")); 353 354 if (lockReason != null && !lockReason.trim().isEmpty()) { 355 updateData.put("lock_reason", new JSONString(lockReason.trim())); 356 } 357 358 params.put("host_filter_data", hostFilterData); 359 params.put("update_data", updateData); 360 361 callModifyHosts(params, new SimpleCallback() { 362 public void doCallback(Object source) { 363 String message = messagePrefix + " "; 364 if (!lock) { 365 message += "un"; 366 } 367 message += "locked"; 368 369 NotifyManager.getInstance().showMessage(message); 370 371 callback.doCallback(source); 372 } 373 }); 374 } 375 getJobTag(JSONObject job)376 public static String getJobTag(JSONObject job) { 377 return Utils.jsonToString(job.get("id")) + "-" + Utils.jsonToString(job.get("owner")); 378 } 379 populateRadioChooser(RadioChooser chooser, String name)380 public static void populateRadioChooser(RadioChooser chooser, String name) { 381 JSONArray options = staticData.getData(name + "_options").isArray(); 382 for (JSONString jsonOption : new JSONArrayList<JSONString>(options)) { 383 chooser.addChoice(Utils.jsonToString(jsonOption)); 384 } 385 } 386 populateListBox(ListBox box, String staticDataKey)387 public static void populateListBox(ListBox box, String staticDataKey) { 388 JSONArray options = staticData.getData(staticDataKey).isArray(); 389 for (JSONString jsonOption : new JSONArrayList<JSONString>(options)) { 390 box.addItem(Utils.jsonToString(jsonOption)); 391 } 392 } 393 populateListBox(SimplifiedList box, String staticDataKey)394 public static void populateListBox(SimplifiedList box, String staticDataKey) { 395 JSONArray options = staticData.getData(staticDataKey).isArray(); 396 for (JSONString jsonOption : new JSONArrayList<JSONString>(options)) { 397 String option = Utils.jsonToString(jsonOption); 398 box.addItem(option, option); 399 } 400 } 401 setSelectedItem(ListBox box, String item)402 public static void setSelectedItem(ListBox box, String item) { 403 box.setSelectedIndex(0); 404 for (int i = 0; i < box.getItemCount(); i++) { 405 if (box.getItemText(i).equals(item)) { 406 box.setSelectedIndex(i); 407 break; 408 } 409 } 410 } 411 removeElement(String id)412 public static void removeElement(String id) { 413 Element element = DOM.getElementById(id); 414 element.getParentElement().removeChild(element); 415 } 416 parsePositiveIntegerInput(String input, String fieldName)417 public static int parsePositiveIntegerInput(String input, String fieldName) { 418 final int parsedInt; 419 try { 420 if (input.equals("") || 421 (parsedInt = Integer.parseInt(input)) <= 0) { 422 String error = "Please enter a positive " + fieldName; 423 NotifyManager.getInstance().showError(error); 424 throw new IllegalArgumentException(); 425 } 426 } catch (NumberFormatException e) { 427 String error = "Invalid " + fieldName + ": \"" + input + "\""; 428 NotifyManager.getInstance().showError(error); 429 throw new IllegalArgumentException(); 430 } 431 return parsedInt; 432 } 433 removeSecondsFromDateField(JSONObject row, String sourceFieldName, String targetFieldName)434 public static void removeSecondsFromDateField(JSONObject row, 435 String sourceFieldName, 436 String targetFieldName) { 437 JSONValue dateValue = row.get(sourceFieldName); 438 String date = ""; 439 if (dateValue.isNull() == null) { 440 date = dateValue.isString().stringValue(); 441 date = date.substring(0, date.length() - 3); 442 } 443 row.put(targetFieldName, new JSONString(date)); 444 } 445 callGetJobHistory(JSONObject params, final SimpleCallback onSuccess, final boolean showMessage)446 public static void callGetJobHistory(JSONObject params, 447 final SimpleCallback onSuccess, 448 final boolean showMessage) { 449 JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 450 rpcProxy.rpcCall("get_job_history", params, new JsonRpcCallback() { 451 @Override 452 public void onSuccess(JSONValue result) { 453 if (showMessage) { 454 NotifyManager.getInstance().showMessage("Get job history succeeded."); 455 } 456 if (onSuccess != null) { 457 onSuccess.doCallback(result); 458 } 459 } 460 }); 461 } 462 } 463