blob: 2f158b95da07ad7465d5adfc75440e2b59c1a15e [file] [log] [blame]
/*
* 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.ignite.mesos;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* The class defines cluster configuration. This configuration created from properties file
* that passed on startup or environment variables.
* <p>
* If Mesos cluster working in Intranet or behind NAT then an access to local resources can be set
* by {@link #ignitePackagePath()} or {@link #ignitePackageUrl()} which should be available from nodes.
*/
public class ClusterProperties {
/** */
private static final Logger log = Logger.getLogger(ClusterProperties.class.getSimpleName());
/** Unlimited. */
public static final double UNLIMITED = Double.MAX_VALUE;
/** */
public static final String MESOS_MASTER_URL = "MESOS_MASTER_URL";
/** */
public static final String DEFAULT_MESOS_MASTER_URL = "zk://localhost:2181/mesos";
/** Mesos master url. */
private String mesosUrl = DEFAULT_MESOS_MASTER_URL;
/** */
public static final String IGNITE_JVM_OPTS = "IGNITE_JVM_OPTS";
/** JVM options. */
private String jvmOpts = "";
/** */
public static final String IGNITE_CLUSTER_NAME = "IGNITE_CLUSTER_NAME";
/** */
public static final String DEFAULT_CLUSTER_NAME = "ignite-cluster";
/** Mesos master url. */
private String clusterName = DEFAULT_CLUSTER_NAME;
/** */
public static final String IGNITE_HTTP_SERVER_HOST = "IGNITE_HTTP_SERVER_HOST";
/** Http server host. */
private String httpSrvHost = null;
/** */
public static final String IGNITE_HTTP_SERVER_PORT = "IGNITE_HTTP_SERVER_PORT";
/** */
public static final String DEFAULT_HTTP_SERVER_PORT = "48610";
/** Http server host. */
private int httpSrvPort = Integer.valueOf(DEFAULT_HTTP_SERVER_PORT);
/** */
public static final String IGNITE_TOTAL_CPU = "IGNITE_TOTAL_CPU";
/** CPU limit. */
private double cpu = UNLIMITED;
/** */
public static final String IGNITE_RUN_CPU_PER_NODE = "IGNITE_RUN_CPU_PER_NODE";
/** CPU limit. */
private double cpuPerNode = UNLIMITED;
/** */
public static final String IGNITE_TOTAL_MEMORY = "IGNITE_TOTAL_MEMORY";
/** Memory limit. */
private double mem = UNLIMITED;
/** */
public static final String IGNITE_MEMORY_PER_NODE = "IGNITE_MEMORY_PER_NODE";
/** Memory limit. */
private double memPerNode = UNLIMITED;
/** */
public static final String IGNITE_TOTAL_DISK_SPACE = "IGNITE_TOTAL_DISK_SPACE";
/** Disk space limit. */
private double disk = UNLIMITED;
/** */
public static final String IGNITE_DISK_SPACE_PER_NODE = "IGNITE_DISK_SPACE_PER_NODE";
/** Disk space limit. */
private double diskPerNode = UNLIMITED;
/** */
public static final String IGNITE_NODE_COUNT = "IGNITE_NODE_COUNT";
/** Node count limit. */
private double nodeCnt = UNLIMITED;
/** */
public static final String IGNITE_MIN_CPU_PER_NODE = "IGNITE_MIN_CPU_PER_NODE";
/** */
public static final double DEFAULT_RESOURCE_MIN_CPU = 1;
/** Min memory per node. */
private double minCpu = DEFAULT_RESOURCE_MIN_CPU;
/** */
public static final String IGNITE_MIN_MEMORY_PER_NODE = "IGNITE_MIN_MEMORY_PER_NODE";
/** */
public static final double DEFAULT_RESOURCE_MIN_MEM = 256;
/** Min memory per node. */
private double minMemory = DEFAULT_RESOURCE_MIN_MEM;
/** */
public static final String IGNITE_VERSION = "IGNITE_VERSION";
/** */
public static final String DEFAULT_IGNITE_VERSION = "latest";
/** Ignite version. */
private String igniteVer = DEFAULT_IGNITE_VERSION;
/** */
public static final String IGNITE_PACKAGE_URL = "IGNITE_PACKAGE_URL";
/** Ignite package url. */
private String ignitePkgUrl;
/** */
public static final String IGNITE_PACKAGE_PATH = "IGNITE_PACKAGE_PATH";
/** Ignite package path. */
private String ignitePkgPath;
/** */
public static final String IGNITE_WORK_DIR = "IGNITE_WORK_DIR";
/** */
public static final String DEFAULT_IGNITE_WORK_DIR = "ignite-releases/";
/** Ignite version. */
private String igniteWorkDir = DEFAULT_IGNITE_WORK_DIR;
/** */
public static final String IGNITE_USERS_LIBS = "IGNITE_USERS_LIBS";
/** Path to users libs. */
private String userLibs = null;
/** */
public static final String IGNITE_USERS_LIBS_URL = "IGNITE_USERS_LIBS_URL";
/** URL to users libs. */
private String userLibsUrl = null;
/** */
public static final String LICENCE_URL = "LICENCE_URL";
/** Licence url. */
private String licenceUrl = null;
/** */
public static final String IGNITE_CONFIG_XML = "IGNITE_XML_CONFIG";
/** Ignite config. */
private String igniteCfg = null;
/** */
public static final String IGNITE_CONFIG_XML_URL = "IGNITE_CONFIG_XML_URL";
/** */
public static final String IGNITE_HTTP_SERVER_IDLE_TIMEOUT = "IGNITE_HTTP_SERVER_IDLE_TIMEOUT";
/** */
public static final long IGNITE_HTTP_SERVER_IDLE_TIMEOUT_DEFAULT = 30000L;
/** Jetty idle timeout. */
private long idleTimeout = IGNITE_HTTP_SERVER_IDLE_TIMEOUT_DEFAULT;
/** Url to ignite config. */
private String igniteCfgUrl = null;
/** */
public static final String IGNITE_HOSTNAME_CONSTRAINT = "IGNITE_HOSTNAME_CONSTRAINT";
/** Url to ignite config. */
private Pattern hostnameConstraint = null;
/** */
public ClusterProperties() {
// No-op.
}
/**
* @return Cluster name.
*/
public String clusterName() {
return clusterName;
}
/**
* @return CPU count limit.
*/
public double cpus() {
return cpu;
}
/**
* Sets CPU count limit.
*
* @param cpu CPU count limit.
*/
public void cpus(double cpu) {
this.cpu = cpu;
}
/**
* @return CPU count limit.
*/
public double cpusPerNode() {
return cpuPerNode;
}
/**
* Sets CPU count limit.
*
* @param cpu CPU per node count limit.
*/
public void cpusPerNode(double cpu) {
this.cpuPerNode = cpu;
}
/**
* @return mem limit.
*/
public double memory() {
return mem;
}
/**
* Sets mem limit.
*
* @param mem Memory.
*/
public void memory(double mem) {
this.mem = mem;
}
/**
* @return mem limit.
*/
public double memoryPerNode() {
return memPerNode;
}
/**
* Sets mem limit.
*
* @param mem Memory.
*/
public void memoryPerNode(double mem) {
this.memPerNode = mem;
}
/**
* @return JVM opts for ignite.
*/
public String jmvOpts() {
return this.jvmOpts;
}
/**
* @return disk limit.
*/
public double disk() {
return disk;
}
/**
* @return disk limit per node.
*/
public double diskPerNode() {
return diskPerNode;
}
/**
* @return instance count limit.
*/
public double instances() {
return nodeCnt;
}
/**
* @return min memory per node.
*/
public double minMemoryPerNode() {
return minMemory;
}
/**
* Sets min memory.
*
* @param minMemory Min memory.
*/
public void minMemoryPerNode(double minMemory) {
this.minMemory = minMemory;
}
/**
* Sets hostname constraint.
*
* @param ptrn Hostname pattern.
*/
public void hostnameConstraint(Pattern ptrn) {
this.hostnameConstraint = ptrn;
}
/**
* @return min cpu count per node.
*/
public double minCpuPerNode() {
return minCpu;
}
/**
* Sets min cpu count per node.
*
* @param minCpu min cpu count per node.
*/
public void minCpuPerNode(double minCpu) {
this.minCpu = minCpu;
}
/**
* @return Ignite version.
*/
public String igniteVer() {
return igniteVer;
}
/**
* @return Working directory.
*/
public String igniteWorkDir() {
return igniteWorkDir;
}
/**
* @return User's libs.
*/
public String userLibs() {
return userLibs;
}
/**
* @return Ignite configuration.
*/
public String igniteCfg() {
return igniteCfg;
}
/**
* @return Master url.
*/
public String masterUrl() {
return mesosUrl;
}
/**
* @return Http server host.
*/
public String httpServerHost() {
return httpSrvHost;
}
/**
* @return Http server port.
*/
public int httpServerPort() {
return httpSrvPort;
}
/**
* Sets the maximum Idle time for a http connection, which will be used for
* jetty server. The server provides resources for ignite mesos framework such as
* ignite archive, user's libs, configurations and etc.
*
* @return Http server idle timeout.
*/
public long idleTimeout() {
return idleTimeout;
}
/**
* URL to ignite package. The URL should to point at valid apache ignite archive.
* This property can be useful if using own apache ignite build.
*
* @return Url to ignite package.
*/
public String ignitePackageUrl() {
return ignitePkgUrl;
}
/**
* Path on local file system to ignite archive. That can be useful when
* Mesos working in Intranet or behind NAT.
*
* @return Path on local host to ignite package.
*/
public String ignitePackagePath() {
return ignitePkgPath;
}
/**
* @return Url to ignite configuration.
*/
public String igniteConfigUrl() {
return igniteCfgUrl;
}
/**
* @return Url to users libs configuration.
*/
public String usersLibsUrl() {
return userLibsUrl;
}
/**
* @return Url to licence.
*/
public String licenceUrl() {
return licenceUrl;
}
/**
* @return Host name constraint.
*/
public Pattern hostnameConstraint() {
return hostnameConstraint;
}
/**
* @param cfg path to config file.
* @return Cluster configuration.
*/
public static ClusterProperties from(String cfg) {
try {
Properties props = null;
if (cfg != null) {
props = new Properties();
try (FileInputStream in = new FileInputStream(cfg)) {
props.load(in);
}
}
ClusterProperties prop = new ClusterProperties();
prop.mesosUrl = getStringProperty(MESOS_MASTER_URL, props, DEFAULT_MESOS_MASTER_URL);
prop.httpSrvHost = getStringProperty(IGNITE_HTTP_SERVER_HOST, props, getNonLoopbackAddress());
String port = System.getProperty("PORT0");
if (port != null && !port.isEmpty())
prop.httpSrvPort = Integer.valueOf(port);
else
prop.httpSrvPort = Integer.valueOf(getStringProperty(IGNITE_HTTP_SERVER_PORT, props,
DEFAULT_HTTP_SERVER_PORT));
prop.clusterName = getStringProperty(IGNITE_CLUSTER_NAME, props, DEFAULT_CLUSTER_NAME);
prop.userLibsUrl = getStringProperty(IGNITE_USERS_LIBS_URL, props, null);
prop.ignitePkgUrl = getStringProperty(IGNITE_PACKAGE_URL, props, null);
prop.ignitePkgPath = getStringProperty(IGNITE_PACKAGE_PATH, props, null);
prop.licenceUrl = getStringProperty(LICENCE_URL, props, null);
prop.igniteCfgUrl = getStringProperty(IGNITE_CONFIG_XML_URL, props, null);
prop.cpu = getDoubleProperty(IGNITE_TOTAL_CPU, props, UNLIMITED);
prop.cpuPerNode = getDoubleProperty(IGNITE_RUN_CPU_PER_NODE, props, UNLIMITED);
prop.mem = getDoubleProperty(IGNITE_TOTAL_MEMORY, props, UNLIMITED);
prop.memPerNode = getDoubleProperty(IGNITE_MEMORY_PER_NODE, props, UNLIMITED);
prop.disk = getDoubleProperty(IGNITE_TOTAL_DISK_SPACE, props, UNLIMITED);
prop.diskPerNode = getDoubleProperty(IGNITE_DISK_SPACE_PER_NODE, props, 1024.0);
prop.nodeCnt = getDoubleProperty(IGNITE_NODE_COUNT, props, UNLIMITED);
prop.minCpu = getDoubleProperty(IGNITE_MIN_CPU_PER_NODE, props, DEFAULT_RESOURCE_MIN_CPU);
prop.minMemory = getDoubleProperty(IGNITE_MIN_MEMORY_PER_NODE, props, DEFAULT_RESOURCE_MIN_MEM);
prop.jvmOpts = getStringProperty(IGNITE_JVM_OPTS, props, "");
prop.igniteVer = getStringProperty(IGNITE_VERSION, props, DEFAULT_IGNITE_VERSION);
prop.igniteWorkDir = getStringProperty(IGNITE_WORK_DIR, props, DEFAULT_IGNITE_WORK_DIR);
prop.igniteCfg = getStringProperty(IGNITE_CONFIG_XML, props, null);
prop.userLibs = getStringProperty(IGNITE_USERS_LIBS, props, null);
String ptrn = getStringProperty(IGNITE_HOSTNAME_CONSTRAINT, props, null);
prop.idleTimeout = getLongProperty(IGNITE_HTTP_SERVER_IDLE_TIMEOUT, props, IGNITE_HTTP_SERVER_IDLE_TIMEOUT_DEFAULT);
if (ptrn != null) {
try {
prop.hostnameConstraint = Pattern.compile(ptrn);
}
catch (PatternSyntaxException e) {
log.log(Level.WARNING, "IGNITE_HOSTNAME_CONSTRAINT has invalid pattern. It will be ignore.", e);
}
}
return prop;
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* @param name Property name.
* @param fileProps Property file.
* @return Property value.
*/
private static double getDoubleProperty(String name, Properties fileProps, Double dfltVal) {
if (fileProps != null && fileProps.containsKey(name))
return Double.valueOf(fileProps.getProperty(name));
String prop = System.getProperty(name);
if (prop == null)
prop = System.getenv(name);
return prop == null ? dfltVal : Double.valueOf(prop);
}
/**
* @param name Property name.
* @param fileProps Property file.
* @return Property value.
*/
private static long getLongProperty(String name, Properties fileProps, Long dfltVal) {
if (fileProps != null && fileProps.containsKey(name))
return Long.valueOf(fileProps.getProperty(name));
String prop = System.getProperty(name);
if (prop == null)
prop = System.getenv(name);
return prop == null ? dfltVal : Long.valueOf(prop);
}
/**
* @param name Property name.
* @param fileProps Property file.
* @return Property value.
*/
private static String getStringProperty(String name, Properties fileProps, String dfltVal) {
if (fileProps != null && fileProps.containsKey(name))
return fileProps.getProperty(name);
String prop = System.getProperty(name);
if (prop == null)
prop = System.getenv(name);
return prop == null ? dfltVal : prop;
}
/**
* Finds a local, non-loopback, IPv4 address
*
* @return The first non-loopback IPv4 address found, or <code>null</code> if no such addresses found
* @throws java.net.SocketException If there was a problem querying the network interfaces
*/
public static String getNonLoopbackAddress() throws SocketException {
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
while (ifaces.hasMoreElements()) {
NetworkInterface iface = ifaces.nextElement();
Enumeration<InetAddress> addrs = iface.getInetAddresses();
while (addrs.hasMoreElements()) {
InetAddress addr = addrs.nextElement();
if (addr instanceof Inet4Address && !addr.isLoopbackAddress())
return addr.getHostAddress();
}
}
throw new RuntimeException("Failed. Could not find non-loopback address");
}
}