Repository navigation
Give a null in the Location cloud response no value, with its nullreason - #96
Merged
Merged
Conversation
A property the cloud response gives as null must have no value, with the text under the property's name followed by nullreason as its message. The tests read the property by name, from the Element Data's map that the JSON Builder reads, and from the typed getter. A property with a value must give that value, and a property the response leaves out must have no value. Mockito is added to the geo-location.cloud tests to stand in for the Cloud Request Engine, the Pipeline and the Flow Data.
The Location cloud engine put each value from the response into the Element Data unwrapped. org.json reads a JSON null as JSONObject.NULL, which is not null, so a property the cloud gave as null held JSONObject.NULL when read by name or from the map, and the JSON Builder wrote it as null with no nullreason. Only the typed getters gave no value, through a separate map of reasons that the engine handed to the Element Data. The engine now stores every property as an AspectPropertyValue, as the Device Detection and IP Intelligence cloud engines do. A JSON null, or no entry, is no value with the text under the property's name followed by nullreason as its message, or Unknown when the response gives none. CloudGeoDataDefault no longer wraps values itself, so its map of reasons, setNoValueReasons on it and on CloudGeoData, and its getters, which only repeated those of GeoDataDefault, are removed. The live value test expected the unwrapped value. It now expects an AspectPropertyValue, and a reason where there is no value, as the Device Detection cloud value test does.
…alue The comment described what the cloud does. The test only checks that a property with no value carries a message, because its type cannot be read, and the engine always sets a message. The comment and the assertion message now say that.
A property the cloud response leaves out altogether must throw PropertyMissingException when read, as the Missing Properties section of the properties specification says and as .NET does. A response with no Location part leaves out every property, so the no part test now expects the exception rather than no value. A property given as null with no nullreason must have no value with the message Unknown, which no test covered once the left out case changed. CloudGeoData.setNoValueReasons stays, deprecated, so callers still compile. A test calls it and checks that the messages the engine set are unchanged.
…ValueReasons The Location cloud engine gave a property the response leaves out no value with the message Unknown. It now stores no entry for that property, so reading it throws PropertyMissingException, as the Missing Properties section of the properties specification says and as .NET does. A property the response gives as null still has no value, with its nullreason as the message. CloudGeoData.setNoValueReasons and its implementation in CloudGeoDataDefault are back, deprecated, so callers still compile. The method has no effect, because the engine sets each message on the value.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
The full build of #93 failed once on Windows Java 8 because of a live cloud answer, in this job (attempt 1 of run 42722443022).
The cloud gave
Suburbas JSON null for the test coordinates. A property the cloud gives as null should have no value, with the text undersuburbnullreasonas its message. The Location cloud Element Data heldorg.json.JSONObject$Nullinstead, whose simple name is theNullin the message. There is no issue for this defect.The cause
At
rc9846076, where the defect was found,GeoLocationCloudEngine.processEngineput each value into the Element Data unwrapped. For a property that is not a list or JavaScript it storedgeoObj.opt(...), and org.json'soptreturns the storedJSONObject.NULLfor a JSON null, which is not Java null. The engine then handed the Element Data a separate map of reasons (lines 138 to 147) throughsetNoValueReasons, which only the typed getters used, throughCloudGeoDataDefault.tryGetValueandsetValue. So, for a property the cloud gave as null,get("Suburb")andasKeyMap()gaveJSONObject.NULL, which the live test read at line 61,asKeyMap()and writesnullreasononly for anAspectPropertyValuewith no value (JsonBuilderElement, lines 284 to 298), wrote"suburb": nullwith nosuburbnullreason,getSuburb()did give no value with the reason.A property the response left out was stored as Java null, so
getgave null, the typed getters gave no value with an empty message, and the JSON Builder wrote no entry.The Device Detection and IP Intelligence cloud engines test with
isNulland store anAspectPropertyValuewith thenullreasontext, so they do not have theJSONObject.NULLdefect.CloudAspectEngineBase.createAPVMap, which the property keyed engines use, is givenJSONObject.toMap(), andtoMapturnsJSONObject.NULLinto Java null before line 293 checks it. Thedependency:treestep of an earlier green run, run 42785280464, shows the Location cloud engine builds againstorg.json:json:jar:20231013, the version linked here.What the specification says
All links are to specifications
rcat 093bf3e.The Processing section of the Cloud Aspect Engine page describes how each value is read.
The same page says, at lines 84 and 85, "Where the response JSON has no portion for the Engine's Data Key, the Cloud Aspect Engine leaves the Element Data without values and raises no error."
The Null values section of the Properties page says what no value is.
The Missing Properties section of the same page covers a property the response leaves out.
The Process section of the JSON Builder Element page says "A Property that has been assigned 'no value' MUST be written as 'null', with the
nullreasonmeta-Property in the table below."What .NET does
On 51degrees-dotnet
rcat 56a5d60,GeoLocationCloudEngine.ProcessCloudEnginepasses the response's part toCreateAPVDictionary, which loops over the response's entries (line 561) and wraps each in anAspectPropertyValue. A JSON null, which theCloudJsonConverterreads as null, gets thenullreasontext as its message (line 605), orUnknownwhen there is none (line 611). A property the response leaves out gets no entry, and reading it throwsPropertyMissingExceptionfrom the missing property service (AspectDataBase.GetAs, lines 314 to 327).What changed
Two points were decided on 10 November. A property the response leaves out throws
PropertyMissingException, as .NET does and as the Missing Properties section says.setNoValueReasonsstays, deprecated, so no caller breaks in a patch release.GeoLocationCloudEngine.processEngineskips a property the response leaves out (line 149), so the Element Data has no entry for it and reading it throwsPropertyMissingException. A response with no Location part therefore leaves every property out, raises no error while processing, and throws when a property is read. Every other property is read as before and stored through the newtoAspectPropertyValue. A value becomes anAspectPropertyValueholding it. A JSON null becomes no value with thenullreasontext as its message, orUnknownwhen the response gives none, as .NET does and as Java'screateAPVMapdoes (lines 304 to 311).isNullis true for no entry. They also leave the message null where the response gives nonullreason(getNoValueReasonin Device Detection and in IP Intelligence), where Location givesUnknown.CloudGeoDataDefaultno longer wraps values itself, so its map of reasons and its getters, which only repeated those ofGeoDataDefaultthrough that map, are removed.setNoValueReasonsstays on it (lines 45 to 55) and onCloudGeoData, marked deprecated. The method has no effect, because the engine now sets each message on the value, and nothing in this repository calls it.ValueTests.valueTypesexpected the unwrapped value. It now expects anAspectPropertyValue, and checks the type of the value inside it, as the Device Detection cloud value test does. A property with no value, as Suburb had on the failed job, now passes, because its type cannot be read then. For such a property the test checks only that it carries a message, and the engine always sets one.GeoLocationCloudEngineTests.ProductPresent_ResponseWithoutPart_PropertyIsMissing, added by Build a cloud engine whose product the resource key lacks, and log that once #84 asProductPresent_ResponseWithoutPart_NoValues, expected no value for a property when the response has no Location part. It now expectsPropertyMissingException, following the first decision.mockito-coreis added to thegeo-location.cloudtest dependencies, the same block Build a cloud engine whose product the resource key lacks, and log that once #84 added, so the merge ofrcleaves one copy. The parent pom manages its version.For the release notes
get(name)andasKeyMap()on the Location cloud Element Data now give anAspectPropertyValuefor each property the response holds, as the Device Detection and IP Intelligence cloud Element Data do. Code that read the unwrapped value by name must checkhasValue()and callgetValue(). The typed getters such asgetTown()keep their signatures.nullreasonnow has that text as its message when read by name, as it already had from the typed getters, and the JSON Builder writes it asnullwith thatnullreason.nullreasonnow has the messageUnknown, by name and from the typed getters, where the typed getters gave an empty message and reading by name gaveJSONObject.NULL. The JSON Builder writes it asnullwithnullreasonUnknown, where it wrotenullwith nonullreason.PropertyMissingExceptionwhen read, by name or from the typed getters. Before, reading by name gave null and the typed getters gave no value with an empty message. The JSON Builder still writes no entry for it.CloudGeoData.setNoValueReasonsis deprecated and has no effect.How to verify
GeoLocationCloudEngineNullValueTestsfeeds the engine a response through a mocked Cloud Request Engine, and reads each property by name, fromasKeyMap(), which the JSON Builder reads, and from the typed getter.NullValue_NoValueWithNullReasonsuburbnull,suburbnullreasongivensuburbnullreasontextNullValueWithoutReason_NoValueUnknownsuburbnull, nosuburbnullreasonUnknownValue_HasValuetownisReadingReadingNoEntry_PropertyIsMissingsuburbentryasKeyMap(), andgetandgetSuburb()throwPropertyMissingExceptionSetNoValueReasons_ChangesNothingsuburbnull,suburbnullreasongiven, thensetNoValueReasonswith another messagesuburbnullreasontextThe red and green runs used a temporary workflow on a
tmp/branch that builds the named modules on Ubuntu with Java 17 and runs the named tests, the live ones with the bespoke resource key.rcff6e4c0 merged in, failed as expected, in two jobs. As committed, the tests do not compile, because the previous fix had removedsetNoValueReasons.rc9846076, failed withExpected an AspectPropertyValue but found org.json.JSONObject$Null.nightly-pull-request.ymlas a dry run onrcff6e4c0, passed. All nine non-macOS jobs succeeded (Ubuntu Java 8, 11, 17 and 21, Ubuntu ARM Java 17, and Windows Java 8, 11, 17 and 21), and Configure printedLeft out 6 macOS entries. EverySetting 'PullRequestSha'line reads750dd4717c20b11067a58ac293ca56db4429a3c2, this draft's head. In every jobGeoLocationCloudEngineNullValueTestsran 5 tests,GeoLocationCloudEngineTests5 and the liveFiftyoneValueTests3, with no failures or errors.macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.
Other drafts
This branch has
rcff6e4c0 merged in, which holds #84, #85, #86, #89, #92, #93 and #94, all now merged. The merge had no conflicts. Of those, only #84 and #86 changed the Location cloud engine, and this draft changes one of #84's tests, as above.What remains
Nothing. The
rchead is built with macOS before it merges intomain.