Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Mar 4, 2024
2 parents 15cd98c + a24361a commit 6758d7a
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 27 deletions.
12 changes: 10 additions & 2 deletions docs/concepts/matching-rules.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,16 @@ However currently the set of matching rules is built-in in midPoint product.

== Query matching

Note that besides in attribute definitions, matching rules can also be used in queries using the tag _<matching>_.
An example:
Note that besides in attribute definitions, matching rules can also be used in queries. In midPoint Query Language, the matching rules are located right behind filter enclosed in square brackets.

[source,midpoint-query]
----
locality =[origIgnoreCase] "Edinburgh"
----
For more information about matching rules in query see xref:./query/midpoint-query-language/introduction.adoc#_matching_rules[matching rules chapter] in introduction to Midpoint Query Language.

In XML query, the matching rules are represented using the tag _<matching>_.
An example for XML query:

.Matching rule specification
[source,xml]
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions docs/concepts/query/midpoint-query-language/errors/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,39 @@ Select version according your midPoint version. +
In this case search in schema "common/common-3" for "LockoutStatusType"

|====

=== Couldn't count objects
image:err-couldnt-count-objects.png[Error couldn't count objects]

This is error message telling that processing of the query failed somehow during processing.

To know why it failed you need to open the error message and see what happened in the messages below.

==== Unknown matching rule 'stringIgnoreCase'

image:err-couldnt-count-objects.png[Error couldn't count objects]

[cols="15h,50" width=85%]
|====
| Request
| Find all users with locality "Edinburgh" ignoring case. Find all with "edinburgh", "EDINBURGH" or "Edinbugh".

| Query
| `locality =[stringIgnoreCase] "Edinburgh"`

| Error message
| Couldn't count objects +
Unknown matching rule 'stringIgnoreCase'.

| Reason
a| The matching rules relate to attribute type. +
locality is of PolystringType and `stringIgnoreCase` matching rule is defined for strings only. +
For polystring you need to use `origIgnoreCase` matching rule.

| Correct query
| `locality =[origIgnoreCase] "Edinburgh"`

| Troubleshooting hints
a| * For more information about matching rules in query see xref:../introduction.adoc#_matching_rules[matching rules chapter] in introduction to Midpoint Query Language.
* List of all matching rules is defined in xref:../../matching-rules.adoc[matching rules] page.

15 changes: 15 additions & 0 deletions docs/concepts/query/midpoint-query-language/introduction.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ less filter - All users which will not be valid after 2021
Comparison filters also supports item path on right side of filter.
For example `activation/validFrom > activation/validTo` should return all objects with incorrectly set activations (activation start is after activation end).

[#_matching_rules]
==== Matching rules
Comparison filter can be even more specified by definition of matching rule in the filter.
The syntax of matching rule in query is: `filter[matchingRuleName]`

.Example of matching rules usage
`givenName =[origIgnoreCase] "Adam"`::
query matches all 'Adam', 'adam' or 'ADAM' in givenName
`emailAddress endsWith[stringIgnoreCase] "@test.com"`::
query matches user with email address ending with specific domain.

See different matching rules in the examples above.
There are different matching rules defined for PolyStringType (givenName) and strings (emailAddress).
List of all matching rules is defined in xref:../../matching-rules.adoc[matching rules] page.

==== String filters

[options="header", cols="15,40", width=70]
Expand Down
90 changes: 73 additions & 17 deletions docs/misc/notifications/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -631,9 +631,25 @@ Not available in expressionFilters.

== Expression Variables

[NOTE]
[TIP]
====
*You can also use shorter notation:*
Please refer to https://download.evolveum.com/midpoint/latest/midpoint-4.9-SNAPSHOT-javadoc/com/evolveum/midpoint/notifications/api/events/Event.html[Javadoc for com.evolveum.midpoint.notifications.api.events.Event] to learn about *all* possible variables.
The methods documented in Javadoc can be used in your expressions.
Other variables are defined for specific event types which are defined as subinterfaces of `Event` package.
====

// FIXME fix when macro is available, to point to specific Javadoc pages for support/master versions...
// FIXME for now, I will point to master as agreed with Igor 4.3.2024.
//Test: xref:/midpoint/#{ver}/midpoint-#{ver}javadoc/com/evolveum/midpoint/notifications/api/events/Event.html[]

//Test 2: https://download.evolveum.com/midpoint/#{ver}/midpoint-#{ver}-javadoc/com/evolveum/midpoint/notifications/api/events/Event.html[Event doc]

// Ver: #{ver} / {{ ver }}


In your expressions, `event` variable contains the whole event object.
Properties of `event` object can be accessed using Java calls, but both Groovy and Velocity allow short usage form:

.*Groovy*
* `event.channel` instead of `event.getChannel()`
Expand All @@ -652,84 +668,109 @@ Please refer to the following documentation for the shorter notation rules:
* *Groovy*: https://groovy-lang.org/objectorientation.html#properties
* *Velocity*: https://velocity.apache.org/engine/1.7/user-guide.html#property-lookup-rules

====

=== Expression Variables for Any Events

[%autowidth]
|===
|Usage in Groovy |Usage in Velocity template |Description
|Groovy (short) | Velocity (short) |Groovy (long)| Velocity (long)|Description

|event.channel
|$event.channel
|event.getChannel()
|$event.getChannel()
|Returns the channel for the event

|event.id
|$event.id
|event.getId()
|$event.getId()
|Returns randomly generated event ID

|event.requestee
|$event.requestee
|event.getRequestee()
|$event.getRequestee()
|Returns the entity that is the object of this event or the owner of the object (e.g. account) of this event

|event.requesteeName
|$event.requesteeName
|event.getRequesteeName()
|$event.getRequesteeName()
|Returns requestee's `name` property.

|event.requesteeDisplayName
|$event.requesteeDisplayName
|event.getRequesteeDisplayName()
|$event.getRequesteeDisplayName()
|Returns requestee's "display name", e.g. user's `fullName` property if it exists.

|event.requesteeObject
|$event.requesteeObject
|event.getRequesteeObject()
|$event.getRequesteeObject()
|Returns the entity that is the object of this event or the owner of the object (e.g. account) of this event

|event.requesteeOid
|$event.requesteeOid
|event.getRequesteeOid()
|$event.getRequesteeOid()
|Returns requestee's oid.

|event.requester
|$event.requester
|event.getRequester()
|$event.getRequester()
|Returns the entity that requested the operation that resulted in the event being generated.

|event.statusAsText
|$event.statusAsText
|event.getStatusAsText()
|$event.getStatusAsText()
|Returns the status of the event converted to text and uppercased, e.g. `SUCCESS`

|event.success
|$event.success
|event.isSuccess()
|$event.isSuccess()
|Returns true if the event resulted in success

|event.failure
|$event.failure
|event.isFailure()
|$event.isFailure()
|Returns true if the event resulted in failure

|===

TIP: You can find more possible expression variables by inspecting https://docs.evolveum.com/midpoint/devel/javadoc/[].
Search *Full Javadoc* for specific version and then search for
`com.evolveum.midpoint.notifications.api.events` to start with.
Other variables are defined for specific event types which are defined as subinterfaces of `Event` package.

Test: xref:/midpoint/#{ver}/midpoint-#{ver}javadoc/com/evolveum/midpoint/notifications/api/events/Event.html[]

Test 2: https://download.evolveum.com/midpoint/#{ver}/midpoint-#{ver}-javadoc/com/evolveum/midpoint/notifications/api/events/Event.html[Event doc]
=== Expression Variables Specific For Model Event

Ver: #{ver} / {{ ver }}
[TIP]
====
Please refer to https://download.evolveum.com/midpoint/latest/midpoint-4.9-SNAPSHOT-javadoc/com/evolveum/midpoint/notifications/api/events/ModelEvent.html[Javadoc for com.evolveum.midpoint.notifications.api.events.ModelEvent] to learn about *all* possible variables.
The methods documented in Javadoc can be used in your expressions.
=== Expression Variables Specific For Model Event
All variables for `Event` can be used as well.
====

[%autowidth]
|===
|Usage in Groovy |Usage in Velocity template | Description
|Groovy (short) | Velocity (short) |Groovy (long)| Velocity (long)|Description

|event.changeType
|$event.changeType
|event.getChangeType()
|$event.getChangeType()
|Returns change type (ADD, MODIFY, DELETE) from the event

|event.contentAsFormattedList
|$event.contentAsFormattedList
|event.getContentAsFormattedList()
|$event.getContentAsFormattedList()
|Returns formatted list of changes for this event. NOTE: The content is rendered in plain text and will not use any HTML formatting.

|event.focusPassword
|$event.focusPassword
|event.getFocusPassword()
|$event.getFocusPassword()
|Returns focal object password if known (e.g. during password generation)
Expand All @@ -738,17 +779,32 @@ Ver: #{ver} / {{ ver }}

=== Expression Variables Specific For ResourceObject Event

[TIP]
====
Please refer to https://download.evolveum.com/midpoint/latest/midpoint-4.9-SNAPSHOT-javadoc/com/evolveum/midpoint/notifications/api/events/ResourceObjectEvent.html[Javadoc for com.evolveum.midpoint.notifications.api.events.ResourceObjectEvent] to learn about *all* possible variables.
The methods documented in Javadoc can be used in your expressions.
All variables for `Event` can be used as well.
====

[%autowidth]
|===
|Usage in Groovy |Usage in Velocity template | Description
|Groovy (short) | Velocity (short) |Groovy (long)| Velocity (long)|Description

|event.changeType
|$event.changeType
|event.getChangeType()
|$event.getChangeType()
|Returns change type (ADD, MODIFY, DELETE) from the event

|event.contentAsFormattedList
|$event.contentAsFormattedList
|event.getContentAsFormattedList()
|$event.getContentAsFormattedList()
|Returns formatted list of changes for this event. NOTE: The content is rendered in plain text and will not use any HTML formatting.

|event.plaintextPassword
|$event.plaintextPassword
|event.getPlaintextPassword()
|event.getPlaintextPassword()
|Returns resource object password if known (e.g. during password generation)
Expand Down Expand Up @@ -783,6 +839,6 @@ Link any other expression documentation discussing variables?
If the configuration doesn't do what is expected, or seemingly does nothing at all, it may
be the right time to add some debug log messages for notifications and transport components.
In the xref:/midpoint/reference/concepts/system-configuration-object/[System Configuration],
add the logers for `NOTIFICATION` and `TRANSPORT` (predefined `LoggingComponentType`-s)
add the loggers for `NOTIFICATION` and `TRANSPORT` (predefined `LoggingComponentType`-s)
and set them to the `DEBUG` level.
This should provide additional information if the notification is skipped and why.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.evolveum.midpoint.prism.impl.PrismContainerValueImpl;
import com.evolveum.midpoint.prism.impl.delta.ContainerDeltaImpl;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.util.CloneUtil;
import com.evolveum.midpoint.schema.TaskExecutionMode;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.SimulationUtil;
Expand All @@ -33,6 +34,8 @@

import com.evolveum.midpoint.util.exception.SchemaException;

import com.evolveum.midpoint.util.exception.SystemException;

import com.google.common.base.Preconditions;
import org.apache.commons.lang3.BooleanUtils;
import org.jetbrains.annotations.NotNull;
Expand All @@ -45,10 +48,16 @@

import static com.evolveum.midpoint.util.MiscUtil.configCheck;

/** Effectively immutable (if constituent definitions are immutable). */
/**
* Definition of a usually multi-valued association item, e.g., `ri:group`.
*
* Effectively immutable (if constituent definitions are immutable), except for the ability of changing the {@link #maxOccurs}
* value.
*/
public class ShadowAssociationDefinition extends AbstractFreezable
implements Serializable, Visitable<Definition>, Freezable, DebugDumpable,
PrismContainerDefinition<ShadowAssociationValueType> {
PrismContainerDefinition<ShadowAssociationValueType>,
MutablePrismContainerDefinition.Unsupported<ShadowAssociationValueType> {

@Serial private static final long serialVersionUID = 1L;

Expand All @@ -64,11 +73,13 @@ public class ShadowAssociationDefinition extends AbstractFreezable

@NotNull private final ComplexTypeDefinition complexTypeDefinition;

private int maxOccurs = -1;

public ShadowAssociationDefinition(
@NotNull ResourceObjectAssociationType definitionBean,
@NotNull ResourceObjectTypeDefinition associationTarget,
@NotNull Object errorCtx) throws ConfigurationException {
this.definitionBean = definitionBean;
this.definitionBean = CloneUtil.toImmutable(definitionBean);
this.associationTarget = associationTarget;
this.complexTypeDefinition = createComplexTypeDefinition();
this.associationAttributeName = MiscUtil.configNonNull(
Expand Down Expand Up @@ -367,7 +378,13 @@ public int getMinOccurs() {

@Override
public int getMaxOccurs() {
return -1;
return maxOccurs;
}

@Override
public void setMaxOccurs(int value) {
checkMutable();
maxOccurs = value;
}

@Override
Expand Down Expand Up @@ -471,8 +488,19 @@ public List<PrismPropertyDefinition<?>> getPropertyDefinitions() {
}

@SuppressWarnings("MethodDoesntCallSuperMethod")
public ShadowAssociationDefinition clone() {
return this;
public @NotNull ShadowAssociationDefinition clone() {
try {
ShadowAssociationDefinition clone =
new ShadowAssociationDefinition(definitionBean, associationTarget, "");
copyDefinitionDataFrom(clone);
return clone;
} catch (ConfigurationException e) {
throw SystemException.unexpected(e, "(during cloning - unexpected because the configuration should be OK");
}
}

private void copyDefinitionDataFrom(ShadowAssociationDefinition source) {
maxOccurs = source.maxOccurs;
}

@Override
Expand Down Expand Up @@ -501,8 +529,9 @@ public boolean canRepresent(@NotNull QName type) {
}

@Override
public MutablePrismContainerDefinition<ShadowAssociationValueType> toMutable() {
throw new UnsupportedOperationException();
public ShadowAssociationDefinition toMutable() {
checkMutableOnExposing();
return this;
}

@Override
Expand Down

0 comments on commit 6758d7a

Please sign in to comment.