45
45
import java .util .Map ;
46
46
import java .util .Map .Entry ;
47
47
import java .util .Optional ;
48
+ import java .util .Set ;
48
49
import java .util .function .Function ;
49
50
import java .util .function .Predicate ;
50
51
import java .util .stream .Collectors ;
@@ -65,30 +66,39 @@ public class SystemIndices {
65
66
66
67
private static final Automaton EMPTY = Automata .makeEmpty ();
67
68
68
- private static final Map <String , Feature > SERVER_SYSTEM_INDEX_DESCRIPTORS = Map .of (
69
- TASKS_FEATURE_NAME ,
69
+ /**
70
+ * This is the source for non-plugin system features.
71
+ */
72
+ private static final Map <String , Feature > SERVER_SYSTEM_FEATURE_DESCRIPTORS = Stream .of (
70
73
new Feature (TASKS_FEATURE_NAME , "Manages task results" , List .of (TASKS_DESCRIPTOR ))
71
- );
74
+ ).collect (Collectors .toUnmodifiableMap (Feature ::getName , Function .identity ()));
75
+
76
+ /**
77
+ * The node's full list of system features is stored here. The map is keyed
78
+ * on the value of {@link Feature#getName()}, and is used for fast lookup of
79
+ * feature objects via {@link #getFeature(String)}.
80
+ */
81
+ private final Map <String , Feature > featureDescriptors ;
72
82
73
83
private final Automaton systemNameAutomaton ;
74
84
private final CharacterRunAutomaton netNewSystemIndexAutomaton ;
75
85
private final CharacterRunAutomaton systemNameRunAutomaton ;
76
86
private final CharacterRunAutomaton systemIndexRunAutomaton ;
77
87
private final CharacterRunAutomaton systemDataStreamIndicesRunAutomaton ;
78
88
private final Predicate <String > systemDataStreamPredicate ;
79
- private final Map <String , Feature > featureDescriptors ;
80
89
private final SystemIndexDescriptor [] indexDescriptors ;
81
90
private final Map <String , SystemDataStreamDescriptor > dataStreamDescriptors ;
82
91
private final Map <String , CharacterRunAutomaton > productToSystemIndicesMatcher ;
83
92
private final ExecutorSelector executorSelector ;
84
93
85
94
/**
86
95
* Initialize the SystemIndices object
87
- * @param pluginAndModulesDescriptors A map of this node's feature names to
88
- * feature objects.
96
+ * @param pluginAndModuleFeatures A list of features from which we will load system indices.
97
+ * These features come from plugins and modules. Non-plugin system
98
+ * features such as Tasks will be added automatically.
89
99
*/
90
- public SystemIndices (Map < String , Feature > pluginAndModulesDescriptors ) {
91
- featureDescriptors = buildSystemIndexDescriptorMap ( pluginAndModulesDescriptors );
100
+ public SystemIndices (List < Feature > pluginAndModuleFeatures ) {
101
+ featureDescriptors = buildFeatureMap ( pluginAndModuleFeatures );
92
102
indexDescriptors = featureDescriptors .values ()
93
103
.stream ()
94
104
.flatMap (f -> f .getIndexDescriptors ().stream ())
@@ -115,21 +125,20 @@ public SystemIndices(Map<String, Feature> pluginAndModulesDescriptors) {
115
125
this .systemNameRunAutomaton = new CharacterRunAutomaton (systemNameAutomaton );
116
126
}
117
127
118
- static void ensurePatternsAllowSuffix (Map <String , Feature > features ) {
128
+ static void ensurePatternsAllowSuffix (Map <String , Feature > featureDescriptors ) {
119
129
String suffixPattern = "*" + UPGRADED_INDEX_SUFFIX ;
120
- final List <String > descriptorsWithNoRoomForSuffix = features . entrySet ()
130
+ final List <String > descriptorsWithNoRoomForSuffix = featureDescriptors . values ()
121
131
.stream ()
122
132
.flatMap (
123
- feature -> feature .getValue ()
124
- .getIndexDescriptors ()
133
+ feature -> feature .getIndexDescriptors ()
125
134
.stream ()
126
135
// The below filter & map are inside the enclosing flapMap so we have access to both the feature and the descriptor
127
136
.filter (descriptor -> overlaps (descriptor .getIndexPattern (), suffixPattern ) == false )
128
137
.map (
129
138
descriptor -> new ParameterizedMessage (
130
139
"pattern [{}] from feature [{}]" ,
131
140
descriptor .getIndexPattern (),
132
- feature .getKey ()
141
+ feature .getName ()
133
142
).getFormattedMessage ()
134
143
)
135
144
)
@@ -167,9 +176,9 @@ private static void checkForDuplicateAliases(Collection<SystemIndexDescriptor> d
167
176
}
168
177
}
169
178
170
- private static Map <String , CharacterRunAutomaton > getProductToSystemIndicesMap (Map <String , Feature > descriptors ) {
179
+ private static Map <String , CharacterRunAutomaton > getProductToSystemIndicesMap (Map <String , Feature > featureDescriptors ) {
171
180
Map <String , Automaton > productToSystemIndicesMap = new HashMap <>();
172
- for (Feature feature : descriptors .values ()) {
181
+ for (Feature feature : featureDescriptors .values ()) {
173
182
feature .getIndexDescriptors ().forEach (systemIndexDescriptor -> {
174
183
if (systemIndexDescriptor .isExternal ()) {
175
184
systemIndexDescriptor .getAllowedElasticProductOrigins ()
@@ -334,12 +343,37 @@ public Predicate<String> getProductSystemIndexNamePredicate(ThreadContext thread
334
343
return automaton ::run ;
335
344
}
336
345
337
- public Map <String , Feature > getFeatures () {
338
- return featureDescriptors ;
346
+ /**
347
+ * Get a set of feature names. This is useful for checking whether particular
348
+ * features are present on the node.
349
+ * @return A set of all feature names
350
+ */
351
+ public Set <String > getFeatureNames () {
352
+ return Set .copyOf (featureDescriptors .keySet ());
353
+ }
354
+
355
+ /**
356
+ * Get a feature by name.
357
+ * @param name Name of a feature.
358
+ * @return The corresponding feature if it exists on this node, null otherwise.
359
+ */
360
+ public Feature getFeature (String name ) {
361
+ return featureDescriptors .get (name );
362
+ }
363
+
364
+ /**
365
+ * Get a collection of the Features this SystemIndices object is managing.
366
+ * @return A collection of Features.
367
+ */
368
+ public Collection <Feature > getFeatures () {
369
+ return List .copyOf (featureDescriptors .values ());
339
370
}
340
371
341
- private static Automaton buildIndexAutomaton (Map <String , Feature > descriptors ) {
342
- Optional <Automaton > automaton = descriptors .values ().stream ().map (SystemIndices ::featureToIndexAutomaton ).reduce (Operations ::union );
372
+ private static Automaton buildIndexAutomaton (Map <String , Feature > featureDescriptors ) {
373
+ Optional <Automaton > automaton = featureDescriptors .values ()
374
+ .stream ()
375
+ .map (SystemIndices ::featureToIndexAutomaton )
376
+ .reduce (Operations ::union );
343
377
return MinimizationOperations .minimize (automaton .orElse (EMPTY ), Integer .MAX_VALUE );
344
378
}
345
379
@@ -362,8 +396,8 @@ private static Automaton featureToIndexAutomaton(Feature feature) {
362
396
return systemIndexAutomaton .orElse (EMPTY );
363
397
}
364
398
365
- private static Automaton buildDataStreamAutomaton (Map <String , Feature > descriptors ) {
366
- Optional <Automaton > automaton = descriptors .values ()
399
+ private static Automaton buildDataStreamAutomaton (Map <String , Feature > featureDescriptors ) {
400
+ Optional <Automaton > automaton = featureDescriptors .values ()
367
401
.stream ()
368
402
.flatMap (feature -> feature .getDataStreamDescriptors ().stream ())
369
403
.map (SystemDataStreamDescriptor ::getDataStreamName )
@@ -373,13 +407,13 @@ private static Automaton buildDataStreamAutomaton(Map<String, Feature> descripto
373
407
return automaton .isPresent () ? MinimizationOperations .minimize (automaton .get (), Integer .MAX_VALUE ) : EMPTY ;
374
408
}
375
409
376
- private static Predicate <String > buildDataStreamNamePredicate (Map <String , Feature > descriptors ) {
377
- CharacterRunAutomaton characterRunAutomaton = new CharacterRunAutomaton (buildDataStreamAutomaton (descriptors ));
410
+ private static Predicate <String > buildDataStreamNamePredicate (Map <String , Feature > featureDescriptors ) {
411
+ CharacterRunAutomaton characterRunAutomaton = new CharacterRunAutomaton (buildDataStreamAutomaton (featureDescriptors ));
378
412
return characterRunAutomaton ::run ;
379
413
}
380
414
381
- private static Automaton buildDataStreamBackingIndicesAutomaton (Map <String , Feature > descriptors ) {
382
- Optional <Automaton > automaton = descriptors .values ()
415
+ private static Automaton buildDataStreamBackingIndicesAutomaton (Map <String , Feature > featureDescriptors ) {
416
+ Optional <Automaton > automaton = featureDescriptors .values ()
383
417
.stream ()
384
418
.map (SystemIndices ::featureToDataStreamBackingIndicesAutomaton )
385
419
.reduce (Operations ::union );
@@ -504,21 +538,19 @@ public enum SystemIndexAccessLevel {
504
538
* Given a collection of {@link SystemIndexDescriptor}s and their sources, checks to see if the index patterns of the listed
505
539
* descriptors overlap with any of the other patterns. If any do, throws an exception.
506
540
*
507
- * @param sourceToFeature A map of source (plugin) names to the SystemIndexDescriptors they provide.
541
+ * @param featureDescriptors A map of feature names to the Features that will provide SystemIndexDescriptors
508
542
* @throws IllegalStateException Thrown if any of the index patterns overlaps with another.
509
543
*/
510
- static void checkForOverlappingPatterns (Map <String , Feature > sourceToFeature ) {
511
- List <Tuple <String , SystemIndexDescriptor >> sourceDescriptorPair = sourceToFeature . entrySet ()
544
+ static void checkForOverlappingPatterns (Map <String , Feature > featureDescriptors ) {
545
+ List <Tuple <String , SystemIndexDescriptor >> sourceDescriptorPair = featureDescriptors . values ()
512
546
.stream ()
513
- .flatMap (entry -> entry . getValue (). getIndexDescriptors ().stream ().map (descriptor -> new Tuple <>(entry . getKey (), descriptor )))
547
+ .flatMap (feature -> feature . getIndexDescriptors ().stream ().map (descriptor -> new Tuple <>(feature . getName (), descriptor )))
514
548
.sorted (Comparator .comparing (d -> d .v1 () + ":" + d .v2 ().getIndexPattern ())) // Consistent ordering -> consistent error message
515
549
.toList ();
516
- List <Tuple <String , SystemDataStreamDescriptor >> sourceDataStreamDescriptorPair = sourceToFeature . entrySet ()
550
+ List <Tuple <String , SystemDataStreamDescriptor >> sourceDataStreamDescriptorPair = featureDescriptors . values ()
517
551
.stream ()
518
- .filter (entry -> entry .getValue ().getDataStreamDescriptors ().isEmpty () == false )
519
- .flatMap (
520
- entry -> entry .getValue ().getDataStreamDescriptors ().stream ().map (descriptor -> new Tuple <>(entry .getKey (), descriptor ))
521
- )
552
+ .filter (feature -> feature .getDataStreamDescriptors ().isEmpty () == false )
553
+ .flatMap (feature -> feature .getDataStreamDescriptors ().stream ().map (descriptor -> new Tuple <>(feature .getName (), descriptor )))
522
554
.sorted (Comparator .comparing (d -> d .v1 () + ":" + d .v2 ().getDataStreamName ())) // Consistent ordering -> consistent error message
523
555
.toList ();
524
556
@@ -577,11 +609,11 @@ private static boolean overlaps(String pattern1, String pattern2) {
577
609
return Operations .isEmpty (Operations .intersection (a1Automaton , a2Automaton )) == false ;
578
610
}
579
611
580
- private static Map <String , Feature > buildSystemIndexDescriptorMap ( Map < String , Feature > featuresMap ) {
581
- final Map <String , Feature > map = Maps .newMapWithExpectedSize (featuresMap .size () + SERVER_SYSTEM_INDEX_DESCRIPTORS .size ());
582
- map .putAll ( featuresMap );
612
+ private static Map <String , Feature > buildFeatureMap ( List < Feature > features ) {
613
+ final Map <String , Feature > map = Maps .newMapWithExpectedSize (features .size () + SERVER_SYSTEM_FEATURE_DESCRIPTORS .size ());
614
+ features . forEach ( feature -> map .put ( feature . getName (), feature ) );
583
615
// put the server items last since we expect less of them
584
- SERVER_SYSTEM_INDEX_DESCRIPTORS .forEach ((source , feature ) -> {
616
+ SERVER_SYSTEM_FEATURE_DESCRIPTORS .forEach ((source , feature ) -> {
585
617
if (map .putIfAbsent (source , feature ) != null ) {
586
618
throw new IllegalArgumentException (
587
619
"plugin or module attempted to define the same source [" + source + "] as a built-in system index"
0 commit comments