Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public boolean equals(Object o) {
return false;
}
DefaultGeometry that = (DefaultGeometry) o;
return this.getOgcGeometry().equals(that.getOgcGeometry());
return this.getOgcGeometry().equals((Object) that.getOgcGeometry());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ESRI 1.2.1 used to test equality by a literal comparison across fields of OGCGeometry types. As of 2.2.4 this was changed to two distinct comparisons: equals(Object) (the standard Java equality op) and equals(OGCGeometry). The later was subsequently deprecated and moved to an Equals(OGCGeometry) method. The code above was calling the (now deprecated) method.

More info can be found on a thread starting from the relevant esri-geometry-api PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: without this change you get failures like the following:

Per-Commit / Matrix - SERVER_VERSION = 'dse-6.8.30', JABBA_VERSION = '[email protected]' / Execute-Tests / com.datastax.dse.driver.api.core.data.geometry.PointIT.should_insert_as_map_keys
...
Error Message
Multiple entries with same key: POINT (1.7976931348623157e+308 4.9000000000000000e-324)=4 and POINT (0 0)=1
Stacktrace
java.lang.IllegalArgumentException: Multiple entries with same key: POINT (1.7976931348623157e+308 4.9000000000000000e-324)=4 and POINT (0 0)=1
	at com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap.conflictException(ImmutableMap.java:382)
	at com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:376)
	at com.datastax.oss.driver.shaded.guava.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket(RegularImmutableMap.java:249)
	at com.datastax.oss.driver.shaded.guava.common.collect.RegularImmutableMap.fromEntryArrayCheckingBucketOverflow(RegularImmutableMap.java:136)
	at com.datastax.oss.driver.shaded.guava.common.collect.RegularImmutableMap.fromEntryArray(RegularImmutableMap.java:98)
	at com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:579)
	at com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap$Builder.buildOrThrow(ImmutableMap.java:607)
	at com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:594)
	at com.datastax.dse.driver.api.core.data.geometry.GeometryIT.should_insert_as_map_keys(GeometryIT.java:236)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:345)
	at org.apache.maven.surefire.junitcore.pc.InvokerStrategy.schedule(InvokerStrategy.java:47)
	at org.apache.maven.surefire.junitcore.pc.Scheduler.schedule(Scheduler.java:316)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java:345)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import com.datastax.dse.driver.api.core.data.geometry.LineString;
import com.datastax.dse.driver.api.core.data.geometry.Point;
import com.esri.core.geometry.ogc.OGCLineString;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.Test;
Expand Down Expand Up @@ -101,8 +104,26 @@ public void should_parse_valid_geo_json() {
}

@Test
public void should_convert_to_geo_json() {
assertThat(lineString.asGeoJson()).isEqualTo(json);
public void should_convert_to_geo_json() throws Exception {

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(lineString.asGeoJson());
assertThat(root.get("type").toString()).isEqualTo("\"LineString\"");

double expected[][] = {{30.0, 10.0}, {10.0, 30.0}, {40.0, 40.0}};
JsonNode coordinatesNode = root.get("coordinates");
assertThat(coordinatesNode.isArray()).isTrue();
ArrayNode coordinatesArray = (ArrayNode) coordinatesNode;
assertThat(coordinatesArray.size()).isEqualTo(3);
for (int i = 0; i < expected.length; ++i) {

JsonNode elemNode = coordinatesArray.get(i);
assertThat(elemNode.isArray()).isTrue();
ArrayNode elemArray = (ArrayNode) elemNode;
assertThat(elemArray.size()).isEqualTo(2);
assertThat(elemArray.get(0).asDouble()).isEqualTo(expected[i][0]);
assertThat(elemArray.get(1).asDouble()).isEqualTo(expected[i][1]);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps the most contentious change in the whole PR. With this code we no longer concern ourselves with the format of the GeoJSON returned by ESRI... we only seek to confirm that we can find the fields we expect at the places we expect them. Any additional content or formatting isn't our concern.

My rationale is that this is really the heart of the matter. We don't claim to follow a specific GeoJSON spec or that any responses will contain only some properties but not any others. With that in mind our objective should be to make sure we don't see any regressions on the props customers actually expect, specifically the "type" and "coordinates" fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: without this change you get failures like the following:

Per-Commit / Matrix - SERVER_VERSION = 'dse-6.9.0', JABBA_VERSION = '[email protected]' / Execute-Tests / com.datastax.dse.driver.internal.core.data.geometry.DefaultLineStringTest.should_convert_to_geo_json
...
Error Message
expected:<...","coordinates":[[30[.0,10.0],[10.0,30.0],[40.0,40.0]]]}"> but was:<...","coordinates":[[30[,10],[10,30],[40,40]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}]}">
Stacktrace
org.junit.ComparisonFailure: expected:<...","coordinates":[[30[.0,10.0],[10.0,30.0],[40.0,40.0]]]}"> but was:<...","coordinates":[[30[,10],[10,30],[40,40]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}]}">
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at com.datastax.dse.driver.internal.core.data.geometry.DefaultLineStringTest.should_convert_to_geo_json(DefaultLineStringTest.java:105)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.apache.maven.surefire.junitcore.JUnitCore.run(JUnitCore.java:49)
	at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.createRequestAndRun(JUnitCoreWrapper.java:120)
	at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.executeEager(JUnitCoreWrapper.java:95)
	at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:75)
	at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:69)
	at org.apache.maven.surefire.junitcore.JUnitCoreProvider.invoke(JUnitCoreProvider.java:146)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)

}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

import com.datastax.dse.driver.api.core.data.geometry.Point;
import com.esri.core.geometry.ogc.OGCPoint;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.Test;
Expand Down Expand Up @@ -83,8 +86,19 @@ public void should_parse_valid_geo_json() {
}

@Test
public void should_convert_to_geo_json() {
assertThat(point.asGeoJson()).isEqualTo(json);
public void should_convert_to_geo_json() throws Exception {

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(point.asGeoJson());
assertThat(root.get("type").toString()).isEqualTo("\"Point\"");

double expected[] = {1.1, 2.2};
JsonNode coordinatesNode = root.get("coordinates");
assertThat(coordinatesNode.isArray()).isTrue();
ArrayNode coordinatesArray = (ArrayNode) coordinatesNode;
assertThat(coordinatesArray.size()).isEqualTo(2);
assertThat(coordinatesArray.get(0).asDouble()).isEqualTo(expected[0]);
assertThat(coordinatesArray.get(1).asDouble()).isEqualTo(expected[1]);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import com.datastax.dse.driver.api.core.data.geometry.Point;
import com.datastax.dse.driver.api.core.data.geometry.Polygon;
import com.esri.core.geometry.ogc.OGCPolygon;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.Test;
Expand Down Expand Up @@ -109,8 +112,44 @@ public void should_parse_valid_geo_json() {
}

@Test
public void should_convert_to_geo_json() {
assertThat(polygon.asGeoJson()).isEqualTo(json);
public void should_convert_to_geo_json() throws Exception {

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(polygon.asGeoJson());
assertThat(root.get("type").toString()).isEqualTo("\"Polygon\"");

/*
Note that the order of values in expected differs from the order of insertion when creating
the Polygon. OGC expects the "exterior" ring of the polygon to be listed in counter-clockwise
order... and that's what this sequence represents (draw it out on a graph if you don't believe me).

Weirdly this is the opposite of the order used for this test when we were using ESRI 1.2.1.
That fact (combined with the fact that only ESRI classes are used for serialization here) makes me
think that the earlier version was just doing it wrong... or at least doing it in a way that
didn't agree with the spec. Either way it is clearly correct that we should go counter-clockwise...
so that's what we're doing.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Part of the explanation here might be that GeoJSON appears to be somewhat looser in ordering the points in a path. There's actually an old ticket for DSE asking for GeoJSON encoding to preserve the OGC ordering even though it isn't required to do so. That ticket was never implemented... which presumably explains why this test looked the way it did (although I'm speculating a bit there).

Either way it is the case that this test (a) uses only ESRI classes locally and (b) is serializing and deserializing data internally (i.e. no interaction with anything outside of ESRI is happening here). It appears that the GeoJSON impl in the new version of esri-geometry-api is more strict about ordering of points... which presumably explains why we've started seeing failures since the upgrade.

double expected[][] = {{30.0, 10.0}, {40.0, 40.0}, {20.0, 40.0}, {10.0, 20.0}, {30.0, 10.0}};
JsonNode coordinatesNode = root.get("coordinates");
assertThat(coordinatesNode.isArray()).isTrue();
ArrayNode coordinatesArray = (ArrayNode) coordinatesNode;

// There's an extra layer here, presumably indicating the bounds of the polygon
assertThat(coordinatesArray.size()).isEqualTo(1);
JsonNode polygonNode = coordinatesArray.get(0);
assertThat(polygonNode.isArray()).isTrue();
ArrayNode polygonArray = (ArrayNode) polygonNode;

assertThat(polygonArray.size()).isEqualTo(5);
for (int i = 0; i < expected.length; ++i) {

JsonNode elemNode = polygonArray.get(i);
assertThat(elemNode.isArray()).isTrue();
ArrayNode elemArray = (ArrayNode) elemNode;
assertThat(elemArray.size()).isEqualTo(2);
assertThat(elemArray.get(0).asDouble()).isEqualTo(expected[i][0]);
assertThat(elemArray.get(1).asDouble()).isEqualTo(expected[i][1]);
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ public void should_find_dependencies_from_file() {
expected.put("com.github.jnr:jffi", withUnverifiedRuntimeVersion("1.2.16"));
expected.put("io.netty:netty-buffer", withUnverifiedRuntimeVersion("4.0.56.Final"));
expected.put("org.ow2.asm:asm-commons", withUnverifiedRuntimeVersion("5.0.3"));
expected.put("org.json:json", withUnverifiedRuntimeVersion("20090211"));
expected.put("org.ow2.asm:asm-util", withUnverifiedRuntimeVersion("5.0.3"));
expected.put("com.github.jnr:jnr-ffi", withUnverifiedRuntimeVersion("2.1.7"));

Expand All @@ -91,7 +90,7 @@ public void should_find_dependencies_from_file() {
new PlatformInfoFinder(this::nullUrlProvider).fetchDependenciesFromFile(inputStream);

// then
assertThat(stringStringMap).hasSize(28);
assertThat(stringStringMap).hasSize(27);
assertThat(stringStringMap).isEqualTo(expected);
}

Expand Down
1 change: 0 additions & 1 deletion core/src/test/resources/insights/test-dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ The following files have been resolved:
org.ow2.asm:asm-analysis:jar:5.0.3:compile
com.github.jnr:jnr-x86asm:jar:1.0.2:compile
io.netty:netty-codec:jar:4.0.56.Final:compile
org.json:json:jar:20090211:compile
com.github.jnr:jffi:jar:native:1.2.16:runtime
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,10 @@ public static CompositeOption esriBundles() {
CoreOptions.wrappedBundle(
mavenBundle("com.esri.geometry", "esri-geometry-api").versionAsInProject())
.exports("com.esri.core.geometry.*")
.imports("org.json", "org.codehaus.jackson")
.imports("com.fasterxml.jackson.*", "com.fasterxml.jackson.databind.*")
.bundleSymbolicName("com.esri.core.geometry")
.overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL),
mavenBundle("org.json", "json").versionAsInProject(),
mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
systemProperty("cassandra.geo").value("true"));
}

Expand Down
8 changes: 1 addition & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<hdrhistogram.version>2.1.12</hdrhistogram.version>
<metrics.version>4.1.18</metrics.version>
<netty.version>4.1.119.Final</netty.version>
<esri.version>1.2.1</esri.version>
<esri.version>2.2.4</esri.version>
<!--
When upgrading TinkerPop please upgrade the version matrix in
manual/core/integration/README.md
Expand All @@ -68,7 +68,6 @@
<slf4j.version>1.7.26</slf4j.version>
<!-- when changing version also update version in LICENSE_binary -->
<reactive-streams.version>1.0.3</reactive-streams.version>
<json.version>20230227</json.version>
<jackson.version>2.13.5</jackson.version>
<jackson-databind.version>${jackson.version}</jackson-databind.version>
<!-- optional dependencies -->
Expand Down Expand Up @@ -162,11 +161,6 @@
<artifactId>esri-geometry-api</artifactId>
<version>${esri.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-core</artifactId>
Expand Down