Skip to content

Use a custom convertor for GeoOrientation to tolerate alternative options in Elasticsearch #3776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions src/Nest/Mapping/Types/Geo/GeoShape/GeoOrientation.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
using System.Runtime.Serialization;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Nest
{
[JsonConverter(typeof(StringEnumConverter))]
[JsonConverter(typeof(GeoOrientationConverter))]
public enum GeoOrientation
{
[EnumMember(Value = "cw")]
ClockWise,

[EnumMember(Value = "ccw")]
CounterClockWise
}

internal class GeoOrientationConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var geoOrientation = (GeoOrientation)value;
switch (geoOrientation)
{
case GeoOrientation.ClockWise:
writer.WriteValue("cw");
break;
case GeoOrientation.CounterClockWise:
writer.WriteValue("ccw");
break;
}
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var enumString = (string)reader.Value;
switch (enumString.ToLower())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think this should use ToLowerInvariant(), rather than use the current culture

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't make the cut for the merge, but will fix for 7.x

{
case "left":
case "cw":
case "clockwise":
return GeoOrientation.ClockWise;
}
// Default, complies with the OGC standard
return GeoOrientation.CounterClockWise;
}

public override bool CanConvert(Type objectType) => true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Linq;
using Elasticsearch.Net;
using FluentAssertions;
using Nest;
using Tests.Core.Extensions;
using Tests.Core.ManagedElasticsearch.Clusters;
using Tests.Domain;
using Tests.Framework;
using Tests.Framework.Integration;

namespace Tests.Mapping.Types.Core.GeoShape
{
public class GeoShapeClusterMetadataApiTests : ApiIntegrationTestBase<WritableCluster, IPutMappingResponse, IPutMappingRequest, PutMappingDescriptor<Project>,
PutMappingRequest<Project>>
{
public GeoShapeClusterMetadataApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }

protected override void IntegrationSetup(IElasticClient client, CallUniqueValues values)
{
foreach (var index in values.Values) client.CreateIndex(index, CreateIndexSettings).ShouldBeValid();
var indices = Infer.Indices(values.Values.Select(i => (IndexName)i));
client.ClusterHealth(f => f.WaitForStatus(WaitForStatus.Yellow).Index(indices))
.ShouldBeValid();
}

protected virtual ICreateIndexRequest CreateIndexSettings(CreateIndexDescriptor create) => create;

protected override bool ExpectIsValid => true;
protected override int ExpectStatusCode => 200;

protected override Func<PutMappingDescriptor<Project>, IPutMappingRequest> Fluent => f => f
.Index(CallIsolatedValue)
.Properties(FluentProperties);

private static Func<PropertiesDescriptor<Project>, IPromise<IProperties>> FluentProperties => f => f
.GeoShape(s => s
.Name(p => p.Location)
.Tree(GeoTree.Quadtree)
.Orientation(GeoOrientation.ClockWise)
.Strategy(GeoStrategy.Recursive)
.TreeLevels(3)
.PointsOnly()
.DistanceErrorPercentage(1.0)
.Coerce()
);

private static IProperties InitializerProperties => new Properties
{
{
"location", new GeoShapeProperty
{
Tree = GeoTree.Quadtree,
Orientation = GeoOrientation.ClockWise,
Strategy = GeoStrategy.Recursive,
TreeLevels = 3,
PointsOnly = true,
DistanceErrorPercentage = 1.0,
Coerce = true
}
}
};

protected override HttpMethod HttpMethod => HttpMethod.PUT;

protected override PutMappingRequest<Project> Initializer => new PutMappingRequest<Project>(CallIsolatedValue, typeof(Project))
{
Properties = InitializerProperties
};

protected override string UrlPath => $"/{CallIsolatedValue}/doc/_mapping";

protected override LazyResponses ClientUsage() => Calls(
(client, f) => client.Map(f),
(client, f) => client.MapAsync(f),
(client, r) => client.Map(r),
(client, r) => client.MapAsync(r)
);

protected override void ExpectResponse(IPutMappingResponse response)
{
// Ensure metadata can be deserialised
var metadata = Client.ClusterState(r => r.Metric(ClusterStateMetric.Metadata));
metadata.IsValid.Should().BeTrue();
}
}
}