Query API: Proposed Features for 4.6

Last modified 08 Feb 2024 16:58 +01:00
This is feature proposal for midPoint 4.6, it intention is to discuss proposed solutions and resulting implementation may differ.

Match on reference and it’s target properties at same time

Filters currently can match reference itself based on it’s parameters such as oid,relation and type or we can use dereferencing paths (paths containing @) to match properties on referenced objects, but we can not match on both.

Design proposal

Adding option for target inside ref filter would allow us to write filters which targets both reference itself and target.

<query>
    <filter>
        <ref>
            <path>assignment/targetRef</path>
            <value relation="default"></value>
            <target>
                <equal>
                  <path>name</path>
                  <value>a-test-4</value>
                </equal>
            </target>
        </ref>
    </filter>
</query>

In Axiom Query this could be:

assignment/targetRef matches (
  relation = "default"
  and @ matches (
    name = 'a-test-4'
  )
)

Also alternative with target is permitted.

assignment/targetRef matches (
  relation = "default"
  and target matches (
    name = 'a-test-4'
  )
)

target would allow any valid filter to be executed. Most common use would be probably use with type filter (to allow matching on target type specific properties), but other filters could be used.

In short ref filter without target filter specified will behave as before, once target filter it is specified it will work as join filter.

Open Question: target exists filter?

Interestingly this allows to construct filter like: assignment/targetRef matches (target not exists) Note that similar filter could be created using path assignment/target/@ not exists Should this filter match any assignment, which target does not exist?

JOIN filter: referencedBy

Related Issues

MID-4343 Support searches that "join" two object types. For example allow to search all roles, that are assigned to particular user.

From description it seems, that we want to find target based on criteria on object which references it - this inverts ref filter relation.

In order for such filter to work user needs to specify following:

  • Reference which is used for reverse search, this could be expressed as path to reference

  • Criteria which referencing object must match.

YAML format
query:
  type: RoleType
  filter:
    referencedBy:
      type: UserType
      path: assignment/targetRef
      filter:
        equal:
          path: archetypeRef/@/name
          value "System User"
. referencedBy (
      @type = UserType
      and @path = assignment/targetRef
      and archetypeRef/@/name = "System User"
)
. referencedBy (
      . type = UserType
      and @path = assignment/targetRef
      and archetypeRef/@/name = "System User"
)
NOTE

This may looks cumbersome, but type and path and target filter properties are neccessary. path specifies which reference is used for search. target provides additional properties (could be empty to match all). type is neccessary to provide schema for parsing path and filter filter, also specify which data should be searched.

Optional: Distinguish between object properties and parent container properties

Current proposed form of referencedBy assumes nested filter starts at object level. This does not allows to write directly filter such as referencedBy and match also on assignment properties and object properties at same time. This could be possible if we allow referencedBy/@type to be any type.

Example: Find all roles, which are assigned to users with System User archetype and their assignment has secret extension attribute
.referencedBy (
  @type = AssignmentType
  and @path = targetRef
  and extension/secret exists
  and . ownedBy (
      @type = UserType
      and archetypeRef/@/name = "System User"
  )
)

If we allow for parent paths and absolute paths, we can say in specification parent is owning element, then this filter could be written also as:

.referencedBy (
  @type = UserType
  and @path = assignment/targetRef
  and ../extension/secret exists
  and /archetypeRef/@/name = "System User"
)

ownedBy filter

ownedBy filter allows for matching indexed containers based on properties of their parent (owning object or container).

The syntax is similar to referencedBy. ownedBy filter can only be applied on self path (.). The properties of ownedBy filter are:

type

(Required) Type of parent / owner

path

(Optional) name / location of container inside parent

filter

(Optional) filter, to which parent needs to conform, filter is explicit element in XML/YAML/JSON. In Axiom any filter which is not special property of ownedBy is automaticly nested in filter.

Example: Find all assignments only using searchContainers

YAML version
ownedBy:
  type: AssignmentHolderType
  path: assignment
Axiom version
. ownedBy ( @type = AssignmentHolderType and @path = assignment)

Example 2

Find all User assignments which has secret extension property set to true and users have archetype System User

YAML version
and:
  - equal:
      path: extension/secret
      value: true
  - ownedBy:
      type: UserType
        path: assignment
        filter:
        equal:
          path: archetypeRef/@/name = "System User"
Axiom version
extension/secret = true
and . ownedBy (
  @type = UserType
  and @path = assignment
  and archetypeRef/@/name = "system User"
)

Default Matching Rule / matching rules upgrade

Related Issues

we already have schema annotation a:matchingRule, which allows to specify matching rule for property, currently this is used in provisioning for normalization of values.

We can extend support of this to Query implementations, that implementation will get default matchingRule from property definition (which is defined by a:matchingRule), or we could define new property to not encroach on current use of a:matchingRule.

This solution would require:

  • changes to *FilterImpl classes - eg. getMatchingRule will return definition.getMatchingRule if matching rule is not defined in xml/axiom.

  • changes to schema XSD - items, where matching rules should be applied, should be annotated using a:matchingRule.

Additionally we should explore allowing specificiation of default matchingRule on simple type definitions to facilitate future use-cases, where this behaviour should be specified by value type (e.g introduction of types such as LdapDN, UUID).

The algorithm for selection of matching rule for search would be prefer most local definition, eg:

  1. If filter specifies matching rule explicitly use it

  2. If property definition specifies matching rule use it

  3. If type definition (if supported) specifies matching rule use it

  4. Use implementation specific matching rule (eg. default in database)

valueIn filter?

This filter allows matching left value against set of right values and returns true if any of left values is contained in right values (difference to equals is if right side is list, any value match returns true).

Was this page helpful?
YES NO
Thanks for your feedback