3131import org .jspecify .annotations .Nullable ;
3232import org .reflections .Reflections ;
3333import org .reflections .scanners .SubTypesScanner ;
34+ import org .slf4j .Logger ;
35+ import org .slf4j .LoggerFactory ;
3436
3537import com .fasterxml .jackson .databind .JsonNode ;
3638import com .google .common .collect .ImmutableList ;
5557import com .linecorp .centraldogma .xds .endpoint .v1 .LocalityLbEndpoint ;
5658import com .linecorp .centraldogma .xds .k8s .v1 .KubernetesEndpointAggregator ;
5759
58- import io .envoyproxy .envoy .config .cluster .v3 .Cluster ;
59- import io .envoyproxy .envoy .config .endpoint .v3 .ClusterLoadAssignment ;
60- import io .envoyproxy .envoy .config .listener .v3 .Listener ;
61- import io .envoyproxy .envoy .config .route .v3 .RouteConfiguration ;
6260import io .envoyproxy .envoy .extensions .filters .network .http_connection_manager .v3 .HttpConnectionManager ;
6361
6462public final class XdsResourceManager {
6563
64+ private static final Logger logger = LoggerFactory .getLogger (XdsResourceManager .class );
65+
6666 public static final String RESOURCE_ID_PATTERN_STRING = "[a-z](?:[a-z0-9_.-]*[a-z0-9])?" ;
6767 public static final Pattern RESOURCE_ID_PATTERN = Pattern .compile ('^' + RESOURCE_ID_PATTERN_STRING + '$' );
6868 // Allows slashes in addition to dots for backward compatibility with resources created before the
@@ -79,25 +79,36 @@ public final class XdsResourceManager {
7979 static {
8080 final MessageMarshaller .Builder builder =
8181 MessageMarshaller .builder ().omittingInsignificantWhitespace (true );
82- builder .register (Listener .getDefaultInstance ())
83- .register (Cluster .getDefaultInstance ())
84- .register (ClusterLoadAssignment .getDefaultInstance ())
85- .register (RouteConfiguration .getDefaultInstance ())
86- .register (KubernetesEndpointAggregator .getDefaultInstance ())
82+ // These Central Dogma-specific types are not in the io.envoyproxy.envoy package, so they
83+ // must be registered explicitly; envoyExtension() does not pick them up.
84+ builder .register (KubernetesEndpointAggregator .getDefaultInstance ())
8785 .register (LocalityLbEndpoint .getDefaultInstance ());
8886 envoyExtension (builder );
8987 JSON_MESSAGE_MARSHALLER = builder .build ();
9088 }
9189
9290 private static void envoyExtension (MessageMarshaller .Builder builder ) {
9391 final Reflections reflections = new Reflections (
94- "io.envoyproxy.envoy.extensions " , HttpConnectionManager .class .getClassLoader (),
92+ "io.envoyproxy.envoy" , HttpConnectionManager .class .getClassLoader (),
9593 new SubTypesScanner (true ));
9694 reflections .getSubTypesOf (GeneratedMessageV3 .class )
9795 .stream ()
98- .filter (c -> !c .getName ().contains ("$" )) // exclude subclasses
96+ .filter (c -> !c .getName ().contains ("$" )) // exclude inner classes
9997 .filter (XdsResourceManager ::hasGetDefaultInstanceMethod )
100- .forEach (builder ::register );
98+ .forEach (c -> {
99+ // register() does not throw; build() does. A test build per class is needed
100+ // to detect unsupported types before adding them to the real builder.
101+ try {
102+ MessageMarshaller .builder ()
103+ .omittingInsignificantWhitespace (true )
104+ .register (c )
105+ .build ();
106+ builder .register (c );
107+ } catch (Exception e ) {
108+ logger .debug ("Skipping proto type not supported by MessageMarshaller: {}" ,
109+ c .getName ());
110+ }
111+ });
101112 }
102113
103114 private static boolean hasGetDefaultInstanceMethod (Class <?> clazz ) {
0 commit comments