Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have EDS resource parse the additional addresses from envoy message #11011

Merged
merged 8 commits into from
Mar 15, 2024
27 changes: 18 additions & 9 deletions xds/src/main/java/io/grpc/xds/XdsEndpointResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.Message;
import io.envoyproxy.envoy.config.core.v3.Address;
import io.envoyproxy.envoy.config.core.v3.HealthStatus;
import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment;
import io.envoyproxy.envoy.config.endpoint.v3.Endpoint;
import io.envoyproxy.envoy.type.v3.FractionalPercent;
import io.grpc.EquivalentAddressGroup;
import io.grpc.xds.Endpoints.DropOverload;
Expand Down Expand Up @@ -190,22 +193,28 @@ static StructOrError<LocalityLbEndpoints> parseLocalityLbEndpoints(
if (!endpoint.hasEndpoint() || !endpoint.getEndpoint().hasAddress()) {
return StructOrError.fromError("LbEndpoint with no endpoint/address");
}
io.envoyproxy.envoy.config.core.v3.SocketAddress socketAddress =
endpoint.getEndpoint().getAddress().getSocketAddress();
InetSocketAddress addr =
new InetSocketAddress(socketAddress.getAddress(), socketAddress.getPortValue());
boolean isHealthy =
endpoint.getHealthStatus() == io.envoyproxy.envoy.config.core.v3.HealthStatus.HEALTHY
|| endpoint.getHealthStatus()
== io.envoyproxy.envoy.config.core.v3.HealthStatus.UNKNOWN;
List<java.net.SocketAddress> addresses = new ArrayList<>();
addresses.add(getInetSocketAddress(endpoint.getEndpoint().getAddress()));
for (Endpoint.AdditionalAddress additionalAddress
: endpoint.getEndpoint().getAdditionalAddressesList()) {
addresses.add(getInetSocketAddress(additionalAddress.getAddress()));
}
boolean isHealthy = (endpoint.getHealthStatus() == HealthStatus.HEALTHY)
|| (endpoint.getHealthStatus() == HealthStatus.UNKNOWN);
endpoints.add(Endpoints.LbEndpoint.create(
new EquivalentAddressGroup(ImmutableList.<java.net.SocketAddress>of(addr)),
new EquivalentAddressGroup(addresses),
Copy link
Contributor

Choose a reason for hiding this comment

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

ImmutableList.copyOf()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addresses is already a new list (created on line 196), so we don't care what is done with it. On top of that the EquivalentAddressGroup constructor copies whatever we give it.
this.addrs = Collections.unmodifiableList(new ArrayList<>(addrs));

endpoint.getLoadBalancingWeight().getValue(), isHealthy));
}
return StructOrError.fromStruct(Endpoints.LocalityLbEndpoints.create(
endpoints, proto.getLoadBalancingWeight().getValue(), proto.getPriority()));
}

private static InetSocketAddress getInetSocketAddress(Address address) {
io.envoyproxy.envoy.config.core.v3.SocketAddress socketAddress = address.getSocketAddress();

return new InetSocketAddress(socketAddress.getAddress(), socketAddress.getPortValue());
}

static final class EdsUpdate implements ResourceUpdate {
final String clusterName;
final Map<Locality, LocalityLbEndpoints> localityLbEndpointsMap;
Expand Down
39 changes: 39 additions & 0 deletions xds/src/test/java/io/grpc/xds/GrpcXdsClientImplDataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
import io.envoyproxy.envoy.type.v3.FractionalPercent.DenominatorType;
import io.envoyproxy.envoy.type.v3.Int64Range;
import io.grpc.ClientInterceptor;
import io.grpc.EquivalentAddressGroup;
import io.grpc.InsecureChannelCredentials;
import io.grpc.LoadBalancer;
import io.grpc.LoadBalancerRegistry;
Expand Down Expand Up @@ -142,6 +143,8 @@
import io.grpc.xds.internal.Matchers;
import io.grpc.xds.internal.Matchers.FractionMatcher;
import io.grpc.xds.internal.Matchers.HeaderMatcher;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -976,6 +979,42 @@ public void parseLocalityLbEndpoints_ignorZeroWeightLocality() {
assertThat(XdsEndpointResource.parseLocalityLbEndpoints(proto)).isNull();
}

@Test
public void parseLocalityLbEndpoints_withDualStackEndpoints() {
String v4Address = "172.14.14.5";
String v6Address = "2001:db8::1";
int port = 8888;

io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints proto =
io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints.newBuilder()
.setLocality(Locality.newBuilder()
.setRegion("region-foo").setZone("zone-foo").setSubZone("subZone-foo"))
.setLoadBalancingWeight(UInt32Value.newBuilder().setValue(100)) // locality weight
.setPriority(1)
.addLbEndpoints(io.envoyproxy.envoy.config.endpoint.v3.LbEndpoint.newBuilder()
.setEndpoint(Endpoint.newBuilder()
.setAddress(Address.newBuilder()
.setSocketAddress(
SocketAddress.newBuilder()
.setAddress(v4Address).setPortValue(port)))
.addAdditionalAddresses(Endpoint.AdditionalAddress.newBuilder()
.setAddress(Address.newBuilder()
.setSocketAddress(
SocketAddress.newBuilder()
.setAddress(v6Address).setPortValue(port)))))
.setHealthStatus(io.envoyproxy.envoy.config.core.v3.HealthStatus.HEALTHY)
.setLoadBalancingWeight(UInt32Value.newBuilder().setValue(20))) // endpoint weight
.build();
StructOrError<LocalityLbEndpoints> struct = XdsEndpointResource.parseLocalityLbEndpoints(proto);
assertThat(struct.getErrorDetail()).isNull();
List<java.net.SocketAddress> socketAddressList = Arrays.asList(
new InetSocketAddress(v4Address, port), new InetSocketAddress(v6Address, port));
EquivalentAddressGroup expectedEag = new EquivalentAddressGroup(socketAddressList);
assertThat(struct.getStruct()).isEqualTo(
LocalityLbEndpoints.create(
Collections.singletonList(LbEndpoint.create(expectedEag, 20, true)), 100, 1));
}

@Test
public void parseLocalityLbEndpoints_invalidPriority() {
io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints proto =
Expand Down