Skip to content

[#150] Keep OrFilter.getRight() an OR for three or more sub-filters - #152

Open
vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:issue150-orfilter-getright
Open

vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:issue150-orfilter-getright

Conversation

@vharseko

@vharseko vharseko commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Fixes #150

Problem

When an OrFilter holds three or more sub-filters, OrFilter.getRight() wraps all of them except the first in an AndFilter. FilterBuilder.or(...) builds exactly such a flat OrFilter. Any code that walks it through getLeft()/getRight() therefore turns or(a, b, c) into OR(a, AND(b, c)), and an object that matches only b or only c stops matching.

The affected callers are ObjectNormalizerFacade.normalizeFilter, AbstractFilterTranslator (and every connector built on it), the FilterHandlers serialization to a remote connector server, and the groovy MapFilterVisitor. OrFilter.accept(ConnectorObject) iterates over the flat list and is not affected.

Change

  • OrFilter.getRight() now returns new OrFilter(right). This one line fixes every caller listed above.
  • FilterBuilderTests:
    • orFilterRightSideKeepsOrForThreeOrMoreSubFilters checks that getRight() of a three-way OR is a two-way OrFilter. It also checks that rebuilding three- and four-way ORs through getLeft()/getRight() keeps the match. This test failed before the fix.
    • andFilterRightSideKeepsAndForThreeOrMoreSubFilters pins the matching behaviour of AndFilter, 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.serialize calls getLeft()/getRight() on the sender, so an upgraded connector server still receives OR(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 binary OrFilter never reaches the broken branch.

Testing

@vharseko vharseko added bug Something isn't working java Pull requests that update java code framework OpenICF-java-framework labels Oct 4, 2026
@vharseko
vharseko requested a review from maximthomas October 4, 2026 09:33

@maximthomas maximthomas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: The fix goes where the bug is, and the test proves it.

  • OrFilter.getRight() now returns new OrFilter(right) (OrFilter.java:84). That single line fixes every getLeft()/getRight() walker, so no walker needs its own patch.
  • orFilterRightSideKeepsOrForThreeOrMoreSubFilters fails when the line is reverted to new AndFilter(right) (assertion at FilterBuilderTests.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.

@vharseko vharseko added connector:groovy Groovy connector tests Test additions or fixes labels Oct 5, 2026
…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
@vharseko
vharseko force-pushed the issue150-orfilter-getright branch from 137bd92 to 11f569e Compare October 5, 2026 13:06
@vharseko

vharseko commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

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 master (now on top of #145 and #139); no conflicts, and FilterBuilderTests, FilterTranslatorTests, ObjectNormalizerFacadeTests and ObjectSerializationTests pass on the rebased head 11f569ef.

@vharseko
vharseko requested a review from maximthomas October 5, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working connector:groovy Groovy connector framework OpenICF-java-framework java Pull requests that update java code tests Test additions or fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OrFilter.getRight() returns an AndFilter for three or more sub-filters

2 participants