25
25
import org .apache .logging .log4j .Logger ;
26
26
import org .apache .lucene .store .LockObtainFailedException ;
27
27
import org .elasticsearch .ElasticsearchException ;
28
+ import org .elasticsearch .Version ;
29
+ import org .elasticsearch .action .admin .indices .rollover .Condition ;
28
30
import org .elasticsearch .cli .EnvironmentAwareCommand ;
29
31
import org .elasticsearch .cli .Terminal ;
30
32
import org .elasticsearch .cli .UserException ;
31
- import org .elasticsearch .cluster .ClusterModule ;
32
33
import org .elasticsearch .cluster .ClusterName ;
33
34
import org .elasticsearch .cluster .ClusterState ;
35
+ import org .elasticsearch .cluster .Diff ;
36
+ import org .elasticsearch .cluster .metadata .MetaData ;
34
37
import org .elasticsearch .common .collect .Tuple ;
38
+ import org .elasticsearch .common .io .stream .StreamOutput ;
35
39
import org .elasticsearch .common .settings .ClusterSettings ;
36
40
import org .elasticsearch .common .settings .Settings ;
37
41
import org .elasticsearch .common .util .BigArrays ;
38
42
import org .elasticsearch .common .xcontent .NamedXContentRegistry ;
43
+ import org .elasticsearch .common .xcontent .XContentBuilder ;
44
+ import org .elasticsearch .common .xcontent .XContentParser ;
39
45
import org .elasticsearch .env .Environment ;
40
46
import org .elasticsearch .env .NodeEnvironment ;
41
47
import org .elasticsearch .env .NodeMetaData ;
42
48
import org .elasticsearch .gateway .PersistedClusterStateService ;
43
- import org .elasticsearch .indices .IndicesModule ;
44
49
45
50
import java .io .IOException ;
46
51
import java .nio .file .Files ;
47
52
import java .nio .file .Path ;
48
53
import java .util .Arrays ;
54
+ import java .util .Collections ;
55
+ import java .util .EnumSet ;
56
+ import java .util .Map ;
49
57
import java .util .Objects ;
50
- import java .util .function .Function ;
51
- import java .util .stream .Collectors ;
52
- import java .util .stream .Stream ;
53
58
54
59
public abstract class ElasticsearchNodeCommand extends EnvironmentAwareCommand {
55
60
private static final Logger logger = LogManager .getLogger (ElasticsearchNodeCommand .class );
@@ -67,10 +72,34 @@ public abstract class ElasticsearchNodeCommand extends EnvironmentAwareCommand {
67
72
protected static final String CS_MISSING_MSG =
68
73
"cluster state is empty, cluster has never been bootstrapped?" ;
69
74
70
- protected static final NamedXContentRegistry namedXContentRegistry = new NamedXContentRegistry (
71
- Stream .of (ClusterModule .getNamedXWriteables ().stream (), IndicesModule .getNamedXContents ().stream ())
72
- .flatMap (Function .identity ())
73
- .collect (Collectors .toList ()));
75
+ // fake the registry here, as command-line tools are not loading plugins, and ensure that it preserves the parsed XContent
76
+ public static final NamedXContentRegistry namedXContentRegistry = new NamedXContentRegistry (Collections .emptyList ()) {
77
+
78
+ @ SuppressWarnings ("unchecked" )
79
+ @ Override
80
+ public <T , C > T parseNamedObject (Class <T > categoryClass , String name , XContentParser parser , C context ) throws IOException {
81
+ // Currently, two unknown top-level objects are present
82
+ if (MetaData .Custom .class .isAssignableFrom (categoryClass )) {
83
+ return (T ) new UnknownMetaDataCustom (name , parser .mapOrdered ());
84
+ }
85
+ if (Condition .class .isAssignableFrom (categoryClass )) {
86
+ // The parsing for conditions is a bit weird as these represent JSON primitives (strings or numbers)
87
+ // TODO: Make Condition non-pluggable
88
+ assert parser .currentToken () == XContentParser .Token .FIELD_NAME : parser .currentToken ();
89
+ if (parser .currentToken () != XContentParser .Token .FIELD_NAME ) {
90
+ throw new UnsupportedOperationException ("Unexpected token for Condition: " + parser .currentToken ());
91
+ }
92
+ parser .nextToken ();
93
+ assert parser .currentToken ().isValue () : parser .currentToken ();
94
+ if (parser .currentToken ().isValue () == false ) {
95
+ throw new UnsupportedOperationException ("Unexpected token for Condition: " + parser .currentToken ());
96
+ }
97
+ return (T ) new UnknownCondition (name , parser .objectText ());
98
+ }
99
+ assert false : "Unexpected category class " + categoryClass + " for name " + name ;
100
+ throw new UnsupportedOperationException ("Unexpected category class " + categoryClass + " for name " + name );
101
+ }
102
+ };
74
103
75
104
public ElasticsearchNodeCommand (String description ) {
76
105
super (description );
@@ -86,7 +115,7 @@ public static PersistedClusterStateService createPersistedClusterStateService(Se
86
115
87
116
String nodeId = nodeMetaData .nodeId ();
88
117
return new PersistedClusterStateService (dataPaths , nodeId , namedXContentRegistry , BigArrays .NON_RECYCLING_INSTANCE ,
89
- new ClusterSettings (settings , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS ), () -> 0L , true );
118
+ new ClusterSettings (settings , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS ), () -> 0L );
90
119
}
91
120
92
121
public static ClusterState clusterState (Environment environment , PersistedClusterStateService .OnDiskState onDiskState ) {
@@ -176,4 +205,78 @@ private static NodeEnvironment.NodePath createNodePath(Path path) {
176
205
OptionParser getParser () {
177
206
return parser ;
178
207
}
208
+
209
+ public static class UnknownMetaDataCustom implements MetaData .Custom {
210
+
211
+ private final String name ;
212
+ private final Map <String , Object > contents ;
213
+
214
+ public UnknownMetaDataCustom (String name , Map <String , Object > contents ) {
215
+ this .name = name ;
216
+ this .contents = contents ;
217
+ }
218
+
219
+ @ Override
220
+ public EnumSet <MetaData .XContentContext > context () {
221
+ return EnumSet .of (MetaData .XContentContext .API , MetaData .XContentContext .GATEWAY );
222
+ }
223
+
224
+ @ Override
225
+ public Diff <MetaData .Custom > diff (MetaData .Custom previousState ) {
226
+ assert false ;
227
+ throw new UnsupportedOperationException ();
228
+ }
229
+
230
+ @ Override
231
+ public String getWriteableName () {
232
+ return name ;
233
+ }
234
+
235
+ @ Override
236
+ public Version getMinimalSupportedVersion () {
237
+ assert false ;
238
+ throw new UnsupportedOperationException ();
239
+ }
240
+
241
+ @ Override
242
+ public void writeTo (StreamOutput out ) throws IOException {
243
+ assert false ;
244
+ throw new UnsupportedOperationException ();
245
+ }
246
+
247
+ @ Override
248
+ public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
249
+ return builder .mapContents (contents );
250
+ }
251
+ }
252
+
253
+ public static class UnknownCondition extends Condition <Object > {
254
+
255
+ public UnknownCondition (String name , Object value ) {
256
+ super (name );
257
+ this .value = value ;
258
+ }
259
+
260
+ @ Override
261
+ public String getWriteableName () {
262
+ return name ;
263
+ }
264
+
265
+ @ Override
266
+ public void writeTo (StreamOutput out ) throws IOException {
267
+ assert false ;
268
+ throw new UnsupportedOperationException ();
269
+ }
270
+
271
+ @ Override
272
+ public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
273
+ return builder .field (name , value );
274
+ }
275
+
276
+ @ Override
277
+ public Result evaluate (Stats stats ) {
278
+ assert false ;
279
+ throw new UnsupportedOperationException ();
280
+ }
281
+ }
179
282
}
0 commit comments