From 89952531d9cfc8a649b9cdde7510aa573ed6bb34 Mon Sep 17 00:00:00 2001 From: jrhee17 Date: Wed, 13 Mar 2024 23:31:42 +0900 Subject: [PATCH 1/3] introduce client.endpoint package --- .../armeria/xds/ConfigSourceClient.java | 3 +- .../armeria/xds/XdsConverterUtil.java | 64 ------------- .../{ => client/endpoint}/XdsConstants.java | 2 +- .../endpoint}/XdsEndpointGroup.java | 26 +++++- .../xds/client/endpoint/XdsEndpointUtil.java | 90 +++++++++++++++++++ .../xds/client/endpoint/package-info.java | 25 ++++++ .../xds/MostlyStaticWithDynamicEdsTest.java | 2 +- .../armeria/xds/XdsEndpointGroupTest.java | 3 +- .../armeria/xds/XdsTestResources.java | 38 +++++++- .../endpoint}/RouteMetadataSubsetTest.java | 57 ++---------- .../endpoint}/XdsConverterUtilTest.java | 6 +- 11 files changed, 189 insertions(+), 127 deletions(-) rename xds/src/main/java/com/linecorp/armeria/xds/{ => client/endpoint}/XdsConstants.java (94%) rename xds/src/main/java/com/linecorp/armeria/xds/{ => client/endpoint}/XdsEndpointGroup.java (87%) create mode 100644 xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointUtil.java create mode 100644 xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/package-info.java rename xds/src/test/java/com/linecorp/armeria/xds/{ => client/endpoint}/RouteMetadataSubsetTest.java (74%) rename xds/src/test/java/com/linecorp/armeria/xds/{ => client/endpoint}/XdsConverterUtilTest.java (94%) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceClient.java b/xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceClient.java index e371c7065ae..012106223b3 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceClient.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceClient.java @@ -30,6 +30,7 @@ import com.linecorp.armeria.client.retry.Backoff; import com.linecorp.armeria.common.SessionProtocol; import com.linecorp.armeria.common.util.SafeCloseable; +import com.linecorp.armeria.xds.client.endpoint.XdsEndpointGroup; import io.envoyproxy.envoy.config.core.v3.ApiConfigSource; import io.envoyproxy.envoy.config.core.v3.ApiConfigSource.ApiType; @@ -65,7 +66,7 @@ final class ConfigSourceClient implements SafeCloseable { final ClusterSnapshot clusterSnapshot = bootstrapClusters.clusterSnapshot(clusterName); checkArgument(clusterSnapshot != null, "Unable to find static cluster '%s'", clusterName); - endpointGroup = new XdsEndpointGroup(clusterSnapshot); + endpointGroup = XdsEndpointGroup.of(clusterSnapshot); final boolean ads = apiConfigSource.getApiType() == ApiType.AGGREGATED_GRPC; final UpstreamTlsContext tlsContext = clusterSnapshot.xdsResource().upstreamTlsContext(); final SessionProtocol sessionProtocol = diff --git a/xds/src/main/java/com/linecorp/armeria/xds/XdsConverterUtil.java b/xds/src/main/java/com/linecorp/armeria/xds/XdsConverterUtil.java index 928fba240a8..bf0f625279f 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/XdsConverterUtil.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/XdsConverterUtil.java @@ -17,81 +17,17 @@ package com.linecorp.armeria.xds; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.linecorp.armeria.xds.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Predicate; - -import com.google.common.base.Strings; -import com.google.protobuf.Struct; -import com.google.protobuf.Value; - -import com.linecorp.armeria.client.Endpoint; import com.linecorp.armeria.common.annotation.Nullable; import io.envoyproxy.envoy.config.core.v3.ApiConfigSource; import io.envoyproxy.envoy.config.core.v3.ApiConfigSource.ApiType; import io.envoyproxy.envoy.config.core.v3.ConfigSource; -import io.envoyproxy.envoy.config.core.v3.SocketAddress; -import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment; -import io.envoyproxy.envoy.config.endpoint.v3.LbEndpoint; final class XdsConverterUtil { private XdsConverterUtil() {} - static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment) { - return convertEndpoints(clusterLoadAssignment, lbEndpoint -> true); - } - - static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment, Struct filterMetadata) { - checkArgument(filterMetadata.getFieldsCount() > 0, - "filterMetadata.getFieldsCount(): %s (expected: > 0)", filterMetadata.getFieldsCount()); - final Predicate lbEndpointPredicate = lbEndpoint -> { - final Struct endpointMetadata = lbEndpoint.getMetadata().getFilterMetadataOrDefault( - SUBSET_LOAD_BALANCING_FILTER_NAME, Struct.getDefaultInstance()); - if (endpointMetadata.getFieldsCount() == 0) { - return false; - } - return containsFilterMetadata(filterMetadata, endpointMetadata); - }; - return convertEndpoints(clusterLoadAssignment, lbEndpointPredicate); - } - - private static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment, - Predicate lbEndpointPredicate) { - return clusterLoadAssignment.getEndpointsList().stream().flatMap( - localityLbEndpoints -> localityLbEndpoints - .getLbEndpointsList() - .stream() - .filter(lbEndpointPredicate) - .map(lbEndpoint -> { - final SocketAddress socketAddress = - lbEndpoint.getEndpoint().getAddress().getSocketAddress(); - final String hostname = lbEndpoint.getEndpoint().getHostname(); - if (!Strings.isNullOrEmpty(hostname)) { - return Endpoint.of(hostname, socketAddress.getPortValue()) - .withIpAddr(socketAddress.getAddress()); - } else { - return Endpoint.of(socketAddress.getAddress(), socketAddress.getPortValue()); - } - })).collect(toImmutableList()); - } - - private static boolean containsFilterMetadata(Struct filterMetadata, Struct endpointMetadata) { - final Map endpointMetadataMap = endpointMetadata.getFieldsMap(); - for (Entry entry : filterMetadata.getFieldsMap().entrySet()) { - final Value value = endpointMetadataMap.get(entry.getKey()); - if (value == null || !value.equals(entry.getValue())) { - return false; - } - } - return true; - } - static void validateConfigSource(@Nullable ConfigSource configSource) { if (configSource == null || configSource.equals(ConfigSource.getDefaultInstance())) { return; diff --git a/xds/src/main/java/com/linecorp/armeria/xds/XdsConstants.java b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsConstants.java similarity index 94% rename from xds/src/main/java/com/linecorp/armeria/xds/XdsConstants.java rename to xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsConstants.java index 51326f9ab2d..c79ffa4b5d5 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/XdsConstants.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsConstants.java @@ -14,7 +14,7 @@ * under the License. */ -package com.linecorp.armeria.xds; +package com.linecorp.armeria.xds.client.endpoint; final class XdsConstants { diff --git a/xds/src/main/java/com/linecorp/armeria/xds/XdsEndpointGroup.java b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java similarity index 87% rename from xds/src/main/java/com/linecorp/armeria/xds/XdsEndpointGroup.java rename to xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java index 993c2eb5001..a0058bf69e9 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/XdsEndpointGroup.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 LINE Corporation + * Copyright 2024 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -14,11 +14,11 @@ * under the License. */ -package com.linecorp.armeria.xds; +package com.linecorp.armeria.xds.client.endpoint; import static com.google.common.base.Preconditions.checkArgument; -import static com.linecorp.armeria.xds.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; -import static com.linecorp.armeria.xds.XdsConverterUtil.convertEndpoints; +import static com.linecorp.armeria.xds.client.endpoint.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; +import static com.linecorp.armeria.xds.client.endpoint.XdsEndpointUtil.convertEndpoints; import static java.util.Objects.requireNonNull; import java.util.List; @@ -37,11 +37,19 @@ import com.linecorp.armeria.client.endpoint.EndpointGroup; import com.linecorp.armeria.common.annotation.UnstableApi; import com.linecorp.armeria.common.util.SafeCloseable; +import com.linecorp.armeria.xds.ClusterSnapshot; +import com.linecorp.armeria.xds.EndpointSnapshot; +import com.linecorp.armeria.xds.ListenerRoot; +import com.linecorp.armeria.xds.ListenerSnapshot; +import com.linecorp.armeria.xds.RouteSnapshot; +import com.linecorp.armeria.xds.SnapshotWatcher; +import com.linecorp.armeria.xds.XdsBootstrap; import io.envoyproxy.envoy.config.cluster.v3.Cluster; import io.envoyproxy.envoy.config.cluster.v3.Cluster.LbSubsetConfig; import io.envoyproxy.envoy.config.cluster.v3.Cluster.LbSubsetConfig.LbSubsetFallbackPolicy; import io.envoyproxy.envoy.config.cluster.v3.Cluster.LbSubsetConfig.LbSubsetSelector; +import io.envoyproxy.envoy.config.core.v3.GrpcService; import io.envoyproxy.envoy.config.core.v3.SocketAddress; import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment; import io.envoyproxy.envoy.config.route.v3.Route; @@ -76,6 +84,16 @@ public static EndpointGroup of(ListenerRoot listenerRoot) { return new XdsEndpointGroup(listenerRoot); } + /** + * Creates a {@link XdsEndpointGroup} based on the specified {@link ClusterSnapshot}. + * This may be useful if one would like to create an {@link EndpointGroup} based on + * a {@link GrpcService}. + */ + public static EndpointGroup of(ClusterSnapshot clusterSnapshot) { + requireNonNull(clusterSnapshot, "clusterSnapshot"); + return new XdsEndpointGroup(clusterSnapshot); + } + XdsEndpointGroup(ListenerRoot listenerRoot) { final SnapshotWatcher watcher = update -> { final RouteSnapshot routeSnapshot = update.routeSnapshot(); diff --git a/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointUtil.java b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointUtil.java new file mode 100644 index 00000000000..0e2e7540b1e --- /dev/null +++ b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointUtil.java @@ -0,0 +1,90 @@ +/* + * Copyright 2024 LINE Corporation + * + * LINE Corporation 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: + * + * https://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 com.linecorp.armeria.xds.client.endpoint; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.linecorp.armeria.xds.client.endpoint.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Predicate; + +import com.google.common.base.Strings; +import com.google.protobuf.Struct; +import com.google.protobuf.Value; + +import com.linecorp.armeria.client.Endpoint; + +import io.envoyproxy.envoy.config.core.v3.SocketAddress; +import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment; +import io.envoyproxy.envoy.config.endpoint.v3.LbEndpoint; + +final class XdsEndpointUtil { + + static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment) { + return convertEndpoints(clusterLoadAssignment, lbEndpoint -> true); + } + + static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment, Struct filterMetadata) { + checkArgument(filterMetadata.getFieldsCount() > 0, + "filterMetadata.getFieldsCount(): %s (expected: > 0)", filterMetadata.getFieldsCount()); + final Predicate lbEndpointPredicate = lbEndpoint -> { + final Struct endpointMetadata = lbEndpoint.getMetadata().getFilterMetadataOrDefault( + SUBSET_LOAD_BALANCING_FILTER_NAME, Struct.getDefaultInstance()); + if (endpointMetadata.getFieldsCount() == 0) { + return false; + } + return containsFilterMetadata(filterMetadata, endpointMetadata); + }; + return convertEndpoints(clusterLoadAssignment, lbEndpointPredicate); + } + + private static List convertEndpoints(ClusterLoadAssignment clusterLoadAssignment, + Predicate lbEndpointPredicate) { + return clusterLoadAssignment.getEndpointsList().stream().flatMap( + localityLbEndpoints -> localityLbEndpoints + .getLbEndpointsList() + .stream() + .filter(lbEndpointPredicate) + .map(lbEndpoint -> { + final SocketAddress socketAddress = + lbEndpoint.getEndpoint().getAddress().getSocketAddress(); + final String hostname = lbEndpoint.getEndpoint().getHostname(); + if (!Strings.isNullOrEmpty(hostname)) { + return Endpoint.of(hostname, socketAddress.getPortValue()) + .withIpAddr(socketAddress.getAddress()); + } else { + return Endpoint.of(socketAddress.getAddress(), socketAddress.getPortValue()); + } + })).collect(toImmutableList()); + } + + private static boolean containsFilterMetadata(Struct filterMetadata, Struct endpointMetadata) { + final Map endpointMetadataMap = endpointMetadata.getFieldsMap(); + for (Entry entry : filterMetadata.getFieldsMap().entrySet()) { + final Value value = endpointMetadataMap.get(entry.getKey()); + if (value == null || !value.equals(entry.getValue())) { + return false; + } + } + return true; + } + + private XdsEndpointUtil() {} +} diff --git a/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/package-info.java b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/package-info.java new file mode 100644 index 00000000000..35829bd9878 --- /dev/null +++ b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 LINE Corporation + * + * LINE Corporation 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: + * + * https://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. + */ + +/** + * Provides client-side {@link com.linecorp.armeria.client.Endpoint} related integrations with xDS. + */ +@NonNullByDefault +@UnstableApi +package com.linecorp.armeria.xds.client.endpoint; + +import com.linecorp.armeria.common.annotation.NonNullByDefault; +import com.linecorp.armeria.common.annotation.UnstableApi; diff --git a/xds/src/test/java/com/linecorp/armeria/xds/MostlyStaticWithDynamicEdsTest.java b/xds/src/test/java/com/linecorp/armeria/xds/MostlyStaticWithDynamicEdsTest.java index 5c69425b7c6..58adfa9ea49 100644 --- a/xds/src/test/java/com/linecorp/armeria/xds/MostlyStaticWithDynamicEdsTest.java +++ b/xds/src/test/java/com/linecorp/armeria/xds/MostlyStaticWithDynamicEdsTest.java @@ -16,11 +16,11 @@ package com.linecorp.armeria.xds; -import static com.linecorp.armeria.xds.RouteMetadataSubsetTest.staticResourceListener; import static com.linecorp.armeria.xds.XdsTestResources.BOOTSTRAP_CLUSTER_NAME; import static com.linecorp.armeria.xds.XdsTestResources.bootstrapCluster; import static com.linecorp.armeria.xds.XdsTestResources.createCluster; import static com.linecorp.armeria.xds.XdsTestResources.loadAssignment; +import static com.linecorp.armeria.xds.XdsTestResources.staticResourceListener; import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; diff --git a/xds/src/test/java/com/linecorp/armeria/xds/XdsEndpointGroupTest.java b/xds/src/test/java/com/linecorp/armeria/xds/XdsEndpointGroupTest.java index e29031c5d20..2075dfe1979 100644 --- a/xds/src/test/java/com/linecorp/armeria/xds/XdsEndpointGroupTest.java +++ b/xds/src/test/java/com/linecorp/armeria/xds/XdsEndpointGroupTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 LINE Corporation + * Copyright 2024 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -39,6 +39,7 @@ import com.linecorp.armeria.server.grpc.GrpcService; import com.linecorp.armeria.testing.junit5.common.EventLoopExtension; import com.linecorp.armeria.testing.junit5.server.ServerExtension; +import com.linecorp.armeria.xds.client.endpoint.XdsEndpointGroup; import io.envoyproxy.controlplane.cache.v3.SimpleCache; import io.envoyproxy.controlplane.cache.v3.Snapshot; diff --git a/xds/src/test/java/com/linecorp/armeria/xds/XdsTestResources.java b/xds/src/test/java/com/linecorp/armeria/xds/XdsTestResources.java index 3405ab10b39..0cdecbf8052 100644 --- a/xds/src/test/java/com/linecorp/armeria/xds/XdsTestResources.java +++ b/xds/src/test/java/com/linecorp/armeria/xds/XdsTestResources.java @@ -63,7 +63,7 @@ public final class XdsTestResources { - static final String BOOTSTRAP_CLUSTER_NAME = "bootstrap-cluster"; + public static final String BOOTSTRAP_CLUSTER_NAME = "bootstrap-cluster"; private XdsTestResources() {} @@ -297,4 +297,40 @@ public static VirtualHost virtualHost(String name, String... clusterNames) { public static Value stringValue(String value) { return Value.newBuilder().setStringValue(value).build(); } + + public static Listener staticResourceListener() { + return staticResourceListener(Metadata.getDefaultInstance()); + } + + public static Listener staticResourceListener(Metadata metadata) { + final RouteAction.Builder routeActionBuilder = RouteAction.newBuilder().setCluster("cluster"); + if (metadata != Metadata.getDefaultInstance()) { + routeActionBuilder.setMetadataMatch(metadata); + } + final VirtualHost virtualHost = + VirtualHost.newBuilder() + .setName("route") + .addDomains("*") + .addRoutes(Route.newBuilder() + .setMatch(RouteMatch.newBuilder().setPrefix("/")) + .setRoute(routeActionBuilder)) + .build(); + final HttpConnectionManager manager = + HttpConnectionManager + .newBuilder() + .setCodecType(CodecType.AUTO) + .setStatPrefix("ingress_http") + .setRouteConfig(RouteConfiguration.newBuilder() + .setName("route") + .addVirtualHosts(virtualHost) + .build()) + .addHttpFilters(HttpFilter.newBuilder() + .setName("envoy.filters.http.router") + .setTypedConfig(Any.pack(Router.getDefaultInstance()))) + .build(); + return Listener.newBuilder() + .setName("listener") + .setApiListener(ApiListener.newBuilder().setApiListener(Any.pack(manager))) + .build(); + } } diff --git a/xds/src/test/java/com/linecorp/armeria/xds/RouteMetadataSubsetTest.java b/xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/RouteMetadataSubsetTest.java similarity index 74% rename from xds/src/test/java/com/linecorp/armeria/xds/RouteMetadataSubsetTest.java rename to xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/RouteMetadataSubsetTest.java index e0b0be2a8f0..5003c107285 100644 --- a/xds/src/test/java/com/linecorp/armeria/xds/RouteMetadataSubsetTest.java +++ b/xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/RouteMetadataSubsetTest.java @@ -14,13 +14,14 @@ * under the License. */ -package com.linecorp.armeria.xds; +package com.linecorp.armeria.xds.client.endpoint; -import static com.linecorp.armeria.xds.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; -import static com.linecorp.armeria.xds.XdsConverterUtilTest.sampleClusterLoadAssignment; import static com.linecorp.armeria.xds.XdsTestResources.BOOTSTRAP_CLUSTER_NAME; import static com.linecorp.armeria.xds.XdsTestResources.bootstrapCluster; +import static com.linecorp.armeria.xds.XdsTestResources.staticResourceListener; import static com.linecorp.armeria.xds.XdsTestResources.stringValue; +import static com.linecorp.armeria.xds.client.endpoint.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; +import static com.linecorp.armeria.xds.client.endpoint.XdsConverterUtilTest.sampleClusterLoadAssignment; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -28,7 +29,6 @@ import org.junit.jupiter.api.extension.RegisterExtension; import com.google.common.collect.ImmutableList; -import com.google.protobuf.Any; import com.google.protobuf.Struct; import com.linecorp.armeria.client.Endpoint; @@ -36,6 +36,8 @@ import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.grpc.GrpcService; import com.linecorp.armeria.testing.junit5.server.ServerExtension; +import com.linecorp.armeria.xds.XdsBootstrap; +import com.linecorp.armeria.xds.XdsTestResources; import io.envoyproxy.controlplane.cache.v3.SimpleCache; import io.envoyproxy.controlplane.cache.v3.Snapshot; @@ -50,17 +52,6 @@ import io.envoyproxy.envoy.config.core.v3.ConfigSource; import io.envoyproxy.envoy.config.core.v3.Metadata; import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment; -import io.envoyproxy.envoy.config.listener.v3.ApiListener; -import io.envoyproxy.envoy.config.listener.v3.Listener; -import io.envoyproxy.envoy.config.route.v3.Route; -import io.envoyproxy.envoy.config.route.v3.RouteAction; -import io.envoyproxy.envoy.config.route.v3.RouteConfiguration; -import io.envoyproxy.envoy.config.route.v3.RouteMatch; -import io.envoyproxy.envoy.config.route.v3.VirtualHost; -import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router; -import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager; -import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.CodecType; -import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter; class RouteMetadataSubsetTest { @@ -156,40 +147,4 @@ void routeMetadataMatch() { Endpoint.of("127.0.0.1", 8082))); } } - - static Listener staticResourceListener() { - return staticResourceListener(Metadata.getDefaultInstance()); - } - - static Listener staticResourceListener(Metadata metadata) { - final RouteAction.Builder routeActionBuilder = RouteAction.newBuilder().setCluster("cluster"); - if (metadata != Metadata.getDefaultInstance()) { - routeActionBuilder.setMetadataMatch(metadata); - } - final VirtualHost virtualHost = - VirtualHost.newBuilder() - .setName("route") - .addDomains("*") - .addRoutes(Route.newBuilder() - .setMatch(RouteMatch.newBuilder().setPrefix("/")) - .setRoute(routeActionBuilder)) - .build(); - final HttpConnectionManager manager = - HttpConnectionManager - .newBuilder() - .setCodecType(CodecType.AUTO) - .setStatPrefix("ingress_http") - .setRouteConfig(RouteConfiguration.newBuilder() - .setName("route") - .addVirtualHosts(virtualHost) - .build()) - .addHttpFilters(HttpFilter.newBuilder() - .setName("envoy.filters.http.router") - .setTypedConfig(Any.pack(Router.getDefaultInstance()))) - .build(); - return Listener.newBuilder() - .setName("listener") - .setApiListener(ApiListener.newBuilder().setApiListener(Any.pack(manager))) - .build(); - } } diff --git a/xds/src/test/java/com/linecorp/armeria/xds/XdsConverterUtilTest.java b/xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/XdsConverterUtilTest.java similarity index 94% rename from xds/src/test/java/com/linecorp/armeria/xds/XdsConverterUtilTest.java rename to xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/XdsConverterUtilTest.java index abdee131e46..883d8c05499 100644 --- a/xds/src/test/java/com/linecorp/armeria/xds/XdsConverterUtilTest.java +++ b/xds/src/test/java/com/linecorp/armeria/xds/client/endpoint/XdsConverterUtilTest.java @@ -14,12 +14,12 @@ * under the License. */ -package com.linecorp.armeria.xds; +package com.linecorp.armeria.xds.client.endpoint; -import static com.linecorp.armeria.xds.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; -import static com.linecorp.armeria.xds.XdsConverterUtil.convertEndpoints; import static com.linecorp.armeria.xds.XdsTestResources.endpoint; import static com.linecorp.armeria.xds.XdsTestResources.stringValue; +import static com.linecorp.armeria.xds.client.endpoint.XdsConstants.SUBSET_LOAD_BALANCING_FILTER_NAME; +import static com.linecorp.armeria.xds.client.endpoint.XdsEndpointUtil.convertEndpoints; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; From b91ab9cd62da4f5e5c65eadd696b8050a0100a61 Mon Sep 17 00:00:00 2001 From: jrhee17 Date: Thu, 14 Mar 2024 22:03:09 +0900 Subject: [PATCH 2/3] add unstable api --- .../linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java | 1 + 1 file changed, 1 insertion(+) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java index a0058bf69e9..e8bf2fc9de6 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/client/endpoint/XdsEndpointGroup.java @@ -89,6 +89,7 @@ public static EndpointGroup of(ListenerRoot listenerRoot) { * This may be useful if one would like to create an {@link EndpointGroup} based on * a {@link GrpcService}. */ + @UnstableApi public static EndpointGroup of(ClusterSnapshot clusterSnapshot) { requireNonNull(clusterSnapshot, "clusterSnapshot"); return new XdsEndpointGroup(clusterSnapshot); From 162e835027eb5b90409a87a55d4a37fafd70dbab Mon Sep 17 00:00:00 2001 From: jrhee17 Date: Sat, 16 Mar 2024 12:17:24 +0900 Subject: [PATCH 3/3] add equality and hashcode for snapshots --- .../linecorp/armeria/xds/ClusterSnapshot.java | 21 +++++++++++++++++++ .../armeria/xds/EndpointSnapshot.java | 18 ++++++++++++++++ .../armeria/xds/ListenerSnapshot.java | 19 +++++++++++++++++ .../linecorp/armeria/xds/RouteSnapshot.java | 19 +++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/ClusterSnapshot.java b/xds/src/main/java/com/linecorp/armeria/xds/ClusterSnapshot.java index 3836b02a5e0..864c8f6870a 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/ClusterSnapshot.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/ClusterSnapshot.java @@ -17,6 +17,7 @@ package com.linecorp.armeria.xds; import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -89,6 +90,26 @@ int index() { return index; } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + final ClusterSnapshot that = (ClusterSnapshot) object; + return index == that.index && Objects.equal(clusterXdsResource, that.clusterXdsResource) && + Objects.equal(endpointSnapshot, that.endpointSnapshot) && + Objects.equal(virtualHost, that.virtualHost) && + Objects.equal(route, that.route); + } + + @Override + public int hashCode() { + return Objects.hashCode(clusterXdsResource, endpointSnapshot, virtualHost, route, index); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/EndpointSnapshot.java b/xds/src/main/java/com/linecorp/armeria/xds/EndpointSnapshot.java index 73ccdbe12a2..8f2b251e0b0 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/EndpointSnapshot.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/EndpointSnapshot.java @@ -17,6 +17,7 @@ package com.linecorp.armeria.xds; import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -38,6 +39,23 @@ public EndpointXdsResource xdsResource() { return endpoint; } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + final EndpointSnapshot that = (EndpointSnapshot) object; + return Objects.equal(endpoint, that.endpoint); + } + + @Override + public int hashCode() { + return Objects.hashCode(endpoint); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/ListenerSnapshot.java b/xds/src/main/java/com/linecorp/armeria/xds/ListenerSnapshot.java index d8909c34a57..fe506144b9f 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/ListenerSnapshot.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/ListenerSnapshot.java @@ -17,6 +17,7 @@ package com.linecorp.armeria.xds; import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -51,6 +52,24 @@ public RouteSnapshot routeSnapshot() { return routeSnapshot; } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + final ListenerSnapshot that = (ListenerSnapshot) object; + return Objects.equal(listenerXdsResource, that.listenerXdsResource) && + Objects.equal(routeSnapshot, that.routeSnapshot); + } + + @Override + public int hashCode() { + return Objects.hashCode(listenerXdsResource, routeSnapshot); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/xds/src/main/java/com/linecorp/armeria/xds/RouteSnapshot.java b/xds/src/main/java/com/linecorp/armeria/xds/RouteSnapshot.java index 2b844c0e4b7..448b33b911d 100644 --- a/xds/src/main/java/com/linecorp/armeria/xds/RouteSnapshot.java +++ b/xds/src/main/java/com/linecorp/armeria/xds/RouteSnapshot.java @@ -23,6 +23,7 @@ import java.util.Map; import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -74,6 +75,24 @@ public Map> virtualHostMap() { return virtualHostMap; } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + final RouteSnapshot that = (RouteSnapshot) object; + return Objects.equal(routeXdsResource, that.routeXdsResource) && + Objects.equal(clusterSnapshots, that.clusterSnapshots); + } + + @Override + public int hashCode() { + return Objects.hashCode(routeXdsResource, clusterSnapshots); + } + @Override public String toString() { return MoreObjects.toStringHelper(this)