xds: Move specialized APIs out of XdsResourceType

StructOrError is a more generic API, but we have StatusOr now so we
don't want new usages of StructOrError. Moving StructOrError out of
io.grpc.xds.client will make it easier to delete StructOrError once
we've migrated to StatusOr in the future.

TRANSPORT_SOCKET_NAME_TLS should also move, but it wasn't immediately
clear to me where it should go.
This commit is contained in:
Eric Anderson 2024-12-16 07:27:37 -08:00
parent a0982ca0a1
commit fe752a290e
5 changed files with 77 additions and 56 deletions

View File

@ -0,0 +1,72 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed 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 io.grpc.xds;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nullable;
/** An object or a String error. */
final class StructOrError<T> {
/**
* Returns a {@link StructOrError} for the successfully converted data object.
*/
public static <T> StructOrError<T> fromStruct(T struct) {
return new StructOrError<>(struct);
}
/**
* Returns a {@link StructOrError} for the failure to convert the data object.
*/
public static <T> StructOrError<T> fromError(String errorDetail) {
return new StructOrError<>(errorDetail);
}
private final String errorDetail;
private final T struct;
private StructOrError(T struct) {
this.struct = checkNotNull(struct, "struct");
this.errorDetail = null;
}
private StructOrError(String errorDetail) {
this.struct = null;
this.errorDetail = checkNotNull(errorDetail, "errorDetail");
}
/**
* Returns struct if exists, otherwise null.
*/
@VisibleForTesting
@Nullable
public T getStruct() {
return struct;
}
/**
* Returns error detail if exists, otherwise null.
*/
@VisibleForTesting
@Nullable
public String getErrorDetail() {
return errorDetail;
}
}

View File

@ -67,6 +67,8 @@ class XdsClusterResource extends XdsResourceType<CdsUpdate> {
static final String AGGREGATE_CLUSTER_TYPE_NAME = "envoy.clusters.aggregate"; static final String AGGREGATE_CLUSTER_TYPE_NAME = "envoy.clusters.aggregate";
static final String ADS_TYPE_URL_CDS = static final String ADS_TYPE_URL_CDS =
"type.googleapis.com/envoy.config.cluster.v3.Cluster"; "type.googleapis.com/envoy.config.cluster.v3.Cluster";
private static final String TYPE_URL_CLUSTER_CONFIG =
"type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig";
private static final String TYPE_URL_UPSTREAM_TLS_CONTEXT = private static final String TYPE_URL_UPSTREAM_TLS_CONTEXT =
"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext"; "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext";
private static final String TYPE_URL_UPSTREAM_TLS_CONTEXT_V2 = private static final String TYPE_URL_UPSTREAM_TLS_CONTEXT_V2 =

View File

@ -78,6 +78,8 @@ class XdsRouteConfigureResource extends XdsResourceType<RdsUpdate> {
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration"; "type.googleapis.com/envoy.config.route.v3.RouteConfiguration";
private static final String TYPE_URL_FILTER_CONFIG = private static final String TYPE_URL_FILTER_CONFIG =
"type.googleapis.com/envoy.config.route.v3.FilterConfig"; "type.googleapis.com/envoy.config.route.v3.FilterConfig";
@VisibleForTesting
static final String HASH_POLICY_FILTER_STATE_KEY = "io.grpc.channel_id";
// TODO(zdapeng): need to discuss how to handle unsupported values. // TODO(zdapeng): need to discuss how to handle unsupported values.
private static final Set<Status.Code> SUPPORTED_RETRYABLE_CODES = private static final Set<Status.Code> SUPPORTED_RETRYABLE_CODES =
Collections.unmodifiableSet(EnumSet.of( Collections.unmodifiableSet(EnumSet.of(

View File

@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.xds.client.XdsClient.canonifyResourceName; import static io.grpc.xds.client.XdsClient.canonifyResourceName;
import static io.grpc.xds.client.XdsClient.isResourceNameValid; import static io.grpc.xds.client.XdsClient.isResourceNameValid;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.Any; import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message; import com.google.protobuf.Message;
@ -41,11 +40,7 @@ public abstract class XdsResourceType<T extends ResourceUpdate> {
static final String TYPE_URL_RESOURCE = static final String TYPE_URL_RESOURCE =
"type.googleapis.com/envoy.service.discovery.v3.Resource"; "type.googleapis.com/envoy.service.discovery.v3.Resource";
protected static final String TRANSPORT_SOCKET_NAME_TLS = "envoy.transport_sockets.tls"; protected static final String TRANSPORT_SOCKET_NAME_TLS = "envoy.transport_sockets.tls";
@VisibleForTesting
public static final String HASH_POLICY_FILTER_STATE_KEY = "io.grpc.channel_id";
protected static final String TYPE_URL_CLUSTER_CONFIG =
"type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig";
protected static final String TYPE_URL_TYPED_STRUCT_UDPA = protected static final String TYPE_URL_TYPED_STRUCT_UDPA =
"type.googleapis.com/udpa.type.v1.TypedStruct"; "type.googleapis.com/udpa.type.v1.TypedStruct";
protected static final String TYPE_URL_TYPED_STRUCT = protected static final String TYPE_URL_TYPED_STRUCT =
@ -249,53 +244,4 @@ public abstract class XdsResourceType<T extends ResourceUpdate> {
this.errors = errors; this.errors = errors;
} }
} }
@VisibleForTesting
public static final class StructOrError<T> {
/**
* Returns a {@link StructOrError} for the successfully converted data object.
*/
public static <T> StructOrError<T> fromStruct(T struct) {
return new StructOrError<>(struct);
}
/**
* Returns a {@link StructOrError} for the failure to convert the data object.
*/
public static <T> StructOrError<T> fromError(String errorDetail) {
return new StructOrError<>(errorDetail);
}
private final String errorDetail;
private final T struct;
private StructOrError(T struct) {
this.struct = checkNotNull(struct, "struct");
this.errorDetail = null;
}
private StructOrError(String errorDetail) {
this.struct = null;
this.errorDetail = checkNotNull(errorDetail, "errorDetail");
}
/**
* Returns struct if exists, otherwise null.
*/
@VisibleForTesting
@Nullable
public T getStruct() {
return struct;
}
/**
* Returns error detail if exists, otherwise null.
*/
@VisibleForTesting
@Nullable
public String getErrorDetail() {
return errorDetail;
}
}
} }

View File

@ -140,7 +140,6 @@ import io.grpc.xds.client.Bootstrapper.ServerInfo;
import io.grpc.xds.client.XdsClient; import io.grpc.xds.client.XdsClient;
import io.grpc.xds.client.XdsResourceType; import io.grpc.xds.client.XdsResourceType;
import io.grpc.xds.client.XdsResourceType.ResourceInvalidException; import io.grpc.xds.client.XdsResourceType.ResourceInvalidException;
import io.grpc.xds.client.XdsResourceType.StructOrError;
import io.grpc.xds.internal.Matchers; import io.grpc.xds.internal.Matchers;
import io.grpc.xds.internal.Matchers.FractionMatcher; import io.grpc.xds.internal.Matchers.FractionMatcher;
import io.grpc.xds.internal.Matchers.HeaderMatcher; import io.grpc.xds.internal.Matchers.HeaderMatcher;
@ -939,7 +938,7 @@ public class GrpcXdsClientImplDataTest {
io.envoyproxy.envoy.config.route.v3.RouteAction.HashPolicy.newBuilder() io.envoyproxy.envoy.config.route.v3.RouteAction.HashPolicy.newBuilder()
.setFilterState( .setFilterState(
FilterState.newBuilder() FilterState.newBuilder()
.setKey(XdsResourceType.HASH_POLICY_FILTER_STATE_KEY))) .setKey(XdsRouteConfigureResource.HASH_POLICY_FILTER_STATE_KEY)))
.addHashPolicy( .addHashPolicy(
io.envoyproxy.envoy.config.route.v3.RouteAction.HashPolicy.newBuilder() io.envoyproxy.envoy.config.route.v3.RouteAction.HashPolicy.newBuilder()
.setQueryParameter( .setQueryParameter(