/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive_grid_cloud_portal.cli.utils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.codec.binary.StringUtils; import org.ow2.proactive.utils.ObjectArrayFormatter; import org.ow2.proactive.utils.Tools; import org.ow2.proactive_grid_cloud_portal.cli.json.MBeanInfoView; import org.ow2.proactive_grid_cloud_portal.cli.json.NodeEventView; import org.ow2.proactive_grid_cloud_portal.cli.json.NodeSourceView; import org.ow2.proactive_grid_cloud_portal.cli.json.TopologyView; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobStatusData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskIdData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskInfoData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskResultData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskStateData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskStatusData; import org.ow2.proactive_grid_cloud_portal.scheduler.dto.UserJobData; import org.ow2.proactive_grid_cloud_portal.utils.ObjectUtility; public final class StringUtility { private StringUtility() { } public static boolean isEmpty(String string) { return string == null || string.length() == 0; } public static boolean isEmpty(String[] array) { return array == null || array.length == 0; } public static String objectArrayFormatterAsString(ObjectArrayFormatter oaf) { return Tools.getStringAsArray(oaf); } public static String formattedDate(long time) { return Tools.getFormattedDate(time); } public static String formattedElapsedTime(long time) { return Tools.getElapsedTime(time); } public static String formattedDuration(long start, long end) { return Tools.getFormattedDuration(start, end); } public static String responseAsString(HttpResponseWrapper response) { return StringUtils.newStringUtf8(response.getContent()); } public static String string(TopologyView topology) { StringBuilder buffer = new StringBuilder(); Set<String> hostList = topology.getDistances().keySet(); buffer.append(String.format("%nHost list(%d):", hostList.size())); for (String host : hostList) { buffer.append(String.format("%s", host)); } ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(80); formatter.setSpace(4); List<String> titles = new ArrayList<>(3); titles.add("Host"); titles.add("Distance (µs)"); titles.add("Host"); formatter.setTitle(titles); formatter.addEmptyLine(); List<String> line; for (String host : hostList) { Map<String, String> hostTopology = topology.getDistances().get(host); if (hostTopology != null) { for (String anotherHost : hostTopology.keySet()) { line = new ArrayList<>(3); line.add(host); line.add(hostTopology.get(anotherHost)); line.add(anotherHost); formatter.addLine(line); } } } buffer.append(objectArrayFormatterAsString(formatter)); return buffer.toString(); } public static String string(NodeEventView[] nodeEvents) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(300); formatter.setSpace(4); List<String> titles = new ArrayList<>(7); titles.add("SOURCE_NAME"); titles.add("HOST_NAME"); titles.add("STATE"); titles.add("SINCE"); titles.add("LOCKED"); titles.add("LOCKED_BY"); titles.add("LOCK_TIME"); titles.add("URL"); titles.add("PROVIDER"); titles.add("USED_BY"); formatter.setTitle(titles); formatter.addEmptyLine(); if (nodeEvents != null) { for (NodeEventView nodeEvent : nodeEvents) { List<String> line = new ArrayList<>(10); line.add(nodeEvent.getNodeSource()); line.add(nodeEvent.getHostName()); line.add(nodeEvent.getNodeState()); line.add(getStateChangeTime(nodeEvent)); line.add(nodeEvent.isLocked()); line.add(toStringNullable(nodeEvent.getNodeLocker())); line.add(getLockTime(nodeEvent)); line.add(nodeEvent.getNodeUrl()); line.add(toStringNullable(nodeEvent.getNodeProvider())); line.add(toStringNullable(nodeEvent.getNodeOwner())); formatter.addLine(line); } } return Tools.getStringAsArray(formatter); } private static String getStateChangeTime(NodeEventView nodeEvent) { long timestamp = Long.parseLong(nodeEvent.getTimeStamp()); String stateChangeTime = Tools.getFormattedDate(timestamp); if (timestamp != -1) { stateChangeTime += " (" + Tools.getElapsedTime(timestamp) + ")"; } return stateChangeTime; } private static String getLockTime(NodeEventView nodeEvent) { long lockTime = Long.parseLong(nodeEvent.getLockTime()); if (lockTime == -1) { return ""; } return Tools.getFormattedDate(lockTime) + " (" + Tools.getElapsedTime(lockTime) + ")"; } private static String getLockState(NodeEventView nodeEvent) { String lockState = nodeEvent.isLocked(); if (Boolean.TRUE.toString().equalsIgnoreCase(lockState)) { lockState += " (by " + nodeEvent.getNodeLocker() + " since "; lockState += Tools.getFormattedDate(Long.parseLong(nodeEvent.getLockTime())); lockState += ")"; } return lockState; } public static String string(NodeSourceView[] nodeSources) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(80); formatter.setSpace(4); List<String> titles = new ArrayList<>(3); titles.add("SOURCE_NAME"); titles.add("DESCRIPTION"); titles.add("ADMINISTRATOR"); formatter.setTitle(titles); formatter.addEmptyLine(); for (NodeSourceView ns : nodeSources) { List<String> line = new ArrayList<>(3); line.add(ns.getSourceName()); line.add(ns.getSourceDescription()); line.add(ns.getNodeSourceAdmin()); formatter.addLine(line); } return Tools.getStringAsArray(formatter); } public static String mBeanInfoAsString(MBeanInfoView[] infoViews) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(80); formatter.setSpace(4); List<String> titles = new ArrayList<>(2); titles.add("Stats:"); titles.add(""); formatter.setTitle(titles); formatter.addEmptyLine(); for (MBeanInfoView infoView : infoViews) { List<String> line = new ArrayList<>(); line.add("" + infoView.getName()); line.add("" + infoView.getValue()); formatter.addLine(line); } return Tools.getStringAsArray(formatter); } public static String jobResultAsString(String id, org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobResultData jobResult) { StringBuilder buffer = new StringBuilder(); buffer.append(String.format("%s result:\n", id)); Map<String, TaskResultData> allResults = jobResult.getAllResults(); for (String taskName : allResults.keySet()) { buffer.append(String.format(taskName + " : " + ObjectUtility.object(allResults.get(taskName).getSerializedValue()))) .append('\n'); } return buffer.toString(); } public static String jobStateAsString(String id, org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobStateData jobState) { StringBuilder buffer = new StringBuilder(); buffer.append(id) .append("\tNAME: ") .append(jobState.getName()) .append("\tOWNER: ") .append(jobState.getOwner()) .append("\tSTATUS: ") .append(jobState.getJobInfo().getStatus()) .append("\t#TASKS: ") .append(jobState.getJobInfo().getTotalNumberOfTasks()); buffer.append('\n'); Collection<TaskStateData> tasks = jobState.getTasks().values(); buffer.append(taskStatesAsString(tasks, true)); return buffer.toString(); } public static String taskStatesAsString(Collection<TaskStateData> tasks, boolean displayTags) { // create formatter ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(80); // space between column formatter.setSpace(4); // title line List<String> list = new ArrayList<>(); list.add("ID"); list.add("NAME"); if (displayTags) { list.add("TAG"); } list.add("ITER"); list.add("DUP"); list.add("STATUS"); list.add("HOSTNAME"); list.add("EXEC DURATION"); list.add("TOT DURATION"); list.add("#NODES USED"); list.add("#EXECUTIONS"); list.add("#NODES KILLED"); formatter.setTitle(list); formatter.addEmptyLine(); for (TaskStateData taskState : tasks) { list = new ArrayList<>(); TaskInfoData taskInfo = taskState.getTaskInfo(); TaskIdData taskId = taskInfo.getTaskId(); list.add(String.valueOf(taskId.getId())); list.add(taskId.getReadableName()); if (displayTags) { list.add(toStringNullable(taskState.getTag())); } list.add((taskState.getIterationIndex() > 0) ? "" + taskState.getIterationIndex() : ""); list.add((taskState.getReplicationIndex() > 0) ? "" + taskState.getReplicationIndex() : ""); list.add(taskInfo.getTaskStatus().toString()); list.add(toStringNullable(taskInfo.getExecutionHostName(), "unknown")); if (taskInfo.getTaskStatus() == TaskStatusData.IN_ERROR) { list.add(Tools.getFormattedDuration(taskInfo.getInErrorTime(), taskInfo.getStartTime())); } else { list.add(Tools.getFormattedDuration(0, taskInfo.getExecutionDuration())); } list.add(Tools.getFormattedDuration(taskInfo.getFinishedTime(), taskInfo.getStartTime())); list.add("" + taskState.getNumberOfNodesNeeded()); list.add((taskState.getMaxNumberOfExecution() - taskInfo.getNumberOfExecutionLeft()) + "/" + taskState.getMaxNumberOfExecution()); list.add((taskState.getMaxNumberOfExecutionOnFailure() - taskInfo.getNumberOfExecutionOnFailureLeft()) + "/" + taskState.getMaxNumberOfExecutionOnFailure()); formatter.addLine(list); } return Tools.getStringAsArray(formatter); } public static String jobsAsString(List<UserJobData> jobs) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(30); formatter.setSpace(4); List<String> columnNames = new ArrayList<>(7); columnNames.add("ID"); columnNames.add("NAME"); columnNames.add("OWNER"); columnNames.add("PRIORITY"); columnNames.add("STATUS"); columnNames.add("START AT"); columnNames.add("DURATION"); formatter.setTitle(columnNames); formatter.addEmptyLine(); for (UserJobData job : jobs) { formatter.addLine(rowList(job)); } return Tools.getStringAsArray(formatter); } public static String credentialsKeysAsString(Set<String> keys) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(30); formatter.setSpace(4); formatter.setTitle(Collections.singletonList("KEY")); formatter.addEmptyLine(); for (String key : keys) { formatter.addLine(Collections.singletonList(key)); } return Tools.getStringAsArray(formatter); } private static List<String> rowList(UserJobData userJobInfo) { org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobInfoData jobInfo = userJobInfo.getJobInfo(); List<String> row = new ArrayList<>(); row.add(String.valueOf(jobInfo.getJobId().getId())); row.add(jobInfo.getJobId().getReadableName()); row.add(userJobInfo.getJobOwner()); row.add(jobInfo.getPriority().toString()); row.add(jobInfo.getStatus().toString()); long startTime = jobInfo.getStartTime(); String date = StringUtility.formattedDate(startTime); if (startTime != -1) date += " (" + StringUtility.formattedElapsedTime(startTime) + ")"; row.add(date); if (userJobInfo.getJobInfo().getStatus() == JobStatusData.IN_ERROR) { row.add(StringUtility.formattedDuration(startTime, jobInfo.getInErrorTime())); } else { row.add(StringUtility.formattedDuration(startTime, jobInfo.getFinishedTime())); } return row; } public static String taskResultsAsString(List<TaskResultData> results) { StringBuffer buf = new StringBuffer(); for (TaskResultData currentResult : results) { buf.append(taskResultAsString(currentResult.getId().getReadableName(), currentResult)); buf.append("\n"); } return buf.toString(); } public static String taskResultAsString(String id, org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskResultData taskResult) { return String.format("%s result: %s", id, ObjectUtility.object(taskResult.getSerializedValue()).toString()); } public static String statsAsString(Map<String, String> stats) { ObjectArrayFormatter formatter = new ObjectArrayFormatter(); formatter.setMaxColumnLength(80); formatter.setSpace(2); List<String> columnNames = new ArrayList<>(2); columnNames.add(""); columnNames.add(""); formatter.setTitle(columnNames); for (Entry<String, String> e : stats.entrySet()) { List<String> row = new ArrayList<>(); row.add(e.getKey()); row.add(e.getValue()); formatter.addLine(row); } return Tools.getStringAsArray(formatter); } private static String toStringNullable(String obj) { return toStringNullable(obj, ""); } private static String toStringNullable(String obj, String defaultValue) { if (obj == null) { return defaultValue; } return obj; } }