extensions/net.sf.basedb.opengrid/trunk/src/net/sf/basedb/opengrid/config/ConnectionInfo.java

Code
Comments
Other
Rev Date Author Line
4254 25 Nov 16 nicklas 1 package net.sf.basedb.opengrid.config;
4067 02 Sep 16 nicklas 2
4257 30 Nov 16 nicklas 3 import org.json.simple.JSONObject;
4257 30 Nov 16 nicklas 4
4278 20 Dec 16 nicklas 5 import net.sf.basedb.core.FileServer;
4254 25 Nov 16 nicklas 6 import net.sf.basedb.opengrid.OpenGridCluster;
4254 25 Nov 16 nicklas 7 import net.sf.basedb.opengrid.SshUtil;
4257 30 Nov 16 nicklas 8 import net.sf.basedb.opengrid.json.JSONOption;
4257 30 Nov 16 nicklas 9 import net.sf.basedb.opengrid.json.JSONOptions;
4278 20 Dec 16 nicklas 10 import net.sf.basedb.util.Values;
4067 02 Sep 16 nicklas 11
4067 02 Sep 16 nicklas 12 /**
4067 02 Sep 16 nicklas 13   Informatation such as the address, port, SSH fingerprint and login
5981 07 Jul 20 nicklas 14   information that is needed to connect via SSH to the cluster.
4067 02 Sep 16 nicklas 15   The information becomes readonly when a {@link OpenGridCluster} instance
4067 02 Sep 16 nicklas 16   has been created.
4067 02 Sep 16 nicklas 17   
4067 02 Sep 16 nicklas 18   @author nicklas
4067 02 Sep 16 nicklas 19   @since 1.0
4067 02 Sep 16 nicklas 20  */
4067 02 Sep 16 nicklas 21 public class ConnectionInfo 
4126 26 Sep 16 nicklas 22   extends AbstractLockable<ConnectionInfo>
4067 02 Sep 16 nicklas 23 {
4257 30 Nov 16 nicklas 24   private String name;
4067 02 Sep 16 nicklas 25   private String address;
4067 02 Sep 16 nicklas 26   private int port;
4067 02 Sep 16 nicklas 27   private String fingerprint;
4450 10 Apr 17 nicklas 28   private String fingerPrintType;
4067 02 Sep 16 nicklas 29   private String user;
4067 02 Sep 16 nicklas 30   private String password;
4741 09 Apr 18 nicklas 31   private String privateKey;
4741 09 Apr 18 nicklas 32   private String privateKeyFormat;
4741 09 Apr 18 nicklas 33   private String privateKeyPassword;
4067 02 Sep 16 nicklas 34   
4067 02 Sep 16 nicklas 35   /**
4067 02 Sep 16 nicklas 36     Create a new connection information instance. The port is
4067 02 Sep 16 nicklas 37     set to 22 by default. All other properties need to be set
4067 02 Sep 16 nicklas 38     before an {@link OpenGridCluster} instance can be created.
4067 02 Sep 16 nicklas 39     After that this instance become locked and it is no longer 
4067 02 Sep 16 nicklas 40     possible to modify the parameters.
4067 02 Sep 16 nicklas 41   */
4067 02 Sep 16 nicklas 42   public ConnectionInfo()
4067 02 Sep 16 nicklas 43   {
4067 02 Sep 16 nicklas 44     this.port = 22;
4067 02 Sep 16 nicklas 45   }
4067 02 Sep 16 nicklas 46   
4067 02 Sep 16 nicklas 47   /**
4067 02 Sep 16 nicklas 48     Create a new connection information instance and clone the
4067 02 Sep 16 nicklas 49     connection information from the given instance. The new
4067 02 Sep 16 nicklas 50     instance will be unlocked.
4067 02 Sep 16 nicklas 51     
4067 02 Sep 16 nicklas 52     @param clone The instance to clone from
4067 02 Sep 16 nicklas 53   */
4067 02 Sep 16 nicklas 54   public ConnectionInfo(ConnectionInfo clone)
4067 02 Sep 16 nicklas 55   {
4257 30 Nov 16 nicklas 56     this.name = clone.name;
4067 02 Sep 16 nicklas 57     this.address = clone.address;
4067 02 Sep 16 nicklas 58     this.port = clone.port;
4067 02 Sep 16 nicklas 59     this.fingerprint = clone.fingerprint;
4067 02 Sep 16 nicklas 60     this.user = clone.user;
4067 02 Sep 16 nicklas 61     this.password = clone.password;
4741 09 Apr 18 nicklas 62     this.privateKey = clone.privateKey;
4741 09 Apr 18 nicklas 63     this.privateKeyFormat = clone.privateKeyFormat;
4741 09 Apr 18 nicklas 64     this.privateKeyPassword = clone.privateKeyPassword;
4067 02 Sep 16 nicklas 65   }
4067 02 Sep 16 nicklas 66   
4278 20 Dec 16 nicklas 67   /**
4278 20 Dec 16 nicklas 68     Create a new connection information and use the information
4278 20 Dec 16 nicklas 69     in the file server for configuration. The file server should
4278 20 Dec 16 nicklas 70     have all required settings or they need to be provided before
4278 20 Dec 16 nicklas 71     a connection can be made.
4278 20 Dec 16 nicklas 72     
4278 20 Dec 16 nicklas 73     @param server A FileServer instance to take parameters from
4278 20 Dec 16 nicklas 74   */
4278 20 Dec 16 nicklas 75   public ConnectionInfo(FileServer server)
4278 20 Dec 16 nicklas 76   {
4278 20 Dec 16 nicklas 77     this();
4278 20 Dec 16 nicklas 78     setName(server.getName());
4278 20 Dec 16 nicklas 79     // Host on a FileServer can be "address:port"
4278 20 Dec 16 nicklas 80     String host = server.getHost();
4278 20 Dec 16 nicklas 81     if (host.contains(":"))
4278 20 Dec 16 nicklas 82     {
4278 20 Dec 16 nicklas 83       int i = host.lastIndexOf(':');
4278 20 Dec 16 nicklas 84       setPort(Values.getInt(host.substring(i+1)));
4278 20 Dec 16 nicklas 85       host = host.substring(0, i);
4278 20 Dec 16 nicklas 86     }
4278 20 Dec 16 nicklas 87     setAddress(host);
4278 20 Dec 16 nicklas 88     setFingerPrint(server.getSshFingerprint());
4278 20 Dec 16 nicklas 89     setUser(server.getUsername());
4278 20 Dec 16 nicklas 90     setPassword(server.getPassword());
4741 09 Apr 18 nicklas 91     
4748 13 Apr 18 nicklas 92     byte[] privateKey = server.getSshPrivateKey();
4748 13 Apr 18 nicklas 93     if (privateKey != null && privateKey.length > 0)
4748 13 Apr 18 nicklas 94     {
4748 13 Apr 18 nicklas 95       setPrivateKey(new String(privateKey));
4748 13 Apr 18 nicklas 96       setPrivateKeyPassword(server.getSshPrivateKeyPassword());
4748 13 Apr 18 nicklas 97       setPrivateKeyFormat(server.getSshPrivateKeyFormat());
4748 13 Apr 18 nicklas 98     }
4278 20 Dec 16 nicklas 99   }
4067 02 Sep 16 nicklas 100   
4067 02 Sep 16 nicklas 101   /**
4257 30 Nov 16 nicklas 102     Get the display name of the cluster.
4257 30 Nov 16 nicklas 103   */
4257 30 Nov 16 nicklas 104   public String getName()
4257 30 Nov 16 nicklas 105   {
4257 30 Nov 16 nicklas 106     return name;
4257 30 Nov 16 nicklas 107   }
4257 30 Nov 16 nicklas 108   
4257 30 Nov 16 nicklas 109   /**
4257 30 Nov 16 nicklas 110     Set the display name of the cluster.
4257 30 Nov 16 nicklas 111     @throws IllegalStateException If this instance has been locked
4257 30 Nov 16 nicklas 112   */
4257 30 Nov 16 nicklas 113   public void setName(String name)
4257 30 Nov 16 nicklas 114   {
4257 30 Nov 16 nicklas 115     checkLocked("setName()");
4257 30 Nov 16 nicklas 116     this.name = name;
4257 30 Nov 16 nicklas 117   }
4257 30 Nov 16 nicklas 118   
4257 30 Nov 16 nicklas 119   
4257 30 Nov 16 nicklas 120   /**
5981 07 Jul 20 nicklas 121     Get the internet address of the primary node.
4067 02 Sep 16 nicklas 122   */
4067 02 Sep 16 nicklas 123   public String getAddress()
4067 02 Sep 16 nicklas 124   {
4067 02 Sep 16 nicklas 125     return address;
4067 02 Sep 16 nicklas 126   }
4067 02 Sep 16 nicklas 127   
4067 02 Sep 16 nicklas 128   /**
5981 07 Jul 20 nicklas 129     Set the internet address to the primary node.
4067 02 Sep 16 nicklas 130     @throws IllegalStateException If this instance has been locked
4067 02 Sep 16 nicklas 131   */
4067 02 Sep 16 nicklas 132   public void setAddress(String address)
4067 02 Sep 16 nicklas 133   {
4126 26 Sep 16 nicklas 134     checkLocked("setAddress()");
4067 02 Sep 16 nicklas 135     this.address = address;
4067 02 Sep 16 nicklas 136   }
4067 02 Sep 16 nicklas 137   
4067 02 Sep 16 nicklas 138   /**
4067 02 Sep 16 nicklas 139     Get the port number to use for connecting to the
5981 07 Jul 20 nicklas 140     primary node.
4067 02 Sep 16 nicklas 141   */
4067 02 Sep 16 nicklas 142   public int getPort()
4067 02 Sep 16 nicklas 143   {
4067 02 Sep 16 nicklas 144     return port;
4067 02 Sep 16 nicklas 145   }
4067 02 Sep 16 nicklas 146   
4067 02 Sep 16 nicklas 147   /**
4067 02 Sep 16 nicklas 148     Set the port number to use for connecting to the
5981 07 Jul 20 nicklas 149     primary node.
4067 02 Sep 16 nicklas 150     @throws IllegalStateException If this instance has been locked
4067 02 Sep 16 nicklas 151   */
4067 02 Sep 16 nicklas 152   public void setPort(int port)
4067 02 Sep 16 nicklas 153   {
4126 26 Sep 16 nicklas 154     checkLocked("setPort()");
4067 02 Sep 16 nicklas 155     this.port = port;
4067 02 Sep 16 nicklas 156   }
4067 02 Sep 16 nicklas 157   
4067 02 Sep 16 nicklas 158   /**
5981 07 Jul 20 nicklas 159     Get the public key SSH fingerprint of the primary
4067 02 Sep 16 nicklas 160     node. This is used to verify that we are connecting to the expected
4067 02 Sep 16 nicklas 161     host and not to a man-in-the-middle. The fingerprint is a string containing 
4067 02 Sep 16 nicklas 162     16 pairs of hexadecimal numbers separated with colon.
4067 02 Sep 16 nicklas 163   */
4067 02 Sep 16 nicklas 164   public String getFingerPrint()
4067 02 Sep 16 nicklas 165   {
4067 02 Sep 16 nicklas 166     return fingerprint;
4067 02 Sep 16 nicklas 167   }
4067 02 Sep 16 nicklas 168   
4067 02 Sep 16 nicklas 169   /**
4067 02 Sep 16 nicklas 170     Set the public key fingerprint for the host so we can verify that the
4067 02 Sep 16 nicklas 171     connection is made to the exepected SSH server. The fingerprint
4067 02 Sep 16 nicklas 172     is a string containing 16 pairs of hexadecimal numbers separated with colon.
4067 02 Sep 16 nicklas 173     
4067 02 Sep 16 nicklas 174     @throws IllegalStateException If this instance has been locked
4067 02 Sep 16 nicklas 175     @throws IllegalArgumentException If the fingerprint is not 16 pairs
4067 02 Sep 16 nicklas 176       of hexadecimal numbers separated with colon
4067 02 Sep 16 nicklas 177   */
4067 02 Sep 16 nicklas 178   public void setFingerPrint(String fingerprint)
4067 02 Sep 16 nicklas 179   {
4126 26 Sep 16 nicklas 180     checkLocked("setFingerPrint()");
4067 02 Sep 16 nicklas 181     this.fingerprint = fingerprint;
4450 10 Apr 17 nicklas 182     this.fingerPrintType = SshUtil.getFingerPrintType(fingerprint);
4067 02 Sep 16 nicklas 183   }
4067 02 Sep 16 nicklas 184   
4067 02 Sep 16 nicklas 185   /**
4450 10 Apr 17 nicklas 186     Get the fingerprint type. Automatically updated by the
4450 10 Apr 17 nicklas 187     {@link #setFingerPrint(String)} method.
4450 10 Apr 17 nicklas 188   */
4450 10 Apr 17 nicklas 189   public String getFingerPrintType()
4450 10 Apr 17 nicklas 190   {
4450 10 Apr 17 nicklas 191     return fingerPrintType;
4450 10 Apr 17 nicklas 192   }
4450 10 Apr 17 nicklas 193   
4450 10 Apr 17 nicklas 194   /**
5981 07 Jul 20 nicklas 195     Get the username to use when connecting to the primary node.
4067 02 Sep 16 nicklas 196   */
4067 02 Sep 16 nicklas 197   public String getUser()
4067 02 Sep 16 nicklas 198   {
4067 02 Sep 16 nicklas 199     return user;
4067 02 Sep 16 nicklas 200   }
4067 02 Sep 16 nicklas 201   
4067 02 Sep 16 nicklas 202   /**
5981 07 Jul 20 nicklas 203     Set the username to use for connecting to the primary node.
4067 02 Sep 16 nicklas 204     @throws IllegalStateException If this instance has been locked
4067 02 Sep 16 nicklas 205   */
4067 02 Sep 16 nicklas 206   public void setUser(String user)
4067 02 Sep 16 nicklas 207   {
4126 26 Sep 16 nicklas 208     checkLocked("setUser()");
4067 02 Sep 16 nicklas 209     this.user = user;
4067 02 Sep 16 nicklas 210   }
4067 02 Sep 16 nicklas 211
4067 02 Sep 16 nicklas 212   /**
5981 07 Jul 20 nicklas 213     Get the password to use when connecting to the primary node.
4067 02 Sep 16 nicklas 214   */
4067 02 Sep 16 nicklas 215   public String getPassword()
4067 02 Sep 16 nicklas 216   {
4067 02 Sep 16 nicklas 217     return password;
4067 02 Sep 16 nicklas 218   }
4067 02 Sep 16 nicklas 219   
4067 02 Sep 16 nicklas 220   /**
5981 07 Jul 20 nicklas 221     Set the password to use for connecting to the primary node.
4067 02 Sep 16 nicklas 222     @throws IllegalStateException If this instance has been locked
4067 02 Sep 16 nicklas 223   */
4067 02 Sep 16 nicklas 224   public void setPassword(String password)
4067 02 Sep 16 nicklas 225   {
4126 26 Sep 16 nicklas 226     checkLocked("setPassword()");
4067 02 Sep 16 nicklas 227     this.password = password;
4067 02 Sep 16 nicklas 228   }
4741 09 Apr 18 nicklas 229   
4741 09 Apr 18 nicklas 230   /**
5981 07 Jul 20 nicklas 231     Get the private key to use when connecting to the primary node.
4741 09 Apr 18 nicklas 232     @since 1.2
4741 09 Apr 18 nicklas 233   */
4741 09 Apr 18 nicklas 234   public String getPrivateKey()
4741 09 Apr 18 nicklas 235   {
4741 09 Apr 18 nicklas 236     return privateKey;
4741 09 Apr 18 nicklas 237   }
4741 09 Apr 18 nicklas 238   
4741 09 Apr 18 nicklas 239   /**
5981 07 Jul 20 nicklas 240     Set the private key to use for connecting to the primary node.
4741 09 Apr 18 nicklas 241     @throws IllegalStateException If this instance has been locked
4741 09 Apr 18 nicklas 242     @since 1.2
4741 09 Apr 18 nicklas 243   */
4741 09 Apr 18 nicklas 244   public void setPrivateKey(String privateKey)
4741 09 Apr 18 nicklas 245   {
4741 09 Apr 18 nicklas 246     checkLocked("setPrivateKey()");
4741 09 Apr 18 nicklas 247     this.privateKey = privateKey;
4741 09 Apr 18 nicklas 248   }
4067 02 Sep 16 nicklas 249
4254 25 Nov 16 nicklas 250   /**
4741 09 Apr 18 nicklas 251     Get the format of the private key (null = auto-detect)
4741 09 Apr 18 nicklas 252     @since 1.2
4741 09 Apr 18 nicklas 253   */
4741 09 Apr 18 nicklas 254   public String getPrivateKeyFormat()
4741 09 Apr 18 nicklas 255   {
4741 09 Apr 18 nicklas 256     return privateKeyFormat;
4741 09 Apr 18 nicklas 257   }
4741 09 Apr 18 nicklas 258   
4741 09 Apr 18 nicklas 259   /**
4741 09 Apr 18 nicklas 260     Set the format of the private key (null = auto-detect).
4741 09 Apr 18 nicklas 261     Supported values are:
4741 09 Apr 18 nicklas 262     
4741 09 Apr 18 nicklas 263      - OpenSSH
4741 09 Apr 18 nicklas 264      - OpenSSHv1
4741 09 Apr 18 nicklas 265      - PuTTY
4741 09 Apr 18 nicklas 266      - PKCS5
4741 09 Apr 18 nicklas 267      - PKCS8
4741 09 Apr 18 nicklas 268     
4741 09 Apr 18 nicklas 269     @throws IllegalStateException If this instance has been locked
4741 09 Apr 18 nicklas 270     @since 1.2
4741 09 Apr 18 nicklas 271   */
4741 09 Apr 18 nicklas 272   public void setPrivateKeyFormat(String privateKeyFormat)
4741 09 Apr 18 nicklas 273   {
4741 09 Apr 18 nicklas 274     checkLocked("setPrivateKeyFormat()");
4741 09 Apr 18 nicklas 275     this.privateKeyFormat = privateKeyFormat;
4741 09 Apr 18 nicklas 276   }
4741 09 Apr 18 nicklas 277   
4741 09 Apr 18 nicklas 278   /**
4741 09 Apr 18 nicklas 279     Get the password for unlocking the private key.
4741 09 Apr 18 nicklas 280     @since 1.2
4741 09 Apr 18 nicklas 281   */
4741 09 Apr 18 nicklas 282   public String getPrivateKeyPassword()
4741 09 Apr 18 nicklas 283   {
4741 09 Apr 18 nicklas 284     return privateKeyPassword;
4741 09 Apr 18 nicklas 285   }
4741 09 Apr 18 nicklas 286   
4741 09 Apr 18 nicklas 287   /**
4741 09 Apr 18 nicklas 288     Set the password to use for unlocking the private key.
4741 09 Apr 18 nicklas 289     @throws IllegalStateException If this instance has been locked
4741 09 Apr 18 nicklas 290     @since 1.2
4741 09 Apr 18 nicklas 291   */
4741 09 Apr 18 nicklas 292   public void setPrivateKeyPassword(String privateKeyPassword)
4741 09 Apr 18 nicklas 293   {
4741 09 Apr 18 nicklas 294     checkLocked("setPrivateKeyPassword()");
4741 09 Apr 18 nicklas 295     this.privateKeyPassword = privateKeyPassword;
4741 09 Apr 18 nicklas 296   }
4741 09 Apr 18 nicklas 297   
4741 09 Apr 18 nicklas 298   /**
4254 25 Nov 16 nicklas 299     Address, fingerprint and user are required. The fingerprint must be a valid string 
4254 25 Nov 16 nicklas 300     (see {@link SshUtil#FINGERPRINT_PATTERN}). The port number must be a positive
4254 25 Nov 16 nicklas 301     integer.
4254 25 Nov 16 nicklas 302    */
4067 02 Sep 16 nicklas 303   @Override
4257 30 Nov 16 nicklas 304   protected void checkValid(boolean forLock) 
4254 25 Nov 16 nicklas 305   {
4257 30 Nov 16 nicklas 306     super.checkValid(forLock);
4254 25 Nov 16 nicklas 307     if (address == null) throw new NullPointerException("address");
4254 25 Nov 16 nicklas 308     if (port <= 0) throw new IllegalArgumentException("Port must be a positive number: " + port);
4254 25 Nov 16 nicklas 309     if (fingerprint == null) throw new NullPointerException("fingerprint");
4450 10 Apr 17 nicklas 310     if (fingerPrintType == null)
4254 25 Nov 16 nicklas 311     {
4450 10 Apr 17 nicklas 312       throw new IllegalArgumentException("Not a valid MD5 or SHA256 fingerprint: " + fingerprint);
4254 25 Nov 16 nicklas 313     }
4254 25 Nov 16 nicklas 314     if (user == null) throw new NullPointerException("user");
4257 30 Nov 16 nicklas 315     if (forLock && name == null) name = toString();
4254 25 Nov 16 nicklas 316   }
4254 25 Nov 16 nicklas 317
4254 25 Nov 16 nicklas 318   @Override
4067 02 Sep 16 nicklas 319   public String toString()
4067 02 Sep 16 nicklas 320   {
4067 02 Sep 16 nicklas 321     return user + "@" + address + ":" + port;
4067 02 Sep 16 nicklas 322   }
4257 30 Nov 16 nicklas 323   
4257 30 Nov 16 nicklas 324   /**
4257 30 Nov 16 nicklas 325     Get the configuration information as a JSON object. By
4257 30 Nov 16 nicklas 326     default the following properties are exposed:
4257 30 Nov 16 nicklas 327     
4296 12 Jan 17 nicklas 328     - name
4296 12 Jan 17 nicklas 329     - address
4296 12 Jan 17 nicklas 330     - port
4296 12 Jan 17 nicklas 331     - fingerprint
4450 10 Apr 17 nicklas 332     - fingerprintType
4296 12 Jan 17 nicklas 333     - user
4257 30 Nov 16 nicklas 334     
4741 09 Apr 18 nicklas 335     If the {@link JSONOption#CONNECTION_PASSWORD} option is enabled
4741 09 Apr 18 nicklas 336     the password is also included.
4741 09 Apr 18 nicklas 337     
4741 09 Apr 18 nicklas 338     If the {@link JSONOption#PRIVATE_KEY} option is enabled
4741 09 Apr 18 nicklas 339     the private key (and password) is also included.    
4257 30 Nov 16 nicklas 340   */
4257 30 Nov 16 nicklas 341   public JSONObject asJSONObject(JSONOptions options)
4257 30 Nov 16 nicklas 342   {
4257 30 Nov 16 nicklas 343     JSONObject json = new JSONObject();
4257 30 Nov 16 nicklas 344     json.put("name", name);
4257 30 Nov 16 nicklas 345     json.put("address", address);
4257 30 Nov 16 nicklas 346     json.put("port", port);
4257 30 Nov 16 nicklas 347     json.put("fingerprint", fingerprint);
4450 10 Apr 17 nicklas 348     json.put("fingerprintType", fingerPrintType);
4257 30 Nov 16 nicklas 349     json.put("user", user);
4257 30 Nov 16 nicklas 350     if (options.isEnabled(JSONOption.CONNECTION_PASSWORD))
4257 30 Nov 16 nicklas 351     {
4257 30 Nov 16 nicklas 352       json.put("password", password);
4257 30 Nov 16 nicklas 353     }
4741 09 Apr 18 nicklas 354     if (options.isEnabled(JSONOption.PRIVATE_KEY))
4741 09 Apr 18 nicklas 355     {
4741 09 Apr 18 nicklas 356       json.put("privateKey", privateKey);
4741 09 Apr 18 nicklas 357       json.put("privateKeyFormat", privateKeyFormat);
4741 09 Apr 18 nicklas 358       json.put("privateKeyPassword", privateKeyPassword);
4741 09 Apr 18 nicklas 359     }
4257 30 Nov 16 nicklas 360     return json;
4257 30 Nov 16 nicklas 361   }
4257 30 Nov 16 nicklas 362   
4067 02 Sep 16 nicklas 363 }