Monday, May 28, 2012

JASSH (JAnalyseSSH) 0.8.0 released

JASSH is a high level scala SSH API for easy and fast operations on remote servers. ( ** project page **)

Latest changes :
  • now using sbt 0.11.3
  • now using sbt-assembly 0.8.1
  • now using sbteclipse 2.1.0-RC1
  • Set of new method to help with commons remote commands :
    fileSize, md5sum, sha1sum, uname, ls, pwd, cd(*), hostname, date, findAfterDate (*) of course only for shell sessions
  • JSCH updated to 0.1.48
  • md5sum method added to SSHTools object
  • manage well connect timeout (default = 30s) and general socket timeout (default = 5mn)

hello scala script

#!/bin/sh
exec java -jar jassh.jar -nocompdaemon -usejavacp -savecompiled "$0" "$@"
!#

print(jassh.SSH.shell("localhost", "test", "testtest") {_ execute "echo Hello `hostname`" } )
  
  

remote vmstat scala script

#!/bin/sh
exec java -jar jassh.jar -nocompdaemon -usejavacp -savecompiled "$0" "$@"
!#

jassh.SSH.once("localhost", "test", "testtest")  {
  _.run("vmstat 1 10", println(_.getOrElse("")).waitForEnd
}

smallest script : print remote system name (uname)

#!/bin/sh
exec java -jar jassh.jar -nocompdaemon -usejavacp -savecompiled "$0" "$@"
!#

println(jassh.SSH.shell("localhost", "test", "testtest") { _.uname})
 

Tuesday, May 8, 2012

SCALA TIPS : remove unnecessary tests when working with collections...

Thanks to scala Option type and scala returning the right type behavior, many various kinds of checks can be removed. Example :

val m = Map("A" -> 1, "B" ->3)

var l1 = List.empty[Int]
var l2 = List.empty[Int]

// Don't write such thing :
if (m.contains("A")) l1 ::= m.get("A").get
if (m.contains("Z")) l1 ::= m.get("Z").get
println(l1)

// Instead just write something like :
l2 ++:= m.get("A")
l2 ++:= m.get("Z")
println(l2)

Because concatenating List[Int] with Option[Int] will get you a List[Int], and if the Option[Int] type value is None, nothing will be added to the list :)

Tuesday, May 1, 2012

Variance and bounds example

class A
class B extends A
class C extends B
class D extends C

class E

class X[+T] {                        // T covariant for input types
  def add[U >: T](x: U): X[U] = this // U contravariant for return type
}

class Y[+T <: A] {                   // This time with an upper bound A
  def add[U >: T <: A](y: U): Y[U] = this
}

val a = new A
val b = new B
val c = new C
val d = new D

val x = new X[C]
val x2 = x.add(b)    // x2 type becomes X[B]
val x3 = x.add(d)    // x3 remains of type X[C]
val x4 = x.add(10)   // x4 type becomes X[Any]
val x6 = x.add("Z")  // x5 type becomes X[java.lang.Object]

val y = new Y[C]
val y2 = y.add(b)    // y2 type becomes X[B]
val y3 = y.add(d)    // y3 remains of type X[C]
//val y4 = y.add(2)  // Won't compile as Y has an upper bound, it must inherits from A


class Z {
  def add[T<%E](e:T) = this  // View Bound, it exists an implicit conversion to E
}
val z  = new Z
//val z1 = z.add(a)  // Won't compile as there no implicit conversion from A to E
implicit def a2E(a:A) = new E
val z2 = z.add(a)