45
45
import org .opensearch .cluster .metadata .IndexNameExpressionResolver ;
46
46
import org .opensearch .cluster .metadata .Metadata ;
47
47
import org .opensearch .cluster .node .DiscoveryNode ;
48
+ import org .opensearch .cluster .node .DiscoveryNodes ;
48
49
import org .opensearch .cluster .routing .allocation .AllocationService ;
49
50
import org .opensearch .cluster .service .ClusterManagerTaskKeys ;
50
51
import org .opensearch .cluster .service .ClusterManagerTaskThrottler ;
53
54
import org .opensearch .common .Priority ;
54
55
import org .opensearch .common .inject .Inject ;
55
56
import org .opensearch .common .settings .ClusterSettings ;
57
+ import org .opensearch .common .settings .Settings ;
58
+ import org .opensearch .common .settings .SettingsException ;
56
59
import org .opensearch .core .action .ActionListener ;
57
60
import org .opensearch .core .common .io .stream .StreamInput ;
61
+ import org .opensearch .node .remotestore .RemoteStoreNodeService ;
58
62
import org .opensearch .threadpool .ThreadPool ;
59
63
import org .opensearch .transport .TransportService ;
60
64
61
65
import java .io .IOException ;
66
+ import java .util .Locale ;
67
+ import java .util .Set ;
68
+ import java .util .stream .Collectors ;
62
69
63
70
/**
64
71
* Transport action for updating cluster settings
@@ -251,6 +258,7 @@ public void onFailure(String source, Exception e) {
251
258
252
259
@ Override
253
260
public ClusterState execute (final ClusterState currentState ) {
261
+ validateCompatibilityModeSettingRequest (request , state );
254
262
final ClusterState clusterState = updater .updateSettings (
255
263
currentState ,
256
264
clusterSettings .upgradeSettings (request .transientSettings ()),
@@ -264,4 +272,49 @@ public ClusterState execute(final ClusterState currentState) {
264
272
);
265
273
}
266
274
275
+ /**
276
+ * Runs various checks associated with changing cluster compatibility mode
277
+ * @param request cluster settings update request, for settings to be updated and new values
278
+ * @param clusterState current state of cluster, for information on nodes
279
+ */
280
+ public void validateCompatibilityModeSettingRequest (ClusterUpdateSettingsRequest request , ClusterState clusterState ) {
281
+ Settings settings = Settings .builder ().put (request .persistentSettings ()).put (request .transientSettings ()).build ();
282
+ if (RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .exists (settings )) {
283
+ String value = settings .get (RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .getKey ()).toLowerCase (Locale .ROOT );
284
+ validateAllNodesOfSameVersion (clusterState .nodes ());
285
+ if (value .equals (RemoteStoreNodeService .CompatibilityMode .STRICT .mode )) {
286
+ validateAllNodesOfSameType (clusterState .nodes ());
287
+ }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Verifies that while trying to change the compatibility mode, all nodes must have the same version.
293
+ * If not, it throws SettingsException error
294
+ * @param discoveryNodes current discovery nodes in the cluster
295
+ */
296
+ private void validateAllNodesOfSameVersion (DiscoveryNodes discoveryNodes ) {
297
+ if (discoveryNodes .getMaxNodeVersion ().equals (discoveryNodes .getMinNodeVersion ()) == false ) {
298
+ throw new SettingsException ("can not change the compatibility mode when all the nodes in cluster are not of the same version" );
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Verifies that while trying to switch to STRICT compatibility mode, all nodes must be of the
304
+ * same type (all remote or all non-remote). If not, it throws SettingsException error
305
+ * @param discoveryNodes current discovery nodes in the cluster
306
+ */
307
+ private void validateAllNodesOfSameType (DiscoveryNodes discoveryNodes ) {
308
+ Set <Boolean > nodeTypes = discoveryNodes .getNodes ()
309
+ .values ()
310
+ .stream ()
311
+ .map (DiscoveryNode ::isRemoteStoreNode )
312
+ .collect (Collectors .toSet ());
313
+ if (nodeTypes .size () != 1 ) {
314
+ throw new SettingsException (
315
+ "can not switch to STRICT compatibility mode when the cluster contains both remote and non-remote nodes"
316
+ );
317
+ }
318
+ }
319
+
267
320
}
0 commit comments