Skip to content

Commit 7f0ac7c

Browse files
authored
Use a custom convertor for GeoOrientation to tolerate alternative options in Elasticsearch (#3776)
Use a custom convertor for GeoOrientation to tolerate alternative options in Elasticsearch
1 parent 7555706 commit 7f0ac7c

File tree

2 files changed

+122
-6
lines changed

2 files changed

+122
-6
lines changed
Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,45 @@
1-
using System.Runtime.Serialization;
1+
using System;
22
using Newtonsoft.Json;
3-
using Newtonsoft.Json.Converters;
43

54
namespace Nest
65
{
7-
[JsonConverter(typeof(StringEnumConverter))]
6+
[JsonConverter(typeof(GeoOrientationConverter))]
87
public enum GeoOrientation
98
{
10-
[EnumMember(Value = "cw")]
119
ClockWise,
12-
13-
[EnumMember(Value = "ccw")]
1410
CounterClockWise
1511
}
12+
13+
internal class GeoOrientationConverter : JsonConverter
14+
{
15+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
16+
{
17+
var geoOrientation = (GeoOrientation)value;
18+
switch (geoOrientation)
19+
{
20+
case GeoOrientation.ClockWise:
21+
writer.WriteValue("cw");
22+
break;
23+
case GeoOrientation.CounterClockWise:
24+
writer.WriteValue("ccw");
25+
break;
26+
}
27+
}
28+
29+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
30+
{
31+
var enumString = (string)reader.Value;
32+
switch (enumString.ToLower())
33+
{
34+
case "left":
35+
case "cw":
36+
case "clockwise":
37+
return GeoOrientation.ClockWise;
38+
}
39+
// Default, complies with the OGC standard
40+
return GeoOrientation.CounterClockWise;
41+
}
42+
43+
public override bool CanConvert(Type objectType) => true;
44+
}
1645
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Linq;
3+
using Elasticsearch.Net;
4+
using FluentAssertions;
5+
using Nest;
6+
using Tests.Core.Extensions;
7+
using Tests.Core.ManagedElasticsearch.Clusters;
8+
using Tests.Domain;
9+
using Tests.Framework;
10+
using Tests.Framework.Integration;
11+
12+
namespace Tests.Mapping.Types.Core.GeoShape
13+
{
14+
public class GeoShapeClusterMetadataApiTests : ApiIntegrationTestBase<WritableCluster, IPutMappingResponse, IPutMappingRequest, PutMappingDescriptor<Project>,
15+
PutMappingRequest<Project>>
16+
{
17+
public GeoShapeClusterMetadataApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
18+
19+
protected override void IntegrationSetup(IElasticClient client, CallUniqueValues values)
20+
{
21+
foreach (var index in values.Values) client.CreateIndex(index, CreateIndexSettings).ShouldBeValid();
22+
var indices = Infer.Indices(values.Values.Select(i => (IndexName)i));
23+
client.ClusterHealth(f => f.WaitForStatus(WaitForStatus.Yellow).Index(indices))
24+
.ShouldBeValid();
25+
}
26+
27+
protected virtual ICreateIndexRequest CreateIndexSettings(CreateIndexDescriptor create) => create;
28+
29+
protected override bool ExpectIsValid => true;
30+
protected override int ExpectStatusCode => 200;
31+
32+
protected override Func<PutMappingDescriptor<Project>, IPutMappingRequest> Fluent => f => f
33+
.Index(CallIsolatedValue)
34+
.Properties(FluentProperties);
35+
36+
private static Func<PropertiesDescriptor<Project>, IPromise<IProperties>> FluentProperties => f => f
37+
.GeoShape(s => s
38+
.Name(p => p.Location)
39+
.Tree(GeoTree.Quadtree)
40+
.Orientation(GeoOrientation.ClockWise)
41+
.Strategy(GeoStrategy.Recursive)
42+
.TreeLevels(3)
43+
.PointsOnly()
44+
.DistanceErrorPercentage(1.0)
45+
.Coerce()
46+
);
47+
48+
private static IProperties InitializerProperties => new Properties
49+
{
50+
{
51+
"location", new GeoShapeProperty
52+
{
53+
Tree = GeoTree.Quadtree,
54+
Orientation = GeoOrientation.ClockWise,
55+
Strategy = GeoStrategy.Recursive,
56+
TreeLevels = 3,
57+
PointsOnly = true,
58+
DistanceErrorPercentage = 1.0,
59+
Coerce = true
60+
}
61+
}
62+
};
63+
64+
protected override HttpMethod HttpMethod => HttpMethod.PUT;
65+
66+
protected override PutMappingRequest<Project> Initializer => new PutMappingRequest<Project>(CallIsolatedValue, typeof(Project))
67+
{
68+
Properties = InitializerProperties
69+
};
70+
71+
protected override string UrlPath => $"/{CallIsolatedValue}/doc/_mapping";
72+
73+
protected override LazyResponses ClientUsage() => Calls(
74+
(client, f) => client.Map(f),
75+
(client, f) => client.MapAsync(f),
76+
(client, r) => client.Map(r),
77+
(client, r) => client.MapAsync(r)
78+
);
79+
80+
protected override void ExpectResponse(IPutMappingResponse response)
81+
{
82+
// Ensure metadata can be deserialised
83+
var metadata = Client.ClusterState(r => r.Metric(ClusterStateMetric.Metadata));
84+
metadata.IsValid.Should().BeTrue();
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)