5454import org .apache .cassandra .distributed .upgrade .ConfigCompatibilityTestGenerate ;
5555import org .yaml .snakeyaml .introspector .Property ;
5656
57+ import static org .apache .cassandra .db .virtual .SettingsTable .BACKWARDS_COMPATIBLE_NAMES ;
58+
5759/**
5860 * To create the test files used by this class, run {@link ConfigCompatibilityTestGenerate}.
5961 */
@@ -181,7 +183,9 @@ private void diff(String original, Set<String> ignore, Set<String> expectedError
181183 Map <Class <?>, Map <String , Replacement >> replacements = Replacements .getNameReplacements (type );
182184 Set <String > missing = new HashSet <>();
183185 Set <String > errors = new HashSet <>();
184- diff (loader , replacements , previous , type , "" , missing , errors );
186+ Map <String , String > backwardsCompatNames = BACKWARDS_COMPATIBLE_NAMES ;
187+
188+ diff (loader , replacements , previous , type , "" , missing , errors , backwardsCompatNames );
185189 missing = Sets .difference (missing , ignore );
186190 errors = Sets .difference (errors , expectedErrors );
187191 StringBuilder msg = new StringBuilder ();
@@ -197,7 +201,7 @@ private void diff(String original, Set<String> ignore, Set<String> expectedError
197201 throw new AssertionError (msg );
198202 }
199203
200- private void diff (Loader loader , Map <Class <?>, Map <String , Replacement >> replacements , ClassTree previous , Class <?> type , String prefix , Set <String > missing , Set <String > errors )
204+ private void diff (Loader loader , Map <Class <?>, Map <String , Replacement >> replacements , ClassTree previous , Class <?> type , String prefix , Set <String > missing , Set <String > errors , Map < String , String > backwardsCompatNames )
201205 {
202206 Map <String , Replacement > replaces = replacements .getOrDefault (type , Collections .emptyMap ());
203207 Map <String , Property > properties = loader .getProperties (type );
@@ -228,7 +232,7 @@ private void diff(Loader loader, Map<Class<?>, Map<String, Replacement>> replace
228232 if (node instanceof ClassTree )
229233 {
230234 // current is nested type
231- diff (loader , replacements , (ClassTree ) node , prop .getType (), prefix + name + "." , missing , errors );
235+ diff (loader , replacements , (ClassTree ) node , prop .getType (), prefix + name + "." , missing , errors , backwardsCompatNames );
232236 }
233237 else
234238 {
@@ -243,7 +247,19 @@ private void diff(Loader loader, Map<Class<?>, Map<String, Replacement>> replace
243247 // previous is leaf, is current?
244248 Map <String , Property > children = Properties .isPrimitive (prop ) || Properties .isCollection (prop ) ? Collections .emptyMap () : loader .getProperties (prop .getType ());
245249 if (!children .isEmpty ())
250+ {
246251 errors .add (String .format ("Property %s used to be a value-type, but now is nested type %s" , name , prop .getType ()));
252+
253+ // Verify SettingsTable maps old name to new nested path for backwards compatibility (e.g., "authenticator" -> "authenticator.class_name")
254+ if (!backwardsCompatNames .containsKey (name ))
255+ {
256+ errors .add (String .format (
257+ "Property %s changed to nested type but is missing from SettingsTable.BACKWARDS_COMPATIBLE_NAMES. " +
258+ "Add mapping for '%s' to its new nested property path." ,
259+ name , name ));
260+ }
261+ }
262+
247263 typeCheck (null , toString (prop .getType ()), ((Leaf ) node ).type , name , errors );
248264 }
249265 }
@@ -332,7 +348,6 @@ else if (type.isArray())
332348 return List .class ;
333349 return type ;
334350 }
335-
336351 @ JsonSerialize (using = NodeSerializer .class )
337352 @ JsonDeserialize (using = NodeDeserializer .class )
338353 private interface Node
0 commit comments