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