Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.OptionalInt;
import net.jcip.annotations.Immutable;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.conf.ConfigurationException;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.hdds.scm.net.HostAndPort;
import org.apache.hadoop.ozone.ha.ConfUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -60,10 +62,10 @@ public class SCMNodeInfo {
private static final Logger LOG = LoggerFactory.getLogger(SCMNodeInfo.class);
private final String serviceId;
private final String nodeId;
private final String blockClientAddress;
private final String scmClientAddress;
private final String scmSecurityAddress;
private final String scmDatanodeAddress;
private final HostAndPort blockClientAddress;
private final HostAndPort scmClientAddress;
private final HostAndPort scmSecurityAddress;
private final HostAndPort scmDatanodeAddress;

/**
* Build SCM Node information from configuration.
Expand Down Expand Up @@ -130,6 +132,9 @@ public static List<SCMNodeInfo> buildNodeInfo(ConfigurationSource conf) {
String scmClientAddress = getHostNameFromConfigKeys(conf,
OZONE_SCM_CLIENT_ADDRESS_KEY,
OZONE_SCM_NAMES).orElse(null);
if (scmClientAddress == null) {
throw new ConfigurationException(OZONE_SCM_CLIENT_ADDRESS_KEY + " is not set");
}

String scmBlockClientAddress = getHostNameFromConfigKeys(conf,
OZONE_SCM_BLOCK_CLIENT_ADDRESS_KEY).orElse(scmClientAddress);
Expand Down Expand Up @@ -162,23 +167,19 @@ public static List<SCMNodeInfo> buildNodeInfo(ConfigurationSource conf) {

scmNodeInfoList.add(new SCMNodeInfo(scmServiceId,
SCM_DUMMY_NODEID,
scmBlockClientAddress == null ? null :
buildAddress(scmBlockClientAddress, scmBlockClientPort),
scmClientAddress == null ? null :
buildAddress(scmClientAddress, scmClientPort),
scmSecurityClientAddress == null ? null :
buildAddress(scmSecurityClientAddress, scmSecurityPort),
scmDatanodeAddress == null ? null :
buildAddress(scmDatanodeAddress, scmDatanodePort)));
buildAddress(scmBlockClientAddress, scmBlockClientPort),
buildAddress(scmClientAddress, scmClientPort),
buildAddress(scmSecurityClientAddress, scmSecurityPort),
buildAddress(scmDatanodeAddress, scmDatanodePort)));

return scmNodeInfoList;

}

}

public static String buildAddress(String address, int port) {
return address + ':' + port;
private static HostAndPort buildAddress(String address, int port) {
return new HostAndPort(address, port);
}

public static int getPort(ConfigurationSource conf,
Expand Down Expand Up @@ -209,14 +210,14 @@ public static int getPort(ConfigurationSource conf,
* @param scmDatanodeAddress
*/
public SCMNodeInfo(String serviceId, String nodeId,
String blockClientAddress, String scmClientAddress,
String scmSecurityAddress, String scmDatanodeAddress) {
HostAndPort blockClientAddress, HostAndPort scmClientAddress,
HostAndPort scmSecurityAddress, HostAndPort scmDatanodeAddress) {
this.serviceId = serviceId;
this.nodeId = nodeId;
this.blockClientAddress = blockClientAddress;
this.scmClientAddress = scmClientAddress;
this.scmSecurityAddress = scmSecurityAddress;
this.scmDatanodeAddress = scmDatanodeAddress;
this.blockClientAddress = Objects.requireNonNull(blockClientAddress, "blockClientAddress == null");
this.scmClientAddress = Objects.requireNonNull(scmClientAddress, "scmClientAddress == null");
this.scmSecurityAddress = Objects.requireNonNull(scmSecurityAddress, "scmSecurityAddress == null");
this.scmDatanodeAddress = Objects.requireNonNull(scmDatanodeAddress, "scmDatanodeAddress == null");
}

public String getServiceId() {
Expand All @@ -228,18 +229,22 @@ public String getNodeId() {
}

public String getBlockClientAddress() {
return blockClientAddress;
return blockClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return blockClientAddress.getHostAndPortString();
return blockClientAddress == null ? null : blockClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These HostAndPort variables in SCMNodeInfo are never null. Let's add Objects.requireNonNull in the constructor instead.

}

public String getScmClientAddress() {
return scmClientAddress;
return scmClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return scmClientAddress.getHostAndPortString();
return scmClientAddress == null ? null : scmClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For comments along the same line, it is better to suggest one change and mention that the suggestion applies to other parts of the code. This makes the review less verbose, plus others do not need to respond to each similar comment.

}

public String getScmSecurityAddress() {
return scmSecurityAddress;
return scmSecurityAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return scmSecurityAddress.getHostAndPortString();
return scmSecurityAddress == null ? null : scmSecurityAddress.getHostAndPortString();

}

public String getScmDatanodeAddress() {
public HostAndPort getScmDatanodeHostPortAddress() {
return scmDatanodeAddress;
}

public String getScmDatanodeAddress() {
return scmDatanodeAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return scmDatanodeAddress.getHostAndPortString();
return scmDatanodeAddress == null ? null : scmDatanodeAddress.getHostAndPortString();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* 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.hadoop.hdds.scm.net;

import java.net.InetSocketAddress;
import org.apache.hadoop.net.NetUtils;

/**
* A class for host and port.
* It also has an address which can be updated from time to time.
*/
public class HostAndPort {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor (naming): this collides with Guava's com.google.common.net.HostAndPort, which is already imported in this same module at HddsUtils.java:36. It also lives in scm.net, which package-info scopes to network topology (NetworkTopology/Node/…) and which already has its own NetUtils — so the import org.apache.hadoop.net.NetUtils here shadows the same-package type. A more specific name/home (e.g. ScmEndpoint) would avoid both. Cheap while the type is new.

— Claude Code (AI-assisted review)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can replace Guava's HostAndPort with this. (Can be done in follow-up if considered out-of-scope.)

private final String host;
private final int port;
private final String hostAndPortString;
private final int hash;
/** The address can be updated from time to time. */
private final InetSocketAddress address;

public HostAndPort(String host, int port) {
this.host = host;
this.port = port;
this.hostAndPortString = host + ":" + port;
this.hash = host.hashCode() ^ Integer.hashCode(port);
// TODO: HDDS-15533 change the address resolution logic and make this.address threadsafe.
this.address = NetUtils.createSocketAddr(hostAndPortString);
}

public String getHostName() {
return host;
}

public int getPort() {
return port;
}

public String getHostAndPortString() {
return hostAndPortString;
}

public InetSocketAddress getAddress() {
return address;
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (!(obj instanceof HostAndPort)) {
return false;
}
final HostAndPort that = (HostAndPort) obj;
// address must not be compared
return this.hash == that.hash
&& this.port == that.port
&& this.host.equals(that.host);
}

@Override
public String toString() {
final InetSocketAddress a = getAddress();
final Object resolved = a != null && a.getAddress() != null ? a.getAddress() : "<unresolved>";
return hostAndPortString + "/" + resolved;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import com.google.common.collect.Sets;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -71,6 +70,7 @@
import org.apache.hadoop.hdds.protocol.DiskBalancerProtocol;
import org.apache.hadoop.hdds.protocol.SecretKeyProtocol;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.scm.net.HostAndPort;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.symmetric.DefaultSecretKeyClient;
import org.apache.hadoop.hdds.security.symmetric.SecretKeyClient;
Expand Down Expand Up @@ -764,12 +764,12 @@ private String reconfigScmNodes(String value) {
LOG.info("Reconfiguring SCM nodes for service ID {} with new SCM nodes {} and remove SCM nodes {}",
scmServiceId, scmNodesIdsToAdd, scmNodesIdsToRemove);

Collection<Pair<String, InetSocketAddress>> scmToAdd = HddsServerUtil.getSCMAddressForDatanodes(
final Collection<Pair<String, HostAndPort>> scmToAdd = HddsServerUtil.getSCMAddressForDatanodes(
getConf(), scmServiceId, scmNodesIdsToAdd);
if (scmToAdd == null) {
throw new IllegalStateException("Reconfiguration failed to get SCM address to add due to wrong configuration");
}
Collection<Pair<String, InetSocketAddress>> scmToRemove = HddsServerUtil.getSCMAddressForDatanodes(
final Collection<Pair<String, HostAndPort>> scmToRemove = HddsServerUtil.getSCMAddressForDatanodes(
getConf(), scmServiceId, scmNodesIdsToRemove);
if (scmToRemove == null) {
throw new IllegalArgumentException(
Expand All @@ -790,10 +790,10 @@ private String reconfigScmNodes(String value) {
}

// Add the new SCM servers
for (Pair<String, InetSocketAddress> pair : scmToAdd) {
for (Pair<String, HostAndPort> pair : scmToAdd) {
String scmNodeId = pair.getLeft();
InetSocketAddress scmAddress = pair.getRight();
if (scmAddress.isUnresolved()) {
final HostAndPort scmAddress = pair.getRight();
if (scmAddress.getAddress().isUnresolved()) {
LOG.warn("Reconfiguration failed to add SCM address {} for SCM service {} since it can't " +
"be resolved, skipping", scmAddress, scmServiceId);
continue;
Expand All @@ -809,9 +809,9 @@ private String reconfigScmNodes(String value) {
}

// Remove the old SCM server
for (Pair<String, InetSocketAddress> pair : scmToRemove) {
for (Pair<String, HostAndPort> pair : scmToRemove) {
String scmNodeId = pair.getLeft();
InetSocketAddress scmAddress = pair.getRight();
final HostAndPort scmAddress = pair.getRight();
try {
connectionManager.removeSCMServer(scmAddress);
context.removeEndpoint(scmAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CaseFormat;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.text.WordUtils;
import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMCommandProto;
import org.apache.hadoop.hdds.scm.net.HostAndPort;
import org.apache.hadoop.hdfs.util.EnumCounters;
import org.apache.hadoop.metrics2.MetricsCollector;
import org.apache.hadoop.metrics2.MetricsInfo;
Expand Down Expand Up @@ -68,9 +68,9 @@ public final class DatanodeQueueMetrics implements MetricsSource {

private Map<SCMCommandProto.Type, MetricsInfo> stateContextCommandQueueMap;
private Map<SCMCommandProto.Type, MetricsInfo> commandDispatcherQueueMap;
private Map<InetSocketAddress, MetricsInfo> incrementalReportsQueueMap;
private Map<InetSocketAddress, MetricsInfo> containerActionQueueMap;
private Map<InetSocketAddress, MetricsInfo> pipelineActionQueueMap;
private Map<HostAndPort, MetricsInfo> incrementalReportsQueueMap;
private Map<HostAndPort, MetricsInfo> containerActionQueueMap;
private Map<HostAndPort, MetricsInfo> pipelineActionQueueMap;

public DatanodeQueueMetrics(DatanodeStateMachine datanodeStateMachine) {
this.registry = new MetricsRegistry(METRICS_SOURCE_NAME);
Expand Down Expand Up @@ -132,19 +132,19 @@ public void getMetrics(MetricsCollector collector, boolean b) {
tmpEnum.get(entry.getKey()));
}

for (Map.Entry<InetSocketAddress, MetricsInfo> entry:
for (Map.Entry<HostAndPort, MetricsInfo> entry:
incrementalReportsQueueMap.entrySet()) {
builder.addGauge(entry.getValue(),
datanodeStateMachine.getContext()
.getIncrementalReportQueueSize().getOrDefault(entry.getKey(), 0));
}
for (Map.Entry<InetSocketAddress, MetricsInfo> entry:
for (Map.Entry<HostAndPort, MetricsInfo> entry:
containerActionQueueMap.entrySet()) {
builder.addGauge(entry.getValue(),
datanodeStateMachine.getContext()
.getContainerActionQueueSize().getOrDefault(entry.getKey(), 0));
}
for (Map.Entry<InetSocketAddress, MetricsInfo> entry:
for (Map.Entry<HostAndPort, MetricsInfo> entry:
pipelineActionQueueMap.entrySet()) {
builder.addGauge(entry.getValue(),
datanodeStateMachine.getContext().getPipelineActionQueueSize()
Expand All @@ -157,7 +157,7 @@ public static synchronized void unRegister() {
DefaultMetricsSystem.instance().unregisterSource(METRICS_SOURCE_NAME);
}

public void addEndpoint(InetSocketAddress endpoint) {
public void addEndpoint(HostAndPort endpoint) {
incrementalReportsQueueMap.computeIfAbsent(endpoint,
k -> getMetricsInfo(INCREMENTAL_REPORT_QUEUE_PREFIX,
CaseFormat.UPPER_UNDERSCORE
Expand All @@ -172,7 +172,7 @@ public void addEndpoint(InetSocketAddress endpoint) {
.to(CaseFormat.UPPER_CAMEL, k.getHostName())));
}

public void removeEndpoint(InetSocketAddress endpoint) {
public void removeEndpoint(HostAndPort endpoint) {
incrementalReportsQueueMap.remove(endpoint);
containerActionQueueMap.remove(endpoint);
pipelineActionQueueMap.remove(endpoint);
Expand Down
Loading