diff --git a/xds/src/main/java/io/grpc/xds/ClientXdsClient.java b/xds/src/main/java/io/grpc/xds/ClientXdsClient.java index a7f57fc41b..0ace80bd00 100644 --- a/xds/src/main/java/io/grpc/xds/ClientXdsClient.java +++ b/xds/src/main/java/io/grpc/xds/ClientXdsClient.java @@ -141,11 +141,9 @@ final class ClientXdsClient extends AbstractXdsClient { List listeners = new ArrayList<>(resources.size()); List listenerNames = new ArrayList<>(resources.size()); try { - for (com.google.protobuf.Any res : resources) { - if (res.getTypeUrl().equals(ResourceType.LDS.typeUrlV2())) { - res = res.toBuilder().setTypeUrl(ResourceType.LDS.typeUrl()).build(); - } - Listener listener = res.unpack(Listener.class); + for (Any res : resources) { + Listener listener = unpackCompatibleType(res, Listener.class, ResourceType.LDS.typeUrl(), + ResourceType.LDS.typeUrlV2()); listeners.add(listener); listenerNames.add(listener.getName()); } @@ -160,12 +158,9 @@ final class ClientXdsClient extends AbstractXdsClient { Map httpConnectionManagers = new HashMap<>(listeners.size()); try { for (Listener listener : listeners) { - Any apiListener = listener.getApiListener().getApiListener(); - if (apiListener.getTypeUrl().equals(TYPE_URL_HTTP_CONNECTION_MANAGER_V2)) { - apiListener = - apiListener.toBuilder().setTypeUrl(TYPE_URL_HTTP_CONNECTION_MANAGER).build(); - } - HttpConnectionManager hcm = apiListener.unpack(HttpConnectionManager.class); + HttpConnectionManager hcm = unpackCompatibleType( + listener.getApiListener().getApiListener(), HttpConnectionManager.class, + TYPE_URL_HTTP_CONNECTION_MANAGER, TYPE_URL_HTTP_CONNECTION_MANAGER_V2); httpConnectionManagers.put(listener.getName(), hcm); } } catch (InvalidProtocolBufferException e) { @@ -671,11 +666,10 @@ final class ClientXdsClient extends AbstractXdsClient { // Unpack RouteConfiguration messages. Map routeConfigs = new HashMap<>(resources.size()); try { - for (com.google.protobuf.Any res : resources) { - if (res.getTypeUrl().equals(ResourceType.RDS.typeUrlV2())) { - res = res.toBuilder().setTypeUrl(ResourceType.RDS.typeUrl()).build(); - } - RouteConfiguration rc = res.unpack(RouteConfiguration.class); + for (Any res : resources) { + RouteConfiguration rc = + unpackCompatibleType(res, RouteConfiguration.class, ResourceType.RDS.typeUrl(), + ResourceType.RDS.typeUrlV2()); routeConfigs.put(rc.getName(), rc); } } catch (InvalidProtocolBufferException e) { @@ -721,11 +715,9 @@ final class ClientXdsClient extends AbstractXdsClient { List clusters = new ArrayList<>(resources.size()); List clusterNames = new ArrayList<>(resources.size()); try { - for (com.google.protobuf.Any res : resources) { - if (res.getTypeUrl().equals(ResourceType.CDS.typeUrlV2())) { - res = res.toBuilder().setTypeUrl(ResourceType.CDS.typeUrl()).build(); - } - Cluster cluster = res.unpack(Cluster.class); + for (Any res : resources) { + Cluster cluster = unpackCompatibleType(res, Cluster.class, ResourceType.CDS.typeUrl(), + ResourceType.CDS.typeUrlV2()); clusters.add(cluster); clusterNames.add(cluster.getName()); } @@ -814,14 +806,10 @@ final class ClientXdsClient extends AbstractXdsClient { "Cluster " + clusterName + ": unsupported custom cluster type: " + typeName); } io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig clusterConfig; - Any unpackedClusterConfig = customType.getTypedConfig(); - if (unpackedClusterConfig.getTypeUrl().equals(TYPE_URL_CLUSTER_CONFIG_V2)) { - unpackedClusterConfig = - unpackedClusterConfig.toBuilder().setTypeUrl(TYPE_URL_CLUSTER_CONFIG).build(); - } try { - clusterConfig = unpackedClusterConfig.unpack( - io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig.class); + clusterConfig = unpackCompatibleType(customType.getTypedConfig(), + io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig.class, + TYPE_URL_CLUSTER_CONFIG, TYPE_URL_CLUSTER_CONFIG_V2); } catch (InvalidProtocolBufferException e) { return StructOrError.fromError("Cluster " + clusterName + ": malformed ClusterConfig: " + e); } @@ -855,19 +843,15 @@ final class ClientXdsClient extends AbstractXdsClient { } if (cluster.hasTransportSocket() && TRANSPORT_SOCKET_NAME_TLS.equals(cluster.getTransportSocket().getName())) { - Any any = cluster.getTransportSocket().getTypedConfig(); - if (any.getTypeUrl().equals(TYPE_URL_UPSTREAM_TLS_CONTEXT_V2)) { - any = any.toBuilder().setTypeUrl(TYPE_URL_UPSTREAM_TLS_CONTEXT).build(); - } - io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext unpacked; try { - unpacked = any.unpack( - io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext.class); + upstreamTlsContext = UpstreamTlsContext.fromEnvoyProtoUpstreamTlsContext( + unpackCompatibleType(cluster.getTransportSocket().getTypedConfig(), + io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext.class, + TYPE_URL_UPSTREAM_TLS_CONTEXT, TYPE_URL_UPSTREAM_TLS_CONTEXT_V2)); } catch (InvalidProtocolBufferException e) { return StructOrError.fromError( "Cluster " + clusterName + ": malformed UpstreamTlsContext: " + e); } - upstreamTlsContext = UpstreamTlsContext.fromEnvoyProtoUpstreamTlsContext(unpacked); } DiscoveryType type = cluster.getType(); @@ -902,11 +886,10 @@ final class ClientXdsClient extends AbstractXdsClient { List clusterLoadAssignments = new ArrayList<>(resources.size()); List claNames = new ArrayList<>(resources.size()); try { - for (com.google.protobuf.Any res : resources) { - if (res.getTypeUrl().equals(ResourceType.EDS.typeUrlV2())) { - res = res.toBuilder().setTypeUrl(ResourceType.EDS.typeUrl()).build(); - } - ClusterLoadAssignment assignment = res.unpack(ClusterLoadAssignment.class); + for (Any res : resources) { + ClusterLoadAssignment assignment = + unpackCompatibleType(res, ClusterLoadAssignment.class, ResourceType.EDS.typeUrl(), + ResourceType.EDS.typeUrlV2()); clusterLoadAssignments.add(assignment); claNames.add(assignment.getClusterName()); } @@ -1018,6 +1001,27 @@ final class ClientXdsClient extends AbstractXdsClient { endpoints, proto.getLoadBalancingWeight().getValue(), proto.getPriority())); } + /** + * Helper method to unpack serialized {@link com.google.protobuf.Any} message, while replacing + * Type URL {@code compatibleTypeUrl} with {@code typeUrl}. + * + * @param The type of unpacked message + * @param any serialized message to unpack + * @param clazz the class to unpack the message to + * @param typeUrl type URL to replace message Type URL, when it's compatible + * @param compatibleTypeUrl compatible Type URL to be replaced with {@code typeUrl} + * @return Unpacked message + * @throws InvalidProtocolBufferException if the message couldn't be unpacked + */ + private static T unpackCompatibleType( + Any any, Class clazz, String typeUrl, String compatibleTypeUrl) + throws InvalidProtocolBufferException { + if (any.getTypeUrl().equals(compatibleTypeUrl)) { + any = any.toBuilder().setTypeUrl(typeUrl).build(); + } + return any.unpack(clazz); + } + private static int getRatePerMillion(FractionalPercent percent) { int numerator = percent.getNumerator(); DenominatorType type = percent.getDenominator();