4242import org .opensearch .cluster .ClusterState ;
4343import org .opensearch .cluster .block .ClusterBlockException ;
4444import org .opensearch .cluster .block .ClusterBlockLevel ;
45- import org .opensearch .cluster .metadata .IndexMetadata ;
4645import org .opensearch .cluster .metadata .IndexNameExpressionResolver ;
4746import org .opensearch .cluster .metadata .Metadata ;
4847import org .opensearch .cluster .node .DiscoveryNode ;
4948import org .opensearch .cluster .node .DiscoveryNodes ;
50- import org .opensearch .cluster .routing .RoutingTable ;
5149import org .opensearch .cluster .routing .allocation .AllocationService ;
5250import org .opensearch .cluster .service .ClusterManagerTaskKeys ;
5351import org .opensearch .cluster .service .ClusterManagerTaskThrottler ;
6058import org .opensearch .common .settings .SettingsException ;
6159import org .opensearch .core .action .ActionListener ;
6260import org .opensearch .core .common .io .stream .StreamInput ;
63- import org .opensearch .index .remote .RemoteMigrationIndexMetadataUpdater ;
6461import org .opensearch .node .remotestore .RemoteStoreNodeService ;
6562import org .opensearch .threadpool .ThreadPool ;
6663import org .opensearch .transport .TransportService ;
6764
6865import java .io .IOException ;
69- import java .util .Collection ;
70- import java .util .Collections ;
71- import java .util .List ;
72- import java .util .Map ;
73- import java .util .Set ;
74- import java .util .stream .Collectors ;
7566
76- import static org .opensearch .index .remote .RemoteMigrationIndexMetadataUpdater . indexHasRemoteStoreSettings ;
67+ import static org .opensearch .index .remote .RemoteStoreUtils . checkAndFinalizeRemoteStoreMigration ;
7768
7869/**
7970 * Transport action for updating cluster settings
@@ -159,8 +150,6 @@ protected void clusterManagerOperation(
159150
160151 private volatile boolean changed = false ;
161152
162- private volatile boolean isSwitchingToStrictMode = false ;
163-
164153 @ Override
165154 public ClusterManagerTaskThrottler .ThrottlingKey getClusterManagerThrottlingKey () {
166155 return clusterUpdateSettingTaskKey ;
@@ -269,27 +258,13 @@ public void onFailure(String source, Exception e) {
269258 @ Override
270259 public ClusterState execute (final ClusterState currentState ) {
271260 boolean isCompatibilityModeChanging = validateCompatibilityModeSettingRequest (request , state );
272- final ClusterState clusterState = updater .updateSettings (
261+ ClusterState clusterState = updater .updateSettings (
273262 currentState ,
274263 clusterSettings .upgradeSettings (request .transientSettings ()),
275264 clusterSettings .upgradeSettings (request .persistentSettings ()),
276265 logger
277266 );
278- /*
279- Remote Store migration: Checks if the applied cluster settings
280- has switched the cluster to STRICT mode. If so, checks and applies
281- appropriate index settings depending on the current set of node types
282- in the cluster
283-
284- This has been intentionally done after the cluster settings update
285- flow. That way we are not interfering with the usual settings update
286- and the cluster state mutation that comes along with it
287- */
288- if (isCompatibilityModeChanging && isSwitchToStrictCompatibilityMode (request )) {
289- ClusterState newStateAfterIndexMdChanges = finalizeMigration (clusterState );
290- changed = newStateAfterIndexMdChanges != currentState ;
291- return newStateAfterIndexMdChanges ;
292- }
267+ clusterState = checkAndFinalizeRemoteStoreMigration (isCompatibilityModeChanging , request , clusterState , logger );
293268 changed = clusterState != currentState ;
294269 return clusterState ;
295270 }
@@ -307,9 +282,10 @@ public ClusterState execute(final ClusterState currentState) {
307282 public boolean validateCompatibilityModeSettingRequest (ClusterUpdateSettingsRequest request , ClusterState clusterState ) {
308283 Settings settings = Settings .builder ().put (request .persistentSettings ()).put (request .transientSettings ()).build ();
309284 if (RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .exists (settings )) {
310- String value = RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .get (settings ).mode ;
311285 validateAllNodesOfSameVersion (clusterState .nodes ());
312- if (RemoteStoreNodeService .CompatibilityMode .STRICT .mode .equals (value )) {
286+ if (RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .get (
287+ settings
288+ ) == RemoteStoreNodeService .CompatibilityMode .STRICT ) {
313289 validateAllNodesOfSameType (clusterState .nodes ());
314290 }
315291 return true ;
@@ -334,99 +310,18 @@ private void validateAllNodesOfSameVersion(DiscoveryNodes discoveryNodes) {
334310 * @param discoveryNodes current discovery nodes in the cluster
335311 */
336312 private void validateAllNodesOfSameType (DiscoveryNodes discoveryNodes ) {
337- Set <Boolean > nodeTypes = discoveryNodes .getNodes ()
313+ boolean allNodesDocrepEnabled = discoveryNodes .getNodes ()
314+ .values ()
315+ .stream ()
316+ .allMatch (discoveryNode -> discoveryNode .isRemoteStoreNode () == false );
317+ boolean allNodesRemoteStoreEnabled = discoveryNodes .getNodes ()
338318 .values ()
339319 .stream ()
340- .map (DiscoveryNode ::isRemoteStoreNode )
341- .collect (Collectors .toSet ());
342- if (nodeTypes .size () != 1 ) {
320+ .allMatch (discoveryNode -> discoveryNode .isRemoteStoreNode ());
321+ if (allNodesDocrepEnabled == false && allNodesRemoteStoreEnabled == false ) {
343322 throw new SettingsException (
344323 "can not switch to STRICT compatibility mode when the cluster contains both remote and non-remote nodes"
345324 );
346325 }
347326 }
348-
349- /**
350- * Finalizes the docrep to remote-store migration process by applying remote store based index settings
351- * on indices that are missing them. No-Op if all indices already have the settings applied through
352- * IndexMetadataUpdater
353- *
354- * @param incomingState mutated cluster state after cluster settings were applied
355- * @return new cluster state with index settings updated
356- */
357- public ClusterState finalizeMigration (ClusterState incomingState ) {
358- Map <String , DiscoveryNode > discoveryNodeMap = incomingState .nodes ().getNodes ();
359- if (discoveryNodeMap .isEmpty () == false ) {
360- // At this point, we have already validated that all nodes in the cluster are of uniform type.
361- // Either all of them are remote store enabled, or all of them are docrep enabled
362- boolean remoteStoreEnabledNodePresent = discoveryNodeMap .values ().stream ().findFirst ().get ().isRemoteStoreNode ();
363- if (remoteStoreEnabledNodePresent == true ) {
364- List <IndexMetadata > indicesWithoutRemoteStoreSettings = getIndicesWithoutRemoteStoreSettings (incomingState );
365- if (indicesWithoutRemoteStoreSettings .isEmpty () == true ) {
366- logger .info ("All indices in the cluster has remote store based index settings" );
367- } else {
368- Metadata mutatedMetadata = applyRemoteStoreSettings (incomingState , indicesWithoutRemoteStoreSettings );
369- return ClusterState .builder (incomingState ).metadata (mutatedMetadata ).build ();
370- }
371- } else {
372- logger .debug ("All nodes in the cluster are not remote nodes. Skipping." );
373- }
374- }
375- return incomingState ;
376- }
377-
378- /**
379- * Filters out indices which does not have remote store based
380- * index settings applied even after all shard copies have
381- * migrated to remote store enabled nodes
382- */
383- private List <IndexMetadata > getIndicesWithoutRemoteStoreSettings (ClusterState clusterState ) {
384- Collection <IndexMetadata > allIndicesMetadata = clusterState .metadata ().indices ().values ();
385- if (allIndicesMetadata .isEmpty () == false ) {
386- List <IndexMetadata > indicesWithoutRemoteSettings = allIndicesMetadata .stream ()
387- .filter (idxMd -> indexHasRemoteStoreSettings (idxMd .getSettings ()) == false )
388- .collect (Collectors .toList ());
389- logger .debug (
390- "Attempting to switch to strict mode. Count of indices without remote store settings {}" ,
391- indicesWithoutRemoteSettings .size ()
392- );
393- return indicesWithoutRemoteSettings ;
394- }
395- return Collections .emptyList ();
396- }
397-
398- /**
399- * Applies remote store index settings through {@link RemoteMigrationIndexMetadataUpdater}
400- */
401- private Metadata applyRemoteStoreSettings (ClusterState clusterState , List <IndexMetadata > indicesWithRemoteStoreSettings ) {
402- Metadata .Builder metadataBuilder = Metadata .builder (clusterState .getMetadata ());
403- RoutingTable currentRoutingTable = clusterState .getRoutingTable ();
404- DiscoveryNodes currentDiscoveryNodes = clusterState .getNodes ();
405- Settings currentClusterSettings = clusterState .metadata ().settings ();
406- for (IndexMetadata indexMetadata : indicesWithRemoteStoreSettings ) {
407- IndexMetadata .Builder indexMetadataBuilder = IndexMetadata .builder (indexMetadata );
408- RemoteMigrationIndexMetadataUpdater indexMetadataUpdater = new RemoteMigrationIndexMetadataUpdater (
409- currentDiscoveryNodes ,
410- currentRoutingTable ,
411- indexMetadata ,
412- currentClusterSettings ,
413- logger
414- );
415- indexMetadataUpdater .maybeAddRemoteIndexSettings (indexMetadataBuilder , indexMetadata .getIndex ().getName ());
416- metadataBuilder .put (indexMetadataBuilder );
417- }
418- return metadataBuilder .build ();
419- }
420-
421- /**
422- * Checks if the incoming cluster settings payload is attempting to switch
423- * the cluster to `STRICT` compatibility mode
424- * Visible only for tests
425- */
426- public boolean isSwitchToStrictCompatibilityMode (ClusterUpdateSettingsRequest request ) {
427- Settings incomingSettings = Settings .builder ().put (request .persistentSettings ()).put (request .transientSettings ()).build ();
428- return RemoteStoreNodeService .CompatibilityMode .STRICT .mode .equals (
429- RemoteStoreNodeService .REMOTE_STORE_COMPATIBILITY_MODE_SETTING .get (incomingSettings ).mode
430- );
431- }
432327}
0 commit comments