Skip to content

Commit

Permalink
Improving hostname and ipaddresses in node objects
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jun 23, 2017
1 parent de08708 commit f55ff84
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 11 deletions.
Expand Up @@ -1043,6 +1043,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="ipAddress" type="xsd:string" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
IP addresses of the node (both IPv4 and IPv6 addresses in textual notation)
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jmxPort" type="xsd:int" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down
Expand Up @@ -46,6 +46,8 @@
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.*;

Expand Down Expand Up @@ -78,7 +80,7 @@ public NodeRegistrar(TaskManagerQuartzImpl taskManager, ClusterManager clusterMa
* @param result Node prism to be used for periodic re-registrations.
*/
void createNodeObject(OperationResult result) throws TaskManagerInitializationException {

nodePrism = createNodePrism(taskManager.getConfiguration());
NodeType node = nodePrism.asObjectable();

Expand Down Expand Up @@ -149,7 +151,8 @@ private PrismObject<NodeType> createNodePrism(TaskManagerConfiguration configura

node.setNodeIdentifier(configuration.getNodeId());
node.setName(new PolyStringType(configuration.getNodeId()));
node.setHostname(getMyAddress());
node.setHostname(getMyHostname());
node.getIpAddress().addAll(getMyIPAdresses());
node.setJmxPort(configuration.getJmxPort());
node.setClustered(configuration.isClustered());
node.setRunning(true);
Expand Down Expand Up @@ -230,15 +233,14 @@ void recordNodeShutdown(OperationResult result) {

/**
* Updates registration of this node (runs periodically within ClusterManager thread).
*
* @param result
*/
void updateNodeObject(OperationResult result) {

LOGGER.trace("Updating this node registration (name {}, oid {})", nodePrism.asObjectable().getName(), nodePrism.getOid());

List<PropertyDelta<?>> modifications = new ArrayList<PropertyDelta<?>>();
modifications.add(PropertyDelta.createReplaceDelta(nodePrism.getDefinition(), NodeType.F_HOSTNAME, getMyAddress()));
modifications.add(PropertyDelta.createReplaceDelta(nodePrism.getDefinition(), NodeType.F_HOSTNAME, getMyHostname()));
modifications.add(PropertyDelta.createReplaceDelta(nodePrism.getDefinition(), NodeType.F_IP_ADDRESS, getMyIPAdresses().toArray(new String[0])));
modifications.add(createCheckInTimeDelta());

try {
Expand All @@ -265,7 +267,8 @@ void updateNodeObject(OperationResult result) {
}
}

/**

/**
* Checks whether this Node object was not overwritten by another node (implying there is duplicate node ID in cluster).
*
* @param result
Expand Down Expand Up @@ -391,20 +394,95 @@ private void registerNodeError(NodeErrorStatusType status) {
LOGGER.warn("Scheduler stopped, please check your cluster configuration as soon as possible; kind of error = " + status);
}

private String getMyAddress() {
private String getMyHostname() {

if (taskManager.getConfiguration().getJmxHostName() != null) {
return taskManager.getConfiguration().getJmxHostName();
} else {
try {
InetAddress address = InetAddress.getLocalHost();
return address.getHostAddress();
// Not entirely correct. But we have no other option here
// other than go native or execute a "hostname" shell command.
// We do not want to do neither.
InetAddress localHost = InetAddress.getLocalHost();

if (localHost == null) {
// Unix
String hostname = System.getenv("HOSTNAME");
if (hostname != null && !hostname.isEmpty()) {
return hostname;
}

// Windows
hostname = System.getenv("COMPUTERNAME");
if (hostname != null && !hostname.isEmpty()) {
return hostname;
}

LOGGER.error("Cannot get local IP address");
// Make sure this has special characters so it cannot be inerpreted as valid hostname
return "(unknown-host)";
}

String hostname = localHost.getCanonicalHostName();
if (hostname != null && !hostname.isEmpty()) {
return hostname;
}

hostname = localHost.getHostName();
if (hostname != null && !hostname.isEmpty()) {
return hostname;
}
return localHost.getHostAddress();
} catch (UnknownHostException e) {
LoggingUtils.logException(LOGGER, "Cannot get local IP address", e);
return "unknown-host";
LoggingUtils.logException(LOGGER, "Cannot get local hostname address", e);
// Make sure this has special characters so it cannot be inerpreted as valid hostname
return "(unknown-host)";
}
}
}

private List<String> getMyIPAdresses() {
List<String> addresses = new ArrayList<>();
Enumeration<NetworkInterface> nets;
try {
nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets)) {
for (InetAddress inetAddres: Collections.list(netint.getInetAddresses())) {
String hostAddress = inetAddres.getHostAddress();
String normalizedAddress = normalizeAddress(hostAddress);
if (!isLocalAddress(normalizedAddress)) {
addresses.add(normalizedAddress);
}
}
}
} catch (SocketException e) {
LoggingUtils.logException(LOGGER, "Cannot get local IP address", e);
return addresses;
}
return addresses;
}

private String normalizeAddress(String hostAddress) {
int i = hostAddress.indexOf('%');
if (i < 0) {
return hostAddress;
} else {
return hostAddress.substring(0, i);
}
}

private boolean isLocalAddress(String addr) {
if (addr.startsWith("127.")) {
return true;
}
if (addr.equals("0:0:0:0:0:0:0:1")) {
return true;
}
if (addr.equals("::1")) {
return true;
}
return false;
}

public PrismObject<NodeType> getNodePrism() {
return nodePrism;
Expand Down

0 comments on commit f55ff84

Please sign in to comment.