1package autotest.afe; 2 3import autotest.afe.create.CreateJobViewPresenter.JobCreateListener; 4import autotest.common.JSONArrayList; 5import autotest.common.JsonRpcCallback; 6import autotest.common.JsonRpcProxy; 7import autotest.common.SimpleCallback; 8import autotest.common.StaticDataRepository; 9import autotest.common.Utils; 10import autotest.common.table.JSONObjectSet; 11import autotest.common.ui.NotifyManager; 12import autotest.common.ui.SimplifiedList; 13 14import com.google.gwt.json.client.JSONArray; 15import com.google.gwt.json.client.JSONBoolean; 16import com.google.gwt.json.client.JSONObject; 17import com.google.gwt.json.client.JSONString; 18import com.google.gwt.json.client.JSONValue; 19import com.google.gwt.user.client.DOM; 20import com.google.gwt.user.client.Element; 21import com.google.gwt.user.client.ui.ListBox; 22 23import java.util.ArrayList; 24import java.util.Collection; 25import java.util.Iterator; 26import java.util.List; 27import java.util.Set; 28 29/** 30 * Utility methods. 31 */ 32public 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 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 57 public static String[] getLabelStrings() { 58 return getFilteredLabelStrings(false, false); 59 } 60 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 87 public static String[] getPlatformStrings() { 88 return getFilteredLabelStrings(true, false); 89 } 90 91 public static String[] getNonPlatformLabelStrings() { 92 return getFilteredLabelStrings(false, true); 93 } 94 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 108 public static JSONString getLockedText(JSONObject host) { 109 boolean locked = host.get("locked").isBoolean().booleanValue(); 110 return new JSONString(locked ? "Yes" : "No"); 111 } 112 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 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 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 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 202 public static void callAbort(JSONObject params, final SimpleCallback onSuccess) { 203 callAbort(params, onSuccess, true); 204 } 205 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 222 public static void callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess) { 223 callAbortSpecialTasks(params, onSuccess, true); 224 } 225 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 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 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 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 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 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 376 public static String getJobTag(JSONObject job) { 377 return Utils.jsonToString(job.get("id")) + "-" + Utils.jsonToString(job.get("owner")); 378 } 379 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 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 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 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 412 public static void removeElement(String id) { 413 Element element = DOM.getElementById(id); 414 element.getParentElement().removeChild(element); 415 } 416 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 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 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