Repository navigation
Name the properties wanted on the cloud Pipeline builders, and test a license key alone against the live service - #131
Merged
Conversation
A Pipeline built by the Device Detection, IP Intelligence or Location cloud builder on a license key alone has to name the properties it wants, and the builders have no way to give them. The tests build each Pipeline against a fake cloud service and read the form it sends.
setRequestedProperties on CloudPipelineBuilderBase takes the fully qualified property names, as a list or as comma separated text, and the Device Detection, IP Intelligence and Location cloud builders pass them to the Cloud Request Engine. A Pipeline can then authenticate on a license key alone, which needs the properties named, and the message that refuses a license key without them names a method the builder has.
The Location cloud engine read the DelayExecution flag and the evidence properties of each property the cloud service lists without allowing for a property that has neither, so building its Pipeline stopped with a NullPointerException. It now reads an absent flag as false and absent evidence properties as none, as the cloud engine base class does.
…ey alone The live test builds the engine with a license key and no resource key, names a property the license grants, one every device data file has and a name that is not a property, and checks that the service answers only what was asked, that a property answered as null has its reason, and that the engine reports the name left out once. It skips when no license key for the cloud service is set. The Cloud 51Did workflow has such a key, so it runs the test there.
…requested-properties
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.
Closes #12.
Problem
#12 asks for a Cloud Request Engine that authenticates on a license key alone and names the properties it wants. #97 put that into
CloudRequestEngineBuilderandCloudRequestEngineDefault, which are onrc. Two parts of #12 were still missing onrcat 30e4886.DeviceDetectionCloudPipelineBuilder(lines 90 to 95),IPIntelligenceCloudPipelineBuilderandGeoLocationCloudPipelineBuilderset only the two keys on the Cloud Request Engine builder, andCloudPipelineBuilderBasehad no option for the properties. So an application that builds its Pipeline with one of these builders and a license key alone was always refused, because the engine builder was given no properties.CloudRequestEngineLiveTests.build_Process_ReadsDeviceDataFromTheLiveService, always sets a resource key. Point 7 of Authenticate a Cloud Request Engine on a license key alone, and name the properties wanted #12 asks for "a live test against the service that authenticates on a license key alone and catches the silent drop, skipping cleanly when no license key is configured".What the specification says
The Cloud Request Engine specification at 6570727d, "License Key", says:
"Requested Properties" says:
"Accepted combinations" gives seven rows, of which two are invalid, a License Key with no Requested Properties and no credential at all, and says "An Engine MUST refuse an invalid combination when it is built, in its builder or constructor, rather than when a request is made." #12's own table gives three invalid rows. The third, a Resource Key with Requested Properties, became valid in the specification after #12 was written ("Each requested Property is added, as null with a reason where no licence grants it."), and the engine builder on
rcfollows the specification (checkCredentials, lines 220 to 235). This draft changes none of those rules."Properties the remote server did not return" says an engine that sent Requested Properties "MUST therefore compare what it asked for against what came back, and report the difference", that "A Property that is present but null MUST count as answered rather than dropped", and that "The report MUST be made once rather than on every request". The new live test checks each of those against the service.
What changed
CloudPipelineBuilderBasegainssetRequestedProperties(List<String>)andsetRequestedProperties(String), the second taking one comma separated string. They have the names and arguments of the two methods onCloudRequestEngineBuilder, and both refuse null withIllegalArgumentException, as those do.DeviceDetectionCloudPipelineBuilder,IPIntelligenceCloudPipelineBuilderandGeoLocationCloudPipelineBuilderpass the list to the Cloud Request Engine builder when it is not empty. The engine builder trims the names, drops empty ones and applies the specification's table, so the Pipeline builders hold no rule of their own. A license key alone with no properties is still refused by the engine builder, with its message that the service "answers 400" and that namessetRequestedProperties.GeoLocationCloudEngine.loadAspectPropertiesreadDelayExecutionfrom the accessible properties answer as aBooleanand passed it where abooleanis needed, so a property whose answer has noDelayExecutionfield stopped the Pipeline build withNullPointerException. The new Location builder tests found it (commit 9810a61). A missingDelayExecutionis nowfalseand a missing list of evidence properties is an empty list, which are the values a property with neither has.CloudRequestEngineLiveTests.build_Process_LicenseKeyAlone_AnswersOnlyWhatWasAskedbuilds an engine on a license key alone and asks for three names, being a property the license grants,device.ismobileand a name that is not a property. It processes twice and checks that the answer has noerrors, thatdevice.ismobileis answered with a value or as null with itsnullreason, that the answer holds nothing that was not asked for, and that the engine logged the left out name in one warning and not two. It skips when no license key is set, or when the one set grants no cloud product. None of its messages holds the service's answer, only the names of the answer's fields, so nothing the service says about a key reaches a build log.pipeline/pipeline.cloudrequestengine. It is the only workflow given a license key for the cloud service, so in every other build the test skips.Every name is new. No public name is removed or renamed, and an application that never calls
setRequestedPropertiessends what it sent before.Tests
Written first (commit 6480cc1).
DeviceDetectionCloudPipelineBuilderTests,IPIntelligenceCloudPipelineBuilderTestsandGeoLocationCloudPipelineBuilderTestseach build a Pipeline against an HTTP client that records the data request, and each has the same six tests.LicenseKeyAlone_RequestedProperties_SentAsValuesandLicenseKeyAlone_RequestedPropertiesAsText_SentAsValues. The request carrieslicenseandvalues, and noresource. The text form is given asdevice.ismobile, device.iscrawlerand sent without the space.BothKeys_RequestedProperties_SendsAllThree.ResourceKey_NoRequestedProperties_SendsNoValues, so a caller that names nothing sends what it sent before.LicenseKeyAlone_NoRequestedProperties_Refused. The build stops withPipelineConfigurationException, the message says why and does not hold the license key, and no request is made.SetRequestedProperties_Null_Refused, for both methods.The runs build the three modules with the modules they need and run the three test classes on the runner's Java, on Ubuntu.
rc(commit 002805e on a temporary branch): run 43532206552. The test build fails with "cannot find symbol" forsetRequestedPropertiesin all three modules, because the Pipeline builders onrchave no such method.NullPointerExceptionof point 3 above.rc1c99b72 was merged in: run 43534359725. With the 51Did license key the license key test ran and passed, and with a key set that has no license key beside it the test skipped.The live test has no red run, because the engine code it runs is already on
rcthrough #97. It is a check of the service.Measured while writing the live test
Measured against
cloud.51degrees.comon 14 November 2026 with the 51Did license key alone, in run 43535823198, which prints only the status and the names of the fields in each answer.valuesdevice.ismobileismobileandismobilenullreason, noerrorsdevice.notaproperty51derrors, and nothing for the third namedevice.ismobilealoneismobile,ismobilenullreasonanderrorsdevice.notaproperty51daloneerrorsonlySo a property the license does not grant, asked for beside one it does, now comes back with a
nullreasonbeside it, where the specification's measurement of 21 September 2026 found it "dropped from the response without being named". The engine onrcalready treats both in the way the specification asks, counting the null as answered and reporting the name that is left out once, which is what the live test checks.Build
The full build of the head ec978df is run 43594483320, and it is green. All nine Build and Test jobs passed (Ubuntu on Java 8, 11, 17 and 21, Ubuntu ARM on Java 17, and Windows on Java 8, 11, 17 and 21). In every job the three new builder test classes (
DeviceDetectionCloudPipelineBuilderTests,IPIntelligenceCloudPipelineBuilderTestsandGeoLocationCloudPipelineBuilderTests) passed 6 of 6, andCloudRequestEngineLiveTestsran 2 tests with 1 skipped, the license key test, as the full build has no license key for the cloud service. All tenSetting 'PullRequestSha'lines, one in Configure and one in each job, name ec978df, and Configure printed "Left out 6 macOS entries".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.
rc1c99b72 is merged into this draft (merge commit ec978df, no conflicts), so the draft holds everythingrcheld then, #43 included. Between the first build and that merge,rcchanged one line in each of three files inpipeline/pipeline.cloudrequestengine, two of them tests and the thirdConstants.java, where the configuration page link in a message changed (#115). The Cloud 51Did Tests workflow on the head, run 43594455688, ran the license key test with a license key set, and it passed with none skipped.rchas since gained #136 and #138, and a trial merge of b33daa0 into this head has no conflicts.What #12 says that is now out of date
This draft closes #12, so the two statements in #12 that no longer hold are corrected here rather than left in the issue.
rcaccepts it. This draft follows the specification.accessibleproperties"answered 401 to a license key with no resource key", and point 5 of its "What to do" asks the engine to skip that request for a license key alone. Measured on 14 November 2026 in run 43535823198, the same request with the 51Did license key alone answered 200 and listed the license's product with its properties. The engine onrc(from Authenticate a Cloud Request Engine on a license key alone, and send the properties named #97) makes that request with the license key in the request body, and the live test builds such an engine and passes, so point 5 is not needed. This draft changes neither.What remains