2525import java .util .Collection ;
2626import java .util .Collections ;
2727import java .util .HashMap ;
28+ import java .util .HashSet ;
2829import java .util .Map ;
2930import java .util .NavigableMap ;
3031import java .util .Set ;
@@ -280,17 +281,24 @@ public static MlConfigVersion getMaxMlConfigVersion(DiscoveryNodes nodes) {
280281 public static Tuple <MlConfigVersion , MlConfigVersion > getMinMaxMlConfigVersion (DiscoveryNodes nodes ) {
281282 MlConfigVersion minMlConfigVersion = MlConfigVersion .CURRENT ;
282283 MlConfigVersion maxMlConfigVersion = MlConfigVersion .FIRST_ML_VERSION ;
284+
285+ // many nodes will have the same versions, so de-duplicate versions first so that we only have to parse unique versions
286+ final Set <String > versions = new HashSet <>();
283287 for (DiscoveryNode node : nodes ) {
284- try {
285- MlConfigVersion mlConfigVersion = getMlConfigVersionForNode (node );
286- if (mlConfigVersion .before (minMlConfigVersion )) {
287- minMlConfigVersion = mlConfigVersion ;
288- }
289- if (mlConfigVersion .after (maxMlConfigVersion )) {
290- maxMlConfigVersion = mlConfigVersion ;
291- }
292- } catch (IllegalStateException e ) {
293- // This means we encountered a node that is after 8.10.0 but has the ML plugin disabled - ignore it
288+ String mlConfigVerStr = node .getAttributes ().get (ML_CONFIG_VERSION_NODE_ATTR );
289+ if (mlConfigVerStr != null ) { // ignore nodes that don't have an ML config version
290+ versions .add (mlConfigVerStr );
291+ }
292+ }
293+
294+ // of the unique versions, find the min and max
295+ for (String version : versions ) {
296+ MlConfigVersion mlConfigVersion = fromString (version );
297+ if (mlConfigVersion .before (minMlConfigVersion )) {
298+ minMlConfigVersion = mlConfigVersion ;
299+ }
300+ if (mlConfigVersion .after (maxMlConfigVersion )) {
301+ maxMlConfigVersion = mlConfigVersion ;
294302 }
295303 }
296304 return new Tuple <>(minMlConfigVersion , maxMlConfigVersion );
@@ -304,6 +312,9 @@ public static MlConfigVersion getMlConfigVersionForNode(DiscoveryNode node) {
304312 return fromId (node .getPre811VersionId ().orElseThrow (() -> new IllegalStateException ("getting legacy version id not possible" )));
305313 }
306314
315+ // supports fromString below
316+ private static final Pattern ML_VERSION_PATTERN = Pattern .compile ("^(\\ d+)\\ .(\\ d+)\\ .(\\ d+)(?:-\\ w+)?$" );
317+
307318 // Parse an MlConfigVersion from a string.
308319 // Note that version "8.10.x" and "8.11.0" are silently converted to "10.0.0".
309320 // This is to support upgrade scenarios in pre-prod QA environments.
@@ -319,7 +330,7 @@ public static MlConfigVersion fromString(String str) {
319330 if (str .startsWith ("8.10." ) || str .equals ("8.11.0" )) {
320331 return V_10 ;
321332 }
322- Matcher matcher = Pattern . compile ( "^( \\ d+) \\ .( \\ d+) \\ .( \\ d+)(?:- \\ w+)?$" ) .matcher (str );
333+ Matcher matcher = ML_VERSION_PATTERN .matcher (str );
323334 if (matcher .matches () == false ) {
324335 throw new IllegalArgumentException ("ML config version [" + str + "] not valid" );
325336 }
0 commit comments