diff --git a/src/Elasticsearch.Net/Serialization/IElasticsearchSerializer.cs b/src/Elasticsearch.Net/Serialization/IElasticsearchSerializer.cs index 0321ca8377d..bdc76fe5c77 100644 --- a/src/Elasticsearch.Net/Serialization/IElasticsearchSerializer.cs +++ b/src/Elasticsearch.Net/Serialization/IElasticsearchSerializer.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Elasticsearch.Net.Extensions; namespace Elasticsearch.Net.Serialization { @@ -25,6 +26,10 @@ public static byte[] SerializeToBytes(this IElasticsearchSerializer serializer, return ms.ToArray(); } } + public static string SerializeToString(this IElasticsearchSerializer serializer, object data, SerializationFormatting formatting = SerializationFormatting.Indented) + { + return serializer.SerializeToBytes(data, formatting).Utf8String(); + } } diff --git a/src/Nest/Aggregations/Aggregation.cs b/src/Nest/Aggregations/Aggregation.cs index 7ab65ca1cd1..dbe9a16d507 100644 --- a/src/Nest/Aggregations/Aggregation.cs +++ b/src/Nest/Aggregations/Aggregation.cs @@ -6,6 +6,7 @@ namespace Nest /// /// Describes an aggregation at request time when its being build /// + [ExactContractJsonConverter(typeof(AggregationJsonConverter))] public interface IAggregation { } diff --git a/src/Nest/Aggregations/AggregationContainer.cs b/src/Nest/Aggregations/AggregationContainer.cs index 68bdb86bc12..96619eaa225 100644 --- a/src/Nest/Aggregations/AggregationContainer.cs +++ b/src/Nest/Aggregations/AggregationContainer.cs @@ -261,7 +261,7 @@ public static implicit operator AggregationContainer(AggregationBase aggregator) } } - public class AggregationContainerDescriptor : IAggregationContainer + public class AggregationContainerDescriptor : DescriptorBase, IAggregationContainer>, IAggregationContainer where T : class { AggregationDictionary IAggregationContainer.Aggregations { get; set; } diff --git a/src/Nest/Aggregations/AggregationJsonConverter.cs b/src/Nest/Aggregations/AggregationJsonConverter.cs index 6ddda2439d2..e67502128f6 100644 --- a/src/Nest/Aggregations/AggregationJsonConverter.cs +++ b/src/Nest/Aggregations/AggregationJsonConverter.cs @@ -8,6 +8,12 @@ namespace Nest { + internal class AggregationJsonConverter : ReadAsTypeJsonConverter + where TReadAs : class + { + + } + internal class AggregationJsonConverter : JsonConverter { private static Regex _numeric = new Regex(@"^[\d.]+(\.[\d.]+)?$"); diff --git a/src/Nest/Aggregations/Bucket/BucketAggregationBase.cs b/src/Nest/Aggregations/Bucket/BucketAggregationBase.cs index 5199663295d..c72f59705c0 100644 --- a/src/Nest/Aggregations/Bucket/BucketAggregationBase.cs +++ b/src/Nest/Aggregations/Bucket/BucketAggregationBase.cs @@ -19,7 +19,7 @@ protected BucketAggregationBase(string name) : base(name) { } } public abstract class BucketAggregationDescriptorBase - : IBucketAggregation + : IBucketAggregation, IDescriptor where TBucketAggregation : BucketAggregationDescriptorBase , TBucketAggregationInterface, IBucketAggregation where T : class diff --git a/src/Nest/Aggregations/Bucket/Children/ChildrenAggregation.cs b/src/Nest/Aggregations/Bucket/Children/ChildrenAggregation.cs index 82309996d58..a151d11e675 100644 --- a/src/Nest/Aggregations/Bucket/Children/ChildrenAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Children/ChildrenAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IChildrenAggregation : IBucketAggregation { [JsonProperty("type")] diff --git a/src/Nest/Aggregations/Bucket/DateHistogram/DateHistogramAggregation.cs b/src/Nest/Aggregations/Bucket/DateHistogram/DateHistogramAggregation.cs index b843e89de61..4c7500943d6 100644 --- a/src/Nest/Aggregations/Bucket/DateHistogram/DateHistogramAggregation.cs +++ b/src/Nest/Aggregations/Bucket/DateHistogram/DateHistogramAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IDateHistogramAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/DateRange/DateRangeAggregation.cs b/src/Nest/Aggregations/Bucket/DateRange/DateRangeAggregation.cs index b419be7ff97..ec536eddc38 100644 --- a/src/Nest/Aggregations/Bucket/DateRange/DateRangeAggregation.cs +++ b/src/Nest/Aggregations/Bucket/DateRange/DateRangeAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IDateRangeAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/DateRange/DateRangeExpression.cs b/src/Nest/Aggregations/Bucket/DateRange/DateRangeExpression.cs index 2e8241df60e..892f5b9e035 100644 --- a/src/Nest/Aggregations/Bucket/DateRange/DateRangeExpression.cs +++ b/src/Nest/Aggregations/Bucket/DateRange/DateRangeExpression.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IDateRangeExpression : INestSerializable + public interface IDateRangeExpression { [JsonProperty(PropertyName = "from")] DateMath From { get; set; } diff --git a/src/Nest/Aggregations/Bucket/Filter/FilterAggregation.cs b/src/Nest/Aggregations/Bucket/Filter/FilterAggregation.cs index e33b1a64908..ab94210a49e 100644 --- a/src/Nest/Aggregations/Bucket/Filter/FilterAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Filter/FilterAggregation.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(FilterAggregationJsonConverter))] + [ContractJsonConverter(typeof(FilterAggregationJsonConverter))] public interface IFilterAggregation : IBucketAggregation { QueryContainer Filter { get; set; } diff --git a/src/Nest/Aggregations/Bucket/Filters/FiltersAggregation.cs b/src/Nest/Aggregations/Bucket/Filters/FiltersAggregation.cs index 9f567c720ae..5c03ba1d5b2 100644 --- a/src/Nest/Aggregations/Bucket/Filters/FiltersAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Filters/FiltersAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IFiltersAggregation : IBucketAggregation { [JsonProperty("filters")] @@ -31,8 +31,8 @@ public class FiltersAggregationDescriptor { Union> IFiltersAggregation.Filters { get; set; } - public FiltersAggregationDescriptor NamedFilters(Func, NamedFiltersContainerBase> selector) => - Assign(a => a.Filters = selector?.Invoke(new NamedFiltersContainerDescriptor())); + public FiltersAggregationDescriptor NamedFilters(Func, IPromise> selector) => + Assign(a => a.Filters = new Union>(selector?.Invoke(new NamedFiltersContainerDescriptor())?.Value)); public FiltersAggregationDescriptor AnonymousFilters(params Func, IQueryContainer>[] selectors) => Assign(a => a.Filters = selectors.Select(s=>s?.Invoke(new QueryContainerDescriptor())).ToListOrNullIfEmpty()); diff --git a/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainer.cs b/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainer.cs new file mode 100644 index 00000000000..b7453e5d831 --- /dev/null +++ b/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainer.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace Nest +{ + [JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))] + public interface INamedFiltersContainer : IIsADictionary + { + } + + public class NamedFiltersContainer: IsADictionary, INamedFiltersContainer + { + public NamedFiltersContainer() : base() { } + public NamedFiltersContainer(IDictionary container) : base(container) { } + public NamedFiltersContainer(Dictionary container) + : base(container.Select(kv => kv).ToDictionary(kv => kv.Key, kv => (IQueryContainer)kv.Value)) + { } + + public void Add(string name, IQueryContainer filter) => BackingDictionary.Add(name, filter); + public void Add(string name, QueryContainer filter) => BackingDictionary.Add(name, filter); + } + + public class NamedFiltersContainerDescriptor : IsADictionaryDescriptor, INamedFiltersContainer, string, IQueryContainer> + where T : class + { + public NamedFiltersContainerDescriptor() : base(new NamedFiltersContainer()) { } + + public NamedFiltersContainerDescriptor Filter(string name, IQueryContainer filter) => Assign(name, filter); + + public NamedFiltersContainerDescriptor Filter(string name, Func, IQueryContainer> selector) => + Assign(name, selector?.Invoke(new QueryContainerDescriptor())); + + public NamedFiltersContainerDescriptor Filter(string name, Func, IQueryContainer> selector) + where TOther : class => + Assign(name, selector?.Invoke(new QueryContainerDescriptor())); + + } + +} diff --git a/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainerBase.cs b/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainerBase.cs deleted file mode 100644 index 1bd4391a11e..00000000000 --- a/src/Nest/Aggregations/Bucket/Filters/NamedFiltersContainerBase.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -namespace Nest -{ - [JsonConverter(typeof(CompositeJsonConverter, VerbatimDictionaryKeysJsonConverter>))] - public interface INamedFiltersContainer - { - } - - [JsonConverter(typeof(CompositeJsonConverter, VerbatimDictionaryKeysJsonConverter>))] - public abstract class NamedFiltersContainerBase : IsADictionary, INamedFiltersContainer - { - protected NamedFiltersContainerBase () : base() { } - protected NamedFiltersContainerBase(IDictionary container) : base(container) { } - - public static implicit operator NamedFiltersContainerBase(Dictionary container) => - new NamedFiltersContainer(container); - - public static implicit operator NamedFiltersContainerBase(Dictionary container) => - new NamedFiltersContainer(container); - } - - public class NamedFiltersContainer: NamedFiltersContainerBase - { - public NamedFiltersContainer() : base() { } - public NamedFiltersContainer(IDictionary container) : base(container) { } - public NamedFiltersContainer(Dictionary container) - : base(container.Select(kv => kv).ToDictionary(kv => kv.Key, kv => (IQueryContainer)kv.Value)) - { } - - public void Add(string name, IQueryContainer filter) => BackingDictionary.Add(name, filter); - public void Add(string name, QueryContainer filter) => BackingDictionary.Add(name, filter); - } - - public class NamedFiltersContainerDescriptor: NamedFiltersContainerBase - where T : class - { - public NamedFiltersContainerDescriptor() : base() { } - protected NamedFiltersContainerDescriptor(IDictionary container) : base(container) { } - - public NamedFiltersContainerDescriptor Filter(string name, IQueryContainer filter) - { - BackingDictionary.Add(name, filter); - return this; - } - - public NamedFiltersContainerDescriptor Filter(string name, Func, IQueryContainer> selector) - { - var filter = selector?.Invoke(new QueryContainerDescriptor()); - if (filter != null) BackingDictionary.Add(name, filter); - return this; - } - - public NamedFiltersContainerDescriptor Filter(string name, Func, IQueryContainer> selector) - where TOther : class - { - var filter = selector?.Invoke(new QueryContainerDescriptor()); - if (filter != null) BackingDictionary.Add(name, filter); - return this; - } - } - -} diff --git a/src/Nest/Aggregations/Bucket/GeoDistance/GeoDistanceAggregation.cs b/src/Nest/Aggregations/Bucket/GeoDistance/GeoDistanceAggregation.cs index 74007f9f014..dfed35170ec 100644 --- a/src/Nest/Aggregations/Bucket/GeoDistance/GeoDistanceAggregation.cs +++ b/src/Nest/Aggregations/Bucket/GeoDistance/GeoDistanceAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IGeoDistanceAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/GeoHashGrid/GeoHashGridAggregation.cs b/src/Nest/Aggregations/Bucket/GeoHashGrid/GeoHashGridAggregation.cs index 19fa27f57ef..04658495ea3 100644 --- a/src/Nest/Aggregations/Bucket/GeoHashGrid/GeoHashGridAggregation.cs +++ b/src/Nest/Aggregations/Bucket/GeoHashGrid/GeoHashGridAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IGeoHashGridAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/Global/GlobalAggregation.cs b/src/Nest/Aggregations/Bucket/Global/GlobalAggregation.cs index bb27b04be8b..4a2f080e1dc 100644 --- a/src/Nest/Aggregations/Bucket/Global/GlobalAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Global/GlobalAggregation.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IGlobalAggregation : IBucketAggregation { } public class GlobalAggregation : BucketAggregationBase, IGlobalAggregation diff --git a/src/Nest/Aggregations/Bucket/Histogram/HistogramAggregation.cs b/src/Nest/Aggregations/Bucket/Histogram/HistogramAggregation.cs index a80f26d10fb..5ef88c8a4dd 100644 --- a/src/Nest/Aggregations/Bucket/Histogram/HistogramAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Histogram/HistogramAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IHistogramAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/IpRange/IpRange.cs b/src/Nest/Aggregations/Bucket/IpRange/IpRange.cs index 33c2c3ec121..1cd95364f52 100644 --- a/src/Nest/Aggregations/Bucket/IpRange/IpRange.cs +++ b/src/Nest/Aggregations/Bucket/IpRange/IpRange.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IIpRange : INestSerializable + public interface IIpRange { [JsonProperty(PropertyName = "from")] string From { get; set; } diff --git a/src/Nest/Aggregations/Bucket/IpRange/IpRangeAggregation.cs b/src/Nest/Aggregations/Bucket/IpRange/IpRangeAggregation.cs index 61195c59e01..3d63b43e92f 100644 --- a/src/Nest/Aggregations/Bucket/IpRange/IpRangeAggregation.cs +++ b/src/Nest/Aggregations/Bucket/IpRange/IpRangeAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IIpRangeAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/Missing/MissingAggregation.cs b/src/Nest/Aggregations/Bucket/Missing/MissingAggregation.cs index fad1ee95aab..994188483d0 100644 --- a/src/Nest/Aggregations/Bucket/Missing/MissingAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Missing/MissingAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IMissingAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/Nested/NestedAggregation.cs b/src/Nest/Aggregations/Bucket/Nested/NestedAggregation.cs index 14d8f710ff4..be9c4c6a2e6 100644 --- a/src/Nest/Aggregations/Bucket/Nested/NestedAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Nested/NestedAggregation.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface INestedAggregation : IBucketAggregation { [JsonProperty("path")] diff --git a/src/Nest/Aggregations/Bucket/Range/RangeAggregation.cs b/src/Nest/Aggregations/Bucket/Range/RangeAggregation.cs index 97812b5b5b0..a5b8d1609a2 100644 --- a/src/Nest/Aggregations/Bucket/Range/RangeAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Range/RangeAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IRangeAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/ReverseNested/ReverseNestedAggregation.cs b/src/Nest/Aggregations/Bucket/ReverseNested/ReverseNestedAggregation.cs index 5cea9a3789b..97dab48c7af 100644 --- a/src/Nest/Aggregations/Bucket/ReverseNested/ReverseNestedAggregation.cs +++ b/src/Nest/Aggregations/Bucket/ReverseNested/ReverseNestedAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IReverseNestedAggregation : IBucketAggregation { [JsonProperty("path")] diff --git a/src/Nest/Aggregations/Bucket/Sampler/SamplerAggregation.cs b/src/Nest/Aggregations/Bucket/Sampler/SamplerAggregation.cs index 6cad22dc771..89aeebc696d 100644 --- a/src/Nest/Aggregations/Bucket/Sampler/SamplerAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Sampler/SamplerAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ISamplerAggregation : IBucketAggregation { [JsonProperty("shard_size")] diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ChiSquareHeuristic.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ChiSquareHeuristic.cs index fd7da433a68..2ae3033eeab 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ChiSquareHeuristic.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ChiSquareHeuristic.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IChiSquareHeuristic : INestSerializable + public interface IChiSquareHeuristic { [JsonProperty("include_negatives")] bool? IncludeNegatives { get; set; } diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/GoogleNormalizedDistanceHeuristic.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/GoogleNormalizedDistanceHeuristic.cs index cd93bf13dcb..51a1a1c8996 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/GoogleNormalizedDistanceHeuristic.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/GoogleNormalizedDistanceHeuristic.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IGoogleNormalizedDistanceHeuristic : INestSerializable + public interface IGoogleNormalizedDistanceHeuristic { [JsonProperty("background_is_superset")] bool? BackgroundIsSuperSet { get; set; } diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/MutualInformationHeuristic.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/MutualInformationHeuristic.cs index 9221ae4c492..fcd76090a12 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/MutualInformationHeuristic.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/MutualInformationHeuristic.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IMutualInformationHeuristic : INestSerializable + public interface IMutualInformationHeuristic { [JsonProperty("include_negatives")] bool? IncludeNegatives { get; set; } diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/PercentageScoreHeuristic.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/PercentageScoreHeuristic.cs index 71bdac28dd1..16782ff88dc 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/PercentageScoreHeuristic.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/PercentageScoreHeuristic.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IPercentageScoreHeuristic : INestSerializable { } + public interface IPercentageScoreHeuristic { } public class PercentageScoreHeuristic { } diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ScriptedHeuristic.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ScriptedHeuristic.cs index 6a721fc2393..823830fb373 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ScriptedHeuristic.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/Heuristics/ScriptedHeuristic.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IScriptedHeuristic : INestSerializable + public interface IScriptedHeuristic { [JsonProperty("script")] IScript Script { get; set; } diff --git a/src/Nest/Aggregations/Bucket/SignificantTerms/SignificantTermsAggregation.cs b/src/Nest/Aggregations/Bucket/SignificantTerms/SignificantTermsAggregation.cs index f3f23ffc044..77f4e9c14e7 100644 --- a/src/Nest/Aggregations/Bucket/SignificantTerms/SignificantTermsAggregation.cs +++ b/src/Nest/Aggregations/Bucket/SignificantTerms/SignificantTermsAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ISignificantTermsAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Bucket/Terms/TermsAggregation.cs b/src/Nest/Aggregations/Bucket/Terms/TermsAggregation.cs index 301e340cf6c..1956d13d345 100644 --- a/src/Nest/Aggregations/Bucket/Terms/TermsAggregation.cs +++ b/src/Nest/Aggregations/Bucket/Terms/TermsAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ITermsAggregation : IBucketAggregation { [JsonProperty("field")] diff --git a/src/Nest/Aggregations/Metric/Average/AverageAggregation.cs b/src/Nest/Aggregations/Metric/Average/AverageAggregation.cs index c6c2ba5f842..174b1a958c9 100644 --- a/src/Nest/Aggregations/Metric/Average/AverageAggregation.cs +++ b/src/Nest/Aggregations/Metric/Average/AverageAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IAverageAggregation : IMetricAggregation { } public class AverageAggregation : MetricAggregationBase, IAverageAggregation diff --git a/src/Nest/Aggregations/Metric/Cardinality/CardinalityAggregation.cs b/src/Nest/Aggregations/Metric/Cardinality/CardinalityAggregation.cs index 1f813ed130d..4153edd1af9 100644 --- a/src/Nest/Aggregations/Metric/Cardinality/CardinalityAggregation.cs +++ b/src/Nest/Aggregations/Metric/Cardinality/CardinalityAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ICardinalityAggregation : IMetricAggregation { [JsonProperty("precision_threshold")] diff --git a/src/Nest/Aggregations/Metric/ExtendedStats/ExtendedStatsAggregation.cs b/src/Nest/Aggregations/Metric/ExtendedStats/ExtendedStatsAggregation.cs index 255b1bc48d1..73faa5ddb6b 100644 --- a/src/Nest/Aggregations/Metric/ExtendedStats/ExtendedStatsAggregation.cs +++ b/src/Nest/Aggregations/Metric/ExtendedStats/ExtendedStatsAggregation.cs @@ -3,7 +3,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IExtendedStatsAggregation : IMetricAggregation { } public class ExtendedStatsAggregation : MetricAggregationBase, IExtendedStatsAggregation diff --git a/src/Nest/Aggregations/Metric/GeoBounds/GeoBoundsAggregation.cs b/src/Nest/Aggregations/Metric/GeoBounds/GeoBoundsAggregation.cs index c2454307773..af3746680ee 100644 --- a/src/Nest/Aggregations/Metric/GeoBounds/GeoBoundsAggregation.cs +++ b/src/Nest/Aggregations/Metric/GeoBounds/GeoBoundsAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IGeoBoundsAggregation : IMetricAggregation { [JsonProperty("wrap_longitude")] diff --git a/src/Nest/Aggregations/Metric/Max/MaxAggregation.cs b/src/Nest/Aggregations/Metric/Max/MaxAggregation.cs index 07bd4d270db..c2ae6dc71cf 100644 --- a/src/Nest/Aggregations/Metric/Max/MaxAggregation.cs +++ b/src/Nest/Aggregations/Metric/Max/MaxAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IMaxAggregation : IMetricAggregation { } public class MaxAggregation : MetricAggregationBase, IMaxAggregation diff --git a/src/Nest/Aggregations/Metric/MetricAggregationBase.cs b/src/Nest/Aggregations/Metric/MetricAggregationBase.cs index d50bab1e702..08f6e29e5b9 100644 --- a/src/Nest/Aggregations/Metric/MetricAggregationBase.cs +++ b/src/Nest/Aggregations/Metric/MetricAggregationBase.cs @@ -33,17 +33,12 @@ protected MetricAggregationBase(string name, Field field) : base(name) } public abstract class MetricAggregationDescriptorBase - : IMetricAggregation + : DescriptorBase, IMetricAggregation where TMetricAggregation : MetricAggregationDescriptorBase , TMetricAggregationInterface, IMetricAggregation where T : class where TMetricAggregationInterface : class, IMetricAggregation { - protected TMetricAggregation Assign(Action assigner) => - Fluent.Assign(((TMetricAggregation)this), assigner); - - protected TMetricAggregationInterface Self => (TMetricAggregation)this; - Field IMetricAggregation.Field { get; set; } IScript IMetricAggregation.Script { get; set; } diff --git a/src/Nest/Aggregations/Metric/Min/MinAggregation.cs b/src/Nest/Aggregations/Metric/Min/MinAggregation.cs index 0779990fc30..7cd2c160b9a 100644 --- a/src/Nest/Aggregations/Metric/Min/MinAggregation.cs +++ b/src/Nest/Aggregations/Metric/Min/MinAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IMinAggregation : IMetricAggregation { } public class MinAggregation : MetricAggregationBase, IMinAggregation diff --git a/src/Nest/Aggregations/Metric/PercentileRanks/PercentileRanksAggregation.cs b/src/Nest/Aggregations/Metric/PercentileRanks/PercentileRanksAggregation.cs index cb09961f2a1..b504495035b 100644 --- a/src/Nest/Aggregations/Metric/PercentileRanks/PercentileRanksAggregation.cs +++ b/src/Nest/Aggregations/Metric/PercentileRanks/PercentileRanksAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { - [JsonConverter(typeof(PercentileRanksAggregationJsonConverter))] + [ContractJsonConverter(typeof(PercentileRanksAggregationJsonConverter))] public interface IPercentileRanksAggregation : IMetricAggregation { IEnumerable Values { get; set; } diff --git a/src/Nest/Aggregations/Metric/Percentiles/Methods/IPercentilesMethod.cs b/src/Nest/Aggregations/Metric/Percentiles/Methods/IPercentilesMethod.cs index af4534aeadb..199087fd0dc 100644 --- a/src/Nest/Aggregations/Metric/Percentiles/Methods/IPercentilesMethod.cs +++ b/src/Nest/Aggregations/Metric/Percentiles/Methods/IPercentilesMethod.cs @@ -9,11 +9,9 @@ namespace Nest { - public interface IPercentilesMethod - { - } + public interface IPercentilesMethod { } - public class PercentilesMethodDescriptor + public class PercentilesMethodDescriptor : DescriptorBase, IPercentilesMethod { public IPercentilesMethod HDRHistogram(Func hdrSelector = null) => hdrSelector?.InvokeOrDefault(new HDRHistogramMethodDescriptor()); diff --git a/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregation.cs b/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregation.cs index b8c1745b79f..38bc816292a 100644 --- a/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregation.cs +++ b/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { - [JsonConverter(typeof(PercentilesAggregationJsonConverter))] + [ContractJsonConverter(typeof(PercentilesAggregationJsonConverter))] public interface IPercentilesAggregation : IMetricAggregation { IEnumerable Percents { get; set; } diff --git a/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregationJsonConverter.cs b/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregationJsonConverter.cs index 26344609c50..0fe99082f1e 100644 --- a/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregationJsonConverter.cs +++ b/src/Nest/Aggregations/Metric/Percentiles/PercentilesAggregationJsonConverter.cs @@ -103,12 +103,12 @@ protected void WriteMethodProperty(IPercentilesMethod method, JsonWriter writer, protected void WriteMetricProperties(IMetricAggregation metric, JsonWriter writer, JsonSerializer serializer) { - var contract = serializer.ContractResolver as SettingsContractResolver; if (metric.Field != null) { + var settings = serializer.GetConnectionSettings(); writer.WritePropertyName("field"); - writer.WriteValue(contract.Infer.Field(metric.Field)); + writer.WriteValue(settings.Inferrer.Field(metric.Field)); } if (metric.Script != null) diff --git a/src/Nest/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregation.cs b/src/Nest/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregation.cs index aac26810152..dcfbfe56ba1 100644 --- a/src/Nest/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregation.cs +++ b/src/Nest/Aggregations/Metric/ScriptedMetric/ScriptedMetricAggregation.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IScriptedMetricAggregation : IMetricAggregation { [JsonProperty("init_script")] diff --git a/src/Nest/Aggregations/Metric/Stats/StatsAggregation.cs b/src/Nest/Aggregations/Metric/Stats/StatsAggregation.cs index b118edcff2b..a4102427b14 100644 --- a/src/Nest/Aggregations/Metric/Stats/StatsAggregation.cs +++ b/src/Nest/Aggregations/Metric/Stats/StatsAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IStatsAggregator : IMetricAggregation { } public class StatsAggregation : MetricAggregationBase, IStatsAggregator diff --git a/src/Nest/Aggregations/Metric/Sum/SumAggregation.cs b/src/Nest/Aggregations/Metric/Sum/SumAggregation.cs index c8894e56fd0..b604893e93d 100644 --- a/src/Nest/Aggregations/Metric/Sum/SumAggregation.cs +++ b/src/Nest/Aggregations/Metric/Sum/SumAggregation.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ISumAggregation : IMetricAggregation { } public class SumAggregation : MetricAggregationBase, ISumAggregation diff --git a/src/Nest/Aggregations/Metric/TopHits/TopHitsAggregation.cs b/src/Nest/Aggregations/Metric/TopHits/TopHitsAggregation.cs index e7c0cce174c..33eb84dfa26 100644 --- a/src/Nest/Aggregations/Metric/TopHits/TopHitsAggregation.cs +++ b/src/Nest/Aggregations/Metric/TopHits/TopHitsAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ITopHitsAggregation : IMetricAggregation { [JsonProperty("from")] @@ -18,7 +18,6 @@ public interface ITopHitsAggregation : IMetricAggregation int? Size { get; set; } [JsonProperty("sort")] - [JsonConverter(typeof(SortCollectionJsonConverter))] IList Sort { get; set; } [JsonProperty("_source")] diff --git a/src/Nest/Aggregations/Metric/ValueCount/ValueCountAggregation.cs b/src/Nest/Aggregations/Metric/ValueCount/ValueCountAggregation.cs index 9d258954098..5a2955134f1 100644 --- a/src/Nest/Aggregations/Metric/ValueCount/ValueCountAggregation.cs +++ b/src/Nest/Aggregations/Metric/ValueCount/ValueCountAggregation.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IValueCountAggregation : IMetricAggregation { } public class ValueCountAggregation : MetricAggregationBase, IValueCountAggregation diff --git a/src/Nest/Aggregations/Pipeline/AverageBucket/AverageBucketAggregation.cs b/src/Nest/Aggregations/Pipeline/AverageBucket/AverageBucketAggregation.cs index 12509d38227..2e69c7afdc1 100644 --- a/src/Nest/Aggregations/Pipeline/AverageBucket/AverageBucketAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/AverageBucket/AverageBucketAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IAverageBucketAggregation : IPipelineAggregation { } public class AverageBucketAggregation diff --git a/src/Nest/Aggregations/Pipeline/BucketScript/BucketScriptAggregation.cs b/src/Nest/Aggregations/Pipeline/BucketScript/BucketScriptAggregation.cs index 2b13c8dd3dc..c66d5dd608d 100644 --- a/src/Nest/Aggregations/Pipeline/BucketScript/BucketScriptAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/BucketScript/BucketScriptAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IBucketScriptAggregation : IPipelineAggregation { [JsonProperty("script")] diff --git a/src/Nest/Aggregations/Pipeline/BucketSelector/BucketSelectorAggregation.cs b/src/Nest/Aggregations/Pipeline/BucketSelector/BucketSelectorAggregation.cs index d068e1a6237..6895c3c2bfd 100644 --- a/src/Nest/Aggregations/Pipeline/BucketSelector/BucketSelectorAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/BucketSelector/BucketSelectorAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IBucketSelectorAggregation : IPipelineAggregation { [JsonProperty("script")] diff --git a/src/Nest/Aggregations/Pipeline/CumulativeSum/CumulativeSumAggregation.cs b/src/Nest/Aggregations/Pipeline/CumulativeSum/CumulativeSumAggregation.cs index bbb569167f2..7eddc3f31b9 100644 --- a/src/Nest/Aggregations/Pipeline/CumulativeSum/CumulativeSumAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/CumulativeSum/CumulativeSumAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ICumulativeSumAggregation : IPipelineAggregation { } public class CumulativeSumAggregation diff --git a/src/Nest/Aggregations/Pipeline/Derivative/DerivativeAggregation.cs b/src/Nest/Aggregations/Pipeline/Derivative/DerivativeAggregation.cs index cdfdff58f2a..b97bd7db948 100644 --- a/src/Nest/Aggregations/Pipeline/Derivative/DerivativeAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/Derivative/DerivativeAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IDerivativeAggregation : IPipelineAggregation { } public class DerivativeAggregation : PipelineAggregationBase, IDerivativeAggregation diff --git a/src/Nest/Aggregations/Pipeline/MaxBucket/MaxBucketAggregation.cs b/src/Nest/Aggregations/Pipeline/MaxBucket/MaxBucketAggregation.cs index c4367a02cd0..b2fe842a5cc 100644 --- a/src/Nest/Aggregations/Pipeline/MaxBucket/MaxBucketAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/MaxBucket/MaxBucketAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IMaxBucketAggregation : IPipelineAggregation { } public class MaxBucketAggregation diff --git a/src/Nest/Aggregations/Pipeline/MinBucket/MinBucketAggregation.cs b/src/Nest/Aggregations/Pipeline/MinBucket/MinBucketAggregation.cs index 741e4d68d24..92ac4afd76a 100644 --- a/src/Nest/Aggregations/Pipeline/MinBucket/MinBucketAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/MinBucket/MinBucketAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface IMinBucketAggregation : IPipelineAggregation { } public class MinBucketAggregation diff --git a/src/Nest/Aggregations/Pipeline/MovingAverage/Models/IMovingAverageModel.cs b/src/Nest/Aggregations/Pipeline/MovingAverage/Models/IMovingAverageModel.cs index eb2bbc87ed7..30e24dc4c2b 100644 --- a/src/Nest/Aggregations/Pipeline/MovingAverage/Models/IMovingAverageModel.cs +++ b/src/Nest/Aggregations/Pipeline/MovingAverage/Models/IMovingAverageModel.cs @@ -6,12 +6,12 @@ namespace Nest { - public interface IMovingAverageModel : INestSerializable + public interface IMovingAverageModel { string Name { get; } } - public class MovingAverageModelDescriptor + public class MovingAverageModelDescriptor : DescriptorBase { public IEwmaModel Ewma(Func ewmaSelector = null) => ewmaSelector.InvokeOrDefault(new EwmaModelDescriptor()); diff --git a/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregation.cs b/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregation.cs index 1d7bbc7f7d4..4abde3269d5 100644 --- a/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(MovingAverageAggregationJsonConverter))] + [ContractJsonConverter(typeof(MovingAverageAggregationJsonConverter))] public interface IMovingAverageAggregation : IPipelineAggregation { IMovingAverageModel Model { get; set; } @@ -56,5 +56,6 @@ public class MovingAverageAggregationDescriptor public MovingAverageAggregationDescriptor Model(Func modelSelector) => Assign(a => a.Model = modelSelector?.Invoke(new MovingAverageModelDescriptor())); + } } diff --git a/src/Nest/Aggregations/Pipeline/PipelineAggregationBase.cs b/src/Nest/Aggregations/Pipeline/PipelineAggregationBase.cs index c2c71c0e2b4..d2f8617d760 100644 --- a/src/Nest/Aggregations/Pipeline/PipelineAggregationBase.cs +++ b/src/Nest/Aggregations/Pipeline/PipelineAggregationBase.cs @@ -34,8 +34,8 @@ public PipelineAggregationBase(string name, IBucketsPath bucketsPath) : base(nam public GapPolicy? GapPolicy { get; set; } } - public abstract class PipelineAggregationDescriptorBase - : IPipelineAggregation + public abstract class PipelineAggregationDescriptorBase + : DescriptorBase, IPipelineAggregation where TPipelineAggregation : PipelineAggregationDescriptorBase , TPipelineAggregationInterface, IPipelineAggregation where TPipelineAggregationInterface : class, IPipelineAggregation @@ -45,9 +45,6 @@ public abstract class PipelineAggregationDescriptorBase assigner) => - Fluent.Assign(((TPipelineAggregation)this), assigner); - public TPipelineAggregation Format(string format) => Assign(a => a.Format = format); public TPipelineAggregation GapPolicy(GapPolicy gapPolicy) => Assign(a => a.GapPolicy = gapPolicy); diff --git a/src/Nest/Aggregations/Pipeline/SerialDifferencing/SerialDifferencingAggregation.cs b/src/Nest/Aggregations/Pipeline/SerialDifferencing/SerialDifferencingAggregation.cs index d306591a6dd..75aedd58a83 100644 --- a/src/Nest/Aggregations/Pipeline/SerialDifferencing/SerialDifferencingAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/SerialDifferencing/SerialDifferencingAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ISerialDifferencingAggregation : IPipelineAggregation { [JsonProperty("lag")] diff --git a/src/Nest/Aggregations/Pipeline/SumBucket/SumBucketAggregation.cs b/src/Nest/Aggregations/Pipeline/SumBucket/SumBucketAggregation.cs index a4c9829a030..9f5e6952a71 100644 --- a/src/Nest/Aggregations/Pipeline/SumBucket/SumBucketAggregation.cs +++ b/src/Nest/Aggregations/Pipeline/SumBucket/SumBucketAggregation.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [ContractJsonConverter(typeof(AggregationJsonConverter))] public interface ISumBucketAggregation : IPipelineAggregation { } public class SumBucketAggregation diff --git a/src/Nest/Analysis/Analyzers/AnalyzerBase.cs b/src/Nest/Analysis/Analyzers/AnalyzerBase.cs index bc64ed4bb20..7467eda7fc3 100644 --- a/src/Nest/Analysis/Analyzers/AnalyzerBase.cs +++ b/src/Nest/Analysis/Analyzers/AnalyzerBase.cs @@ -5,6 +5,7 @@ namespace Nest { + [ContractJsonConverter(typeof(AnalyzerJsonConverter))] public interface IAnalyzer { [JsonProperty(PropertyName = "version")] diff --git a/src/Nest/Analysis/CharFilters/CharFilterBase.cs b/src/Nest/Analysis/CharFilters/CharFilterBase.cs index d3630f25909..7722fbe878b 100644 --- a/src/Nest/Analysis/CharFilters/CharFilterBase.cs +++ b/src/Nest/Analysis/CharFilters/CharFilterBase.cs @@ -3,6 +3,7 @@ namespace Nest { + [ContractJsonConverter(typeof(CharFilterJsonConverter))] public interface ICharFilter { [JsonProperty("version")] diff --git a/src/Nest/Analysis/TokenFilters/TokenFilterBase.cs b/src/Nest/Analysis/TokenFilters/TokenFilterBase.cs index 13e7968fc63..3fe5f5ccd52 100644 --- a/src/Nest/Analysis/TokenFilters/TokenFilterBase.cs +++ b/src/Nest/Analysis/TokenFilters/TokenFilterBase.cs @@ -4,6 +4,7 @@ namespace Nest { + [ContractJsonConverter(typeof(TokenFilterJsonConverter))] public interface ITokenFilter { [JsonProperty("version")] diff --git a/src/Nest/Analysis/Tokenizers/TokenizerBase.cs b/src/Nest/Analysis/Tokenizers/TokenizerBase.cs index 203a5afb033..8cb1e6c6448 100644 --- a/src/Nest/Analysis/Tokenizers/TokenizerBase.cs +++ b/src/Nest/Analysis/Tokenizers/TokenizerBase.cs @@ -5,6 +5,7 @@ namespace Nest { + [ContractJsonConverter(typeof(TokenizerJsonConverter))] public interface ITokenizer { [JsonProperty(PropertyName = "version")] diff --git a/src/Nest/Cluster/ClusterReroute/Commands/IClusterRerouteCommand.cs b/src/Nest/Cluster/ClusterReroute/Commands/IClusterRerouteCommand.cs index 8d9374fbcfa..9721142fa66 100644 --- a/src/Nest/Cluster/ClusterReroute/Commands/IClusterRerouteCommand.cs +++ b/src/Nest/Cluster/ClusterReroute/Commands/IClusterRerouteCommand.cs @@ -6,6 +6,7 @@ namespace Nest { + [ContractJsonConverter(typeof(ClusterRerouteCommandJsonConverter))] public interface IClusterRerouteCommand { [JsonIgnore] diff --git a/src/Nest/CommonAbstractions/ConnectionSettings/ClrTypeMapping.cs b/src/Nest/CommonAbstractions/ConnectionSettings/ClrTypeMapping.cs index 1d1b5f2baa9..4db9922a9a9 100644 --- a/src/Nest/CommonAbstractions/ConnectionSettings/ClrTypeMapping.cs +++ b/src/Nest/CommonAbstractions/ConnectionSettings/ClrTypeMapping.cs @@ -54,46 +54,41 @@ public class ClrTypeMapping : IClrTypeMapping where T : class public IList> Properties { get; set; } } - public class ClrTypeMappingDescriptor : IClrTypeMapping where T : class + public class ClrTypeMappingDescriptor : DescriptorBase,IClrTypeMapping> , IClrTypeMapping + where T : class { - ClrTypeMappingDescriptor _assign(Action> assigner) => Fluent.Assign(this, assigner); - Type IClrTypeMapping.Type { get; } = typeof (T); - string IClrTypeMapping.IndexName { get; set; } - string IClrTypeMapping.TypeName { get; set; } - Expression> IClrTypeMapping.IdProperty { get; set; } - IList> IClrTypeMapping.Properties { get; set; } = new List>(); /// /// When specified dictates the default Elasticsearch index name for /// - public ClrTypeMappingDescriptor IndexName(string indexName) => _assign(a => a.IndexName = indexName); + public ClrTypeMappingDescriptor IndexName(string indexName) => Assign(a => a.IndexName = indexName); /// /// When specified dictates the default Elasticsearch type name for /// - public ClrTypeMappingDescriptor TypeName(string typeName) => _assign(a => a.TypeName = typeName); + public ClrTypeMappingDescriptor TypeName(string typeName) => Assign(a => a.TypeName = typeName); /// /// Allows you to set a default Id property on that NEST will evaluate /// - public ClrTypeMappingDescriptor IdProperty(Expression> property) => _assign(a => a.IdProperty = property); + public ClrTypeMappingDescriptor IdProperty(Expression> property) => Assign(a => a.IdProperty = property); /// /// When specified allows you to ignore on clr type /// public ClrTypeMappingDescriptor Ignore(Expression> property) => - _assign(a => a.Properties.Add(new IgnorePropertyMapping(property))); + Assign(a => a.Properties.Add(new IgnorePropertyMapping(property))); /// /// When specified allows you to rename on clr type /// public ClrTypeMappingDescriptor Rename(Expression> property, string newName) => - _assign(a => a.Properties.Add(new RenamePropertyMapping(property, newName))); + Assign(a => a.Properties.Add(new RenamePropertyMapping(property, newName))); } @@ -121,11 +116,7 @@ protected ClrPropertyMappingBase(Expression> property) Self.Property = property; } - IPropertyMapping IClrTypePropertyMapping.ToPropertyMapping() - { - if (Self.Ignore) return PropertyMapping.Ignored; - return new PropertyMapping {Name = Self.NewName}; - } + IPropertyMapping IClrTypePropertyMapping.ToPropertyMapping() => Self.Ignore ? PropertyMapping.Ignored : new PropertyMapping {Name = Self.NewName}; } public class IgnorePropertyMapping : ClrPropertyMappingBase where T : class diff --git a/src/Nest/CommonAbstractions/Extensions/JsonExtensions.cs b/src/Nest/CommonAbstractions/Extensions/JsonExtensions.cs new file mode 100644 index 00000000000..92ff0928ada --- /dev/null +++ b/src/Nest/CommonAbstractions/Extensions/JsonExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Nest.Resolvers; +using Newtonsoft.Json; + +namespace Nest +{ + internal static class JsonExtensions + { + public static IConnectionSettingsValues GetConnectionSettings(this JsonSerializer serializer) + { + var contract = serializer.ContractResolver as ElasticContractResolver; + if (contract?.ConnectionSettings == null) + throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); + return contract.ConnectionSettings; + } + + public static TConverter GetStatefulConverter(this JsonSerializer serializer) + where TConverter : JsonConverter + { + var resolver = serializer.ContractResolver as ElasticContractResolver; + var realConverter = resolver?.PiggyBackState?.ActualJsonConverter as TConverter; + if (realConverter == null) + throw new DslException($"could not find a stateful {typeof(TConverter).Name} converter"); + + return realConverter; + } + } +} diff --git a/src/Nest/CommonAbstractions/Infer/Features/FeaturesJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Features/FeaturesJsonConverter.cs index 96bf6045a02..a744bd8b418 100644 --- a/src/Nest/CommonAbstractions/Infer/Features/FeaturesJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Features/FeaturesJsonConverter.cs @@ -19,10 +19,8 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract?.ConnectionSettings == null) - throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); - var s = ((IUrlParameter)marker).GetString(contract.ConnectionSettings); + var settings = serializer.GetConnectionSettings(); + var s = ((IUrlParameter)marker).GetString(settings); writer.WriteValue(s); } diff --git a/src/Nest/CommonAbstractions/Infer/Field/Field.cs b/src/Nest/CommonAbstractions/Infer/Field/Field.cs index cbd8e6f148d..e153535dac3 100644 --- a/src/Nest/CommonAbstractions/Infer/Field/Field.cs +++ b/src/Nest/CommonAbstractions/Infer/Field/Field.cs @@ -9,6 +9,7 @@ namespace Nest { + [ContractJsonConverter(typeof(FieldJsonConverter))] public class Field : IEquatable, IUrlParameter { public string Name { get; set; } diff --git a/src/Nest/CommonAbstractions/Infer/Field/FieldJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Field/FieldJsonConverter.cs index 0cf8d72b6fc..35554881cbc 100644 --- a/src/Nest/CommonAbstractions/Infer/Field/FieldJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Field/FieldJsonConverter.cs @@ -7,12 +7,6 @@ namespace Nest { internal class FieldJsonConverter : JsonConverter { - private readonly ElasticInferrer _infer; - public FieldJsonConverter(IConnectionSettingsValues connectionSettings) - { - _infer = new ElasticInferrer(connectionSettings); - } - public override bool CanRead => false; public override bool CanWrite => true; @@ -27,7 +21,8 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - writer.WriteValue(this._infer.Field(field)); + var settings = serializer.GetConnectionSettings(); + writer.WriteValue(settings.Inferrer.Field(field)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { diff --git a/src/Nest/CommonAbstractions/Infer/Fields/Fields.cs b/src/Nest/CommonAbstractions/Infer/Fields/Fields.cs index 191761bbda4..8ba3fe563db 100644 --- a/src/Nest/CommonAbstractions/Infer/Fields/Fields.cs +++ b/src/Nest/CommonAbstractions/Infer/Fields/Fields.cs @@ -9,6 +9,7 @@ namespace Nest { + [ContractJsonConverter(typeof(FieldsJsonConverter))] public class Fields : IUrlParameter { internal readonly List ListOfFields; diff --git a/src/Nest/CommonAbstractions/Infer/Fields/FieldsJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Fields/FieldsJsonConverter.cs index ede0a59f688..9e292e7bbbc 100644 --- a/src/Nest/CommonAbstractions/Infer/Fields/FieldsJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Fields/FieldsJsonConverter.cs @@ -7,12 +7,6 @@ namespace Nest { internal class FieldsJsonConverter : JsonConverter { - private readonly ElasticInferrer _infer; - public FieldsJsonConverter(IConnectionSettingsValues connectionSettings) - { - _infer = new ElasticInferrer(connectionSettings); - } - public override bool CanRead => true; public override bool CanWrite => true; @@ -23,9 +17,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s { var fields = value as Fields; writer.WriteStartArray(); + var infer = serializer.GetConnectionSettings().Inferrer; foreach (var f in fields?.ListOfFields ?? Enumerable.Empty()) { - writer.WriteValue(this._infer.Field(f)); + writer.WriteValue(infer.Field(f)); } writer.WriteEndArray(); } diff --git a/src/Nest/CommonAbstractions/Infer/Id/IdJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Id/IdJsonConverter.cs index ca3317501b1..863880cd57d 100644 --- a/src/Nest/CommonAbstractions/Infer/Id/IdJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Id/IdJsonConverter.cs @@ -31,14 +31,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s } if (id.Document != null) { - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract != null && contract.ConnectionSettings != null) - { - var indexName = contract.Infer.Id(id.Document.GetType(), id.Document); - writer.WriteValue(indexName); - } - else throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); - } + var settings = serializer.GetConnectionSettings(); + var indexName = settings.Inferrer.Id(id.Document.GetType(), id.Document); + writer.WriteValue(indexName); + } else writer.WriteValue(id.Value); } } diff --git a/src/Nest/CommonAbstractions/Infer/IndexName/IndexName.cs b/src/Nest/CommonAbstractions/Infer/IndexName/IndexName.cs index ff5abdd330c..be94b46df44 100644 --- a/src/Nest/CommonAbstractions/Infer/IndexName/IndexName.cs +++ b/src/Nest/CommonAbstractions/Infer/IndexName/IndexName.cs @@ -7,7 +7,7 @@ namespace Nest { - [JsonConverter(typeof(IndexNameJsonConverter))] + [ContractJsonConverter(typeof(IndexNameJsonConverter))] public class IndexName : IEquatable, IUrlParameter { public string Name { get; set; } diff --git a/src/Nest/CommonAbstractions/Infer/IndexName/IndexNameJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/IndexName/IndexNameJsonConverter.cs index 28cdf494d58..c956092e545 100644 --- a/src/Nest/CommonAbstractions/Infer/IndexName/IndexNameJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/IndexName/IndexNameJsonConverter.cs @@ -19,13 +19,9 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract != null && contract.ConnectionSettings != null) - { - var indexName = contract.Infer.IndexName(marker); - writer.WriteValue(indexName); - } - else throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); + var settings = serializer.GetConnectionSettings(); + var indexName = settings.Inferrer.IndexName(marker); + writer.WriteValue(indexName); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) diff --git a/src/Nest/CommonAbstractions/Infer/Indices/IndicesJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Indices/IndicesJsonConverter.cs index 1e918d0e992..ca8db61c35b 100644 --- a/src/Nest/CommonAbstractions/Infer/Indices/IndicesJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Indices/IndicesJsonConverter.cs @@ -19,16 +19,14 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract == null || contract.ConnectionSettings == null) - throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); marker.Match( all=> writer.WriteNull(), many => { + var settings = serializer.GetConnectionSettings(); writer.WriteStartArray(); foreach(var m in many.Indices.Cast()) - writer.WriteValue(m.GetString(contract.ConnectionSettings)); + writer.WriteValue(m.GetString(settings)); writer.WriteEndArray(); } ); diff --git a/src/Nest/CommonAbstractions/Infer/Indices/IndicesMultiSyntaxJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Indices/IndicesMultiSyntaxJsonConverter.cs index a40ec2a36f6..aa5f11708ff 100644 --- a/src/Nest/CommonAbstractions/Infer/Indices/IndicesMultiSyntaxJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Indices/IndicesMultiSyntaxJsonConverter.cs @@ -19,12 +19,9 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract == null || contract.ConnectionSettings == null) - throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); marker.Match( all=> writer.WriteValue("_all"), - many => writer.WriteValue(((IUrlParameter)marker).GetString(contract.ConnectionSettings)) + many => writer.WriteValue(((IUrlParameter)marker).GetString(serializer.GetConnectionSettings())) ); } diff --git a/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyName.cs b/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyName.cs index 30a8cb1b3e9..d9bad64823b 100644 --- a/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyName.cs +++ b/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyName.cs @@ -9,6 +9,7 @@ namespace Nest { + [ContractJsonConverter(typeof(PropertyNameJsonConverter))] public class PropertyName : IEquatable, IUrlParameter { public string Name { get; set; } diff --git a/src/Nest/CommonAbstractions/Infer/TypeName/TypeName.cs b/src/Nest/CommonAbstractions/Infer/TypeName/TypeName.cs index c87912163e9..b3a9b9e4d6f 100644 --- a/src/Nest/CommonAbstractions/Infer/TypeName/TypeName.cs +++ b/src/Nest/CommonAbstractions/Infer/TypeName/TypeName.cs @@ -5,7 +5,7 @@ namespace Nest { - [JsonConverter(typeof(TypeNameJsonConverter))] + [ContractJsonConverter(typeof(TypeNameJsonConverter))] public class TypeName : IEquatable , IUrlParameter { public string Name { get; set; } diff --git a/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameJsonConverter.cs index f145ca78752..302a6c44655 100644 --- a/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameJsonConverter.cs @@ -21,13 +21,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract != null && contract.ConnectionSettings != null) - { - var typeName = contract.Infer.TypeName(marker); - writer.WriteValue(typeName); - } - else throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); + var settings = serializer.GetConnectionSettings(); + + var typeName = settings.Inferrer.TypeName(marker); + writer.WriteValue(typeName); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) diff --git a/src/Nest/CommonAbstractions/Infer/Types/TypesJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Types/TypesJsonConverter.cs index 137c6c5dcf8..497c25c71ba 100644 --- a/src/Nest/CommonAbstractions/Infer/Types/TypesJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Types/TypesJsonConverter.cs @@ -19,16 +19,14 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract == null || contract.ConnectionSettings == null) - throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); marker.Match( all=> writer.WriteNull(), many => { + var settings = serializer.GetConnectionSettings(); writer.WriteStartArray(); foreach(var m in many.Types.Cast()) - writer.WriteValue(m.GetString(contract.ConnectionSettings)); + writer.WriteValue(m.GetString(settings)); writer.WriteEndArray(); } ); diff --git a/src/Nest/CommonAbstractions/Infer/Types/TypesMultiSyntaxJsonConverter.cs b/src/Nest/CommonAbstractions/Infer/Types/TypesMultiSyntaxJsonConverter.cs index a7cc303badd..c293d9b7c2a 100644 --- a/src/Nest/CommonAbstractions/Infer/Types/TypesMultiSyntaxJsonConverter.cs +++ b/src/Nest/CommonAbstractions/Infer/Types/TypesMultiSyntaxJsonConverter.cs @@ -19,12 +19,9 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteNull(); return; } - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract == null || contract.ConnectionSettings == null) - throw new Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver"); marker.Match( all=> writer.WriteNull(), - many => writer.WriteValue(((IUrlParameter)marker).GetString(contract.ConnectionSettings)) + many => writer.WriteValue(((IUrlParameter)marker).GetString(serializer.GetConnectionSettings())) ); } diff --git a/src/Nest/CommonAbstractions/RawJson/ICustomJson.cs b/src/Nest/CommonAbstractions/RawJson/ICustomJson.cs index b41a43e2d0b..6be6600987a 100644 --- a/src/Nest/CommonAbstractions/RawJson/ICustomJson.cs +++ b/src/Nest/CommonAbstractions/RawJson/ICustomJson.cs @@ -10,10 +10,4 @@ public interface ICustomJson { object GetCustomJson(); } - - /// - /// Any object that implements this interface will automatically have all - /// JsonProperties of all of its implementing interfaces discovered. - /// - public interface INestSerializable { } } \ No newline at end of file diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/ContractJsonConverterAttribute.cs b/src/Nest/CommonAbstractions/SerializationBehavior/ContractJsonConverterAttribute.cs new file mode 100644 index 00000000000..0a17493de64 --- /dev/null +++ b/src/Nest/CommonAbstractions/SerializationBehavior/ContractJsonConverterAttribute.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace Nest +{ + + public class ContractJsonConverterAttribute : Attribute + { + public JsonConverter Converter { get; } + + public ContractJsonConverterAttribute(Type jsonConverter) + { + if (typeof(JsonConverter).IsAssignableFrom(jsonConverter)) + { + Converter = jsonConverter.CreateInstance(); + } + } + } + public class ExactContractJsonConverterAttribute : Attribute + { + public JsonConverter Converter { get; } + + public ExactContractJsonConverterAttribute(Type jsonConverter) + { + if (typeof(JsonConverter).IsAssignableFrom(jsonConverter)) + { + Converter = jsonConverter.CreateInstance(); + } + } + } +} \ No newline at end of file diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/ElasticContractResolver.cs b/src/Nest/CommonAbstractions/SerializationBehavior/ElasticContractResolver.cs index 62eac823b8a..d3534e69208 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/ElasticContractResolver.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/ElasticContractResolver.cs @@ -9,13 +9,6 @@ namespace Nest.Resolvers { - - internal static class IsPromiseExtension - { - public static bool IsAssignableFrom(this Type objectType) where T : class => - typeof (T).IsAssignableFrom(objectType); - } - public class ElasticContractResolver : DefaultContractResolver { public static JsonSerializer Empty { get; } = new JsonSerializer(); @@ -26,6 +19,11 @@ public class ElasticContractResolver : DefaultContractResolver /// public IConnectionSettingsValues ConnectionSettings { get; private set; } + /// + /// Signals to custom converter that it can get serialization state from one of the converters. Ugly but massive performance gain + /// + internal JsonConverterPiggyBackState PiggyBackState { get; set; } + public ElasticContractResolver(IConnectionSettingsValues connectionSettings) { this.ConnectionSettings = connectionSettings; @@ -38,44 +36,14 @@ protected override JsonContract CreateContract(Type objectType) // this will only be called once and then cached - if (typeof(IDictionary).IsAssignableFrom(objectType) - - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - && !objectType.IsAssignableFrom() - ) + if (typeof(IDictionary).IsAssignableFrom(objectType) && !typeof(IIsADictionary).IsAssignableFrom(objectType)) contract.Converter = new VerbatimDictionaryKeysJsonConverter(); - - else if (objectType == typeof(IAggregation)) contract.Converter = new AggregationJsonConverter(); - else if (objectType == typeof(ISimilarity)) contract.Converter = new SimilarityJsonConverter(); - else if (objectType == typeof(ICharFilter)) contract.Converter = new CharFilterJsonConverter(); - else if (objectType == typeof(IAnalyzer)) contract.Converter = new AnalyzerJsonConverter(); - else if (objectType == typeof(ITokenizer)) contract.Converter = new TokenizerJsonConverter(); - else if (objectType == typeof(ITokenFilter)) contract.Converter = new TokenFilterJsonConverter(); - - - - else if (typeof(IClusterRerouteCommand).IsAssignableFrom(objectType)) - contract.Converter = new ClusterRerouteCommandJsonConverter(); - else if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) contract.Converter = new IsoDateTimeConverter(); + else if (!objectType.FullName.StartsWith("Nest.", StringComparison.OrdinalIgnoreCase)) return contract; - else if (objectType == typeof(TypeName)) contract.Converter = new TypeNameJsonConverter(); - else if (objectType == typeof(IndexName)) contract.Converter = new IndexNameJsonConverter(); - else if (objectType == typeof(Fields)) contract.Converter = new FieldsJsonConverter(this.ConnectionSettings); - else if (objectType == typeof(Field)) contract.Converter = new FieldJsonConverter(this.ConnectionSettings); - else if (objectType == typeof(PropertyName)) contract.Converter = new PropertyNameJsonConverter(this.ConnectionSettings); - - //TODO these should not be necessary here - else if (objectType == typeof(MultiSearchResponse)) contract.Converter = new MultiSearchJsonConverter(); - else if (objectType == typeof(MultiGetResponse)) contract.Converter = new MultiGetHitJsonConverter(); - else if (typeof(IHit).IsAssignableFrom(objectType)) contract.Converter = new DefaultHitJsonConverter(); + else if (ApplyExactContractJsonAttribute(objectType, contract)) return contract; + else if (ApplyContractJsonAttribute(objectType, contract)) return contract; if (this.ConnectionSettings.ContractConverters.HasAny()) { @@ -88,68 +56,40 @@ protected override JsonContract CreateContract(Type objectType) break; } } - return contract; } + private bool ApplyExactContractJsonAttribute(Type objectType, JsonContract contract) + { + var attribute = objectType.GetCustomAttributes(typeof(ExactContractJsonConverterAttribute)).FirstOrDefault() as ExactContractJsonConverterAttribute; + if (attribute?.Converter == null) return false; + contract.Converter = attribute.Converter; + return true; + } + private bool ApplyContractJsonAttribute(Type objectType, JsonContract contract) + { + foreach (var t in this.TypeWithInterfaces(objectType)) + { + var attribute = t.GetCustomAttributes(typeof(ContractJsonConverterAttribute), true).FirstOrDefault() as ContractJsonConverterAttribute; + if (attribute?.Converter == null) continue; + contract.Converter = attribute.Converter; + return true; + } + return false; + } + + private IEnumerable TypeWithInterfaces(Type objectType) + { + yield return objectType; + foreach (var i in objectType.GetInterfaces()) yield return i; + } + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { - var defaultProperties = base.CreateProperties(type, memberSerialization); - var lookup = defaultProperties.ToLookup(p => p.PropertyName); - - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - - defaultProperties = PropertiesOf(type, memberSerialization, defaultProperties, lookup); - - return defaultProperties.GroupBy(p => p.PropertyName).Select(p => p.First()).ToList(); + //descriptors implement properties explicitly these are not picked up by default + return !typeof(IDescriptor).IsAssignableFrom(type) + ? base.CreateProperties(type, memberSerialization) : + PropertiesOfAll(type, memberSerialization); } public IList PropertiesOfAllInterfaces(Type t, MemberSerialization memberSerialization) @@ -159,7 +99,7 @@ from i in t.GetInterfaces() select base.CreateProperties(i, memberSerialization) ) .SelectMany(interfaceProps => interfaceProps) - .DistinctBy(p=>p.PropertyName) + .DistinctBy(p => p.PropertyName) .ToList(); } @@ -168,29 +108,10 @@ public IList PropertiesOfAll(Type t, MemberSerialization memberSer { return base.CreateProperties(t, memberSerialization) .Concat(PropertiesOfAllInterfaces(t, memberSerialization)) - .DistinctBy(p=>p.PropertyName) + .DistinctBy(p => p.PropertyName) .ToList(); } - private IList PropertiesOf(Type type, MemberSerialization memberSerialization, IList defaultProperties, ILookup lookup, bool append = false) - { - if (!typeof (T).IsAssignableFrom(type)) return defaultProperties; - var jsonProperties = ( - from i in type.GetInterfaces() - select base.CreateProperties(i, memberSerialization) - ) - .SelectMany(interfaceProps => interfaceProps) - .Where(p => !lookup.Contains(p.PropertyName)); - if (!append) - { - foreach (var p in jsonProperties) - { - defaultProperties.Add(p); - } - return defaultProperties; - } - return jsonProperties.Concat(defaultProperties).ToList(); - } protected override string ResolvePropertyName(string fieldName) { @@ -205,9 +126,9 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ var property = base.CreateProperty(member, memberSerialization); // Skip serialization of empty collections that has DefaultValueHandling set to Ignore. - if (property.DefaultValueHandling.HasValue - && property.DefaultValueHandling.Value == DefaultValueHandling.Ignore - && !typeof(string).IsAssignableFrom(property.PropertyType) + if (property.DefaultValueHandling.HasValue + && property.DefaultValueHandling.Value == DefaultValueHandling.Ignore + && !typeof(string).IsAssignableFrom(property.PropertyType) && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) { Predicate shouldSerialize = obj => diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/ReserializeJsonConverter.cs b/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/ReserializeJsonConverter.cs index 0756d6f2430..30627601783 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/ReserializeJsonConverter.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/ReserializeJsonConverter.cs @@ -55,11 +55,12 @@ protected virtual void SerializeJson(JsonWriter writer, object value, TInterface this.Reserialize(writer, value, serializer); } - protected void Reserialize(JsonWriter writer, object value, JsonSerializer serializer) + protected void Reserialize(JsonWriter writer, object value, JsonSerializer serializer, Action inlineWriter = null) { var properties = value.GetType().GetCachedObjectProperties(); if (properties.Count == 0) return; writer.WriteStartObject(); + inlineWriter?.Invoke(writer); foreach (var p in properties) { if (p.Ignored) continue; diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/VerbatimDictionaryKeysConverter.cs b/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/VerbatimDictionaryKeysConverter.cs index ad7ee3899b9..4b0e49c7710 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/VerbatimDictionaryKeysConverter.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/VerbatimDictionaryKeysConverter.cs @@ -24,11 +24,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - var contract = serializer.ContractResolver as SettingsContractResolver; var dictionary = value as IDictionary; if (dictionary == null) return; + var settings = serializer.GetConnectionSettings(); + writer.WriteStartObject(); foreach (DictionaryEntry entry in dictionary) { @@ -39,16 +40,16 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s var propertyName = entry.Key as PropertyName; var indexName = entry.Key as IndexName; var typeName = entry.Key as TypeName; - if (contract == null) + if (settings == null) key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture); else if (fieldName != null) - key = contract.Infer.Field(fieldName); + key = settings.Inferrer.Field(fieldName); else if (propertyName != null) - key = contract.Infer.PropertyName(propertyName); + key = settings.Inferrer.PropertyName(propertyName); else if (indexName != null) - key = contract.Infer.IndexName(indexName); + key = settings.Inferrer.IndexName(indexName); else if (typeName != null) - key = contract.Infer.TypeName(typeName); + key = settings.Inferrer.TypeName(typeName); else key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture); writer.WritePropertyName(key); diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/NestSerializer.cs b/src/Nest/CommonAbstractions/SerializationBehavior/NestSerializer.cs index 2427657b788..76ae379e5e2 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/NestSerializer.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/NestSerializer.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -79,7 +80,10 @@ internal JsonSerializerSettings CreateSettings(SerializationFormatting formattin }; _settings.ModifyJsonSerializerSettings?.Invoke(settings); - settings.ContractResolver = new SettingsContractResolver(settings.ContractResolver, this._settings) { PiggyBackState = piggyBackState }; + + var contract = settings.ContractResolver as ElasticContractResolver; + if (contract == null) throw new Exception($"NEST needs an instance of {nameof(ElasticContractResolver)} registered on Json.NET's JsonSerializerSettings"); + contract.PiggyBackState = piggyBackState; return settings; } diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/SettingsContractResolver.cs b/src/Nest/CommonAbstractions/SerializationBehavior/SettingsContractResolver.cs deleted file mode 100644 index 55e6a3d378a..00000000000 --- a/src/Nest/CommonAbstractions/SerializationBehavior/SettingsContractResolver.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Newtonsoft.Json.Serialization; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Nest.Resolvers -{ - class SettingsContractResolver : IContractResolver - { - /// - /// ConnectionSettings can be requested by JsonConverter's. - /// - public IConnectionSettingsValues ConnectionSettings { get; private set; } - - public ElasticInferrer Infer { get; private set; } - - private IContractResolver _wrapped; - - /// - /// Signals to custom converter that it can get serialization state from one of the converters - /// Ugly but massive performance gain - /// - internal JsonConverterPiggyBackState PiggyBackState { get; set; } - - public SettingsContractResolver(IContractResolver wrapped, IConnectionSettingsValues connectionSettings) - { - this.ConnectionSettings = connectionSettings; - this.Infer = new ElasticInferrer(this.ConnectionSettings); - this._wrapped = wrapped ?? new DefaultContractResolver(); - } - - public JsonContract ResolveContract(Type type) - { - return this._wrapped.ResolveContract(type); - } - } -} diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/StatefulDeserialization/ConcreteTypeConverter.cs b/src/Nest/CommonAbstractions/SerializationBehavior/StatefulDeserialization/ConcreteTypeConverter.cs index be209421952..c2a628c7d28 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/StatefulDeserialization/ConcreteTypeConverter.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/StatefulDeserialization/ConcreteTypeConverter.cs @@ -62,8 +62,8 @@ internal class ConcreteTypeConverter : JsonConverter where T : class internal readonly Type _baseType; internal readonly Func, Type> _concreteTypeSelector; - public override bool CanWrite { get { return false; } } - public override bool CanRead { get { return true; } } + public override bool CanWrite => false; + public override bool CanRead => true; public ConcreteTypeConverter() {} @@ -78,18 +78,13 @@ public ConcreteTypeConverter(Func, Type> concreteTypeSelec public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - var elasticContractResolver = serializer.ContractResolver as SettingsContractResolver; - if (elasticContractResolver != null && elasticContractResolver.PiggyBackState != null - && elasticContractResolver.PiggyBackState.ActualJsonConverter != null) - { - var realConcreteConverter = elasticContractResolver.PiggyBackState.ActualJsonConverter as ConcreteTypeConverter; - if (realConcreteConverter != null) - return ConcreteTypeConverter.GetUsingConcreteTypeConverter(reader, serializer, realConcreteConverter); - } + var realConverter = serializer.GetStatefulConverter>(); + if (realConverter != null) + return ConcreteTypeConverter.GetUsingConcreteTypeConverter(reader, serializer, realConverter); var instance = (Hit)(typeof(Hit).CreateInstance()); serializer.Populate(reader, instance); - instance.Fields = new FieldSelection(elasticContractResolver.ConnectionSettings, instance._fields); + instance.Fields = new FieldSelection(serializer.GetConnectionSettings(), instance._fields); return instance; } @@ -161,15 +156,15 @@ internal static Type GetConcreteTypeUsingSelector( JObject jObject, out object selection) where T: class { - var elasticContractResolver = serializer.ContractResolver as SettingsContractResolver; + var settings = serializer.GetConnectionSettings(); var baseType = realConcreteConverter._baseType; var selector = realConcreteConverter._concreteTypeSelector; //Hit hitDynamic = new Hit(); dynamic d = jObject; var fields = jObject["fields"]; - var fieldSelectionData = fields != null ? fields.ToObject>() : null; - var sel = new FieldSelection(elasticContractResolver.ConnectionSettings, fieldSelectionData); + var fieldSelectionData = fields?.ToObject>(); + var sel = new FieldSelection(settings, fieldSelectionData); var hitDynamic = new Hit(); //favor manual mapping over doing Populate twice. hitDynamic._fields = fieldSelectionData; @@ -192,7 +187,7 @@ internal static Type GetConcreteTypeUsingSelector( fieldSelectionType = typeof(FieldSelection<>).MakeGenericType(concreteType); ConcreteTypeConverter.TypeToFieldTypes.TryAdd(concreteType, fieldSelectionType); } - selection = fieldSelectionType.CreateInstance(elasticContractResolver.ConnectionSettings, fieldSelectionData); + selection = fieldSelectionType.CreateInstance(settings, fieldSelectionData); return concreteType; } } diff --git a/src/Nest/CommonOptions/Range/Range.cs b/src/Nest/CommonOptions/Range/Range.cs index d2cb991dc81..86f5e93eeb2 100644 --- a/src/Nest/CommonOptions/Range/Range.cs +++ b/src/Nest/CommonOptions/Range/Range.cs @@ -7,7 +7,7 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] [JsonConverter(typeof(ReadAsTypeJsonConverter))] - public interface IRange : INestSerializable + public interface IRange { [JsonProperty(PropertyName = "from")] double? From { get; set; } diff --git a/src/Nest/CommonOptions/Scripting/Script.cs b/src/Nest/CommonOptions/Scripting/Script.cs index f0089568fa6..2ac1f56e4eb 100644 --- a/src/Nest/CommonOptions/Scripting/Script.cs +++ b/src/Nest/CommonOptions/Scripting/Script.cs @@ -29,16 +29,13 @@ public abstract class Script : IScript public static implicit operator Script(string inline) => new InlineScript(inline); } - public class ScriptDescriptorBase : IScript + public class ScriptDescriptorBase : DescriptorBase, IScript where TDescriptor : ScriptDescriptorBase, TInterface, IScript where TInterface : class, IScript { Dictionary IScript.Params { get; set; } string IScript.Lang { get; set; } - protected TDescriptor Assign(Action assigner) => - Fluent.Assign(((TDescriptor)this), assigner); - public TDescriptor Params(Dictionary scriptParams) => Assign(a => a.Params = scriptParams); public TDescriptor Params(Func, FluentDictionary> paramsSelector) => @@ -47,7 +44,7 @@ public TDescriptor Params(Func, FluentDictionar public TDescriptor Lang(string lang) => Assign(a => a.Lang = lang); } - public class ScriptDescriptor + public class ScriptDescriptor : DescriptorBase { public IFileScript File(string file, Func fileScript = null) => fileScript.InvokeOrDefault(new FileScriptDescriptor().File(file)); diff --git a/src/Nest/CommonOptions/Sorting/SortCollectionJsonConverter.cs b/src/Nest/CommonOptions/Sorting/SortCollectionJsonConverter.cs deleted file mode 100644 index 2cb13b24574..00000000000 --- a/src/Nest/CommonOptions/Sorting/SortCollectionJsonConverter.cs +++ /dev/null @@ -1,114 +0,0 @@ -using Nest.Resolvers; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Nest -{ - internal class SortCollectionJsonConverter : JsonConverter - { - public override bool CanConvert(Type objectType) => typeof(IList).IsAssignableFrom(objectType); - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var sorts = new List(); - while (reader.TokenType != JsonToken.EndArray) - { - reader.Read(); - if (reader.TokenType == JsonToken.EndArray) - break; - reader.Read(); - var field = reader.Value as string; - reader.Read(); - - if (field == "_geo_distance") - { - var j = JObject.Load(reader); - if (j != null) - { - var sort = j.ToObject(serializer); - if (sort != null) - { - LoadGeoDistanceSortLocation(sort, j); - sorts.Add(sort); - } - } - } - else if (field == "_script") - { - var j = JObject.Load(reader); - if (j != null) - { - var sort = j.ToObject(serializer); - if (sort != null) - { - sorts.Add(sort); - } - } - } - else - { - var j = JObject.Load(reader); - if (j != null) - { - var sort = j.ToObject(serializer); - if (sort != null) - { - sort.Field = field; - sorts.Add(sort); - } - } - } - reader.Read(); - } - return sorts; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var sorts = value as IList; - if (sorts == null) return; - - var contract = serializer.ContractResolver as SettingsContractResolver; - if (contract == null) - throw new Exception("Can not serialize sort because the current json contract does not extend SettingsContractResolver"); - - writer.WriteStartArray(); - foreach (var sort in sorts) - { - - writer.WriteStartObject(); - var fieldName = contract.Infer.Field(sort.SortKey); - writer.WritePropertyName(fieldName); - serializer.Serialize(writer, sort); - writer.WriteEndObject(); - } - writer.WriteEndArray(); - } - - private void LoadGeoDistanceSortLocation(GeoDistanceSort sort, JObject j) - { - var field = j.Properties().FirstOrDefault(p => !GeoDistanceSort.Params.Contains(p.Name)); - - if (field != null) - { - sort.Field = field.Name; - - try - { - sort.PinLocation = field.Value.Value(); - } - catch { } - - try - { - sort.Points = field.Value.Value>(); - } - catch { } - } - } - } -} diff --git a/src/Nest/CommonOptions/Sorting/SortJsonConverter.cs b/src/Nest/CommonOptions/Sorting/SortJsonConverter.cs new file mode 100644 index 00000000000..3ae5d98fc48 --- /dev/null +++ b/src/Nest/CommonOptions/Sorting/SortJsonConverter.cs @@ -0,0 +1,85 @@ +using Nest.Resolvers; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Nest +{ + internal class SortJsonConverter : ReserializeJsonConverter + { + public override bool CanRead => true; + public override bool CanWrite => true; + public override bool CanConvert(Type objectType) => typeof(ISort).IsAssignableFrom(objectType); + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + ISort sort = null; + reader.Read(); + var field = reader.Value as string; + + if (field == "_geo_distance") + { + reader.Read(); + var jObject = JObject.Load(reader); + var geoLocationProp = jObject.Properties().First(p => p.Value.Type == JTokenType.Array); + using (var r = jObject.CreateReader()) + { + var s = FromJson.ReadAs(r, objectType, existingValue, serializer); + s.Field = geoLocationProp.Name; + using (var rr = geoLocationProp.Value.CreateReader()) + s.Points =FromJson.ReadAs>(rr, objectType, existingValue, serializer); + sort = s; + } + } + else if (field == "_script") + { + reader.Read(); + var s = FromJson.ReadAs(reader, objectType, existingValue, serializer); + sort = s; + } + else + { + reader.Read(); + var s = FromJson.ReadAs(reader, objectType, existingValue, serializer); + s.Field = field; + sort = s; + } + reader.Read(); + return sort; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var s = value as ISort; + if (s?.SortKey == null) return; + + writer.WriteStartObject(); + var settings = serializer.GetConnectionSettings(); + + switch (s.SortKey.Name ?? string.Empty) + { + case "_script": + writer.WritePropertyName("_script"); + base.Reserialize(writer, s, serializer); + break; + case "_geo_distance": + var geo = s as IGeoDistanceSort; + writer.WritePropertyName("_geo_distance"); + base.Reserialize(writer, s, serializer, w => + { + writer.WritePropertyName(settings.Inferrer.Field(geo.Field)); + serializer.Serialize(writer, geo.Points); + }); + break; + default: + writer.WritePropertyName(settings.Inferrer.Field(s.SortKey)); + base.Reserialize(writer, s, serializer); + break; + } + writer.WriteEndObject(); + } + } +} diff --git a/src/Nest/Document/Multiple/Bulk/BulkOperation/BulkOperationBase.cs b/src/Nest/Document/Multiple/Bulk/BulkOperation/BulkOperationBase.cs index 3e24c42a325..07275d5162e 100644 --- a/src/Nest/Document/Multiple/Bulk/BulkOperation/BulkOperationBase.cs +++ b/src/Nest/Document/Multiple/Bulk/BulkOperation/BulkOperationBase.cs @@ -25,15 +25,13 @@ public virtual string GetIdForOperation(ElasticInferrer inferrer) } } - public abstract class BulkOperationDescriptorBase : IBulkOperation + public abstract class BulkOperationDescriptorBase : DescriptorBase, IBulkOperation { - private IBulkOperation Self => this; - protected abstract string BulkOperationType { get; } - string IBulkOperation.Operation { get { return this.BulkOperationType; } } + string IBulkOperation.Operation => this.BulkOperationType; protected abstract Type BulkOperationClrType { get; } - Type IBulkOperation.ClrType { get { return this.BulkOperationClrType; } } + Type IBulkOperation.ClrType => this.BulkOperationClrType; IndexName IBulkOperation.Index { get; set; } diff --git a/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs b/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs index 55aa019849a..846889fc17d 100644 --- a/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs +++ b/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs @@ -17,8 +17,9 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s { var bulk = value as IBulkRequest; if (value == null) return; - var contract = serializer.ContractResolver as SettingsContractResolver; - var elasticsearchSerializer = contract?.ConnectionSettings.Serializer; + + var settings = serializer?.GetConnectionSettings(); + var elasticsearchSerializer = settings?.Serializer; if (elasticsearchSerializer == null) return ; foreach(var op in bulk.Operations) @@ -27,7 +28,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s if (op.Index.EqualsMarker(bulk.Index)) op.Index = null; op.Type = op.Type ?? bulk.Type ?? op.ClrType; if (op.Type.EqualsMarker(bulk.Type)) op.Type = null; - op.Id = op.GetIdForOperation(contract.Infer); + op.Id = op.GetIdForOperation(settings.Inferrer); var opJson = elasticsearchSerializer.SerializeToBytes(op, SerializationFormatting.None); writer.WriteRaw($"{{\"{op.Operation}\":" + opJson.Utf8String() + "}\n"); diff --git a/src/Nest/Document/Multiple/MultiGet/Request/IMultiGetOperation.cs b/src/Nest/Document/Multiple/MultiGet/Request/IMultiGetOperation.cs index c6c2673fc22..a1395d3093b 100644 --- a/src/Nest/Document/Multiple/MultiGet/Request/IMultiGetOperation.cs +++ b/src/Nest/Document/Multiple/MultiGet/Request/IMultiGetOperation.cs @@ -5,24 +5,24 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - [JsonConverter(typeof(ReadAsTypeJsonConverter>))] + [JsonConverter(typeof(ReadAsTypeJsonConverter>))] public interface IMultiGetOperation { [JsonProperty(PropertyName = "_index")] IndexName Index { get; set; } - + [JsonProperty(PropertyName = "_type")] TypeName Type { get; set; } - + [JsonProperty(PropertyName = "_id")] Id Id { get; set; } - + [JsonProperty(PropertyName = "fields")] - IList Fields { get; set; } - + Fields Fields { get; set; } + [JsonProperty(PropertyName = "_routing")] string Routing { get; set; } - + [JsonProperty(PropertyName = "_source")] Union Source { get; set; } diff --git a/src/Nest/Document/Multiple/MultiGet/Request/MultiGetOperation.cs b/src/Nest/Document/Multiple/MultiGet/Request/MultiGetOperation.cs index ed46c295c6d..38ac6aa8a18 100644 --- a/src/Nest/Document/Multiple/MultiGet/Request/MultiGetOperation.cs +++ b/src/Nest/Document/Multiple/MultiGet/Request/MultiGetOperation.cs @@ -16,7 +16,6 @@ public MultiGetOperation(Id id) this.Type = typeof(T); } - Type IMultiGetOperation.ClrType => typeof(T); public IndexName Index { get; set; } @@ -25,7 +24,7 @@ public MultiGetOperation(Id id) public Id Id { get; set; } - public IList Fields { get; set; } + public Fields Fields { get; set; } public Union Source { get; set; } @@ -42,17 +41,15 @@ public MultiGetOperation(Id id) public object Document { get; set; } } - public class MultiGetOperationDescriptor : IMultiGetOperation + public class MultiGetOperationDescriptor : DescriptorBase, IMultiGetOperation>, IMultiGetOperation where T : class { - private IMultiGetOperation Self => this; - IndexName IMultiGetOperation.Index { get; set; } TypeName IMultiGetOperation.Type { get; set; } Id IMultiGetOperation.Id { get; set; } string IMultiGetOperation.Routing { get; set; } Union IMultiGetOperation.Source { get; set; } - IList IMultiGetOperation.Fields { get; set; } + Fields IMultiGetOperation.Fields { get; set; } Type IMultiGetOperation.ClrType => typeof(T); bool IMultiGetOperation.CanBeFlattened => @@ -86,87 +83,38 @@ public MultiGetOperationDescriptor(bool allowExplicitIndex) /// /// Manually set the index, default to the default index or the index set for the type on the connectionsettings. /// - public MultiGetOperationDescriptor Index(string index) - { - if (index.IsNullOrEmpty()) return this; - Self.Index = index; - return this; - } + public MultiGetOperationDescriptor Index(IndexName index) => Assign(a => a.Index = index); + /// /// Manualy set the type to get the object from, default to whatever /// T will be inferred to if not passed. /// - public MultiGetOperationDescriptor Type(string type) - { - if (type.IsNullOrEmpty()) return this; - Self.Type = type; - return this; - } - + public MultiGetOperationDescriptor Type(TypeName type) => Assign(a=> a.Type = type); - /// - /// Manually set the type of which a typename will be inferred - /// - public MultiGetOperationDescriptor Type(Type type) - { - if (type == null) return this; - Self.Type = type; - return this; - } - - public MultiGetOperationDescriptor Id(Id id) - { - Self.Id = id; - return this; - } + public MultiGetOperationDescriptor Id(Id id) => Assign(a => a.Id = id); /// /// Control how the document's source is loaded /// - public MultiGetOperationDescriptor Source(bool? sourceEnabled = true) - { - Self.Source = sourceEnabled; - return this; - } + public MultiGetOperationDescriptor Source(bool? sourceEnabled = true) => Assign(a => a.Source = sourceEnabled); /// /// Control how the document's source is loaded /// - public MultiGetOperationDescriptor Source(Func, ISourceFilter> source) - { - Self.Source = new Union(source(new SourceFilterDescriptor())); - return this; - } + public MultiGetOperationDescriptor Source(Func, ISourceFilter> source) => + Assign(a => a.Source = new Union(source(new SourceFilterDescriptor()))); /// /// Set the routing for the get operation /// - public MultiGetOperationDescriptor Routing(string routing) - { - routing.ThrowIfNullOrEmpty("routing"); - Self.Routing = routing; - return this; - } + public MultiGetOperationDescriptor Routing(string routing) => Assign(a => a.Routing = routing); /// /// Allows to selectively load specific fields for each document /// represented by a search hit. Defaults to load the internal _source field. /// - public MultiGetOperationDescriptor Fields(params Expression>[] expressions) - { - Self.Fields = expressions.Select(e => (Field)e).ToList(); - return this; - } - - /// - /// Allows to selectively load specific fields for each document - /// represented by a search hit. Defaults to load the internal _source field. - /// - public MultiGetOperationDescriptor Fields(params string[] fields) - { - Self.Fields = fields.Select(f => (Field)f).ToList(); - return this; - } + public MultiGetOperationDescriptor Fields(Func, IPromise> fields) => + Assign(a => a.Fields = fields?.Invoke(new FieldsDescriptor())?.Value); } } \ No newline at end of file diff --git a/src/Nest/Document/Multiple/MultiGet/Response/MultiGetHitJsonConverter.cs b/src/Nest/Document/Multiple/MultiGet/Response/MultiGetHitJsonConverter.cs index 2f3020bd474..4c249ea55c8 100644 --- a/src/Nest/Document/Multiple/MultiGet/Response/MultiGetHitJsonConverter.cs +++ b/src/Nest/Document/Multiple/MultiGet/Response/MultiGetHitJsonConverter.cs @@ -20,10 +20,10 @@ private class MultiHitTuple private readonly IMultiGetRequest _request; private static MethodInfo MakeDelegateMethodInfo = typeof(MultiGetHitJsonConverter).GetMethod("CreateMultiHit", BindingFlags.Static | BindingFlags.NonPublic); - + internal MultiGetHitJsonConverter() { - + } public MultiGetHitJsonConverter(IMultiGetRequest request) @@ -39,16 +39,15 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s private static void CreateMultiHit(MultiHitTuple tuple, JsonSerializer serializer, ICollection> collection) where T : class { var hit = new MultiGetHit(); - var reader = tuple.Hit.CreateReader(); + var reader = tuple.Hit.CreateReader(); serializer.Populate(reader, hit); - var contract = serializer.ContractResolver as SettingsContractResolver; - var settings = contract.ConnectionSettings; + var settings = serializer.GetConnectionSettings(); var f = new FieldSelection(settings); var source = tuple.Hit["fields"]; if (source != null) { - ((IFieldSelection)f).FieldValuesDictionary = serializer.Deserialize>( source.CreateReader()); + ((IFieldSelection)f).FieldValuesDictionary = serializer.Deserialize>(source.CreateReader()); hit.FieldSelection = f; } @@ -60,13 +59,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist { if (this._request == null) { - var realConverter = ( - (serializer.ContractResolver as SettingsContractResolver) - ?.PiggyBackState?.ActualJsonConverter as MultiGetHitJsonConverter - ); - if (realConverter == null) - throw new DslException("could not find a stateful multigethit converter"); - + var realConverter = serializer.GetStatefulConverter(); return realConverter.ReadJson(reader, objectType, existingValue, serializer); } @@ -74,7 +67,6 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist var jsonObject = JObject.Load(reader); var docsJarray = (JArray)jsonObject["docs"]; - var multiGetDescriptor = this._request; if (this._request == null || docsJarray == null) return response; diff --git a/src/Nest/Document/Multiple/MultiGet/Response/MultiGetResponse.cs b/src/Nest/Document/Multiple/MultiGet/Response/MultiGetResponse.cs index f3ea35fb77b..775a9f3046d 100644 --- a/src/Nest/Document/Multiple/MultiGet/Response/MultiGetResponse.cs +++ b/src/Nest/Document/Multiple/MultiGet/Response/MultiGetResponse.cs @@ -22,6 +22,8 @@ public interface IMultiGetResponse : IResponse } [JsonObject] + //TODO validate this, ported over from ElasticContractResolver but it seems out of place + [ContractJsonConverter(typeof(MultiGetHitJsonConverter))] public class MultiGetResponse : BaseResponse, IMultiGetResponse { public MultiGetResponse() diff --git a/src/Nest/Document/Multiple/Reindex/Reindex.cs b/src/Nest/Document/Multiple/Reindex/Reindex.cs index a15b9f6e0aa..6a9e2587f31 100644 --- a/src/Nest/Document/Multiple/Reindex/Reindex.cs +++ b/src/Nest/Document/Multiple/Reindex/Reindex.cs @@ -33,10 +33,8 @@ public ReindexRequest(IndexName from, IndexName to) } } - public class ReindexDescriptor : IReindexRequest where T : class + public class ReindexDescriptor : DescriptorBase, IReindexRequest>, IReindexRequest where T : class { - ReindexDescriptor Assign(Action assign) => Fluent.Assign(this, assign); - IndexName IReindexRequest.To { get; set; } IndexName IReindexRequest.From { get; set; } string IReindexRequest.Scroll { get; set; } diff --git a/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs b/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs index 90ce95901bd..02e47bec738 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs @@ -5,7 +5,7 @@ namespace Nest { - [JsonConverter(typeof(IndexSettingsConverter))] + [ContractJsonConverter(typeof(IndexSettingsConverter))] public interface IDynamicIndexSettings : IIsADictionary { /// diff --git a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs index 8f789b6d327..7d0a4bb96d4 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs @@ -6,7 +6,7 @@ namespace Nest { - [JsonConverter(typeof(IndexSettingsConverter))] + [ContractJsonConverter(typeof(IndexSettingsConverter))] public interface IIndexSettings : IDynamicIndexSettings { /// diff --git a/src/Nest/IndexModules/Similarity/Similarity.cs b/src/Nest/IndexModules/Similarity/Similarity.cs index 559d997a778..50f279cbcb6 100644 --- a/src/Nest/IndexModules/Similarity/Similarity.cs +++ b/src/Nest/IndexModules/Similarity/Similarity.cs @@ -5,6 +5,7 @@ namespace Nest { + [ContractJsonConverter(typeof(SimilarityJsonConverter))] public interface ISimilarity { [JsonProperty("type")] diff --git a/src/Nest/Indices/AliasManagement/Aliases.cs b/src/Nest/Indices/AliasManagement/Aliases.cs index 129a5863101..95ad9ed72cd 100644 --- a/src/Nest/Indices/AliasManagement/Aliases.cs +++ b/src/Nest/Indices/AliasManagement/Aliases.cs @@ -5,7 +5,7 @@ namespace Nest { - [JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))] + [JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))] public interface IAliases : IIsADictionary { } public class Aliases : IsADictionary, IAliases { diff --git a/src/Nest/Indices/MappingManagement/PutMapping/PutMappingRequest.cs b/src/Nest/Indices/MappingManagement/PutMapping/PutMappingRequest.cs index 5cd7b313d49..b670fa90753 100644 --- a/src/Nest/Indices/MappingManagement/PutMapping/PutMappingRequest.cs +++ b/src/Nest/Indices/MappingManagement/PutMapping/PutMappingRequest.cs @@ -12,7 +12,7 @@ public partial interface IPutMappingRequest : ITypeMapping public interface IPutMappingRequest : IPutMappingRequest where T : class { } - public partial class PutMappingRequest : RequestBase, IPutMappingRequest + public partial class PutMappingRequest { // Needed for ReadAsType internal PutMappingRequest() { } @@ -26,7 +26,7 @@ internal PutMappingRequest() { } /// public IEnumerable DynamicDateFormats { get; set; } /// - public IDictionary DynamicTemplates { get; set; } + public IDynamicTemplateContainer DynamicTemplates { get; set; } /// public DynamicMapping? Dynamic { get; set; } /// @@ -77,7 +77,7 @@ public PutMappingRequest() : this(typeof(T), typeof(T)) { } /// public IEnumerable DynamicDateFormats { get; set; } /// - public IDictionary DynamicTemplates { get; set; } + public IDynamicTemplateContainer DynamicTemplates { get; set; } /// public DynamicMapping? Dynamic { get; set; } /// @@ -130,7 +130,7 @@ public PutMappingDescriptor(IndexName index, TypeName type) : base(r=>r.Required IEnumerable ITypeMapping.DynamicDateFormats { get; set; } string ITypeMapping.Analyzer { get; set; } string ITypeMapping.SearchAnalyzer { get; set; } - IDictionary ITypeMapping.DynamicTemplates { get; set; } + IDynamicTemplateContainer ITypeMapping.DynamicTemplates { get; set; } DynamicMapping? ITypeMapping.Dynamic { get; set; } IFieldNamesField ITypeMapping.FieldNamesField { get; set; } IIdField ITypeMapping.IdField { get; set; } @@ -204,15 +204,11 @@ public PutMappingDescriptor AutoMap(IPropertyVisitor visitor = null) => Assig public PutMappingDescriptor NumericDetection(bool detect = true) => Assign(a => a.NumericDetection = detect); /// - public PutMappingDescriptor Transform(Func mappingTransformSelector) - { - //TODO MappingTransform needs a descriptor so we no longer make this call mutate state - var t = mappingTransformSelector?.Invoke(new MappingTransformDescriptor()); - if (t == null) return this; - if (((IPutMappingRequest)this).Transform == null) ((IPutMappingRequest)this).Transform = new List(); - ((IPutMappingRequest)this).Transform.Add(t); - return this; - } + public PutMappingDescriptor Transform(IEnumerable transforms) => Assign(a => a.Transform = transforms.ToListOrNullIfEmpty()); + + /// + public PutMappingDescriptor Transform(Func>> selector) => + Assign(a => a.Transform = selector?.Invoke(new MappingTransformsDescriptor())?.Value); /// public PutMappingDescriptor IdField(Func idMapper) => Assign(a => a.IdField = idMapper?.Invoke(new IdFieldDescriptor())); @@ -245,18 +241,7 @@ public PutMappingDescriptor Properties(Func, IPromise Assign(a => a.Properties = propertiesSelector?.Invoke(new PropertiesDescriptor(a.Properties))?.Value); /// - public PutMappingDescriptor DynamicTemplates(Func, DynamicTemplatesDescriptor> dynamicTemplatesSelector) - { - //TODO _DELETES concept is wrong? - dynamicTemplatesSelector.ThrowIfNull("dynamicTemplatesSelector"); - var templates = dynamicTemplatesSelector(new DynamicTemplatesDescriptor()); - if (((IPutMappingRequest)this).DynamicTemplates == null) - ((IPutMappingRequest)this).DynamicTemplates = new Dictionary(); - foreach (var t in templates._Deletes) - ((IPutMappingRequest)this).DynamicTemplates.Remove(t); - foreach (var t in templates.Templates) - ((IPutMappingRequest)this).DynamicTemplates[t.Key] = t.Value; - return this; - } + public PutMappingDescriptor DynamicTemplates(Func, IPromise> dynamicTemplatesSelector) => + Assign(a => a.DynamicTemplates = dynamicTemplatesSelector?.Invoke(new DynamicTemplateContainerDescriptor())?.Value); } } \ No newline at end of file diff --git a/src/Nest/Mapping/AttributeBased/CompletionAttribute.cs b/src/Nest/Mapping/AttributeBased/CompletionAttribute.cs index 71fb5751e6d..af41a4e49b6 100644 --- a/src/Nest/Mapping/AttributeBased/CompletionAttribute.cs +++ b/src/Nest/Mapping/AttributeBased/CompletionAttribute.cs @@ -13,7 +13,7 @@ public class CompletionAttribute : ElasticsearchPropertyAttribute, ICompletionPr bool? ICompletionProperty.PreserveSeparators { get; set; } bool? ICompletionProperty.PreservePositionIncrements { get; set; } int? ICompletionProperty.MaxInputLength { get; set; } - IDictionary ICompletionProperty.Context { get; set; } + ISuggestContextMapping ICompletionProperty.Context { get; set; } public string SearchAnalyzer { get { return Self.SearchAnalyzer; } set { Self.SearchAnalyzer = value; } } public string Analyzer { get { return Self.Analyzer; } set { Self.Analyzer = value; } } diff --git a/src/Nest/Mapping/CodeBased/PropertyMapping.cs b/src/Nest/Mapping/CodeBased/PropertyMapping.cs index 34d00549de1..a4cbb57ee42 100644 --- a/src/Nest/Mapping/CodeBased/PropertyMapping.cs +++ b/src/Nest/Mapping/CodeBased/PropertyMapping.cs @@ -9,7 +9,8 @@ namespace Nest { - public class PropertyMappingDescriptor where TDocument : class + public class PropertyMappingDescriptor : DescriptorBase, IDescriptor> + where TDocument : class { internal IList> Mappings { get; } = new List>(); diff --git a/src/Nest/Mapping/DynamicTemplate/DynamicTemplate.cs b/src/Nest/Mapping/DynamicTemplate/DynamicTemplate.cs index 4ca56f1db70..ec6e5fc2bfd 100644 --- a/src/Nest/Mapping/DynamicTemplate/DynamicTemplate.cs +++ b/src/Nest/Mapping/DynamicTemplate/DynamicTemplate.cs @@ -4,103 +4,64 @@ namespace Nest { - public class DynamicTemplate - { + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + [JsonConverter(typeof(ReadAsTypeJsonConverter))] + public interface IDynamicTemplate + { [JsonProperty("match")] - public string Match { get; set; } + string Match { get; set; } [JsonProperty("unmatch")] - public string Unmatch { get; set; } + string Unmatch { get; set; } [JsonProperty("match_mapping_type")] - public string MatchMappingType { get; set; } + string MatchMappingType { get; set; } [JsonProperty("path_match")] - public string PathMatch { get; set; } + string PathMatch { get; set; } [JsonProperty("path_unmatch")] - public string PathUnmatch { get; set; } - - [JsonProperty("mapping"), JsonConverter(typeof(PropertyJsonConverter))] - public IProperty Mapping { get; set; } + string PathUnmatch { get; set; } - } + [JsonProperty("mapping")] + IProperty Mapping { get; set; } + } - public class DynamicTemplatesDescriptor where T : class + public class DynamicTemplate { - internal IDictionary Templates = new Dictionary(); - internal IList _Deletes = new List(); - - public DynamicTemplatesDescriptor Add( - Func, DynamicTemplateDescriptor> templateSelector) - { - templateSelector.ThrowIfNull("templateSelector"); - var d = templateSelector(new DynamicTemplateDescriptor()); - if (d == null || d._Name.IsNullOrEmpty()) - throw new Exception("Could not get name for dynamic template"); - - this.Templates[d._Name] = d._Template; - return this; - } - public DynamicTemplatesDescriptor Remove(string name) - { - this._Deletes.Add(name); - return this; - } + public string Match { get; set; } + + public string Unmatch { get; set; } + + public string MatchMappingType { get; set; } + + public string PathMatch { get; set; } + + public string PathUnmatch { get; set; } + + public IProperty Mapping { get; set; } } - public class DynamicTemplateDescriptor where T : class + + public class DynamicTemplateDescriptor : DescriptorBase, IDynamicTemplate>, IDynamicTemplate + where T : class { - internal string _Name { get; private set; } - internal DynamicTemplate _Template { get; private set; } - - public DynamicTemplateDescriptor() - { - this._Template = new DynamicTemplate(); - } - - public DynamicTemplateDescriptor Name(string name) - { - this._Name = name; - return this; - } - - public DynamicTemplateDescriptor Match(string match) - { - this._Template.Match = match; - return this; - } - - public DynamicTemplateDescriptor Unmatch(string unMatch) - { - this._Template.Unmatch = unMatch; - return this; - } - - public DynamicTemplateDescriptor MatchMappingType(string matchMappingType) - { - this._Template.MatchMappingType = matchMappingType; - return this; - } - - public DynamicTemplateDescriptor PathMatch(string pathMatch) - { - this._Template.PathMatch = pathMatch; - return this; - } - - public DynamicTemplateDescriptor PathUnmatch(string pathUnmatch) - { - this._Template.PathUnmatch = pathUnmatch; - return this; - } - - public DynamicTemplateDescriptor Mapping(Func, IProperty> mappingSelector) - { - mappingSelector.ThrowIfNull("mappingSelector"); - var mapping = mappingSelector(new SingleMappingDescriptor()); - - this._Template.Mapping = mapping; - return this; - } + string IDynamicTemplate.Match { get; set; } + string IDynamicTemplate.Unmatch { get; set; } + string IDynamicTemplate.MatchMappingType { get; set; } + string IDynamicTemplate.PathMatch { get; set; } + string IDynamicTemplate.PathUnmatch { get; set; } + IProperty IDynamicTemplate.Mapping { get; set; } + + public DynamicTemplateDescriptor Match(string match) => Assign(a => a.Match = match); + + public DynamicTemplateDescriptor Unmatch(string unMatch) => Assign(a => a.Unmatch = unMatch); + + public DynamicTemplateDescriptor MatchMappingType(string matchMappingType) => Assign(a => a.MatchMappingType = matchMappingType); + + public DynamicTemplateDescriptor PathMatch(string pathMatch) => Assign(a => a.PathMatch = pathMatch); + + public DynamicTemplateDescriptor PathUnmatch(string pathUnmatch) => Assign(a => a.PathUnmatch = pathUnmatch); + + public DynamicTemplateDescriptor Mapping(Func, IProperty> mappingSelector) => Assign(a => a.Mapping = mappingSelector?.Invoke(new SingleMappingDescriptor())); } } \ No newline at end of file diff --git a/src/Nest/Mapping/DynamicTemplate/DynamicTemplateContainer.cs b/src/Nest/Mapping/DynamicTemplate/DynamicTemplateContainer.cs new file mode 100644 index 00000000000..16077506358 --- /dev/null +++ b/src/Nest/Mapping/DynamicTemplate/DynamicTemplateContainer.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace Nest +{ + + [JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))] + public interface IDynamicTemplateContainer : IIsADictionary { } + public class DynamicTemplateContainer : IsADictionary, IDynamicTemplateContainer + { + public DynamicTemplateContainer() : base() { } + public DynamicTemplateContainer(IDictionary container) : base(container) { } + public DynamicTemplateContainer(Dictionary container) + : base(container.Select(kv => kv).ToDictionary(kv => kv.Key, kv => kv.Value)) + { } + + /// + /// Add any setting to the index + /// + public void Add(string name, IDynamicTemplate dynamicTemplate) => BackingDictionary.Add(name, dynamicTemplate); + } + + public class DynamicTemplateContainerDescriptor : IsADictionaryDescriptor, IDynamicTemplateContainer, string, IDynamicTemplate> + where T : class + { + public DynamicTemplateContainerDescriptor() : base(new DynamicTemplateContainer()) { } + + public DynamicTemplateContainerDescriptor DynamicTemplate(string name, Func, IDynamicTemplate> selector) => Assign(name, selector?.Invoke(new DynamicTemplateDescriptor())); + } +} diff --git a/src/Nest/Mapping/DynamicTemplate/DynamicTemplatesJsonConverter.cs b/src/Nest/Mapping/DynamicTemplate/DynamicTemplatesJsonConverter.cs deleted file mode 100644 index 1422721e1d8..00000000000 --- a/src/Nest/Mapping/DynamicTemplate/DynamicTemplatesJsonConverter.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Nest -{ - internal class DynamicTemplatesJsonConverter : JsonConverter - { - public override bool CanWrite => true; - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var dict = value as Dictionary; - if (dict == null || !dict.HasAny()) - return; - - writer.WriteStartArray(); - foreach (var p in dict) - { - writer.WriteStartObject(); - { - writer.WritePropertyName(p.Key); - serializer.Serialize(writer, p.Value); - } - writer.WriteEndObject(); - } - - writer.WriteEndArray(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, - JsonSerializer serializer) - { - var dict = new Dictionary(); - - JArray o = JArray.Load(reader); - - foreach (JObject p in o) - { - var prop = p.Properties().First(); - var po = prop.Value as JObject; - var name = prop.Name; - if (po ==null) - continue; - - var template = serializer.Deserialize(po.CreateReader(), typeof(DynamicTemplate)) as DynamicTemplate; - if (template == null) - continue; - - dict.Add(name, template); - } - return dict; - } - - public override bool CanConvert(Type objectType) => objectType == typeof(IDictionary); - } -} \ No newline at end of file diff --git a/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs b/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs index a5981b3e13a..8db54294dab 100644 --- a/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs +++ b/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs @@ -3,8 +3,8 @@ namespace Nest { - public class SingleMappingDescriptor - : IPropertiesDescriptor + public class SingleMappingDescriptor : + DescriptorBase, IPropertiesDescriptor>, IPropertiesDescriptor where T : class { public IProperty String(Func, IStringProperty> selector) => diff --git a/src/Nest/Mapping/Transform/MappingTransform.cs b/src/Nest/Mapping/Transform/MappingTransform.cs index 157014c5045..abed2c83ad5 100644 --- a/src/Nest/Mapping/Transform/MappingTransform.cs +++ b/src/Nest/Mapping/Transform/MappingTransform.cs @@ -52,5 +52,15 @@ public class MappingTransformDescriptor : DescriptorBase Assign(a => a.Language = language); public MappingTransformDescriptor Language(ScriptLang language) => Assign(a => a.Language = language.GetStringValue()); + + } + + public class MappingTransformsDescriptor: DescriptorPromiseBase> + { + public MappingTransformsDescriptor() : base(new List()) { } + + public MappingTransformsDescriptor Add(Func selector) => + Assign(a => a.AddIfNotNull(selector?.Invoke(new MappingTransformDescriptor()))); + } } diff --git a/src/Nest/Mapping/Transform/MappingTransformJsonConverter.cs b/src/Nest/Mapping/Transform/MappingTransformJsonConverter.cs index a6c77bafa83..e6e0c0c4b59 100644 --- a/src/Nest/Mapping/Transform/MappingTransformJsonConverter.cs +++ b/src/Nest/Mapping/Transform/MappingTransformJsonConverter.cs @@ -9,7 +9,7 @@ namespace Nest { internal class MappingTransformCollectionJsonConverter : JsonConverter { - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override bool CanConvert(Type objectType) => objectType == typeof(IMappingTransform); diff --git a/src/Nest/Mapping/TypeMapping.cs b/src/Nest/Mapping/TypeMapping.cs index 5c529aa6c10..47d4f8b50f2 100644 --- a/src/Nest/Mapping/TypeMapping.cs +++ b/src/Nest/Mapping/TypeMapping.cs @@ -70,9 +70,8 @@ public interface ITypeMapping [JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))] FluentDictionary Meta { get; set; } - [JsonProperty("dynamic_templates", TypeNameHandling = TypeNameHandling.None)] - [JsonConverter(typeof(DynamicTemplatesJsonConverter))] - IDictionary DynamicTemplates { get; set; } + [JsonProperty("dynamic_templates")] + IDynamicTemplateContainer DynamicTemplates { get; set; } [JsonProperty("dynamic")] DynamicMapping? Dynamic { get; set; } @@ -96,7 +95,7 @@ public class TypeMapping : ITypeMapping /// public IEnumerable DynamicDateFormats { get; set; } /// - public IDictionary DynamicTemplates { get; set; } + public IDynamicTemplateContainer DynamicTemplates { get; set; } /// public IFieldNamesField FieldNamesField { get; set; } /// @@ -139,7 +138,7 @@ public class TypeMappingDescriptor : DescriptorBase, bool? ITypeMapping.DateDetection { get; set; } DynamicMapping? ITypeMapping.Dynamic { get; set; } IEnumerable ITypeMapping.DynamicDateFormats { get; set; } - IDictionary ITypeMapping.DynamicTemplates { get; set; } + IDynamicTemplateContainer ITypeMapping.DynamicTemplates { get; set; } IFieldNamesField ITypeMapping.FieldNamesField { get; set; } IIdField ITypeMapping.IdField { get; set; } IIndexField ITypeMapping.IndexField { get; set; } @@ -207,15 +206,11 @@ public class TypeMappingDescriptor : DescriptorBase, public TypeMappingDescriptor NumericDetection(bool detect = true) => Assign(a => a.NumericDetection = detect); /// - public TypeMappingDescriptor Transform(Func mappingTransformSelector) - { - //TODO MappingTransform needs a descriptor so we no longer make this call mutate state - var t = mappingTransformSelector?.Invoke(new MappingTransformDescriptor()); - if (t == null) return this; - if (Self.Transform == null) Self.Transform = new List(); - Self.Transform.Add(t); - return this; - } + public TypeMappingDescriptor Transform(IEnumerable transforms) => Assign(a => a.Transform = transforms.ToListOrNullIfEmpty()); + + /// + public TypeMappingDescriptor Transform(Func>> selector) => + Assign(a => a.Transform = selector?.Invoke(new MappingTransformsDescriptor())?.Value); /// public TypeMappingDescriptor IdField(Func idMapper) => Assign(a => a.IdField = idMapper?.Invoke(new IdFieldDescriptor())); @@ -248,19 +243,8 @@ public TypeMappingDescriptor Properties(Func, Propert Assign(a => a.Properties = propertiesSelector?.Invoke(new PropertiesDescriptor(Self.Properties))?.PromisedValue); /// - public TypeMappingDescriptor DynamicTemplates(Func, DynamicTemplatesDescriptor> dynamicTemplatesSelector) - { - //TODO _DELETES concept is wrong? - dynamicTemplatesSelector.ThrowIfNull("dynamicTemplatesSelector"); - var templates = dynamicTemplatesSelector(new DynamicTemplatesDescriptor()); - if (Self.DynamicTemplates == null) - Self.DynamicTemplates = new Dictionary(); - foreach (var t in templates._Deletes) - Self.DynamicTemplates.Remove(t); - foreach (var t in templates.Templates) - Self.DynamicTemplates[t.Key] = t.Value; - return this; - } + public TypeMappingDescriptor DynamicTemplates(Func, IPromise> dynamicTemplatesSelector) => + Assign(a => a.DynamicTemplates = dynamicTemplatesSelector?.Invoke(new DynamicTemplateContainerDescriptor())?.Value); } } diff --git a/src/Nest/Mapping/Types/Property.cs b/src/Nest/Mapping/Types/Property.cs index dd82a1e32ae..e08deabdc85 100644 --- a/src/Nest/Mapping/Types/Property.cs +++ b/src/Nest/Mapping/Types/Property.cs @@ -6,6 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] + [ContractJsonConverter(typeof(PropertyJsonConverter))] public interface IProperty : IFieldMapping { PropertyName Name { get; set; } diff --git a/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs b/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs index 87406ae0f0d..5d80e2b78ff 100644 --- a/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs +++ b/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs @@ -28,7 +28,7 @@ public interface ICompletionProperty : IProperty int? MaxInputLength { get; set; } [JsonProperty("context")] - IDictionary Context { get ;set;} + ISuggestContextMapping Context { get; set; } } [JsonObject(MemberSerialization.OptIn)] @@ -42,51 +42,40 @@ public CompletionProperty() : base("completion") { } public bool? PreserveSeparators { get; set; } public bool? PreservePositionIncrements { get; set; } public int? MaxInputLength { get; set; } - public IDictionary Context { get ;set;} + public ISuggestContextMapping Context { get; set; } } - public class CompletionPropertyDescriptor + public class CompletionPropertyDescriptor : PropertyDescriptorBase, ICompletionProperty, T>, ICompletionProperty where T : class - { + { string ICompletionProperty.SearchAnalyzer { get; set; } string ICompletionProperty.Analyzer { get; set; } bool? ICompletionProperty.Payloads { get; set; } bool? ICompletionProperty.PreserveSeparators { get; set; } bool? ICompletionProperty.PreservePositionIncrements { get; set; } int? ICompletionProperty.MaxInputLength { get; set; } - IDictionary ICompletionProperty.Context { get; set; } + ISuggestContextMapping ICompletionProperty.Context { get; set; } public CompletionPropertyDescriptor() : base("completion") { } - public CompletionPropertyDescriptor SearchAnalyzer(string searchAnalyzer) => + public CompletionPropertyDescriptor SearchAnalyzer(string searchAnalyzer) => Assign(a => a.SearchAnalyzer = searchAnalyzer); public CompletionPropertyDescriptor Analyzer(string analyzer) => Assign(a => a.Analyzer = analyzer); public CompletionPropertyDescriptor Payloads(bool payloads = true) => Assign(a => a.Payloads = payloads); - public CompletionPropertyDescriptor PreserveSeparators(bool preserveSeparators = true) => + public CompletionPropertyDescriptor PreserveSeparators(bool preserveSeparators = true) => Assign(a => a.PreserveSeparators = preserveSeparators); - public CompletionPropertyDescriptor PreservePositionIncrements(bool preservePositionIncrements = true) => + public CompletionPropertyDescriptor PreservePositionIncrements(bool preservePositionIncrements = true) => Assign(a => a.PreservePositionIncrements = preservePositionIncrements); public CompletionPropertyDescriptor MaxInputLength(int maxInputLength) => Assign(a => a.MaxInputLength = maxInputLength); - public CompletionPropertyDescriptor Context(Func, SuggestContextMappingDescriptor> contextDescriptor) => Assign(a => - { - a.Context = a.Context ?? new Dictionary(); - - var selector = contextDescriptor(new SuggestContextMappingDescriptor()); - - foreach (var context in selector._Contexts) - { - if (a.Context.ContainsKey(context.Key)) - a.Context[context.Key] = context.Value; - else - a.Context.Add(context.Key, context.Value); - } - }); - } + public CompletionPropertyDescriptor Context(Func, IPromise> selector) => + Assign(a => a.Context = selector?.Invoke(new SuggestContextMappingDescriptor())?.Value); + + } } \ No newline at end of file diff --git a/src/Nest/Modules/SnapshotAndRestore/Snapshot/Snapshot/SnapshotRequest.cs b/src/Nest/Modules/SnapshotAndRestore/Snapshot/Snapshot/SnapshotRequest.cs index 8047fde2eee..507445fe2ec 100644 --- a/src/Nest/Modules/SnapshotAndRestore/Snapshot/Snapshot/SnapshotRequest.cs +++ b/src/Nest/Modules/SnapshotAndRestore/Snapshot/Snapshot/SnapshotRequest.cs @@ -9,7 +9,7 @@ namespace Nest public partial interface ISnapshotRequest { [JsonProperty("indices")] - [JsonConverter(typeof(TypesJsonConverter))] + [JsonConverter(typeof(IndicesMultiSyntaxJsonConverter))] Indices Indices { get; set; } [JsonProperty("ignore_unavailable")] diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index 75c5df48c3e..da78e04e71d 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -61,7 +61,7 @@ - + @@ -115,6 +115,7 @@ + @@ -166,6 +167,7 @@ + @@ -252,6 +254,7 @@ + @@ -289,6 +292,7 @@ + @@ -382,9 +386,9 @@ - + - + @@ -424,6 +428,10 @@ + + + + @@ -515,7 +523,7 @@ - + @@ -577,8 +585,8 @@ - - + + @@ -596,7 +604,7 @@ - + @@ -630,7 +638,7 @@ - + @@ -684,18 +692,17 @@ - - + + - - + - - - - - + + + + + @@ -811,7 +818,7 @@ - + @@ -820,9 +827,9 @@ - + - + @@ -1030,7 +1037,7 @@ - + @@ -1040,7 +1047,6 @@ - @@ -1075,7 +1081,6 @@ - @@ -1106,6 +1111,9 @@ + + +