You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sh...@apache.org on 2015/06/03 20:14:43 UTC
[26/39] airavata git commit: Refactored gfac sub modules,
merged gfac-ssh, gfac-gsissh, gfac-local,
gfac-monitor and gsissh modules and create gface-impl,
removed implementation from gfac-core to gfac-impl
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/SlurmOutputParser.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/SlurmOutputParser.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/SlurmOutputParser.java
new file mode 100644
index 0000000..11fb4ce
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/SlurmOutputParser.java
@@ -0,0 +1,190 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.api.job;
+
+import org.apache.airavata.gfac.ssh.api.SSHApiException;
+import org.apache.airavata.gfac.ssh.impl.JobStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SlurmOutputParser implements OutputParser {
+ private static final Logger log = LoggerFactory.getLogger(SlurmOutputParser.class);
+ public static final int JOB_NAME_OUTPUT_LENGTH = 8;
+ public static final String STATUS = "status";
+
+ public void parseSingleJob(JobDescriptor descriptor, String rawOutput) throws SSHApiException {
+ log.info(rawOutput);
+ String[] info = rawOutput.split("\n");
+ String lastString = info[info.length - 1];
+ if (lastString.contains("JOB ID")) {
+ // because there's no state
+ descriptor.setStatus("U");
+ } else {
+ int column = 0;
+ System.out.println(lastString);
+ for (String each : lastString.split(" ")) {
+ if (each.trim().isEmpty()) {
+ continue;
+ } else {
+ switch (column) {
+ case 0:
+ descriptor.setJobID(each);
+ column++;
+ break;
+ case 1:
+ descriptor.setPartition(each);
+ column++;
+ break;
+ case 2:
+ descriptor.setJobName(each);
+ column++;
+ break;
+ case 3:
+ descriptor.setUserName(each);
+ column++;
+ break;
+ case 4:
+ descriptor.setStatus(each);
+ column++;
+ break;
+ case 5:
+ descriptor.setUsedCPUTime(each);
+ column++;
+ break;
+ case 6:
+ try {
+ int nodes = Integer.parseInt(each);
+ descriptor.setNodes(nodes);
+ }catch (Exception e){
+ log.error("Node count read from command output is not an integer !!!");
+ }
+ column++;
+ break;
+ case 7:
+ descriptor.setNodeList(each);
+ column++;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * This can be used to parseSingleJob the outpu of sbatch and extrac the jobID from the content
+ *
+ * @param rawOutput
+ * @return
+ */
+ public String parseJobSubmission(String rawOutput) throws SSHApiException {
+ // FIXME : use regex to match correct jobId;
+ log.info(rawOutput);
+ String[] info = rawOutput.split("\n");
+ for (String anInfo : info) {
+ if (anInfo.contains("Submitted batch job")) {
+ String[] split = anInfo.split("Submitted batch job");
+ return split[1].trim();
+ }
+ }
+ return "";
+// throw new SSHApiException(rawOutput); //todo//To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public JobStatus parseJobStatus(String jobID, String rawOutput) throws SSHApiException {
+ log.info(rawOutput);
+ Pattern pattern = Pattern.compile(jobID + "(?=\\s+\\S+\\s+\\S+\\s+\\S+\\s+(?<" + STATUS + ">\\w+))");
+ Matcher matcher = pattern.matcher(rawOutput);
+ if (matcher.find()) {
+ return JobStatus.valueOf(matcher.group(STATUS));
+ }
+ return null;
+ }
+
+ public void parseJobStatuses(String userName, Map<String, JobStatus> statusMap, String rawOutput) throws SSHApiException {
+ log.debug(rawOutput);
+ String[] info = rawOutput.split("\n");
+ String lastString = info[info.length - 1];
+ if (lastString.contains("JOBID") || lastString.contains("PARTITION")) {
+ log.info("There are no jobs with this username ... ");
+ return;
+ }
+// int lastStop = 0;
+ for (String jobID : statusMap.keySet()) {
+ String jobId = jobID.split(",")[0];
+ String jobName = jobID.split(",")[1];
+ boolean found = false;
+ for (int i = 0; i < info.length; i++) {
+ if (info[i].contains(jobName.substring(0, 8))) {
+ // now starts processing this line
+ log.info(info[i]);
+ String correctLine = info[i];
+ String[] columns = correctLine.split(" ");
+ List<String> columnList = new ArrayList<String>();
+ for (String s : columns) {
+ if (!"".equals(s)) {
+ columnList.add(s);
+ }
+ }
+ try {
+ statusMap.put(jobID, JobStatus.valueOf(columnList.get(4)));
+ } catch (IndexOutOfBoundsException e) {
+ statusMap.put(jobID, JobStatus.valueOf("U"));
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ log.error("Couldn't find the status of the Job with JobName: " + jobName + "Job Id: " + jobId);
+ }
+ }
+ }
+
+ @Override
+ public String parseJobId(String jobName, String rawOutput) throws SSHApiException {
+ String regJobId = "jobId";
+ if (jobName == null) {
+ return null;
+ } else if(jobName.length() > JOB_NAME_OUTPUT_LENGTH) {
+ jobName = jobName.substring(0, JOB_NAME_OUTPUT_LENGTH);
+ }
+ Pattern pattern = Pattern.compile("(?=(?<" + regJobId + ">\\d+)\\s+\\w+\\s+" + jobName + ")"); // regex - look ahead and match
+ if (rawOutput != null) {
+ Matcher matcher = pattern.matcher(rawOutput);
+ if (matcher.find()) {
+ return matcher.group(regJobId);
+ } else {
+ log.error("No match is found for JobName");
+ return null;
+ }
+ } else {
+ log.error("Error: RawOutput shouldn't be null");
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEJobConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEJobConfiguration.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEJobConfiguration.java
new file mode 100644
index 0000000..4fbbe30
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEJobConfiguration.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.api.job;
+
+import org.apache.airavata.gfac.ssh.impl.RawCommandInfo;
+import org.apache.commons.io.FilenameUtils;
+
+import java.io.File;
+
+public class UGEJobConfiguration implements JobManagerConfiguration {
+
+ private String jobDescriptionTemplateName;
+
+ private String scriptExtension;
+
+ private String installedPath;
+
+ private OutputParser parser;
+
+ public UGEJobConfiguration() {
+ // this can be used to construct and use setter methods to set all the params in order
+ }
+
+ public UGEJobConfiguration(String jobDescriptionTemplateName,
+ String scriptExtension, String installedPath, OutputParser parser) {
+ this.jobDescriptionTemplateName = jobDescriptionTemplateName;
+ this.scriptExtension = scriptExtension;
+ this.parser = parser;
+ if (installedPath.endsWith("/")) {
+ this.installedPath = installedPath;
+ } else {
+ this.installedPath = installedPath + "/";
+ }
+ }
+
+ public RawCommandInfo getCancelCommand(String jobID) {
+ return new RawCommandInfo(this.installedPath + "qdel " + jobID);
+ }
+
+ public String getJobDescriptionTemplateName() {
+ return jobDescriptionTemplateName;
+ }
+
+ public void setJobDescriptionTemplateName(String jobDescriptionTemplateName) {
+ this.jobDescriptionTemplateName = jobDescriptionTemplateName;
+ }
+
+ public RawCommandInfo getMonitorCommand(String jobID) {
+ return new RawCommandInfo(this.installedPath + "qstat -j " + jobID);
+ }
+
+ public String getScriptExtension() {
+ return scriptExtension;
+ }
+
+ public RawCommandInfo getSubmitCommand(String workingDirectory, String pbsFilePath) {
+ return new RawCommandInfo(this.installedPath + "qsub " +
+ workingDirectory + File.separator + FilenameUtils.getName(pbsFilePath));
+ }
+
+ public String getInstalledPath() {
+ return installedPath;
+ }
+
+ public void setInstalledPath(String installedPath) {
+ this.installedPath = installedPath;
+ }
+
+ public OutputParser getParser() {
+ return parser;
+ }
+
+ public void setParser(OutputParser parser) {
+ this.parser = parser;
+ }
+
+ public RawCommandInfo getUserBasedMonitorCommand(String userName) {
+ return new RawCommandInfo(this.installedPath + "qstat -u " + userName);
+ }
+
+ @Override
+ public RawCommandInfo getJobIdMonitorCommand(String jobName, String userName) {
+ // For PBS there is no option to get jobDetails by JobName, so we search with userName
+ return new RawCommandInfo(this.installedPath + "qstat -u " + userName);
+ }
+
+ @Override
+ public String getBaseCancelCommand() {
+ return "qdel";
+ }
+
+ @Override
+ public String getBaseMonitorCommand() {
+ return "qstat";
+ }
+
+ @Override
+ public String getBaseSubmitCommand() {
+ return "qsub ";
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEOutputParser.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEOutputParser.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEOutputParser.java
new file mode 100644
index 0000000..a6cc3ed
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/api/job/UGEOutputParser.java
@@ -0,0 +1,188 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.api.job;
+
+import org.apache.airavata.gfac.ssh.api.SSHApiException;
+import org.apache.airavata.gfac.ssh.impl.JobStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class UGEOutputParser implements OutputParser{
+ private static final Logger log = LoggerFactory.getLogger(PBSOutputParser.class);
+ public static final String JOB_ID = "jobId";
+
+ public void parseSingleJob(JobDescriptor jobDescriptor, String rawOutput) {
+ log.debug(rawOutput);
+ String[] info = rawOutput.split("\n");
+ String[] line;
+ for (int i = 0; i < info.length; i++) {
+ if (info[i].contains("=")) {
+ line = info[i].split("=", 2);
+ } else {
+ line = info[i].split(":", 2);
+ }
+ if (line.length >= 2) {
+ String header = line[0].trim();
+ log.debug("Header = " + header);
+ String value = line[1].trim();
+ log.debug("value = " + value);
+
+ if (header.equals("Variable_List")) {
+ while (info[i + 1].startsWith("\t")) {
+ value += info[i + 1];
+ i++;
+ }
+ value = value.replaceAll("\t", "");
+ jobDescriptor.setVariableList(value);
+ } else if ("Job Id".equals(header)) {
+ jobDescriptor.setJobID(value);
+ } else if ("Job_Name".equals(header)) {
+ jobDescriptor.setJobName(value);
+ } else if ("Account_Name".equals(header)) {
+ jobDescriptor.setAcountString(value);
+ } else if ("job_state".equals(header)) {
+ jobDescriptor.setStatus(value);
+ } else if ("Job_Owner".equals(header)) {
+ jobDescriptor.setOwner(value);
+ } else if ("resources_used.cput".equals(header)) {
+ jobDescriptor.setUsedCPUTime(value);
+ } else if ("resources_used.mem".equals(header)) {
+ jobDescriptor.setUsedMemory(value);
+ } else if ("resources_used.walltime".equals(header)) {
+ jobDescriptor.setEllapsedTime(value);
+ } else if ("job_state".equals(header)) {
+ jobDescriptor.setStatus(value);
+ } else if ("queue".equals(header))
+ jobDescriptor.setQueueName(value);
+ else if ("ctime".equals(header)) {
+ jobDescriptor.setCTime(value);
+ } else if ("qtime".equals(header)) {
+ jobDescriptor.setQTime(value);
+ } else if ("mtime".equals(header)) {
+ jobDescriptor.setMTime(value);
+ } else if ("start_time".equals(header)) {
+ jobDescriptor.setSTime(value);
+ } else if ("comp_time".equals(header)) {
+ jobDescriptor.setCompTime(value);
+ } else if ("exec_host".equals(header)) {
+ jobDescriptor.setExecuteNode(value);
+ } else if ("Output_Path".equals(header)) {
+ if (info[i + 1].contains("=") || info[i + 1].contains(":"))
+ jobDescriptor.setStandardOutFile(value);
+ else {
+ jobDescriptor.setStandardOutFile(value + info[i + 1].trim());
+ i++;
+ }
+ } else if ("Error_Path".equals(header)) {
+ if (info[i + 1].contains("=") || info[i + 1].contains(":"))
+ jobDescriptor.setStandardErrorFile(value);
+ else {
+ String st = info[i + 1].trim();
+ jobDescriptor.setStandardErrorFile(value + st);
+ i++;
+ }
+
+ } else if ("submit_args".equals(header)) {
+ while (i + 1 < info.length) {
+ if (info[i + 1].startsWith("\t")) {
+ value += info[i + 1];
+ i++;
+ } else
+ break;
+ }
+ value = value.replaceAll("\t", "");
+ jobDescriptor.setSubmitArgs(value);
+ }
+ }
+ }
+ }
+
+ public String parseJobSubmission(String rawOutput) {
+ log.debug(rawOutput);
+ if (rawOutput != null && !rawOutput.isEmpty()) {
+ String[] info = rawOutput.split("\n");
+ String lastLine = info[info.length - 1];
+ return lastLine.split(" ")[2]; // In PBS stdout is going to be directly the jobID
+ } else {
+ return "";
+ }
+ }
+
+ public JobStatus parseJobStatus(String jobID, String rawOutput) {
+ Pattern pattern = Pattern.compile("job_number:[\\s]+" + jobID);
+ Matcher matcher = pattern.matcher(rawOutput);
+ if (matcher.find()) {
+ return JobStatus.Q; // fixme; return correct status.
+ }
+ return JobStatus.U;
+ }
+
+ public void parseJobStatuses(String userName, Map<String, JobStatus> statusMap, String rawOutput) {
+ log.debug(rawOutput);
+ String[] info = rawOutput.split("\n");
+ int lastStop = 0;
+ for (String jobID : statusMap.keySet()) {
+ for(int i=lastStop;i<info.length;i++){
+ if(jobID.split(",")[0].contains(info[i].split(" ")[0]) && !"".equals(info[i].split(" ")[0])){
+ // now starts processing this line
+ log.info(info[i]);
+ String correctLine = info[i];
+ String[] columns = correctLine.split(" ");
+ List<String> columnList = new ArrayList<String>();
+ for (String s : columns) {
+ if (!"".equals(s)) {
+ columnList.add(s);
+ }
+ }
+ lastStop = i+1;
+ if ("E".equals(columnList.get(4))) {
+ // There is another status with the same letter E other than error status
+ // to avoid that we make a small tweek to the job status
+ columnList.set(4, "Er");
+ }
+ statusMap.put(jobID, JobStatus.valueOf(columnList.get(4)));
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public String parseJobId(String jobName, String rawOutput) throws SSHApiException {
+ if (jobName.length() > 10) {
+ jobName = jobName.substring(0, 10);
+ }
+ Pattern pattern = Pattern.compile("(?<" + JOB_ID + ">\\S+)\\s+\\S+\\s+(" + jobName + ")");
+ Matcher matcher = pattern.matcher(rawOutput);
+ if (matcher.find()) {
+ return matcher.group(JOB_ID);
+ }
+ return null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/config/ConfigReader.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/config/ConfigReader.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/config/ConfigReader.java
new file mode 100644
index 0000000..9658fba
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/config/ConfigReader.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.config;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Reads basic configurations.
+ */
+public class ConfigReader {
+
+ private static final String CONFIGURATION_FILE = "gsissh.properties";
+
+
+ private Properties properties;
+
+ /**
+ * Reads configurations from the class path configuration file.
+ * @throws IOException If an error occurred while reading configurations.
+ */
+ public ConfigReader() throws IOException {
+ this.properties = getPropertiesFromClasspath(CONFIGURATION_FILE);
+ }
+
+ private Properties getPropertiesFromClasspath(String propFileName) throws IOException {
+ Properties props = new Properties();
+ InputStream inputStream = this.getClass().getClassLoader()
+ .getResourceAsStream(propFileName);
+
+ if (inputStream == null) {
+ throw new FileNotFoundException("System configuration file '" + propFileName
+ + "' not found in the classpath");
+ }
+
+ props.load(inputStream);
+
+ return props;
+ }
+
+ public String getConfiguration(String key) {
+ return this.properties.getProperty(key);
+ }
+
+
+ /**
+ * Gets all the SSH related properties used by JSch.
+ * @return All properties.
+ */
+ public Properties getProperties() {
+ return this.properties;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/DefaultJobSubmissionListener.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/DefaultJobSubmissionListener.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/DefaultJobSubmissionListener.java
new file mode 100644
index 0000000..d60ea32
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/DefaultJobSubmissionListener.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.impl;
+
+import org.apache.airavata.gfac.ssh.api.SSHApiException;
+import org.apache.airavata.gfac.ssh.api.job.JobDescriptor;
+import org.apache.airavata.gfac.ssh.listener.JobSubmissionListener;
+
+public class DefaultJobSubmissionListener extends JobSubmissionListener {
+
+ public void statusChanged(JobDescriptor jobDescriptor) throws SSHApiException {
+ System.out.println("Job status has changed to : " + jobDescriptor.getStatus());
+ }
+
+ @Override
+ public void statusChanged(JobStatus jobStatus) throws SSHApiException {
+ System.out.println("Job status has changed to : " + jobStatus.toString());
+ }
+
+ @Override
+ public boolean isJobDone() throws SSHApiException {
+ return getJobStatus().equals(JobStatus.C);
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/GSISSHAbstractCluster.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/GSISSHAbstractCluster.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/GSISSHAbstractCluster.java
new file mode 100644
index 0000000..814a7e1
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/GSISSHAbstractCluster.java
@@ -0,0 +1,767 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+import java.security.SecureRandom;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.airavata.gfac.ssh.api.Cluster;
+import org.apache.airavata.gfac.ssh.api.CommandExecutor;
+import org.apache.airavata.gfac.ssh.api.SSHApiException;
+import org.apache.airavata.gfac.ssh.api.ServerInfo;
+import org.apache.airavata.gfac.core.authentication.AuthenticationInfo;
+import org.apache.airavata.gfac.core.authentication.GSIAuthenticationInfo;
+import org.apache.airavata.gfac.core.authentication.SSHKeyAuthentication;
+import org.apache.airavata.gfac.core.authentication.SSHPasswordAuthentication;
+import org.apache.airavata.gfac.core.authentication.SSHPublicKeyAuthentication;
+import org.apache.airavata.gfac.core.authentication.SSHPublicKeyFileAuthentication;
+import org.apache.airavata.gfac.ssh.api.job.JobDescriptor;
+import org.apache.airavata.gfac.ssh.api.job.JobManagerConfiguration;
+import org.apache.airavata.gfac.ssh.api.job.OutputParser;
+import org.apache.airavata.gfac.ssh.config.ConfigReader;
+import org.apache.airavata.gfac.ssh.jsch.ExtendedJSch;
+import org.apache.airavata.gfac.ssh.util.SSHAPIUIKeyboardInteractive;
+import org.apache.airavata.gfac.ssh.util.SSHKeyPasswordHandler;
+import org.apache.airavata.gfac.ssh.util.SSHUtils;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.jcraft.jsch.ExtendedSession;
+import com.jcraft.jsch.GSISSHIdentityFile;
+import com.jcraft.jsch.GSISSHIdentityRepository;
+import com.jcraft.jsch.Identity;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+public class GSISSHAbstractCluster implements Cluster {
+
+ private static final Logger log = LoggerFactory.getLogger(GSISSHAbstractCluster.class);
+ public static final String X509_CERT_DIR = "X509_CERT_DIR";
+ public static final String SSH_SESSION_TIMEOUT = "ssh.session.timeout";
+
+ public JobManagerConfiguration jobManagerConfiguration;
+
+ private ServerInfo serverInfo;
+
+ private AuthenticationInfo authenticationInfo;
+
+ private Session session;
+
+ private ConfigReader configReader;
+
+ private JSch defaultJSch;
+
+ private static Identity identityFile = null;
+
+ public GSISSHAbstractCluster(ServerInfo serverInfo, AuthenticationInfo authenticationInfo, JobManagerConfiguration config) throws SSHApiException {
+ this(serverInfo, authenticationInfo);
+ this.jobManagerConfiguration = config;
+ }
+
+ public GSISSHAbstractCluster(ServerInfo serverInfo, AuthenticationInfo authenticationInfo) throws SSHApiException {
+
+ reconnect(serverInfo, authenticationInfo);
+ }
+
+ public GSISSHAbstractCluster(JobManagerConfiguration config) {
+ this.jobManagerConfiguration = config;
+ }
+ private synchronized void reconnect(ServerInfo serverInfo, AuthenticationInfo authenticationInfo) throws SSHApiException {
+ this.serverInfo = serverInfo;
+
+ this.authenticationInfo = authenticationInfo;
+
+ if (authenticationInfo instanceof GSIAuthenticationInfo) {
+ JSch.setConfig("gssapi-with-mic.x509", "org.apache.airavata.gfac.ssh.GSSContextX509");
+ JSch.setConfig("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMICGSSCredentials");
+ System.setProperty(X509_CERT_DIR, (String) ((GSIAuthenticationInfo) authenticationInfo).getProperties().
+ get("X509_CERT_DIR"));
+ }
+
+
+ try {
+ this.configReader = new ConfigReader();
+ } catch (IOException e) {
+ throw new SSHApiException("Unable to load system configurations.", e);
+ }
+ try {
+ if(defaultJSch == null){
+ defaultJSch = createJSch(authenticationInfo);
+ }
+ log.debug("Connecting to server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " with user name - "
+ + serverInfo.getUserName());
+
+ session = createSession(defaultJSch,serverInfo.getUserName(), serverInfo.getHost(), serverInfo.getPort());
+ }
+ catch (Exception e) {
+ throw new SSHApiException("An exception occurred while creating SSH session." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName(), e);
+ }
+
+ //=============================================================
+ // Handling vanilla SSH pieces
+ //=============================================================
+ if (authenticationInfo instanceof SSHPasswordAuthentication) {
+ String password = ((SSHPasswordAuthentication) authenticationInfo).
+ getPassword(serverInfo.getUserName(), serverInfo.getHost());
+
+ session.setUserInfo(new SSHAPIUIKeyboardInteractive(password));
+
+ // TODO figure out why we need to set password to session
+ session.setPassword(password);
+
+ } else if (authenticationInfo instanceof SSHPublicKeyFileAuthentication) {
+
+ SSHPublicKeyFileAuthentication sshPublicKeyFileAuthentication
+ = (SSHPublicKeyFileAuthentication) authenticationInfo;
+ String privateKeyFile = sshPublicKeyFileAuthentication.
+ getPrivateKeyFile(serverInfo.getUserName(), serverInfo.getHost());
+
+ logDebug("The private key file for vanilla SSH " + privateKeyFile);
+
+ String publicKeyFile = sshPublicKeyFileAuthentication.
+ getPublicKeyFile(serverInfo.getUserName(), serverInfo.getHost());
+
+ logDebug("The public key file for vanilla SSH " + publicKeyFile);
+
+ try {
+ identityFile = GSISSHIdentityFile.newInstance(privateKeyFile, null, defaultJSch);
+ } catch (JSchException e) {
+ throw new SSHApiException("An exception occurred while initializing keys using files. " +
+ "(private key and public key)." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName() + " private key file - " + privateKeyFile + ", public key file - " +
+ publicKeyFile, e);
+ }
+
+ // Add identity to identity repository
+ GSISSHIdentityRepository identityRepository = new GSISSHIdentityRepository(defaultJSch);
+ identityRepository.add(identityFile);
+
+ // Set repository to session
+ session.setIdentityRepository(identityRepository);
+
+ // Set the user info
+ SSHKeyPasswordHandler sshKeyPasswordHandler
+ = new SSHKeyPasswordHandler((SSHKeyAuthentication) authenticationInfo);
+
+ session.setUserInfo(sshKeyPasswordHandler);
+
+ } else if (authenticationInfo instanceof SSHPublicKeyAuthentication) {
+
+ SSHPublicKeyAuthentication sshPublicKeyAuthentication
+ = (SSHPublicKeyAuthentication) authenticationInfo;
+ try {
+ String name = serverInfo.getUserName() + "_" + serverInfo.getHost();
+ identityFile = GSISSHIdentityFile.newInstance(name,
+ sshPublicKeyAuthentication.getPrivateKey(serverInfo.getUserName(), serverInfo.getHost()),
+ sshPublicKeyAuthentication.getPublicKey(serverInfo.getUserName(), serverInfo.getHost()), defaultJSch);
+ } catch (JSchException e) {
+ throw new SSHApiException("An exception occurred while initializing keys using byte arrays. " +
+ "(private key and public key)." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName(), e);
+ }
+
+ // Add identity to identity repository
+ GSISSHIdentityRepository identityRepository = new GSISSHIdentityRepository(defaultJSch);
+ identityRepository.add(identityFile);
+
+ // Set repository to session
+ session.setIdentityRepository(identityRepository);
+
+ // Set the user info
+ SSHKeyPasswordHandler sshKeyPasswordHandler
+ = new SSHKeyPasswordHandler((SSHKeyAuthentication) authenticationInfo);
+
+ session.setUserInfo(sshKeyPasswordHandler);
+
+ }
+
+ // Not a good way, but we dont have any choice
+ if (session instanceof ExtendedSession) {
+ if (authenticationInfo instanceof GSIAuthenticationInfo) {
+ ((ExtendedSession) session).setAuthenticationInfo((GSIAuthenticationInfo) authenticationInfo);
+ }
+ }
+
+ try {
+ session.connect(Integer.parseInt(configReader.getConfiguration(SSH_SESSION_TIMEOUT)));
+ } catch (Exception e) {
+ throw new SSHApiException("An exception occurred while connecting to server." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName(), e);
+ }
+ }
+
+ public synchronized JobDescriptor cancelJob(String jobID) throws SSHApiException {
+ JobStatus jobStatus = getJobStatus(jobID);
+ if (jobStatus == null || jobStatus == JobStatus.U) {
+ log.info("Validation before cancel is failed, couldn't found job in remote host to cancel. Job may be already completed|failed|canceled");
+ return null;
+ }
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getCancelCommand(jobID);
+
+ StandardOutReader stdOutReader = new StandardOutReader();
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.getSession(), stdOutReader);
+ String outputifAvailable = getOutputifAvailable(stdOutReader, "Error reading output of job submission", jobManagerConfiguration.getBaseCancelCommand());
+ // this might not be the case for all teh resources, if so Cluster implementation can override this method
+ // because here after cancelling we try to get the job description and return it back
+ try {
+ return this.getJobDescriptorById(jobID);
+ } catch (Exception e) {
+ //its ok to fail to get status when the job is gone
+ return null;
+ }
+ }
+
+ public synchronized String submitBatchJobWithScript(String scriptPath, String workingDirectory) throws SSHApiException {
+ this.scpTo(workingDirectory, scriptPath);
+
+ // since this is a constant we do not ask users to fill this
+
+// RawCommandInfo rawCommandInfo = new RawCommandInfo(this.installedPath + this.jobManagerConfiguration.getSubmitCommand() + " " +
+// workingDirectory + File.separator + FilenameUtils.getName(scriptPath));
+
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getSubmitCommand(workingDirectory,scriptPath);
+ StandardOutReader standardOutReader = new StandardOutReader();
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.session, standardOutReader);
+
+ //Check whether pbs submission is successful or not, if it failed throw and exception in submitJob method
+ // with the error thrown in qsub command
+ //
+ String outputifAvailable = getOutputifAvailable(standardOutReader,"Error reading output of job submission",jobManagerConfiguration.getBaseSubmitCommand());
+ OutputParser outputParser = jobManagerConfiguration.getParser();
+ return outputParser.parseJobSubmission(outputifAvailable);
+ }
+
+ public synchronized String submitBatchJob(JobDescriptor jobDescriptor) throws SSHApiException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ URL resource = this.getClass().getClassLoader().getResource(jobManagerConfiguration.getJobDescriptionTemplateName());
+
+ if (resource == null) {
+ String error = "System configuration file '" + jobManagerConfiguration.getJobDescriptionTemplateName()
+ + "' not found in the classpath";
+ throw new SSHApiException(error);
+ }
+
+ Source xslt = new StreamSource(new File(resource.getPath()));
+ Transformer transformer;
+ StringWriter results = new StringWriter();
+ File tempPBSFile = null;
+ try {
+ // generate the pbs script using xslt
+ transformer = factory.newTransformer(xslt);
+ Source text = new StreamSource(new ByteArrayInputStream(jobDescriptor.toXML().getBytes()));
+ transformer.transform(text, new StreamResult(results));
+ String scriptContent = results.toString().replaceAll("^[ |\t]*\n$", "");
+ if (scriptContent.startsWith("\n")) {
+ scriptContent = scriptContent.substring(1);
+ }
+// log.debug("generated PBS:" + results.toString());
+
+ // creating a temporary file using pbs script generated above
+ int number = new SecureRandom().nextInt();
+ number = (number < 0 ? -number : number);
+
+ tempPBSFile = new File(Integer.toString(number) + jobManagerConfiguration.getScriptExtension());
+ FileUtils.writeStringToFile(tempPBSFile, scriptContent);
+
+ //reusing submitBatchJobWithScript method to submit a job
+ String jobID = null;
+ int retry = 3;
+ while(retry>0) {
+ try {
+ jobID = this.submitBatchJobWithScript(tempPBSFile.getAbsolutePath(),
+ jobDescriptor.getWorkingDirectory());
+ retry=0;
+ } catch (SSHApiException e) {
+ retry--;
+ if(retry==0) {
+ throw e;
+ }else{
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ log.error("Error occured during job submission but doing a retry");
+ }
+ }
+ }
+ log.debug("Job has successfully submitted, JobID : " + jobID);
+ if (jobID != null) {
+ return jobID.replace("\n", "");
+ } else {
+ return null;
+ }
+ } catch (TransformerConfigurationException e) {
+ throw new SSHApiException("Error parsing PBS transformation", e);
+ } catch (TransformerException e) {
+ throw new SSHApiException("Error generating PBS script", e);
+ } catch (IOException e) {
+ throw new SSHApiException("An exception occurred while connecting to server." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName(), e);
+ } finally {
+ if (tempPBSFile != null) {
+ tempPBSFile.delete();
+ }
+ }
+ }
+
+
+ public void generateJobScript(JobDescriptor jobDescriptor) throws SSHApiException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ URL resource = this.getClass().getClassLoader().getResource(jobManagerConfiguration.getJobDescriptionTemplateName());
+
+ if (resource == null) {
+ String error = "System configuration file '" + jobManagerConfiguration.getJobDescriptionTemplateName()
+ + "' not found in the classpath";
+ throw new SSHApiException(error);
+ }
+
+ Source xslt = new StreamSource(new File(resource.getPath()));
+ Transformer transformer;
+ StringWriter results = new StringWriter();
+ File tempPBSFile = null;
+ try {
+ // generate the pbs script using xslt
+ transformer = factory.newTransformer(xslt);
+ Source text = new StreamSource(new ByteArrayInputStream(jobDescriptor.toXML().getBytes()));
+ transformer.transform(text, new StreamResult(results));
+ String scriptContent = results.toString().replaceAll("^[ |\t]*\n$", "");
+ if (scriptContent.startsWith("\n")) {
+ scriptContent = scriptContent.substring(1);
+ }
+// log.debug("generated PBS:" + results.toString());
+
+ // creating a temporary file using pbs script generated above
+ int number = new SecureRandom().nextInt();
+ number = (number < 0 ? -number : number);
+
+ tempPBSFile = new File(Integer.toString(number) + jobManagerConfiguration.getScriptExtension());
+ log.info("File Path: " + tempPBSFile.getAbsolutePath());
+ log.info("File Content: " + scriptContent);
+ FileUtils.writeStringToFile(tempPBSFile, scriptContent);
+ } catch (TransformerConfigurationException e) {
+ throw new SSHApiException("Error parsing PBS transformation", e);
+ } catch (TransformerException e) {
+ throw new SSHApiException("Error generating PBS script", e);
+ } catch (IOException e) {
+ throw new SSHApiException("An exception occurred while connecting to server." +
+ "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() +
+ " connecting user name - "
+ + serverInfo.getUserName(), e);
+ } finally {
+ if (tempPBSFile != null) {
+ tempPBSFile.delete();
+ }
+ }
+ }
+
+
+
+ public synchronized JobDescriptor getJobDescriptorById(String jobID) throws SSHApiException {
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getMonitorCommand(jobID);
+ StandardOutReader stdOutReader = new StandardOutReader();
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.getSession(), stdOutReader);
+ String result = getOutputifAvailable(stdOutReader, "Error getting job information from the resource !",jobManagerConfiguration.getBaseMonitorCommand());
+ JobDescriptor jobDescriptor = new JobDescriptor();
+ jobManagerConfiguration.getParser().parseSingleJob(jobDescriptor, result);
+ return jobDescriptor;
+ }
+
+ public synchronized JobStatus getJobStatus(String jobID) throws SSHApiException {
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getMonitorCommand(jobID);
+ StandardOutReader stdOutReader = new StandardOutReader();
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.getSession(), stdOutReader);
+ String result = getOutputifAvailable(stdOutReader, "Error getting job information from the resource !", jobManagerConfiguration.getBaseMonitorCommand());
+ return jobManagerConfiguration.getParser().parseJobStatus(jobID, result);
+ }
+
+ @Override
+ public String getJobIdByJobName(String jobName, String userName) throws SSHApiException {
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getJobIdMonitorCommand(jobName, userName);
+ StandardOutReader stdOutReader = new StandardOutReader();
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.getSession(), stdOutReader);
+ String result = getOutputifAvailable(stdOutReader, "Error getting job information from the resource !",
+ jobManagerConfiguration.getJobIdMonitorCommand(jobName,userName).getCommand());
+ return jobManagerConfiguration.getParser().parseJobId(jobName, result);
+ }
+
+ private static void logDebug(String message) {
+ if (log.isDebugEnabled()) {
+ log.debug(message);
+ }
+ }
+
+ public JobManagerConfiguration getJobManagerConfiguration() {
+ return jobManagerConfiguration;
+ }
+
+ public void setJobManagerConfiguration(JobManagerConfiguration jobManagerConfiguration) {
+ this.jobManagerConfiguration = jobManagerConfiguration;
+ }
+
+ public synchronized void scpTo(String remoteFile, String localFile) throws SSHApiException {
+ int retry = 3;
+ while (retry > 0) {
+ try {
+ if (!session.isConnected()) {
+ session.connect();
+ }
+ log.info("Transfering file:/" + localFile + " To:" + serverInfo.getHost() + ":" + remoteFile);
+ SSHUtils.scpTo(remoteFile, localFile, session);
+ retry = 0;
+ } catch (IOException e) {
+ retry--;
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during scping local file:" + localFile + " to remote file "
+ + serverInfo.getHost() + ":rFile : " + remoteFile, e);
+ }
+ } catch (JSchException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during scping local file:" + localFile + " to remote file "
+ + serverInfo.getHost() + ":rFile : " + remoteFile, e);
+ }
+ }
+ }
+ }
+
+ public synchronized void scpFrom(String remoteFile, String localFile) throws SSHApiException {
+ int retry = 3;
+ while(retry>0) {
+ try {
+ if (!session.isConnected()) {
+ session.connect();
+ }
+ log.info("Transfering from:" + serverInfo.getHost() + ":" + remoteFile + " To:" + "file:/" + localFile);
+ SSHUtils.scpFrom(remoteFile, localFile, session);
+ retry=0;
+ } catch (IOException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during scping local file:" + localFile + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ }else{
+ log.error("Error performing scp but doing a retry");
+ }
+ } catch (JSchException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if(retry==0) {
+ throw new SSHApiException("Failed during scping local file:" + localFile + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ }else{
+ log.error("Error performing scp but doing a retry");
+ }
+ }
+ }
+ }
+
+ public synchronized void scpThirdParty(String remoteFileSource, String remoteFileTarget) throws SSHApiException {
+ try {
+ if(!session.isConnected()){
+ session.connect();
+ }
+ log.info("Transfering from:" + remoteFileSource + " To: " + remoteFileTarget);
+ SSHUtils.scpThirdParty(remoteFileSource, remoteFileTarget, session);
+ } catch (IOException e) {
+ throw new SSHApiException("Failed during scping file:" + remoteFileSource + " to remote file "
+ +remoteFileTarget , e);
+ } catch (JSchException e) {
+ throw new SSHApiException("Failed during scping file:" + remoteFileSource + " to remote file "
+ +remoteFileTarget, e);
+ }
+ }
+
+ public synchronized void makeDirectory(String directoryPath) throws SSHApiException {
+ int retry = 3;
+ while (retry > 0) {
+ try {
+ if (!session.isConnected()) {
+ session.connect();
+ }
+ log.info("Creating directory: " + serverInfo.getHost() + ":" + directoryPath);
+ SSHUtils.makeDirectory(directoryPath, session);
+ retry = 0;
+ } catch (IOException e) {
+ throw new SSHApiException("Failed during creating directory:" + directoryPath + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ } catch (JSchException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during creating directory :" + directoryPath + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ }
+ } catch (SSHApiException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during creating directory :" + directoryPath + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ }
+ }
+ }
+ }
+
+ public synchronized List<String> listDirectory(String directoryPath) throws SSHApiException {
+ int retry = 3;
+ List<String> files = null;
+ while (retry > 0) {
+ try {
+ if (!session.isConnected()) {
+ session.connect();
+ }
+ log.info("Listing directory: " + serverInfo.getHost() + ":" + directoryPath);
+ files = SSHUtils.listDirectory(directoryPath, session);
+ retry=0;
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during listing directory:" + directoryPath + " to remote file ", e);
+ }
+ } catch (JSchException e) {
+ retry--;
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during listing directory :" + directoryPath + " to remote file ", e);
+ }
+ }catch (SSHApiException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed during listing directory :" + directoryPath + " to remote file "
+ + serverInfo.getHost() + ":rFile", e);
+ }
+ }
+ }
+ return files;
+ }
+
+ public synchronized void getJobStatuses(String userName, Map<String,JobStatus> jobIDs)throws SSHApiException {
+ int retry = 3;
+ RawCommandInfo rawCommandInfo = jobManagerConfiguration.getUserBasedMonitorCommand(userName);
+ StandardOutReader stdOutReader = new StandardOutReader();
+ while (retry > 0){
+ try {
+ log.info("Executing RawCommand : " + rawCommandInfo.getCommand());
+ CommandExecutor.executeCommand(rawCommandInfo, this.getSession(), stdOutReader);
+ retry=0;
+ } catch (SSHApiException e) {
+ retry--;
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error(e1.getMessage(), e1);
+ }
+ reconnect(serverInfo, authenticationInfo);
+ if (retry == 0) {
+ throw new SSHApiException("Failed Getting statuses to remote file", e);
+ }
+ }
+ }
+ String result = getOutputifAvailable(stdOutReader, "Error getting job information from the resource !", jobManagerConfiguration.getBaseMonitorCommand());
+ jobManagerConfiguration.getParser().parseJobStatuses(userName, jobIDs, result);
+ }
+
+ public ServerInfo getServerInfo() {
+ return serverInfo;
+ }
+
+ public AuthenticationInfo getAuthenticationInfo() {
+ return authenticationInfo;
+ }
+
+ /**
+ * This gaurantee to return a valid session
+ *
+ * @return
+ */
+ public Session getSession() {
+ return this.session;
+ }
+
+ /**
+ * This method will read standard output and if there's any it will be parsed
+ *
+ * @param jobIDReaderCommandOutput
+ * @param errorMsg
+ * @return
+ * @throws SSHApiException
+ */
+ private String getOutputifAvailable(StandardOutReader jobIDReaderCommandOutput, String errorMsg, String command) throws SSHApiException {
+ String stdOutputString = jobIDReaderCommandOutput.getStdOutputString();
+ String stdErrorString = jobIDReaderCommandOutput.getStdErrorString();
+ log.info("StandardOutput Returned:" + stdOutputString);
+ log.info("StandardError Returned:" +stdErrorString);
+ String[] list = command.split(File.separator);
+ command = list[list.length - 1];
+ // We are checking for stderr containing the command issued. Thus ignores the verbose logs in stderr.
+ if (stdErrorString != null && stdErrorString.contains(command.trim()) && !stdErrorString.contains("Warning")) {
+ log.error("Standard Error output : " + stdErrorString);
+ throw new SSHApiException(errorMsg + "\n\r StandardOutput: "+ stdOutputString + "\n\r StandardError: "+ stdErrorString);
+ }else if(stdOutputString.contains("error")){
+ throw new SSHApiException(errorMsg + "\n\r StandardOutput: "+ stdOutputString + "\n\r StandardError: "+ stdErrorString);
+ }
+ return stdOutputString;
+ }
+
+ public void disconnect() throws SSHApiException {
+ if(getSession().isConnected()){
+ getSession().disconnect();
+ }
+ }
+ /**
+
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
+ * @return the new default JSch implementation.
+ * @throws JSchException
+ * known host keys cannot be loaded.
+ */
+ protected JSch createJSch(AuthenticationInfo authenticationInfo) throws JSchException {
+// final File fs = new File(System.getProperty("user.home"));
+ if(authenticationInfo instanceof GSIAuthenticationInfo){
+ final JSch jsch = new ExtendedJSch();
+// knownHosts(jsch, fs);
+ return jsch;
+ }else{
+ final JSch jsch = new JSch();
+// knownHosts(jsch, fs);
+ return jsch;
+ }
+
+ }
+ /**
+ * Create a new remote session for the requested address.
+ *
+ * @param user
+ * login to authenticate as.
+ * @param host
+ * server name to connect to.
+ * @param port
+ * port number of the SSH daemon (typically 22).
+ * @return new session instance, but otherwise unconfigured.
+ * @throws JSchException
+ * the session could not be created.
+ */
+ private Session createSession(JSch jsch, String user, String host, int port) throws JSchException {
+ final Session session = jsch.getSession(user, host, port);
+ // We retry already in getSession() method. JSch must not retry
+ // on its own.
+ session.setConfig("MaxAuthTries", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+ session.setTimeout(Integer.parseInt(configReader.getConfiguration(SSH_SESSION_TIMEOUT)));
+ java.util.Properties config = this.configReader.getProperties();
+ session.setConfig(config);
+
+ return session;
+ }
+ private static void knownHosts(final JSch sch,final File home) throws JSchException {
+ if (home == null)
+ return;
+ final File known_hosts = new File(new File(home, ".ssh"), "known_hosts"); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ final FileInputStream in = new FileInputStream(known_hosts);
+ try {
+ sch.setKnownHosts(in);
+ } finally {
+ in.close();
+ }
+ } catch (FileNotFoundException none) {
+ // Oh well. They don't have a known hosts in home.
+ } catch (IOException err) {
+ // Oh well. They don't have a known hosts in home.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/JobStatus.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/JobStatus.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/JobStatus.java
new file mode 100644
index 0000000..648d955
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/JobStatus.java
@@ -0,0 +1,110 @@
+ /*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+ package org.apache.airavata.gfac.ssh.impl;
+
+ /**
+ * This will contains all the PBS specific job statuses.
+ * C - Job is completed after having run/
+ * E - Job is exiting after having run.
+ * H - Job is held.
+ * Q - job is queued, eligible to run or routed.
+ * R - job is running.
+ * T - job is being moved to new location.
+ * W - job is waiting for its execution time
+ * (-a option) to be reached.
+ * S - (Unicos only) job is suspend.
+ */
+ public enum JobStatus {
+ C, E, H, Q, R, T, W, S,U,F,CA,CD,CF,CG,NF,PD,PR,TO,qw,t,r,h,Er,Eqw,PEND,RUN,PSUSP,USUSP,SSUSP,DONE,EXIT,UNKWN,ZOMBI;
+
+ public static JobStatus fromString(String status){
+ if(status != null){
+ if("C".equals(status)){
+ return JobStatus.C;
+ }else if("E".equals(status)){
+ return JobStatus.E;
+ }else if("H".equals(status)){
+ return JobStatus.H;
+ }else if("Q".equals(status)){
+ return JobStatus.Q;
+ }else if("R".equals(status)){
+ return JobStatus.R;
+ }else if("T".equals(status)){
+ return JobStatus.T;
+ }else if("W".equals(status)){
+ return JobStatus.W;
+ }else if("S".equals(status)){
+ return JobStatus.S;
+ }else if("F".equals(status)){
+ return JobStatus.F;
+ }else if("S".equals(status)){
+ return JobStatus.S;
+ }else if("CA".equals(status)){
+ return JobStatus.CA;
+ }else if("CF".equals(status)){
+ return JobStatus.CF;
+ }else if("CD".equals(status)){
+ return JobStatus.CD;
+ }else if("CG".equals(status)){
+ return JobStatus.CG;
+ }else if("NF".equals(status)){
+ return JobStatus.NF;
+ }else if("PD".equals(status)){
+ return JobStatus.PD;
+ }else if("PR".equals(status)){
+ return JobStatus.PR;
+ }else if("TO".equals(status)){
+ return JobStatus.TO;
+ }else if("U".equals(status)){
+ return JobStatus.U;
+ }else if("qw".equals(status)){
+ return JobStatus.qw;
+ }else if("t".equals(status)){
+ return JobStatus.t;
+ }else if("r".equals(status)){
+ return JobStatus.r;
+ }else if("h".equals(status)){
+ return JobStatus.h;
+ }else if("Er".equals(status)){
+ return JobStatus.Er;
+ }else if("Eqw".equals(status)){
+ return JobStatus.Er;
+ }else if("RUN".equals(status)){ // LSF starts here
+ return JobStatus.RUN;
+ }else if("PEND".equals(status)){
+ return JobStatus.PEND;
+ }else if("DONE".equals(status)){
+ return JobStatus.DONE;
+ }else if("PSUSP".equals(status)){
+ return JobStatus.PSUSP;
+ }else if("USUSP".equals(status)){
+ return JobStatus.USUSP;
+ }else if("SSUSP".equals(status)){
+ return JobStatus.SSUSP;
+ }else if("EXIT".equals(status)){
+ return JobStatus.EXIT;
+ }else if("ZOMBI".equals(status)){
+ return JobStatus.ZOMBI;
+ }
+ }
+ return JobStatus.U;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/PBSCluster.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/PBSCluster.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/PBSCluster.java
new file mode 100644
index 0000000..def84d5
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/PBSCluster.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.impl;
+
+import org.apache.airavata.gfac.ssh.api.*;
+import org.apache.airavata.gfac.ssh.api.authentication.*;
+import org.apache.airavata.gfac.ssh.api.job.JobManagerConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This is the default implementation of a cluster.
+ * this has most of the methods to be used by the end user of the
+ * library.
+ */
+public class PBSCluster extends GSISSHAbstractCluster {
+ private static final Logger log = LoggerFactory.getLogger(PBSCluster.class);
+
+
+ public PBSCluster(JobManagerConfiguration jobManagerConfiguration) {
+ super(jobManagerConfiguration);
+ }
+ public PBSCluster(ServerInfo serverInfo, AuthenticationInfo authenticationInfo, JobManagerConfiguration config) throws SSHApiException {
+ super(serverInfo, authenticationInfo,config);
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/RawCommandInfo.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/RawCommandInfo.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/RawCommandInfo.java
new file mode 100644
index 0000000..9ac2ba0
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/RawCommandInfo.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl;
+
+import org.apache.airavata.gfac.ssh.api.CommandInfo;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 8/14/13
+ * Time: 5:18 PM
+ */
+
+/**
+ * The raw command information. String returned by getCommand is directly executed in SSH
+ * shell. E.g :- getCommand return string set for rawCommand - "/opt/torque/bin/qsub /home/ogce/test.pbs".
+ */
+public class RawCommandInfo implements CommandInfo {
+
+ private String rawCommand;
+
+ public RawCommandInfo(String cmd) {
+ this.rawCommand = cmd;
+ }
+
+ public String getCommand() {
+ return this.rawCommand;
+ }
+
+ public String getRawCommand() {
+ return rawCommand;
+ }
+
+ public void setRawCommand(String rawCommand) {
+ this.rawCommand = rawCommand;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SSHUserInfo.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SSHUserInfo.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SSHUserInfo.java
new file mode 100644
index 0000000..e878dff
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SSHUserInfo.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl;
+
+import com.jcraft.jsch.UserInfo;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 9/20/13
+ * Time: 2:31 PM
+ */
+
+public class SSHUserInfo implements UserInfo {
+
+ private String password;
+
+ public SSHUserInfo(String pwd) {
+ this.password = pwd;
+ }
+
+ public String getPassphrase() {
+ return this.password;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public boolean promptPassword(String message) {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean promptPassphrase(String message) {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean promptYesNo(String message) {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void showMessage(String message) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/StandardOutReader.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/StandardOutReader.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/StandardOutReader.java
new file mode 100644
index 0000000..265a57d
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/StandardOutReader.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.gfac.ssh.impl;
+
+import com.jcraft.jsch.Channel;
+
+import org.apache.airavata.gfac.ssh.api.CommandOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class StandardOutReader implements CommandOutput {
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardOutReader.class);
+ String stdOutputString = null;
+ ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
+ public void onOutput(Channel channel) {
+ try {
+ StringBuffer pbsOutput = new StringBuffer("");
+ InputStream inputStream = channel.getInputStream();
+ byte[] tmp = new byte[1024];
+ do {
+ while (inputStream.available() > 0) {
+ int i = inputStream.read(tmp, 0, 1024);
+ if (i < 0) break;
+ pbsOutput.append(new String(tmp, 0, i));
+ }
+ } while (!channel.isClosed()) ;
+ String output = pbsOutput.toString();
+ this.setStdOutputString(output);
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+
+ }
+
+
+ public void exitCode(int code) {
+ System.out.println("Program exit code - " + code);
+ }
+
+ public String getStdOutputString() {
+ return stdOutputString;
+ }
+
+ public void setStdOutputString(String stdOutputString) {
+ this.stdOutputString = stdOutputString;
+ }
+
+ public String getStdErrorString() {
+ return errorStream.toString();
+ }
+
+ public OutputStream getStandardError() {
+ return errorStream;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SystemCommandOutput.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SystemCommandOutput.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SystemCommandOutput.java
new file mode 100644
index 0000000..24d218b
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/SystemCommandOutput.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl;
+
+import com.jcraft.jsch.Channel;
+import org.apache.airavata.gfac.ssh.api.CommandOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 8/15/13
+ * Time: 10:44 AM
+ */
+
+public class SystemCommandOutput implements CommandOutput {
+
+ private static final Logger logger = LoggerFactory.getLogger(SystemCommandOutput.class);
+ public void onOutput(Channel channel) {
+ try {
+ InputStream inputStream = channel.getInputStream();
+
+ byte[] tmp = new byte[1024];
+ while (true) {
+ while (inputStream.available() > 0) {
+ int i = inputStream.read(tmp, 0, 1024);
+ if (i < 0) break;
+ System.out.print(new String(tmp, 0, i));
+ }
+ if (channel.isClosed()) {
+ System.out.println("exit-status: " + channel.getExitStatus());
+ break;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ignored) {
+ }
+ }
+
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+
+ }
+
+ public OutputStream getStandardError() {
+ return System.err;
+ }
+
+ public void exitCode(int code) {
+ System.out.println("Program exit code - " + code);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPasswordAuthenticationInfo.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPasswordAuthenticationInfo.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPasswordAuthenticationInfo.java
new file mode 100644
index 0000000..29cd154
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPasswordAuthenticationInfo.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl.authentication;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 9/20/13
+ * Time: 12:15 PM
+ */
+
+import org.apache.airavata.gfac.core.authentication.SSHPasswordAuthentication;
+
+/**
+ * An authenticator used for raw SSH sessions. Gives SSH user name, password
+ * directly.
+ * This is only an example implementation.
+ */
+public class DefaultPasswordAuthenticationInfo implements SSHPasswordAuthentication {
+
+ private String password;
+
+ public DefaultPasswordAuthenticationInfo(String pwd) {
+ this.password = pwd;
+ }
+
+ public String getPassword(String userName, String hostName) {
+ return password;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyAuthentication.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyAuthentication.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyAuthentication.java
new file mode 100644
index 0000000..35595ed
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyAuthentication.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl.authentication;
+
+import org.apache.airavata.gfac.core.authentication.SSHPublicKeyAuthentication;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 10/4/13
+ * Time: 11:44 AM
+ */
+
+/**
+ * Default public key authentication.
+ * Note : This is only a sample implementation.
+ */
+public class DefaultPublicKeyAuthentication implements SSHPublicKeyAuthentication {
+
+ private byte[] privateKey;
+ private byte[] publicKey;
+ private String passPhrase = null;
+
+ public DefaultPublicKeyAuthentication(byte[] priv, byte[] pub) {
+ this.privateKey = priv;
+ this.publicKey = pub;
+ }
+
+ public DefaultPublicKeyAuthentication(byte[] priv, byte[] pub, String pass) {
+ this.privateKey = priv;
+ this.publicKey = pub;
+ this.passPhrase = pass;
+ }
+
+ public String getPassPhrase() {
+ return passPhrase;
+ }
+
+ public void bannerMessage(String message) {
+ System.out.println(message);
+ }
+
+ public byte[] getPrivateKey(String userName, String hostName) {
+ return privateKey;
+ }
+
+ public byte[] getPublicKey(String userName, String hostName) {
+ return publicKey;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/7b809747/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyFileAuthentication.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyFileAuthentication.java b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyFileAuthentication.java
new file mode 100644
index 0000000..480213c
--- /dev/null
+++ b/modules/gfac/gfac-impl/src/main/java/org/apache/airavata/gfac/gsi/ssh/impl/authentication/DefaultPublicKeyFileAuthentication.java
@@ -0,0 +1,70 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.gfac.ssh.impl.authentication;
+
+import org.apache.airavata.gfac.core.authentication.SSHPublicKeyFileAuthentication;
+
+/**
+ * User: AmilaJ (amilaj@apache.org)
+ * Date: 10/4/13
+ * Time: 11:40 AM
+ */
+
+/**
+ * Default public key authentication using files.
+ * Note : This is only a sample implementation.
+ */
+public class DefaultPublicKeyFileAuthentication implements SSHPublicKeyFileAuthentication {
+
+ private String publicKeyFile;
+ private String privateKeyFile;
+ private String passPhrase = null;
+
+ public DefaultPublicKeyFileAuthentication(String pubFile, String privFile) {
+ this.publicKeyFile = pubFile;
+ this.privateKeyFile = privFile;
+
+ }
+
+ public DefaultPublicKeyFileAuthentication(String pubFile, String privFile, String pass) {
+ this.publicKeyFile = pubFile;
+ this.privateKeyFile = privFile;
+ this.passPhrase = pass;
+
+ }
+
+ public String getPassPhrase() {
+ return passPhrase;
+ }
+
+ public void bannerMessage(String message) {
+ System.out.println(message);
+ }
+
+ public String getPublicKeyFile(String userName, String hostName) {
+ return publicKeyFile;
+ }
+
+ public String getPrivateKeyFile(String userName, String hostName) {
+ return privateKeyFile;
+ }
+}