diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
index 9ff1be4dfbb..be92db4d1a5 100644
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
@@ -1043,6 +1043,13 @@
+
+
+
+ IP addresses of the node (both IPv4 and IPv6 addresses in textual notation)
+
+
+
diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/NodeRegistrar.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/NodeRegistrar.java
index 2639350a52b..20adacfcb6b 100644
--- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/NodeRegistrar.java
+++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/NodeRegistrar.java
@@ -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.*;
@@ -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();
@@ -149,7 +151,8 @@ private PrismObject 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);
@@ -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> modifications = new ArrayList>();
- 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 {
@@ -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
@@ -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 getMyIPAdresses() {
+ List addresses = new ArrayList<>();
+ Enumeration 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 getNodePrism() {
return nodePrism;