Commits

Arul Dhesiaseelan committed 7857e3c

Upgrading Jsoup to 1.6.1 and Scribe to 1.2.1. Adding initial prototype for SCPAction.

Comments (0)

Files changed (10)

     <module>untarfile-action</module>
     <module>unzipfile-action</module>
     <module>webservice-trigger</module>
+    <module>scp-action</module>
   </modules>
   <prerequisites>
     <maven>2.0.9</maven>
     <assembly.directory>${project.build.directory}/assembly</assembly.directory>
     <flux.version>7.11.1</flux.version>
     <amqp.version>2.4.1</amqp.version>
-    <jsoup.version>1.5.2</jsoup.version>
-    <scribe.version>1.2.0</scribe.version>
+    <jsoup.version>1.6.1</jsoup.version>
+    <scribe.version>1.2.1</scribe.version>
     <commons.io.version>1.2</commons.io.version>
     <commons.cli.version>1.1</commons.cli.version>
     <commons.codec.version>1.4</commons.codec.version>

scp-action/pom.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>plugins</artifactId>
+    <groupId>com.fluxcorp.plugins</groupId>
+    <version>1.0.3.SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.fluxcorp.plugins</groupId>
+  <artifactId>scp-action</artifactId>
+  <name>SCP Action</name>
+  <packaging>jar</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>net.schmizz</groupId>
+      <artifactId>sshj</artifactId>
+      <version>0.5.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.jcraft</groupId>
+      <artifactId>jzlib</artifactId>
+      <version>1.0.7</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>1.6.1</version>
+    </dependency>
+  </dependencies>
+</project>

scp-action/src/main/java/flux/SCPAction.java

+package flux;
+
+/**
+ * SCPAction that transfers files over SSH.
+ *
+ * @author arul@fluxcorp.com
+ */
+public interface SCPAction extends Action {
+
+  /**
+   * Set the Host.
+   *
+   * @param host name of the host where broker is running.
+   */
+  public void setHost(String host);
+
+  /**
+   * Set the password.
+   *
+   * @param password password.
+   */
+  public void setPassword(String password);
+
+  /**
+   * Set the download flag. Defaults to true. For, upload set this to false.
+   *
+   * @param download download.
+   */
+  public void setDownload(boolean download);
+
+  /**
+   * Set the local filename.
+   *
+   * @param localFile Local filename
+   */
+  public void setLocalFile(String localFile);
+
+  /**
+   * Set the remote path.
+   *
+   * @param remotePath Remote path.
+   */
+  public void setRemotePath(String remotePath);
+
+  /**
+   * Set the username.
+   *
+   * @param username username.
+   */
+  public void setUsername(String username);
+}

scp-action/src/main/java/flux/SCPActionFactory.java

+package flux;
+
+import flux.dev.AdapterFactory;
+import fluximpl.FlowChartImpl;
+import fluximpl.SCPActionImpl;
+
+/**
+ * Factory for creating SCPAction.
+ *
+ * @author arul@fluxcorp.com
+ */
+public class SCPActionFactory implements AdapterFactory {
+
+  private FlowChartImpl flowChart;
+
+  public void init(FlowChartImpl flowChart) {
+    this.flowChart = flowChart;
+  } // init
+
+  public SCPAction makeSCPAction(String name) {
+    return new SCPActionImpl(flowChart, name);
+  } // makeSCPAction()
+} // class SCPActionFactory

scp-action/src/main/java/fluximpl/SCPActionImpl.java

+package fluximpl;
+
+import flux.EngineException;
+import flux.FlowContext;
+import flux.SCPAction;
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.xfer.FileSystemFile;
+import net.schmizz.sshj.xfer.scp.SCPFileTransfer;
+
+import java.util.Set;
+
+/**
+ * Implementation for SCPAction.
+ *
+ * @author arul@fluxcorp.com
+ */
+public class SCPActionImpl extends ActionImpl implements SCPAction {
+
+  private static final String ACTION_VARIABLE = "SCP_ACTION_VARIABLE";
+
+  public SCPActionImpl() {
+    super(new FlowChartImpl(), "SCP Action");
+  }
+
+  public SCPActionImpl(FlowChartImpl fc, String name) {
+    super(fc, name);
+  }
+
+  public Set<String> getHiddenVariableNames() {
+    // The returned raw type is a Set of String.
+    @SuppressWarnings("unchecked")
+    Set<String> set = super.getHiddenVariableNames();
+    set.add(ACTION_VARIABLE);
+    return set;
+  }
+
+  @Override
+  public void verify() throws EngineException {
+    if (StringUtil.isNullOrEmpty(getHost())) {
+      throw new EngineException("Expected \"Host\" to be non-null or non-empty, but it was null or empty.");
+    } // if
+    if (StringUtil.isNullOrEmpty(getUsername())) {
+      throw new EngineException("Expected \"Username\" to be non-null or non-empty, but it was null or empty.");
+    } // if
+    if (StringUtil.isNullOrEmpty(getLocalFile())) {
+      throw new EngineException("Expected \"Local file\" to be non-null or non-empty, but it was null or empty.");
+    } // if
+    if (StringUtil.isNullOrEmpty(getRemotePath())) {
+      throw new EngineException("Expected \"Remote path\" to be non-null or non-empty, but it was null or empty.");
+    } // if
+  }
+
+  @Override
+  public void setHost(String host) {
+    SCPActionVariable var = getVariable();
+    var.setHost(host);
+    putVariable(var);
+  }
+
+  public String getHost() {
+    return getVariable().getHost();
+  }
+
+  @Override
+  public void setPassword(String password) {
+    SCPActionVariable var = getVariable();
+    if (password != null) {
+      var.setPassword(Password.makePassword(password));
+    }
+    putVariable(var);
+  }
+
+  public String getPassword() {
+    Password password = getVariable().getPassword();
+    if (password != null) {
+      return password.getEncryptedPassword();
+    }
+    return null;
+
+  }
+
+  @Override
+  public void setUsername(String username) {
+    SCPActionVariable var = getVariable();
+    var.setUsername(username);
+    putVariable(var);
+  }
+
+  public String getUsername() {
+    return getVariable().getUsername();
+  }
+
+  @Override
+  public void setDownload(boolean download) {
+    SCPActionVariable var = getVariable();
+    var.setDownload(download);
+    putVariable(var);
+  }
+
+  public boolean getDownload() {
+    return getVariable().isDownload();
+  }
+
+  @Override
+  public void setLocalFile(String localFile) {
+    SCPActionVariable var = getVariable();
+    var.setLocalFile(localFile);
+    putVariable(var);
+  }
+
+  public String getLocalFile() {
+    return getVariable().getLocalFile();
+  }
+
+  @Override
+  public void setRemotePath(String remotePath) {
+    SCPActionVariable var = getVariable();
+    var.setRemotePath(remotePath);
+    putVariable(var);
+  }
+
+  public String getRemotePath() {
+    return getVariable().getRemotePath();
+  }
+
+  @Override
+  public Object execute(FlowContext flowContext) throws Exception {
+    final SSHClient ssh = new SSHClient();
+    ssh.loadKnownHosts();
+    ssh.connect(getHost());
+    try {
+      if (StringUtil.isNullOrEmpty(getPassword())) {
+        ssh.authPublickey(getUsername());
+      }
+      if (!StringUtil.isNullOrEmpty(getUsername()) && !StringUtil.isNullOrEmpty(getPassword())) {
+        ssh.authPassword(getUsername(), getPassword());
+      }
+      final SCPFileTransfer scp = ssh.newSCPFileTransfer();
+      if (getDownload()) {
+        scp.download(getRemotePath(), new FileSystemFile(getLocalFile()));
+      } else {
+        scp.upload(new FileSystemFile(getLocalFile()), getRemotePath());
+      }
+    } finally {
+      ssh.disconnect();
+    }
+
+    return null;  //To change body of implemented methods use File | Settings | File Templates.
+  }
+
+  private SCPActionVariable getVariable() {
+    if (!getVariableManager().contains(ACTION_VARIABLE)) {
+      getVariableManager().put(ACTION_VARIABLE, new SCPActionVariable());
+    }
+    return (SCPActionVariable) getVariableManager().get(ACTION_VARIABLE);
+  }
+
+  private void putVariable(SCPActionVariable variable) {
+    getVariableManager().put(ACTION_VARIABLE, variable);
+  }
+}

scp-action/src/main/java/fluximpl/SCPActionImplBeanInfo.java

+package fluximpl;
+
+import java.awt.*;
+import java.beans.BeanDescriptor;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.util.Arrays;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+/**
+ * BeanInfo for SCPAction.
+ *
+ * @author arul@fluxcorp.com
+ */
+public class SCPActionImplBeanInfo extends ActionImplBeanInfo {
+  /**
+   * A small image for this custom action to be displayed in the Flux GUI.
+   */
+  private Image smallImage;
+
+  /**
+   * A large image for this custom action to be displayed in the Flux GUI.
+   */
+  private Image bigImage;
+
+  protected BeanDescriptor bd = new BeanDescriptor(SCPActionImpl.class);
+
+  public SCPActionImplBeanInfo(BeanDescriptor bd) {
+    super();
+    this.bd = bd;
+    setCategory(bd, ActionImplBeanInfo.FILE);
+  }
+
+  public SCPActionImplBeanInfo() {
+    super();
+    bd.setDisplayName("SCP Action");
+    bd.setShortDescription("Performs SCP.");
+    setCategory(bd, ActionImplBeanInfo.FILE);
+  }
+
+
+  public Image getIcon(int type) {
+    if (type == BeanInfo.ICON_COLOR_16x16) {
+      return getSmallImage();
+    } // if
+    if (type == BeanInfo.ICON_COLOR_32x32) {
+      return getBigImage();
+    } // if
+    return null;
+  } // getIcon()
+
+  /**
+   * Returns a small image that represents this JavaBean.
+   *
+   * @return A small image that represents this JavaBean.
+   */
+  private Image getSmallImage() {
+    if (smallImage == null) {
+      smallImage = loadImage("/SCPActionImpl_small.png");
+    } // if
+    return smallImage;
+  } // getSmallImage()
+
+  /**
+   * Returns a large image that represents this JavaBean.
+   *
+   * @return A large image that represents this JavaBean.
+   */
+  private Image getBigImage() {
+    if (bigImage == null) {
+      bigImage = loadImage("/SCPActionImpl_big.png");
+    } // if
+    return bigImage;
+  } // getBigImage()
+
+
+  public BeanDescriptor getBeanDescriptor() {
+    return bd;
+  }
+
+  public PropertyDescriptor[] getPropertyDescriptors() {
+    Vector<PropertyDescriptor> descriptors = new Vector<PropertyDescriptor>(Arrays.asList(super.getPropertyDescriptors()));
+    try {
+      int order = 10;
+      descriptors.add(makePropertyDescriptor("host", "Hostname", SCPActionImpl.class.getName(), "getHost", true, null, order++, false, false, false, false));
+      descriptors.add(makePropertyDescriptor("username", "Username", SCPActionImpl.class.getName(), "getUsername", false, null, order++, false, false, false, false));
+      descriptors.add(makePropertyDescriptor("password", "Password", SCPActionImpl.class.getName(), "getPassword", false, null, order++, false, false, false, true));
+      descriptors.add(makePropertyDescriptor("localFile", "Local File", SCPActionImpl.class.getName(), "getLocalFile", true, null, order++, false, false, false, false));
+      descriptors.add(makePropertyDescriptor("remotePath", "Remote Path", SCPActionImpl.class.getName(), "getRemotePath", true, null, order++, false, false, false, false));
+      descriptors.add(makePropertyDescriptor("download", "Download", SCPActionImpl.class.getName(), "getDownload", false, null, order++, false, false, false, false));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new IllegalStateException("Could not create property descriptor.");
+    } // catch
+
+    return descriptors.toArray(new PropertyDescriptor[descriptors.size()]);
+  }
+
+  public PropertyDescriptor makePropertyDescriptor(String propertyName, String displayName, String className, String readMethod, boolean required, String propertyEditor, int order, boolean preferred, boolean common, boolean indexed, boolean password) throws IntrospectionException, ClassNotFoundException {
+    PropertyDescriptor descriptor;
+    try {
+      descriptor = new PropertyDescriptor(propertyName, getClazz(className));
+    }
+    catch (IntrospectionException e) {
+      descriptor = new PropertyDescriptor(propertyName, getClazz(className), readMethod, null);
+    }
+
+    return makePropertyDescriptor(displayName, required, propertyEditor, order, preferred, common, descriptor, password);
+  }
+
+  public PropertyDescriptor makePropertyDescriptor(String displayName, boolean required, String propertyEditor, int order, boolean preferred, boolean common, PropertyDescriptor descriptor, boolean password) throws ClassNotFoundException {
+    descriptor.setDisplayName(displayName);
+    descriptor.setValue("required", required);
+    descriptor.setValue("common", common);
+    descriptor.setValue("password", password);
+    descriptor.setPreferred(preferred);
+    String description = findPropertyDescription(this.getBeanDescriptor().getBeanClass(), descriptor.getName(), resourceBundle);
+    if (description != null) {
+      descriptor.setShortDescription(description);
+    }
+    descriptor.setHidden(false);
+    if (propertyEditor != null) {
+      descriptor.setPropertyEditorClass(getClazz(propertyEditor));
+    }
+    if (order != 0) {
+      descriptor.setValue("order", new Integer(order));
+    }
+    return descriptor;
+  }
+
+  private String findPropertyDescription(Class beanClass, String propertyName, ResourceBundle resourceBundle) {
+    String description = null;
+    try {
+      String className = beanClass.toString().replaceFirst("^class ", "");
+      String descPropertyName = className + "." + propertyName;
+      description = resourceBundle.getString(descPropertyName);
+    } catch (Exception e) {
+      Class superClass = beanClass.getSuperclass();
+      if (superClass != null) {
+        return findPropertyDescription(superClass, propertyName, resourceBundle);
+      } else {
+        return null;
+      }
+    }
+    return description;
+  }
+
+  public Class getClazz(String className) throws ClassNotFoundException {
+    try {
+      return Class.forName(className);
+    }
+    catch (ClassNotFoundException e) {
+      Thread t = Thread.currentThread();
+      ClassLoader cl = t.getContextClassLoader();
+      return cl.loadClass(className);
+    }
+  }
+
+  public void setCategory(BeanDescriptor beanDescriptor, String category) {
+    beanDescriptor.setValue("category", category);
+  }
+
+}

scp-action/src/main/java/fluximpl/SCPActionVariable.java

+package fluximpl;
+
+import java.io.Serializable;
+
+/**
+ * SCPAction variable.
+ *
+ * @author arul@fluxcorp.com
+ */
+public class SCPActionVariable implements Serializable {
+  private String username;
+  private Password password;
+  private String host;
+  private boolean download = true;
+  private String localFile;
+  private String remotePath;
+
+  public String getUsername() {
+    return username;
+  }
+
+  public void setUsername(String username) {
+    this.username = username;
+  }
+
+  public Password getPassword() {
+    return password;
+  }
+
+  public void setPassword(Password password) {
+    this.password = password;
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public void setHost(String host) {
+    this.host = host;
+  }
+
+  public boolean isDownload() {
+    return download;
+  }
+
+  public void setDownload(boolean download) {
+    this.download = download;
+  }
+
+  public String getLocalFile() {
+    return localFile;
+  }
+
+  public void setLocalFile(String localFile) {
+    this.localFile = localFile;
+  }
+
+  public String getRemotePath() {
+    return remotePath;
+  }
+
+  public void setRemotePath(String remotePath) {
+    this.remotePath = remotePath;
+  }
+}

scp-action/src/test/java/examples/Exec.java

+package examples;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.common.IOUtils;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import net.schmizz.sshj.connection.channel.direct.Session.Command;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/** This examples demonstrates how a remote command can be executed. */
+public class Exec {
+
+    public static void main(String... args)
+            throws IOException {
+        final SSHClient ssh = new SSHClient();
+        ssh.loadKnownHosts();
+
+        ssh.connect("linuxvm");
+        try {
+            ssh.authPublickey(System.getProperty("user.name"));
+//            ssh.authPublickey("aruld", "C:\\Users\\aruld\\.ssh\\id_dsa");
+            final Session session = ssh.startSession();
+            try {
+                final Command cmd = session.exec("ping -c 1 google.com");
+                System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
+                cmd.join(5, TimeUnit.SECONDS);
+                System.out.println("\n** exit status: " + cmd.getExitStatus());
+            } finally {
+                session.close();
+            }
+        } finally {
+            ssh.disconnect();
+        }
+    }
+
+}

scp-action/src/test/java/examples/SCPDownload.java

+package examples;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.xfer.FileSystemFile;
+
+import java.io.IOException;
+
+/** This example demonstrates downloading of a file over SCP from the SSH server. */
+public class SCPDownload {
+
+    public static void main(String[] args)
+            throws IOException {
+        SSHClient ssh = new SSHClient();
+        // ssh.useCompression(); // Can lead to significant speedup (needs JZlib in classpath)
+        ssh.loadKnownHosts();
+        ssh.connect("localhost");
+        try {
+            ssh.authPublickey(System.getProperty("user.name"));
+            ssh.newSCPFileTransfer().download("test_file", new FileSystemFile("/tmp/"));
+        } finally {
+            ssh.disconnect();
+        }
+    }
+
+}

scp-action/src/test/java/examples/SCPUpload.java

+package examples;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.xfer.FileSystemFile;
+
+import java.io.File;
+import java.io.IOException;
+
+/** This example demonstrates uploading of a file over SCP to the SSH server. */
+public class SCPUpload {
+
+    public static void main(String[] args)
+            throws IOException, ClassNotFoundException {
+        SSHClient ssh = new SSHClient();
+        ssh.loadKnownHosts();
+        ssh.connect("localhost");
+        try {
+            ssh.authPublickey(System.getProperty("user.name"));
+
+            // Present here to demo algorithm renegotiation - could have just put this before connect()
+            // Make sure JZlib is in classpath for this to work
+            ssh.useCompression();
+
+            final String src = System.getProperty("user.home") + File.separator + "test_file";
+            ssh.newSCPFileTransfer().upload(new FileSystemFile(src), "/tmp/");
+        } finally {
+            ssh.disconnect();
+        }
+    }
+}