diff --git a/src/Nest/DSL/RestoreDescriptor.cs b/src/Nest/DSL/RestoreDescriptor.cs index 82f2ae6c7a6..ba6b03cafc4 100644 --- a/src/Nest/DSL/RestoreDescriptor.cs +++ b/src/Nest/DSL/RestoreDescriptor.cs @@ -19,7 +19,10 @@ public interface IRestoreRequest : IRepositorySnapshotPath IgnoreIndexSettings { get; set; } } internal static class RestorePathInfo @@ -43,6 +46,8 @@ public RestoreRequest(string repository, string snapshot) : base(repository, sna public string RenamePattern { get; set; } public string RenameReplacement { get; set; } + public IUpdateSettingsRequest IndexSettings { get; set; } + public List IgnoreIndexSettings { get; set; } protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo pathInfo) { @@ -61,7 +66,9 @@ public partial class RestoreDescriptor : RepositorySnapshotPathDescriptor IRestoreRequest.IgnoreIndexSettings { get; set; } + public RestoreDescriptor Index(string index) { return this.Indices(index); @@ -104,10 +111,30 @@ public RestoreDescriptor RenameReplacement(string renameReplacement) return this; } + public RestoreDescriptor IndexSettings(Func settingsSelector) + { + settingsSelector.ThrowIfNull("settings"); + Self.IndexSettings = settingsSelector(new UpdateSettingsDescriptor()); + return this; + } + + public RestoreDescriptor IgnoreIndexSettings(List ignoreIndexSettings) + { + ignoreIndexSettings.ThrowIfNull("ignoreIndexSettings"); + Self.IgnoreIndexSettings = ignoreIndexSettings; + return this; + } + + public RestoreDescriptor IgnoreIndexSettings(params string[] ignoreIndexSettings) + { + ignoreIndexSettings.ThrowIfNull("ignoreIndexSettings"); + this.IgnoreIndexSettings(ignoreIndexSettings.ToList()); + return this; + } + protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo pathInfo) { RestorePathInfo.Update(pathInfo, this); } - } } diff --git a/src/Nest/DSL/UpdateSettingsDescriptor.cs b/src/Nest/DSL/UpdateSettingsDescriptor.cs index 4c549c82ba3..e77b6d85c5f 100644 --- a/src/Nest/DSL/UpdateSettingsDescriptor.cs +++ b/src/Nest/DSL/UpdateSettingsDescriptor.cs @@ -1,116 +1,154 @@ using System; using System.Collections.Generic; -using System.Linq; using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest -{ +{ + public class UpdatableSettings + { + public const string NumberOfReplicas = "index.number_of_replicas"; + public const string AutoExpandReplicas = "index.auto_expand_replicas"; + public const string BlocksReadOnly = "index.blocks.read_only"; + public const string BlocksRead = "index.blocks.read"; + public const string BlocksWrite = "index.blocks.write"; + public const string BlocksMetadata = "index.blocks.metadata"; + public const string RefreshInterval = "index.refresh_interval"; + public const string IndexConcurrency = "index.index_concurrency"; + public const string Codec = "index.codec"; + public const string CodecBloomLoad = "index.codec.bloom.load"; + public const string FailOnMergeFailure = "index.fail_on_merge_failure"; + public const string TranslogFlushTreshHoldOps = "index.translog.flush_threshold_ops"; + public const string TranslogFlushThresholdSize = "index.translog.flush_threshold_size"; + public const string TranslogFlushThresholdPeriod = "index.translog.flush_threshold_period"; + public const string TranslogDisableFlush = "index.translog.disable_flush"; + public const string CacheFilterMaxSize = "index.cache.filter.max_size"; + public const string CacheFilterExpire = "index.cache.filter.expire"; + public const string CacheQueryEnable = "index.cache.query.enable"; + public const string GatewaySnapshotInterval = "index.gateway.snapshot_interval"; + public const string RoutingAllocationInclude = "index.routing.allocation.include"; + public const string RoutingAllocationExclude = "index.routing.allocation.exclude"; + public const string RoutingAllocationRequire = "index.routing.allocation.require"; + public const string RoutingAllocationEnable = "index.routing.allocation.enable"; + public const string RoutingAllocationDisableAllication = "index.routing.allocation.disable_allocation"; + public const string RoutingAllocationDisableNewAllocation = "index.routing.allocation.disable_new_allocation"; + public const string RoutingAllocationDisableReplicaAllocation = "index.routing.allocation.disable_replica_allocation"; + public const string RoutingAllocationTotalShardsPerNode = "index.routing.allocation.total_shards_per_node"; + public const string RecoveryInitialShards = "index.recovery.initial_shards"; + public const string GcDeletes = "index.gc_deletes"; + public const string TtlDisablePurge = "index.ttl.disable_purge"; + public const string TranslogFsType = "index.translog.fs.type"; + public const string CompoundFormat = "index.compound_format"; + public const string CompoundOnFlush = "index.compound_on_flush"; + public const string WarmersEnabled = "index.warmer.enabled"; + public const string Analysis = "analysis"; + } + public interface IUpdateSettingsRequest : IIndexOptionalPath { - [JsonProperty("index.number_of_replicas")] + [JsonProperty(UpdatableSettings.NumberOfReplicas)] int? NumberOfReplicas { get; set; } - [JsonProperty("index.auto_expand_replicas")] + [JsonProperty(UpdatableSettings.AutoExpandReplicas)] object AutoExpandReplicas { get; set; } - [JsonProperty("index.blocks.read_only")] + [JsonProperty(UpdatableSettings.BlocksReadOnly)] bool? BlocksReadOnly { get; set; } - [JsonProperty("index.blocks.read")] + [JsonProperty(UpdatableSettings.BlocksRead)] bool? BlocksRead { get; set; } - [JsonProperty("index.blocks.write")] + [JsonProperty(UpdatableSettings.BlocksWrite)] bool? BlocksWrite { get; set; } - [JsonProperty("index.blocks.metadata")] + [JsonProperty(UpdatableSettings.BlocksMetadata)] bool? BlocksMetadata { get; set; } - [JsonProperty("index.refresh_interval")] + [JsonProperty(UpdatableSettings.RefreshInterval)] string RefreshInterval { get; set; } - [JsonProperty("index.index_concurrency")] + [JsonProperty(UpdatableSettings.IndexConcurrency)] int? IndexConcurrency { get; set; } - [JsonProperty("index.codec")] + [JsonProperty(UpdatableSettings.Codec)] string Codec { get; set; } - [JsonProperty("index.codec.bloom.load")] + [JsonProperty(UpdatableSettings.CodecBloomLoad)] bool? CodecBloomLoad { get; set; } - [JsonProperty("index.fail_on_merge_failure")] + [JsonProperty(UpdatableSettings.FailOnMergeFailure)] bool? FailOnMergeFailure { get; set; } - [JsonProperty("index.translog.flush_threshold_ops")] + [JsonProperty(UpdatableSettings.TranslogFlushTreshHoldOps)] string TranslogFlushTreshHoldOps { get; set; } - [JsonProperty("index.translog.flush_threshold_size")] + [JsonProperty(UpdatableSettings.TranslogFlushThresholdSize)] string TranslogFlushThresholdSize { get; set; } - [JsonProperty("index.translog.flush_threshold_period")] + [JsonProperty(UpdatableSettings.TranslogFlushThresholdPeriod)] string TranslogFlushThresholdPeriod { get; set; } - [JsonProperty("index.translog.disable_flush")] + [JsonProperty(UpdatableSettings.TranslogDisableFlush)] bool? TranslogDisableFlush { get; set; } - [JsonProperty("index.cache.filter.max_size")] + [JsonProperty(UpdatableSettings.CacheFilterMaxSize)] string CacheFilterMaxSize { get; set; } - [JsonProperty("index.cache.filter.expire")] + [JsonProperty(UpdatableSettings.CacheFilterExpire)] string CacheFilterExpire { get; set; } - [JsonProperty("index.cache.query.enable")] + [JsonProperty(UpdatableSettings.CacheQueryEnable)] bool? CacheQueryEnable { get; set; } - [JsonProperty("index.gateway.snapshot_interval")] + [JsonProperty(UpdatableSettings.GatewaySnapshotInterval)] string GatewaySnapshotInterval { get; set; } - [JsonProperty("index.routing.allocation.include")] + [JsonProperty(UpdatableSettings.RoutingAllocationInclude)] IDictionary RoutingAllocationInclude { get; set; } - [JsonProperty("index.routing.allocation.exclude")] + [JsonProperty(UpdatableSettings.RoutingAllocationExclude)] IDictionary RoutingAllocationExclude { get; set; } - [JsonProperty("index.routing.allocation.require")] + [JsonProperty(UpdatableSettings.RoutingAllocationRequire)] IDictionary RoutingAllocationRequire { get; set; } - [JsonProperty("index.routing.allocation.enable")] + [JsonProperty(UpdatableSettings.RoutingAllocationEnable)] RoutingAllocationEnableOption? RoutingAllocationEnable { get; set; } - [JsonProperty("index.routing.allocation.disable_allocation")] + [JsonProperty(UpdatableSettings.RoutingAllocationDisableAllication)] bool? RoutingAllocationDisableAllication { get; set; } - [JsonProperty("index.routing.allocation.disable_new_allocation")] + [JsonProperty(UpdatableSettings.RoutingAllocationDisableNewAllocation)] bool? RoutingAllocationDisableNewAllocation { get; set; } - [JsonProperty("index.routing.allocation.disable_replica_allocation")] + [JsonProperty(UpdatableSettings.RoutingAllocationDisableReplicaAllocation)] bool? RoutingAllocationDisableReplicaAllocation { get; set; } - [JsonProperty("index.routing.allocation.total_shards_per_node")] + [JsonProperty(UpdatableSettings.RoutingAllocationTotalShardsPerNode)] int? RoutingAllocationTotalShardsPerNode { get; set; } - [JsonProperty("index.recovery.initial_shards")] + [JsonProperty(UpdatableSettings.RecoveryInitialShards)] string RecoveryInitialShards { get; set; } - [JsonProperty("index.gc_deletes")] + [JsonProperty(UpdatableSettings.GcDeletes)] bool? GcDeletes { get; set; } - [JsonProperty("index.ttl.disable_purge")] + [JsonProperty(UpdatableSettings.TtlDisablePurge)] bool? TtlDisablePurge { get; set; } - [JsonProperty("index.translog.fs.type")] + [JsonProperty(UpdatableSettings.TranslogFsType)] string TranslogFsType { get; set; } - [JsonProperty("index.compound_format")] + [JsonProperty(UpdatableSettings.CompoundFormat)] bool? CompoundFormat { get; set; } - [JsonProperty("index.compound_on_flush")] + [JsonProperty(UpdatableSettings.CompoundOnFlush)] bool? CompoundOnFlush { get; set; } - [JsonProperty("index.warmer.enabled")] + [JsonProperty(UpdatableSettings.WarmersEnabled)] bool? WarmersEnabled { get; set; } - [JsonProperty("analysis")] + [JsonProperty(UpdatableSettings.Analysis)] AnalysisSettings Analysis { get; set; } } diff --git a/src/Tests/Nest.Tests.Integration/Core/Repository/RestoreTests.cs b/src/Tests/Nest.Tests.Integration/Core/Repository/RestoreTests.cs index 7f10587f3ea..3184c0954f8 100644 --- a/src/Tests/Nest.Tests.Integration/Core/Repository/RestoreTests.cs +++ b/src/Tests/Nest.Tests.Integration/Core/Repository/RestoreTests.cs @@ -90,7 +90,7 @@ public void SnapshotRestore() var indexExistsResponse = this.Client.IndexExists(f => f.Index(_restoredIndexName)); indexExistsResponse.Exists.Should().BeTrue(); - + var count = this.Client.Count(descriptor => descriptor.Index(_restoredIndexName)).Count; var indexContent = this.Client.SourceMany(_indexedElements.Select(x => (long)x.Id), _restoredIndexName); @@ -99,6 +99,43 @@ public void SnapshotRestore() indexContent.ShouldBeEquivalentTo(_indexedElements); } + [Test] + [SkipVersion("0 - 1.4.9", "Requires index_settings and ignore_index_settings parameters which have been added in ES 1.5.0")] + public void SnapshotRestore_IndexSettings() + { + var updateSettingsResponse = this.Client.UpdateSettings(descriptor => descriptor.BlocksWrite()); + updateSettingsResponse.IsValid.Should().BeTrue(); + + var snapshotResponse = this.Client.Snapshot(_repositoryName, _snapshotName, selector: f => f + .Index(_indexName) + .WaitForCompletion(true) + .IgnoreUnavailable() + .Partial()); + snapshotResponse.IsValid.Should().BeTrue(); + + var d = ElasticsearchConfiguration.DefaultIndex; + var restoreResponse = this.Client.Restore(_repositoryName, _snapshotName, r => r + .WaitForCompletion(true) + .RenamePattern(d + "_(.+)") + .RenameReplacement(d + "_restored_$1") + .Index(_indexName) + .IgnoreUnavailable(true) + .IndexSettings(descriptor => descriptor + .RefreshInterval("123s")) + .IgnoreIndexSettings(UpdatableSettings.BlocksWrite)); + + restoreResponse.IsValid.Should().BeTrue(); + _restoredIndexName = _indexName.Replace(d + "_", d + "_restored_"); + + var indexExistsResponse = this.Client.IndexExists(f => f.Index(_restoredIndexName)); + indexExistsResponse.Exists.Should().BeTrue(); + + var indexSettingsResponse = this.Client.GetIndexSettings(descriptor => descriptor.Index(_restoredIndexName)); + indexSettingsResponse.IsValid.Should().BeTrue(); + indexSettingsResponse.IndexSettings.Settings[UpdatableSettings.RefreshInterval].Should().Be("123s"); + indexSettingsResponse.IndexSettings.Settings[UpdatableSettings.BlocksWrite].Should().BeNull(); + } + [Test] [SkipVersion("0 - 1.0.9", "Requires the snapshot status api which was added in ES 1.1")] public void SnapshotRestoreObservable() diff --git a/src/Tests/Nest.Tests.Unit/Core/Repository/Restore.json b/src/Tests/Nest.Tests.Unit/Core/Repository/Restore.json new file mode 100644 index 00000000000..4b3d966d735 --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Core/Repository/Restore.json @@ -0,0 +1,13 @@ +{ + "indices": [ + "index" + ], + "index_settings": { + "index.number_of_replicas": 0, + "index.blocks.read": true + }, + "ignore_index_settings": [ + "index.refresh_interval", + "index.auto_expand_replicas" + ] +} \ No newline at end of file diff --git a/src/Tests/Nest.Tests.Unit/Core/Repository/RestoreTests.cs b/src/Tests/Nest.Tests.Unit/Core/Repository/RestoreTests.cs new file mode 100644 index 00000000000..73abab60235 --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Core/Repository/RestoreTests.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Elasticsearch.Net; +using FluentAssertions; +using NUnit.Framework; + +namespace Nest.Tests.Unit.Core.Repository +{ + public class RestoreTests : BaseJsonTests + { + [Test] + public void Restore() + { + var restoreResponse = _client.Restore("repository", "snapshotName", + descriptor => descriptor + .Index("index") + .IndexSettings(settingsDescriptor => settingsDescriptor + .NumberOfReplicas(0) + .BlocksRead()) + .IgnoreIndexSettings(UpdatableSettings.RefreshInterval, UpdatableSettings.AutoExpandReplicas)); + + restoreResponse.ConnectionStatus.RequestUrl.Should().Be("http://localhost:9200/_snapshot/repository/snapshotName/_restore"); + this.JsonEquals(restoreResponse.ConnectionStatus.Request, MethodInfo.GetCurrentMethod()); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void Null_IgnoreIndexSettings_ThorwException() + { + List ignoreIndexSettings = null; + _client.Restore("repository", "snapshotName", + descriptor => descriptor + .Index("index") + .IgnoreIndexSettings(ignoreIndexSettings)); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void Null_IndexSettings_ThorwException() + { + Func settingsSelector = null; + + var restoreResponse = _client.Restore("repository", "snapshotName", + descriptor => descriptor + .Index("index") + .IndexSettings(settingsSelector)); + } + } +} diff --git a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj index 0098b796011..b9df1046f7f 100644 --- a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj +++ b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj @@ -201,6 +201,7 @@ + @@ -683,6 +684,9 @@ Always + + Always + Always