Conversation
maximthomas
left a comment
There was a problem hiding this comment.
praise: The fix goes where the bug is, and the test proves it.
OrFilter.getRight()now returnsnew OrFilter(right)(OrFilter.java:84). That single line fixes everygetLeft()/getRight()walker, so no walker needs its own patch.orFilterRightSideKeepsOrForThreeOrMoreSubFiltersfails when the line is reverted tonew AndFilter(right)(assertion atFilterBuilderTests.java:243) and passes with the fix.
suggestion (non-blocking): The description says this line fixes the FilterHandlers remote path. That is only true once the client that sends the filter runs this framework.
OpenICF-java-framework/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/FilterHandlers.java:72-73, :63-66
CompositeFilterHandler.serialize calls getLeft()/getRight() on the sending side, and deserialize rebuilds a binary filter. This means an n-ary OR is rewritten before it goes on the wire. Suppose a connector server runs this fix but the client does not. The client sends OrFilter{a, AndFilter{b, c}}, and the server drops objects that match only b or only c. The server cannot repair this, because that AND looks exactly like a real one. The reverse case, a new client with an old server, works correctly. The PR body becomes the squash commit message, so one sentence there will save debugging time in mixed-version deployments:
The remote connector server path is fixed once the side that serializes the filter (the client) runs this framework: `CompositeFilterHandler.serialize` calls `getLeft()`/`getRight()` on the sender, so an upgraded connector server still receives `OR(a, AND(b, c))` from an older client.…r more sub-filters OrFilter.getRight() wrapped the remaining sub-filters in an AndFilter, so every caller that walks getLeft()/getRight() (ObjectNormalizerFacade, AbstractFilterTranslator, FilterHandlers serialization, the groovy MapFilterVisitor) turned or(a, b, c) into OR(a, AND(b, c)). Fixes OpenIdentityPlatform#150
137bd92 to
11f569e
Compare
|
Added a "Mixed-version deployments" section to the description with the client-side caveat and the new-client/old-server case. Also rebased the branch onto current |
Fixes #150
Problem
When an
OrFilterholds three or more sub-filters,OrFilter.getRight()wraps all of them except the first in anAndFilter.FilterBuilder.or(...)builds exactly such a flatOrFilter. Any code that walks it throughgetLeft()/getRight()therefore turnsor(a, b, c)intoOR(a, AND(b, c)), and an object that matches onlybor onlycstops matching.The affected callers are
ObjectNormalizerFacade.normalizeFilter,AbstractFilterTranslator(and every connector built on it), theFilterHandlersserialization to a remote connector server, and the groovyMapFilterVisitor.OrFilter.accept(ConnectorObject)iterates over the flat list and is not affected.Change
OrFilter.getRight()now returnsnew OrFilter(right). This one line fixes every caller listed above.FilterBuilderTests:orFilterRightSideKeepsOrForThreeOrMoreSubFilterschecks thatgetRight()of a three-way OR is a two-wayOrFilter. It also checks that rebuilding three- and four-way ORs throughgetLeft()/getRight()keeps the match. This test failed before the fix.andFilterRightSideKeepsAndForThreeOrMoreSubFilterspins the matching behaviour ofAndFilter, which was already correct.Mixed-version deployments
The remote connector server path is fixed once the side that serializes the filter (the client) runs this framework.
CompositeFilterHandler.serializecallsgetLeft()/getRight()on the sender, so an upgraded connector server still receivesOR(a, AND(b, c))from an older client and cannot tell that AND from a real one. A new client talking to an older server works correctly: it sends a binary tree, and a binaryOrFilternever reaches the broken branch.Testing
connector-framework:FilterBuilderTestsandFilterTranslatorTestspass (23 tests).connector-framework-internal:ObjectNormalizerFacadeTests,ObjectSerializationTestsandLocalConnectorInfoManagerTestspass (114 tests).connector-framework-internalhit an unrelated race inLocalConnectorInfoManagerTests.testBatchUseCase3Failure, reported as Flaky LocalConnectorInfoManagerTests.testBatchUseCase3Failure: asserts no batch results right after executeBatch #151. The test passed on the rerun.