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

Code
Comments
Other
Rev Date Author Line
4254 25 Nov 16 nicklas 1 package net.sf.basedb.opengrid.config;
4254 25 Nov 16 nicklas 2
4741 09 Apr 18 nicklas 3 import java.io.File;
4741 09 Apr 18 nicklas 4 import java.io.FileNotFoundException;
4741 09 Apr 18 nicklas 5 import java.io.IOException;
4254 25 Nov 16 nicklas 6 import java.io.InputStream;
4254 25 Nov 16 nicklas 7 import java.net.URL;
4741 09 Apr 18 nicklas 8 import java.nio.file.Files;
4254 25 Nov 16 nicklas 9 import java.util.ArrayList;
4254 25 Nov 16 nicklas 10 import java.util.List;
4254 25 Nov 16 nicklas 11
4254 25 Nov 16 nicklas 12 import org.jdom2.Document;
4254 25 Nov 16 nicklas 13 import org.jdom2.Element;
4254 25 Nov 16 nicklas 14 import org.slf4j.LoggerFactory;
4254 25 Nov 16 nicklas 15
4254 25 Nov 16 nicklas 16 import net.sf.basedb.core.ConfigurationException;
4254 25 Nov 16 nicklas 17 import net.sf.basedb.opengrid.OpenGridCluster;
7075 27 Mar 23 nicklas 18 import net.sf.basedb.opengrid.service.OpenGridService;
4254 25 Nov 16 nicklas 19 import net.sf.basedb.util.FileUtil;
4254 25 Nov 16 nicklas 20 import net.sf.basedb.util.Values;
4254 25 Nov 16 nicklas 21 import net.sf.basedb.util.XmlUtil2;
7075 27 Mar 23 nicklas 22 import net.sf.basedb.util.extensions.logging.ExtensionsLog;
7075 27 Mar 23 nicklas 23 import net.sf.basedb.util.extensions.logging.ExtensionsLogger;
4254 25 Nov 16 nicklas 24
4254 25 Nov 16 nicklas 25 /**
4254 25 Nov 16 nicklas 26   Helper class for reading cluster configuration settings from an
4301 13 Jan 17 nicklas 27   XML file. Each cluster is configured in a <cluster> element.
4254 25 Nov 16 nicklas 28   The following attributes are used to configure a
4254 25 Nov 16 nicklas 29   {@link ConnectionInfo} instance:
4254 25 Nov 16 nicklas 30   
4254 25 Nov 16 nicklas 31   * address (required)
4254 25 Nov 16 nicklas 32   * port (optional, defaults to: 22/SSH)
4254 25 Nov 16 nicklas 33   * fingerprint (required)
4254 25 Nov 16 nicklas 34   * user (required)
4741 09 Apr 18 nicklas 35   * password (optional, if not specified password authentication is disabled)
4254 25 Nov 16 nicklas 36   
4741 09 Apr 18 nicklas 37   The <key-file> child element can be used for private key authentication.
4741 09 Apr 18 nicklas 38   The value should be the path to a file containing the private key. The 'type'
4741 09 Apr 18 nicklas 39   attribute specifies the key type. If not specified, auto-detection will be attempted.
4741 09 Apr 18 nicklas 40   The following attributes are supported:
4741 09 Apr 18 nicklas 41   
4741 09 Apr 18 nicklas 42   * type ('OpenSSH', 'OpenSSHv1', 'PuTTY', 'PKCS5' or PKCS8')
4741 09 Apr 18 nicklas 43   * password (needed if the private key file is password protected)
4741 09 Apr 18 nicklas 44   
4254 25 Nov 16 nicklas 45   Child elements are used for creating a {@link ClusterConfig} instance:
4254 25 Nov 16 nicklas 46   
4301 13 Jan 17 nicklas 47   * <job-folder> (required)
4355 14 Feb 17 nicklas 48   * <tmp-folder>, <tmp-folder-debug> (optional, defauls to ${TMPDIR})
4301 13 Jan 17 nicklas 49   * <date-command> (optional, the command must return date+time in format 2016-11-25 14:18:27, 
4254 25 Nov 16 nicklas 50      defaults to: date +'%Y-%m-%d %T') 
4301 13 Jan 17 nicklas 51   * <host-info-command> (optional)
4301 13 Jan 17 nicklas 52   * <opengrid-info-command> (optional)
4301 13 Jan 17 nicklas 53   * <job-agent-id> (optional)
4301 13 Jan 17 nicklas 54   * <nodes> (optional, should contain one or more <node name="..." /> child elements)
4741 09 Apr 18 nicklas 55   
4254 25 Nov 16 nicklas 56   @author nicklas
4254 25 Nov 16 nicklas 57   @since 1.0
4254 25 Nov 16 nicklas 58 */
4254 25 Nov 16 nicklas 59 public class XmlConfig 
4254 25 Nov 16 nicklas 60 {
4254 25 Nov 16 nicklas 61   
7075 27 Mar 23 nicklas 62   private static final ExtensionsLogger logger = 
7075 27 Mar 23 nicklas 63     ExtensionsLog.getLogger(OpenGridService.ID, true).wrap(LoggerFactory.getLogger(XmlConfig.class));
4254 25 Nov 16 nicklas 64   
4254 25 Nov 16 nicklas 65   private List<OpenGridCluster> clusters;
4254 25 Nov 16 nicklas 66
4254 25 Nov 16 nicklas 67   /**
4254 25 Nov 16 nicklas 68     Create a new configuration instance.
4254 25 Nov 16 nicklas 69   */
4254 25 Nov 16 nicklas 70   public XmlConfig()
4254 25 Nov 16 nicklas 71   {
4254 25 Nov 16 nicklas 72     this.clusters = new ArrayList<>();
4254 25 Nov 16 nicklas 73   }
4254 25 Nov 16 nicklas 74   
4254 25 Nov 16 nicklas 75   /**
4254 25 Nov 16 nicklas 76     Read cluster configuration from a resource on the class path.
4254 25 Nov 16 nicklas 77   */
4254 25 Nov 16 nicklas 78   public void readFromResource(String path)
4254 25 Nov 16 nicklas 79   {
4254 25 Nov 16 nicklas 80     URL configUrl = XmlConfig.class.getResource(path);
4254 25 Nov 16 nicklas 81   
4254 25 Nov 16 nicklas 82     InputStream is = null;
4254 25 Nov 16 nicklas 83     try
4254 25 Nov 16 nicklas 84     {
4254 25 Nov 16 nicklas 85       logger.debug("Loading configuration from; " + configUrl);
4254 25 Nov 16 nicklas 86       is = configUrl == null ? null : configUrl.openStream();
4254 25 Nov 16 nicklas 87       if (is == null)
4254 25 Nov 16 nicklas 88       {
4254 25 Nov 16 nicklas 89         throw new ConfigurationException("Can't find the configuration file. " +
4254 25 Nov 16 nicklas 90             "Make sure '" + path + "' is in the CLASSPATH.");
4254 25 Nov 16 nicklas 91       }
4254 25 Nov 16 nicklas 92       
4254 25 Nov 16 nicklas 93       Document dom = XmlUtil2.getValidatedXml(configUrl, null);
4254 25 Nov 16 nicklas 94       Element root = dom.getRootElement();
4254 25 Nov 16 nicklas 95       
4254 25 Nov 16 nicklas 96       List<Element> clusterElements = (List<Element>)root.getChildren("cluster");
4254 25 Nov 16 nicklas 97       for (Element ce : clusterElements)
4254 25 Nov 16 nicklas 98       {
5981 07 Jul 20 nicklas 99         // Cluster type
5981 07 Jul 20 nicklas 100         ClusterType clusterType = ClusterType.valueOf(ce.getAttributeValue("type", "OPENGRID").toUpperCase());
5981 07 Jul 20 nicklas 101         
4254 25 Nov 16 nicklas 102         // Connection parameters
4254 25 Nov 16 nicklas 103         ConnectionInfo ci = new ConnectionInfo();
4254 25 Nov 16 nicklas 104         ci.setAddress(Values.getStringOrNull(ce.getAttributeValue("address")));
4254 25 Nov 16 nicklas 105         ci.setPort(Values.getInt(ce.getAttributeValue("port"), 22));
4254 25 Nov 16 nicklas 106         ci.setFingerPrint(Values.getStringOrNull(ce.getAttributeValue("fingerprint")));
4254 25 Nov 16 nicklas 107         ci.setUser(Values.getStringOrNull(ce.getAttributeValue("user")));
4254 25 Nov 16 nicklas 108         ci.setPassword(Values.getStringOrNull(ce.getAttributeValue("password")));
4257 30 Nov 16 nicklas 109         ci.setName(Values.getStringOrNull(ce.getAttributeValue("name")));
4254 25 Nov 16 nicklas 110         
4741 09 Apr 18 nicklas 111         Element keyFileElement = ce.getChild("key-file");
4741 09 Apr 18 nicklas 112         if (keyFileElement != null)
4741 09 Apr 18 nicklas 113         {
4741 09 Apr 18 nicklas 114           File f = new File(keyFileElement.getTextTrim());
4741 09 Apr 18 nicklas 115           ci.setPrivateKey(readTextFile(f));
4742 09 Apr 18 nicklas 116           ci.setPrivateKeyFormat(Values.getStringOrNull(keyFileElement.getAttributeValue("type")));
4741 09 Apr 18 nicklas 117           ci.setPrivateKeyPassword(Values.getStringOrNull(keyFileElement.getAttributeValue("password")));
4741 09 Apr 18 nicklas 118         }
4741 09 Apr 18 nicklas 119         
4254 25 Nov 16 nicklas 120         // Other cluster configuration settings
5981 07 Jul 20 nicklas 121         ClusterConfig cfg = new ClusterConfig(clusterType);
4254 25 Nov 16 nicklas 122         cfg.setJobFolder(Values.getStringOrNull(ce.getChildTextTrim("job-folder")));
4264 14 Dec 16 nicklas 123         String tmpFolder = Values.getStringOrNull(ce.getChildTextTrim("tmp-folder"));
4264 14 Dec 16 nicklas 124         if (tmpFolder != null) cfg.setTmpFolder(tmpFolder, false);
4264 14 Dec 16 nicklas 125         String tmpFolderDebug = Values.getStringOrNull(ce.getChildTextTrim("tmp-folder-debug"));
5985 10 Jul 20 nicklas 126         if (tmpFolderDebug != null) cfg.setTmpFolder(tmpFolderDebug, true);
4257 30 Nov 16 nicklas 127         String dateCmd = Values.getStringOrNull(ce.getChildTextTrim("date-command"));
4257 30 Nov 16 nicklas 128         if (dateCmd != null) cfg.setDateCommand(dateCmd);
4257 30 Nov 16 nicklas 129         String hostInfoCmd = Values.getStringOrNull(ce.getChildTextTrim("host-info-command"));
4257 30 Nov 16 nicklas 130         if (hostInfoCmd != null) cfg.setHostInfoCommand(hostInfoCmd);
4257 30 Nov 16 nicklas 131         String openGridInfoCmd = Values.getStringOrNull(ce.getChildTextTrim("opengrid-info-command"));
4257 30 Nov 16 nicklas 132         if (openGridInfoCmd != null) cfg.setOpenGridInfoCommand(openGridInfoCmd);
4255 28 Nov 16 nicklas 133         String jobAgentExternalId = Values.getStringOrNull(ce.getChildTextTrim("job-agent-id"));
4255 28 Nov 16 nicklas 134         if (jobAgentExternalId != null) cfg.setJobAgentExternalId(jobAgentExternalId);
4254 25 Nov 16 nicklas 135         
6827 31 Aug 22 nicklas 136         Element optionsElement = ce.getChild("options");
6827 31 Aug 22 nicklas 137         if (optionsElement != null)
6827 31 Aug 22 nicklas 138         {
6827 31 Aug 22 nicklas 139           List<Element> optionList = optionsElement.getChildren();
6827 31 Aug 22 nicklas 140           for (Element oe : optionList)
6827 31 Aug 22 nicklas 141           {
6827 31 Aug 22 nicklas 142             cfg.setCustomOption(oe.getName(), oe.getTextTrim());
6827 31 Aug 22 nicklas 143           }
6827 31 Aug 22 nicklas 144         }
6827 31 Aug 22 nicklas 145         
4275 19 Dec 16 nicklas 146         Element nodesElement = ce.getChild("nodes");
4275 19 Dec 16 nicklas 147         if (nodesElement != null)
4275 19 Dec 16 nicklas 148         {
4275 19 Dec 16 nicklas 149           List<Element> nodeList = (List<Element>)nodesElement.getChildren("node");
4275 19 Dec 16 nicklas 150           for (Element ne : nodeList)
4275 19 Dec 16 nicklas 151           {
4275 19 Dec 16 nicklas 152             NodeConfig node = new NodeConfig();
4275 19 Dec 16 nicklas 153             node.setName(Values.getStringOrNull(ne.getAttributeValue("name")));
4275 19 Dec 16 nicklas 154             cfg.addNode(node);
4275 19 Dec 16 nicklas 155           }
4275 19 Dec 16 nicklas 156         }
4275 19 Dec 16 nicklas 157         
4254 25 Nov 16 nicklas 158         OpenGridCluster cluster = new OpenGridCluster(ci, cfg);
4254 25 Nov 16 nicklas 159         clusters.add(cluster);
4254 25 Nov 16 nicklas 160       }
4254 25 Nov 16 nicklas 161
4254 25 Nov 16 nicklas 162     }
4254 25 Nov 16 nicklas 163     catch (Exception ex)
4254 25 Nov 16 nicklas 164     {
4254 25 Nov 16 nicklas 165       String msg = "Could not load configuration: " + path;
4741 09 Apr 18 nicklas 166       if (ex.getMessage() != null) msg += " (" + ex.getMessage() + ")";
4254 25 Nov 16 nicklas 167       logger.error(msg, ex);
4254 25 Nov 16 nicklas 168       throw new RuntimeException(msg, ex);
4254 25 Nov 16 nicklas 169     }
4254 25 Nov 16 nicklas 170     finally
4254 25 Nov 16 nicklas 171     {
4254 25 Nov 16 nicklas 172       FileUtil.close(is);
4254 25 Nov 16 nicklas 173     }
4254 25 Nov 16 nicklas 174   }
4254 25 Nov 16 nicklas 175   
4254 25 Nov 16 nicklas 176   /**
4254 25 Nov 16 nicklas 177     Get all clusters loaded so far.
4254 25 Nov 16 nicklas 178   */
4254 25 Nov 16 nicklas 179   public List<OpenGridCluster> getClusters()
4254 25 Nov 16 nicklas 180   {
4254 25 Nov 16 nicklas 181     return clusters;
4254 25 Nov 16 nicklas 182   }
4254 25 Nov 16 nicklas 183
4741 09 Apr 18 nicklas 184   
4741 09 Apr 18 nicklas 185   private String readTextFile(File f)
4741 09 Apr 18 nicklas 186     throws IOException
4741 09 Apr 18 nicklas 187   {
4741 09 Apr 18 nicklas 188     if (!f.exists() || !f.isFile())
4741 09 Apr 18 nicklas 189     {
4741 09 Apr 18 nicklas 190       throw new FileNotFoundException(f.getAbsolutePath());
4741 09 Apr 18 nicklas 191     }
4741 09 Apr 18 nicklas 192     
4741 09 Apr 18 nicklas 193     byte[] data = Files.readAllBytes(f.toPath());
4741 09 Apr 18 nicklas 194     return new String(data);
4741 09 Apr 18 nicklas 195   }
4741 09 Apr 18 nicklas 196   
4254 25 Nov 16 nicklas 197 }