From c11ee7a10c91c3e1df3e13797df48073598f8b22 Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Tue, 2 Jul 2019 10:07:02 -0400 Subject: [PATCH 1/2] Geo: add validator that only checks altitude By default, we don't check ranges while indexing geo_shapes. As a result, it is possible to index geoshapes that contain contains coordinates outside of -90 +90 and -180 +180 ranges. Such geoshapes will break SQL and ML retrieval mechanism. This commit removes these restriction from the validator used in SQL and ML retrieval. --- .../geo/utils/StandardValidator.java | 128 ++++++++++++++++++ .../common/geo/GeometryParser.java | 5 +- .../common/geo/GeometryParserTests.java | 15 ++ .../extractor/fields/ExtractedField.java | 4 +- .../xpack/sql/jdbc/TypeConverter.java | 4 +- .../xpack/sql/qa/jdbc/JdbcAssert.java | 4 +- .../qa/src/main/resources/geo/geosql.csv-spec | 15 ++ .../function/scalar/geo/GeoShape.java | 4 +- 8 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java diff --git a/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java b/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java new file mode 100644 index 0000000000000..3e5d9d1adc9aa --- /dev/null +++ b/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java @@ -0,0 +1,128 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.geo.utils; + +import org.elasticsearch.geo.geometry.Circle; +import org.elasticsearch.geo.geometry.Geometry; +import org.elasticsearch.geo.geometry.GeometryCollection; +import org.elasticsearch.geo.geometry.GeometryVisitor; +import org.elasticsearch.geo.geometry.Line; +import org.elasticsearch.geo.geometry.LinearRing; +import org.elasticsearch.geo.geometry.MultiLine; +import org.elasticsearch.geo.geometry.MultiPoint; +import org.elasticsearch.geo.geometry.MultiPolygon; +import org.elasticsearch.geo.geometry.Point; +import org.elasticsearch.geo.geometry.Polygon; +import org.elasticsearch.geo.geometry.Rectangle; + +/** + * Validator that only checks that checks that altitude only shows up if ignoreZValue is set to true. + */ +public class StandardValidator implements GeometryValidator { + + private final boolean ignoreZValue; + + public StandardValidator(boolean ignoreZValue) { + this.ignoreZValue = ignoreZValue; + } + + protected void checkAltitude(double zValue) { + if (ignoreZValue == false && Double.isNaN(zValue) == false) { + throw new IllegalArgumentException("found Z value [" + zValue + "] but [ignore_z_value] " + + "parameter is [" + ignoreZValue + "]"); + } + } + + @Override + public void validate(Geometry geometry) { + if (ignoreZValue == false) { + geometry.visit(new GeometryVisitor() { + + @Override + public Void visit(Circle circle) throws RuntimeException { + checkAltitude(circle.getAlt()); + return null; + } + + @Override + public Void visit(GeometryCollection collection) throws RuntimeException { + for (Geometry g : collection) { + g.visit(this); + } + return null; + } + + @Override + public Void visit(Line line) throws RuntimeException { + for (int i = 0; i < line.length(); i++) { + checkAltitude(line.getAlt(i)); + } + return null; + } + + @Override + public Void visit(LinearRing ring) throws RuntimeException { + for (int i = 0; i < ring.length(); i++) { + checkAltitude(ring.getAlt(i)); + } + return null; + } + + @Override + public Void visit(MultiLine multiLine) throws RuntimeException { + return visit((GeometryCollection) multiLine); + } + + @Override + public Void visit(MultiPoint multiPoint) throws RuntimeException { + return visit((GeometryCollection) multiPoint); + } + + @Override + public Void visit(MultiPolygon multiPolygon) throws RuntimeException { + return visit((GeometryCollection) multiPolygon); + } + + @Override + public Void visit(Point point) throws RuntimeException { + checkAltitude(point.getAlt()); + return null; + } + + @Override + public Void visit(Polygon polygon) throws RuntimeException { + polygon.getPolygon().visit(this); + for (int i = 0; i < polygon.getNumberOfHoles(); i++) { + polygon.getHole(i).visit(this); + } + return null; + } + + @Override + public Void visit(Rectangle rectangle) throws RuntimeException { + checkAltitude(rectangle.getMinAlt()); + checkAltitude(rectangle.getMaxAlt()); + return null; + } + }); + } + } +} + diff --git a/server/src/main/java/org/elasticsearch/common/geo/GeometryParser.java b/server/src/main/java/org/elasticsearch/common/geo/GeometryParser.java index e58372d825507..31fc87baf7580 100644 --- a/server/src/main/java/org/elasticsearch/common/geo/GeometryParser.java +++ b/server/src/main/java/org/elasticsearch/common/geo/GeometryParser.java @@ -22,7 +22,7 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.geo.geometry.Geometry; -import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.GeometryValidator; import org.elasticsearch.geo.utils.WellKnownText; @@ -36,10 +36,9 @@ public final class GeometryParser { private final GeoJson geoJsonParser; private final WellKnownText wellKnownTextParser; - private final GeometryValidator validator; public GeometryParser(boolean rightOrientation, boolean coerce, boolean ignoreZValue) { - validator = new GeographyValidator(ignoreZValue); + GeometryValidator validator = new StandardValidator(ignoreZValue); geoJsonParser = new GeoJson(rightOrientation, coerce, validator); wellKnownTextParser = new WellKnownText(coerce, validator); } diff --git a/server/src/test/java/org/elasticsearch/common/geo/GeometryParserTests.java b/server/src/test/java/org/elasticsearch/common/geo/GeometryParserTests.java index 13b3f8f67b321..92d129de4d3f7 100644 --- a/server/src/test/java/org/elasticsearch/common/geo/GeometryParserTests.java +++ b/server/src/test/java/org/elasticsearch/common/geo/GeometryParserTests.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.geo.geometry.Line; import org.elasticsearch.geo.geometry.LinearRing; import org.elasticsearch.geo.geometry.Point; import org.elasticsearch.geo.geometry.Polygon; @@ -103,6 +104,20 @@ public void testWKTParsing() throws Exception { parser.nextToken(); // Field Value assertEquals(new Point(0, 100), new GeometryParser(true, randomBoolean(), randomBoolean()).parse(parser)); } + + // Make sure we can parse values outside the normal lat lon boundaries + XContentBuilder lineGeoJson = XContentFactory.jsonBuilder() + .startObject() + .field("foo", "LINESTRING (100 0, 200 10)") + .endObject(); + + try (XContentParser parser = createParser(lineGeoJson)) { + parser.nextToken(); // Start object + parser.nextToken(); // Field Name + parser.nextToken(); // Field Value + assertEquals(new Line(new double[]{0, 10}, new double[]{100, 200} ), + new GeometryParser(true, randomBoolean(), randomBoolean()).parse(parser)); + } } public void testNullParsing() throws Exception { diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/fields/ExtractedField.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/fields/ExtractedField.java index e297695152435..7dafbb5f4dcf0 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/fields/ExtractedField.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/fields/ExtractedField.java @@ -9,7 +9,7 @@ import org.elasticsearch.geo.geometry.Geometry; import org.elasticsearch.geo.geometry.Point; import org.elasticsearch.geo.geometry.ShapeType; -import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import org.elasticsearch.search.SearchHit; @@ -127,7 +127,7 @@ public boolean supportsFromSource() { } private static class GeoShapeField extends FromSource { - private static final WellKnownText wkt = new WellKnownText(true, new GeographyValidator(true)); + private static final WellKnownText wkt = new WellKnownText(true, new StandardValidator(true)); GeoShapeField(String alias, String name) { super(alias, name); diff --git a/x-pack/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/TypeConverter.java b/x-pack/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/TypeConverter.java index 0a1c0826695bd..82615662d7147 100644 --- a/x-pack/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/TypeConverter.java +++ b/x-pack/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/TypeConverter.java @@ -5,7 +5,7 @@ */ package org.elasticsearch.xpack.sql.jdbc; -import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import org.elasticsearch.xpack.sql.proto.StringUtils; @@ -55,7 +55,7 @@ */ final class TypeConverter { - private static WellKnownText WKT = new WellKnownText(true, new GeographyValidator(true)); + private static WellKnownText WKT = new WellKnownText(true, new StandardValidator(true)); private TypeConverter() {} diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java b/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java index 256d7cb612cf0..e26313cbad9a5 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java +++ b/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/jdbc/JdbcAssert.java @@ -10,7 +10,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.geo.geometry.Geometry; import org.elasticsearch.geo.geometry.Point; -import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import org.elasticsearch.xpack.sql.jdbc.EsType; import org.elasticsearch.xpack.sql.proto.StringUtils; @@ -52,7 +52,7 @@ public class JdbcAssert { private static final IntObjectHashMap SQL_TO_TYPE = new IntObjectHashMap<>(); - private static final WellKnownText WKT = new WellKnownText(true, new GeographyValidator(true)); + private static final WellKnownText WKT = new WellKnownText(true, new StandardValidator(true)); static { for (EsType type : EsType.values()) { diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec index 31f3857216c0b..8ee9a44adff9a 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec @@ -286,3 +286,18 @@ Phoenix |Americas |-111.97350500151515 Chicago |Americas |-87.63787407428026 New York |Americas |-73.9900270756334 ; + +selectLargeLat +SELECT ST_X(ST_WKTToSQL('LINESTRING (200 100, 300 400)')) x; + + x:d +200.0 +; + +selectLargeLon +SELECT ST_Y(ST_WKTToSQL('LINESTRING (200 100, 300 400)')) y; + + y:d +100.0 +// end::y +; \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoShape.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoShape.java index 1c3d1e7c9358b..ad0bbdd7c94c8 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoShape.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/GeoShape.java @@ -29,7 +29,7 @@ import org.elasticsearch.geo.geometry.Point; import org.elasticsearch.geo.geometry.Polygon; import org.elasticsearch.geo.geometry.Rectangle; -import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.GeometryValidator; import org.elasticsearch.geo.utils.WellKnownText; import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; @@ -51,7 +51,7 @@ public class GeoShape implements ToXContentFragment, NamedWriteable { private final Geometry shape; - private static final GeometryValidator validator = new GeographyValidator(true); + private static final GeometryValidator validator = new StandardValidator(true); private static final GeometryParser GEOMETRY_PARSER = new GeometryParser(true, true, true); From ef0c5f36598b23553e9c3255160adf61b49074c9 Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Thu, 4 Jul 2019 10:26:13 -0400 Subject: [PATCH 2/2] Add geometry-specific tests for the standard validator --- .../elasticsearch/geo/utils/StandardValidator.java | 2 +- .../org/elasticsearch/geo/geometry/CircleTests.java | 6 ++++++ .../geo/geometry/GeometryCollectionTests.java | 7 +++++++ .../org/elasticsearch/geo/geometry/LineTests.java | 7 +++++++ .../elasticsearch/geo/geometry/LinearRingTests.java | 7 +++++++ .../elasticsearch/geo/geometry/MultiLineTests.java | 10 ++++++++++ .../elasticsearch/geo/geometry/MultiPointTests.java | 9 +++++++++ .../geo/geometry/MultiPolygonTests.java | 13 +++++++++++++ .../org/elasticsearch/geo/geometry/PointTests.java | 6 ++++++ .../elasticsearch/geo/geometry/PolygonTests.java | 8 ++++++++ .../elasticsearch/geo/geometry/RectangleTests.java | 7 +++++++ 11 files changed, 81 insertions(+), 1 deletion(-) diff --git a/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java b/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java index 3e5d9d1adc9aa..37a3a5bac5e74 100644 --- a/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java +++ b/libs/geo/src/main/java/org/elasticsearch/geo/utils/StandardValidator.java @@ -33,7 +33,7 @@ import org.elasticsearch.geo.geometry.Rectangle; /** - * Validator that only checks that checks that altitude only shows up if ignoreZValue is set to true. + * Validator that only checks that altitude only shows up if ignoreZValue is set to true. */ public class StandardValidator implements GeometryValidator { diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/CircleTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/CircleTests.java index e8912a39fb435..14107494928bd 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/CircleTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/CircleTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.geo.utils.GeographyValidator; import org.elasticsearch.geo.utils.GeometryValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -59,5 +60,10 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> validator.validate(new Circle(10, 200, 1))); assertEquals("invalid longitude 200.0; must be between -180.0 and 180.0", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate(new Circle(10, 200, 1, 20))); + assertEquals("found Z value [1.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new Circle(10, 200, 1, 20)); } } diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/GeometryCollectionTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/GeometryCollectionTests.java index c78c47dfbcd96..7d2b155c6714b 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/GeometryCollectionTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/GeometryCollectionTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.geo.geometry; import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -58,5 +59,11 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> new GeometryCollection<>( Arrays.asList(new Point(10, 20), new Point(10, 20, 30)))); assertEquals("all elements of the collection should have the same number of dimension", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new GeometryCollection(Collections.singletonList(new Point(10, 20, 30))))); + assertEquals("found Z value [30.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new GeometryCollection(Collections.singletonList(new Point(10, 20, 30)))); } } diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LineTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LineTests.java index b9f8cb37f5422..1b447bad74caa 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LineTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LineTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.geo.utils.GeographyValidator; import org.elasticsearch.geo.utils.GeometryValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -59,6 +60,12 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> validator.validate(new Line(new double[]{1, 100, 3, 1}, new double[]{3, 4, 5, 3}))); assertEquals("invalid latitude 100.0; must be between -90.0 and 90.0", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new Line(new double[]{1, 2}, new double[]{3, 4}, new double[]{6, 5}))); + assertEquals("found Z value [6.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new Line(new double[]{1, 2}, new double[]{3, 4}, new double[]{6, 5})); } public void testWKTValidation() { diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LinearRingTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LinearRingTests.java index 07e9e866233e7..34ebb8e25d596 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LinearRingTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/LinearRingTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.geo.utils.GeographyValidator; import org.elasticsearch.geo.utils.GeometryValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import org.elasticsearch.test.ESTestCase; @@ -58,6 +59,12 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> validator.validate(new LinearRing(new double[]{1, 100, 3, 1}, new double[]{3, 4, 5, 3}))); assertEquals("invalid latitude 100.0; must be between -90.0 and 90.0", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 1, 1, 1}))); + assertEquals("found Z value [1.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 1, 1, 1})); } public void testVisitor() { diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiLineTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiLineTests.java index 9ed782e65cc06..c406f4b485bc3 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiLineTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiLineTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.geo.geometry; import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -50,4 +51,13 @@ public void testBasicSerialization() throws IOException, ParseException { assertEquals("multilinestring EMPTY", wkt.toWKT(MultiLine.EMPTY)); assertEquals(MultiLine.EMPTY, wkt.fromWKT("multilinestring EMPTY)")); } + + public void testValidation() { + IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new MultiLine(Collections.singletonList(new Line(new double[]{1, 2}, new double[]{3, 4}, new double[]{6, 5}))))); + assertEquals("found Z value [6.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate( + new MultiLine(Collections.singletonList(new Line(new double[]{1, 2}, new double[]{3, 4}, new double[]{6, 5})))); + } } diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPointTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPointTests.java index c170adf9c9411..1d13693288bed 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPointTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPointTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.geo.geometry; import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -61,4 +62,12 @@ public void testBasicSerialization() throws IOException, ParseException { assertEquals("multipoint EMPTY", wkt.toWKT(MultiPoint.EMPTY)); assertEquals(MultiPoint.EMPTY, wkt.fromWKT("multipoint EMPTY)")); } + + public void testValidation() { + IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new MultiPoint(Collections.singletonList(new Point(1, 2 ,3))))); + assertEquals("found Z value [3.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new MultiPoint(Collections.singletonList(new Point(1, 2 ,3)))); + } } diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPolygonTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPolygonTests.java index 9918dfa546c82..77389dccaeb57 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPolygonTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/MultiPolygonTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.geo.geometry; import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -52,4 +53,16 @@ public void testBasicSerialization() throws IOException, ParseException { assertEquals("multipolygon EMPTY", wkt.toWKT(MultiPolygon.EMPTY)); assertEquals(MultiPolygon.EMPTY, wkt.fromWKT("multipolygon EMPTY)")); } + + public void testValidation() { + IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new MultiPolygon(Collections.singletonList( + new Polygon(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 2, 3, 1})) + )))); + assertEquals("found Z value [1.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate( + new MultiPolygon(Collections.singletonList( + new Polygon(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 2, 3, 1}))))); + } } diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PointTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PointTests.java index 82e8fc40e75e9..888a0f97809e6 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PointTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PointTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.geo.utils.GeographyValidator; import org.elasticsearch.geo.utils.GeometryValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -51,6 +52,11 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> validator.validate(new Point(10, 500))); assertEquals("invalid longitude 500.0; must be between -180.0 and 180.0", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate(new Point(1, 2, 3))); + assertEquals("found Z value [3.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new Point(1, 2, 3)); } public void testWKTValidation() { diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PolygonTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PolygonTests.java index adbe1f38cdcc0..11cbae50f460e 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PolygonTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/PolygonTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.geo.geometry; import org.elasticsearch.geo.utils.GeographyValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -70,6 +71,13 @@ public void testInitValidation() { () -> new Polygon(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{5, 4, 3, 5}), Collections.singletonList(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3})))); assertEquals("holes must have the same number of dimensions as the polygon", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new Polygon(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 2, 3, 1})))); + assertEquals("found Z value [1.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate( + new Polygon(new LinearRing(new double[]{1, 2, 3, 1}, new double[]{3, 4, 5, 3}, new double[]{1, 2, 3, 1}))); } public void testWKTValidation() { diff --git a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/RectangleTests.java b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/RectangleTests.java index 8bd1494eb34a9..ce80611cb60cd 100644 --- a/libs/geo/src/test/java/org/elasticsearch/geo/geometry/RectangleTests.java +++ b/libs/geo/src/test/java/org/elasticsearch/geo/geometry/RectangleTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.geo.utils.GeographyValidator; import org.elasticsearch.geo.utils.GeometryValidator; +import org.elasticsearch.geo.utils.StandardValidator; import org.elasticsearch.geo.utils.WellKnownText; import java.io.IOException; @@ -59,5 +60,11 @@ public void testInitValidation() { ex = expectThrows(IllegalArgumentException.class, () -> validator.validate(new Rectangle(1, 2, 2, 3, 5, Double.NaN))); assertEquals("only one altitude value is specified", ex.getMessage()); + + ex = expectThrows(IllegalArgumentException.class, () -> new StandardValidator(false).validate( + new Rectangle(30, 40, 50, 10, 20, 60))); + assertEquals("found Z value [20.0] but [ignore_z_value] parameter is [false]", ex.getMessage()); + + new StandardValidator(true).validate(new Rectangle(30, 40, 50, 10, 20, 60)); } }