/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.utils.cluster.sge.internal; import java.io.IOException; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import de.rcenvironment.core.utils.cluster.ClusterJobInformation; import de.rcenvironment.core.utils.cluster.ClusterJobInformation.ClusterJobState; import de.rcenvironment.core.utils.cluster.ClusterService; import de.rcenvironment.core.utils.cluster.internal.AbstractClusterService; import de.rcenvironment.core.utils.cluster.internal.ClusterJobTimesInformation; import de.rcenvironment.core.utils.cluster.internal.ClusterJobInformationImpl; import de.rcenvironment.core.utils.ssh.jsch.SshSessionConfiguration; /** * SGE implementation of {@link ClusterService}. * @author Doreen Seider */ public class SgeClusterService extends AbstractClusterService { private static final int INDEX_JOBID = 0; private static final int INDEX_JOBNAME = 1; private static final int INDEX_USER = 2; private static final int INDEX_JOBSTATE = 3; private static final int INDEX_REMAININGTIME = 5; private static final int INDEX_QUEUETIME = 6; private static final int INDEX_STARTTIME = 6; private static final int SECTION_ACTIVE_JOBS = 0; private static final int SECTION_WAITING_JOBS = 1; private static final int SECTION_WAITING_JOBS_WITH_DEPENDENCIES = 2; private static final int SECTION_UNSCHEDULED_JOBS = 3; // private static final int INDEX_QUEUE = 2; // only for OSGi @Deprecated public SgeClusterService() {} public SgeClusterService(SshSessionConfiguration sshConfiguration, Map<String, String> pathToQueuingSystemCommands) { super(sshConfiguration, pathToQueuingSystemCommands); } @Override protected Set<ClusterJobInformation> fetchAndParseClusterJobInformation() throws IOException { String stdout = executesCommand(jschSession, buildMainCommand("showq"), REMOTE_WORK_DIR); Map<String, ClusterJobInformation> jobInformation = parseStdoutForClusterJobInformation(stdout); latestFetchedJobInformation = Collections.unmodifiableMap(jobInformation); latestFetch = new Date().getTime(); return new HashSet<ClusterJobInformation>(jobInformation.values()); } @Override public String cancelClusterJobs(List<String> jobIds) throws IOException { StringBuilder commandBuilder = new StringBuilder(buildMainCommand("qdel")); for (String jobId : jobIds) { commandBuilder.append(" "); commandBuilder.append(jobId); } try { executesCommand(jschSession, commandBuilder.toString(), REMOTE_WORK_DIR); } catch (IllegalArgumentException e) { return e.getMessage(); } return ""; } // visibility is protected for test purposes protected Map<String, ClusterJobInformation> parseStdoutForClusterJobInformation(String stdout) { Map<String, ClusterJobInformation> jobInformation = new HashMap<String, ClusterJobInformation>(); int section = SECTION_ACTIVE_JOBS; boolean inSection = false; boolean emptyRowPassed = false; String[] lines = stdout.split("\n"); for (String line : lines) { String[] lineTokens = line.split("(\\s+)"); if (inSection) { if (lineTokens.length <= 1) { if (!emptyRowPassed) { emptyRowPassed = true; } else { emptyRowPassed = false; inSection = false; section++; } } else { ClusterJobInformation information = extractClusterJobInformation(lineTokens, section); jobInformation.put(information.getJobId(), information); } } else { for (String attribute : lineTokens) { if (attribute.matches("JOBID")) { inSection = true; break; } } } } return jobInformation; } private ClusterJobInformation extractClusterJobInformation(String[] lineTokens, int section) { ClusterJobInformationImpl information = new ClusterJobInformationImpl(); information.setJobId(lineTokens[INDEX_JOBID]); information.setJobName(lineTokens[INDEX_JOBNAME]); information.setUser(lineTokens[INDEX_USER]); information.setJobState(getClusterJobState(lineTokens[INDEX_JOBSTATE])); information.setClusterJobTimesInformation(extractClusterJobTimesInformation(lineTokens, section)); return information; } private ClusterJobState getClusterJobState(String stateToken) { try { return ClusterJobState.valueOf(stateToken); } catch (IllegalArgumentException e) { return ClusterJobState.Unknown; } } private ClusterJobTimesInformation extractClusterJobTimesInformation(String[] lineTokens, int section) { ClusterJobTimesInformation information = new ClusterJobTimesInformation(); information.setJobId(lineTokens[INDEX_JOBID]); switch (section) { case SECTION_ACTIVE_JOBS: information.setRemainingTime(lineTokens[INDEX_REMAININGTIME]); information.setStartTime(getTime(lineTokens, INDEX_STARTTIME)); break; case SECTION_WAITING_JOBS: case SECTION_WAITING_JOBS_WITH_DEPENDENCIES: case SECTION_UNSCHEDULED_JOBS: default: information.setQueueTime(getTime(lineTokens, INDEX_QUEUETIME)); break; } return information; } private String getTime(String[] lineTokens, int startIndex) { StringBuffer stringBuffer = new StringBuffer(); for (int i = startIndex; i < lineTokens.length; i++) { stringBuffer.append(lineTokens[i]); stringBuffer.append(" "); } return stringBuffer.delete(stringBuffer.length() - 1, stringBuffer.length()).toString(); } }