filters and filter strings

Download Filters and Filter Strings

If you can't read please download the document

Upload: bradders60

Post on 30-Oct-2015

902 views

Category:

Documents


62 download

TRANSCRIPT

  • Filters and Filter Strings

    This document describes specification of filter strings and Filter objects. Filters restrict the results of queries or

    constrain system actions to sets of objects that meet the filter criteria.

  • Filters and Filter Strings Page 2 of 22

    Copyright 2012 SailPoint Technologies, Inc., All Rights Reserved.

    SailPoint Technologies, Inc. makes no warranty of any kind with regard to this manual, including, but not limited to, the implied

    warranties of merchantability and fitness for a particular purpose. SailPoint Technologies shall not be liable for errors contained herein or

    direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance, or use of this material.

    Restricted Rights Legend. All rights are reserved. No part of this document may be photocopied, reproduced, or translated to another

    language without the prior written consent of SailPoint Technologies. The information contained in this document is subject to change

    without notice.

    Use, duplication or disclosure by the U.S. Government is subject to restrictions as set forth in subparagraph (c) (1) (ii) of the Rights in

    Technical Data and Computer Software clause at DFARS 252.227-7013 for DOD agencies, and subparagraphs (c) (1) and (c) (2) of the

    Commercial Computer Software Restricted Rights clause at FAR 52.227-19 for other agencies.

    Regulatory/Export Compliance. The export and reexport of this software is controlled for export purposes by the U.S. Government. By

    accepting this software and/or documentation, licensee agrees to comply with all U.S. and foreign export laws and regulations as they

    relate to software and related documentation. Licensee will not export or reexport outside the United States software or documentation,

    whether directly or indirectly, to any Prohibited Party and will not cause, approve or otherwise intentionally facilitate others in so doing.

    A Prohibited Party includes: a party in a U.S. embargoed country or country the United States has named as a supporter of international

    terrorism; a party involved in proliferation; a party identified by the U.S. Government as a Denied Party; a party named on the U.S.

    Government's Entities List; a party prohibited from participation in export or reexport transactions by a U.S. Government General Order;

    a party listed by the U.S. Government's Office of Foreign Assets Control as ineligible to participate in transactions subject to U.S.

    jurisdiction; or any party that licensee knows or has reason to know has violated or plans to violate U.S. or foreign export laws or

    regulations. Licensee shall ensure that each of its software users complies with U.S. and foreign export laws and regulations as they relate

    to software and related documentation.

    Trademark Notices. Copyright 2012 SailPoint Technologies, Inc. All rights reserved. SailPoint, the SailPoint logo, SailPoint IdentityIQ,

    and SailPoint Identity Analyzer are trademarks of SailPoint Technologies, Inc. and may not be used without the prior express written

    permission of SailPoint Technologies, Inc. All other trademarks shown herein are owned by the respective companies or persons

    indicated.

  • Filters and Filter Strings Page 3 of 22

    Table of Contents Introduction ............................................................................................................................................................. 4

    Filter Strings ............................................................................................................................................................. 5

    Property Specification .......................................................................................................................................... 5

    Multi-valued Identity and Account Attributes .................................................................................................. 5

    Datatype-Specific Syntax .................................................................................................................................. 6

    Evaluation Operations .......................................................................................................................................... 6

    Basic Operators ................................................................................................................................................ 6

    Method Operators............................................................................................................................................ 8

    Complex Query Method Operators .................................................................................................................. 8

    Grouping of Evaluations ....................................................................................................................................... 9

    Filter Objects .......................................................................................................................................................... 11

    Operator Methods ............................................................................................................................................. 11

    Basic Operator Methods................................................................................................................................. 11

    Complex Operator Methods ........................................................................................................................... 12

    Filter Modifiers ............................................................................................................................................... 13

    Filter Builder Helper Class .............................................................................................................................. 13

    Adding Multiple Filter Conditions to a Filter Object ........................................................................................... 15

    Adding a Single Criterion ................................................................................................................................ 15

    Adding Filters with And .................................................................................................................................. 15

    Adding Filters with Or ..................................................................................................................................... 16

    Adding Filters with Different Relationships .................................................................................................... 16

    QueryOptions Objects ............................................................................................................................................ 18

    Adding a Filter to QueryOptions ......................................................................................................................... 18

    Passing QueryOptions to a SailPointContext Method ........................................................................................ 19

    Other Commonly Used QueryOptions/SailPointContext Features ..................................................................... 20

    Ordering with QueryOptions .......................................................................................................................... 20

    Counting Objects with QueryOptions and SailPointContext........................................................................... 21

  • Filters and Filter Strings Page 4 of 22

    Introduction

    Filters are used in many places throughout IdentityIQ to allow actions to be applied to a subset of system

    objects. IdentityIQ contains a Filter object that includes a set of methods for structuring a filtering request.

    Many areas of IdentityIQs user interface support specification of a filter string that can be turned into a Filter

    object by the system. The Filter object is then used to restrict the system action to only objects that match the

    criteria specified in the filter string.

    Database queries are executed through the SailPointContext object. Options applicable to each query (including

    filters, ordering, grouping, etc.) are specified in a QueryOptions object. The filter option in a QueryOptions

    object is specified as a Filter object. To execute a query based on a Filter object, create a Filter object, add that

    Filter to a QueryOptions object, and specify that QueryOptions object in the SailPointContext method call that

    executes the query. When a filter string is entered in the UI, all of these steps are done automatically behind

    the scenes. When a query is run from a rule, all of these must be explicitly specified in the rule logic.

    This document covers the specifics of writing filter strings, building Filter objects, and adding filters to a

    QueryOptions object. It includes example code to show how a query is executed from a rule through a

    SailPointContext object.

  • Filters and Filter Strings Page 5 of 22

    Filter Strings

    In the IdentityIQ user interface, filters can be specified as filter strings that are then compiled by the filter

    compiler to create a Filter object.

    Some examples of places where filter strings can be specified include:

    In the Attributes section of some Application Definitions (LDAP, ADAM) (Iterate Search Filter)

    On Lifecycle Events (Identity filter)

    On certain Tasks (Data Export, Identity Refresh, Policy Scan)

    On the Advanced Analytics window (Advanced Search option on Identity Search)

    The filter compiler interprets a specific grammar whose syntax resembles Java. Its basic rules are:

    String literals must be in double quotes (e.g. department == Accounting)

    True/false (no quotes) are treated as Boolean literals (e.g. isActive == true)

    Numeric digits (no quotes) are treated as numbers

    Fully-qualified constants are resolved to enums (e.g. type == CertificationItem.Type.Exception)

    Everything else is assumed to be the property name

    Property Specification

    Only persistent properties in the object model can be specified in the query filter. In general, these are the

    properties available through the public get and set methods shown in the IdentityIQ Javadocs that ship with

    the product. The property names to specify match the method names without the get/set prefix. For

    example, the first name property is accessible through the getFirstname() method, so the property for the

    filter string would be firstname (the first letter of the property name is always lowercase; the rest matches the

    camel case of the method name). Attributes of objects contained within the Identity object can be queried with

    the object.attribute syntax (e.g. bundles.name or links.application.name).

    Multi-valued Identity and Account Attributes

    Most multi-valued attributes in the system can be queried directly through method operators (described in the

    Method Operators section below), but multi-valued Identity Attributes and Account Attributes are special cases

    that require a slightly more complex query syntax to access. The multi-valued Identity attributes can be

    accessed through the IdentityExternalAttribute object, and multi-valued Account attributes can be queried

    through the LinkExternalAttribute object using this syntax:

    IdentityExternalAttribute.collectionCondition(

    "((id.join(IdentityExternalAttribute.objectId) &&

    IdentityExternalAttribute.attributeName i== \"IdentityAttributeName\" &&

    IdentityExternalAttribute.value.startsWith(\"attributevalue\")

    ))"

    )

    or

  • Filters and Filter Strings Page 6 of 22

    LinkExternalAttribute.collectionCondition(

    "((links.id.join(LinkExternalAttribute.objectId) &&

    LinkExternalAttribute.attributeName i== \"AccountAttributeName\" &&

    LinkExternalAttribute.value.startsWith(\"attributevalue\")

    ))"

    )

    Example:

    IdentityExternalAttribute.collectionCondition("

    ((id.join(IdentityExternalAttribute.objectId) &&

    IdentityExternalAttribute.attributeName i== \"costcenter\" &&

    IdentityExternalAttribute.value.startsWith(\"R01e\")

    ))"

    )

    The component statements in these queries (specifically, collectionCondition and join) are further described in

    the Complex Query Method Operators section of this document.

    Datatype-Specific Syntax

    The table below indicates the syntax required to add filters of various data types to the filter source.

    Field Data Types Structure Example

    String value department == Accounting

    Numeric value location DATE$1318884600000

    Char (single character) value middleInitial == D

    Float Value (floating point literal) average < 250.144

    Enumeration EnumName.EnumValue Type == CertificationItem.Type.Exception

    NOTE: The IdentityIQ object model currently has no persistent Char or Float fields, and it is rare for

    Enumerations to be queried through these pages. Those three data types are included here primarily as

    interesting information.

    Evaluation Operations

    Basic Operators

    Object attributes can be evaluated against a specified value (or another field) using the basic equality/inequality

    operators, expressed like Java equality/inequality statements:

    Operation Operator Symbol Example

    Equal == department == "Accounting"

    Not equal != region != "Europe"

    Less than < scorecard.compositeScore < 300

    Greater than > scorecard.compositeScore > 900

  • Filters and Filter Strings Page 7 of 22

    Less than or equal to = 10

    Greater than or equal to >= tenure

  • Filters and Filter Strings Page 8 of 22

    Method Operators

    These methods can be specified on the comparison attributes to invoke additional evaluation options:

    Method Operator Description Example

    in() inIgnoreCase()

    Propertys value is one of the specified string values

    department.in({"Accounting",

    "Finance"})

    containsAll()* ** containsAllIgnoreCase()* **

    Property is a multi-valued field that contains all the values listed (field must be a list of normal datatypes, not objects)

    certification.certifiers.con

    tainsAll({"Mark.Smith","Susa

    n.Jones"})

    isNull() Propertys value is null manager.isNull()

    notNull() Propertys value is not null region.notNull()

    isEmpty()* Multi-valued property is empty controlledScopes.isEmpty()

    startsWith() startsWithIgnoreCase()

    Property starts with the specified string value

    location.startsWith("Lon")

    endsWith() endsWithIgnoreCase()

    Property ends with the specified string value

    jobTitle.endsWithIgnoreCase(

    "Clerk")

    contains() containsIgnoreCase()

    Property contains the specified string value somewhere within it

    phone.contains("-454-")

    *These methods can be used with standard multi-valued attributes; multi-valued extended Identity Attributes

    and Account Attributes cannot use these methods and must instead use a collectionCondition query as

    illustrated in Multi-valued Identity and Account Attributes above.

    ** ContainsAll() and containsAllIgnoreCase() cannot currently be used on Identity filters in the UI. This is

    because all of the pre-configured multi-valued Identity attributes are objects (so the property values cannot be

    specified in string format for the comparison) and all custom configured multi-valued Identity attributes must be

    accessed through the IdentityExtendedAttributes object using the collectionCondition syntax.

    NOTE: Queries using the contains() and endsWith() methods may be slow performing.

    Complex Query Method Operators

    Complex query filters can be specified using these additional method operators. They are specified on the

    comparison attributes just like the method operators discussed in the previous section.

    Method Operator Description and Examples

    join (joinProperty) Creates a connection between two objects based on the named properties NOTE: JoinProperty is case sensitive; the object name must be capitalized. Likewise, any additional criteria that apply to the second object must be prefixed by the (case-sensitive) object name.

    Example: department.join(Bundle.name) && Bundle.owner.name ==

    "Walter.Henderson"

    This is an identity search filter that joins to the Bundle object based on the Identitys department. It returns only Identities who are assigned to a department with a correspondingly named role that is owned by Walter

  • Filters and Filter Strings Page 9 of 22

    Henderson.

    collectionCondition (compound filter string)

    Allows a separate filter string to be specified that will be executed against the specified property. This is useful when a multi-valued property is another object, such as Link, and multiple query criteria need to be imposed against attributes of that object to find the ones that should be used as filters against the primary object

    Example: Query for Identities with a privileged AD account

    links.collectionCondition("application.name == \"AD\" &&

    privileged == \"true\"")

    This query cannot be specified with separate statements because links.application.name == AD && links.privileged == true would return any Identity who has any account on AD and any account that is privileged. For example, if Joe.Smith has a privileged account on RACF and a normal account on AD, he would still be in the return set from the normal anded statements but would not be returned from the collectionCondition query.

    NOTE: The entire condition must be expressed in quotes, and any quotes required within the condition must be escaped (\). The collectionCondition() method only applies and only works when the filter condition is a compound filter string (more than one condition is specified using && or ||).

    subquery (objectName, attribute name, subquery filter string)

    Subquery runs a specified query on a secondary object, connected to the primary object by the property name and the secondary objects specified property. NOTE: ObjectName is case sensitive, and both the attribute name and subquery filter string must be specified in quotes. Quotes within the subquery filter string must be escaped (\).

    Example: department.subquery(sailpoint.object.Bundle, "name",

    "owner.name i== \"Walter.Henderson\"")

    This is another way of expressing the same filter that was described in the join method above.

    Grouping of Evaluations

    Evaluations can be grouped in sets using and or or operators. These are expressed in the filter string syntax

    with && and || respectively. Additionally, parentheses can be used to enforce a hierarchy to the grouping

    operations. Any condition can be negated by specifying ! before the parentheses.

    Example Statements Evaluation Explanation

    department == Accounting || department.isNull() Returns all Identities who are assigned to the Accounting department or who have no assigned department value (null department attribute)

    (department == Accounting || department.isNull()) && manager.name == Adam.Smith

    Returns all Identities who report to manager Adam Smith and who are either in the Accounting

  • Filters and Filter Strings Page 10 of 22

    department or have no assigned department

    department == Accounting || (department.isNull() && manager.name == Adam.Smith)

    Returns all Identities who are either in the Accounting department or who report to Adam Smith and have no department value assigned

    !(department == Accounting) Returns all Identities who are in any department other than Accounting (i.e. not in Accounting)

  • Filters and Filter Strings Page 11 of 22

    Filter Objects

    A Filter object represents a set of query criteria, which can range from a simple, single condition to the most

    complex set of conditions that can be expressed in a SQL where clause. A Filter object is built by adding each

    of the required filter conditions to it. Each condition is specified through the appropriate operator method, and

    multiple filters are connected to each other using the and and or methods.

    Operator Methods

    Operator methods are used to specify each condition in the filter. They represent the basic evaluation options

    available on a SQL query.

    Basic Operator Methods

    The signature for the operators in this table is [methodName](String propertyName, Object value) (e.g.

    eq(propertyName, value)). The like() method can use this signature or can include specification of a third

    matchMode parameter, as shown.

    Operator Method Description Example

    eq () Checks that the given property is equal to the given value

    Filter.eq("name", myName)

    ne() Checks that the given property is not equal to the given value

    Filter.ne("owner", myIdentity)

    lt(), le() Checks that the given property is less than / less than or equal to the given value

    Filter.lt("scorecard.compositeScore", maxRiskThreshold)

    gt(), ge() Checks that the given property is greater than / greater than or equal to the given value

    Filter.ge("scorecard.compositeScore", riskTolerance)

    like(propertyName, value) or like(propertyName, value, matchMode)

    Checks that the given property contains the value as a substring; location in the string is restricted by matchMode if provided. Possible matchModes are START, END, EXACT (equivalent to equals), and ANYWHERE (default if omitted)

    Filter.like("region", "America") Filter.like("application.name", "Enterprise", Filter.MatchMode.START)

    The signature for the operators in the table below is [methodName](String propertyName, Collection value)

    (e.g. in(propertyName, value)).

    Operator Method Description Example*

    in() Checks that the given property has a value within the given set of values

    Filter.in("region", regions)

    containsAll() Checks that the given multi-valued property contains all the given values

    Filter.containsAll("certifiers", certifiers)

    *Regions and certifiers, in these examples, are Collections of strings.

  • Filters and Filter Strings Page 12 of 22

    The signature for the following operators is [methodName](String propertyName) (e.g. notNull(region)).

    Operator Method Description Example

    notnull() Checks that the given property value is non-null

    Filter.notnull("manager")

    isnull() Checks that the given propertys value is null Filter.isnull("department")

    isempty() Checks that the given multi-valued property is empty

    Filter.isempty("controlledScopes")

    NOTE: Multi-valued Identity and Account (Link) Extended Attributes cannot be accessed through the

    containsAll() and isEmpty() methods because of the way these values are stored. A helper class

    ExternalAttributeFilterBuilder has been created to assist in building the required filter syntax for accessing

    these attributes. See Filter Builder Helper Class for more information.

    Complex Operator Methods

    These operator methods are used to specify more complex conditions in the filter.

    join() is used when a condition needs to be checked on a separate object and the only available

    reference to the second object is through an ID or other matching property, as opposed to a direct

    reference; it is usually specified in conjunction with another criterion that evaluates an attribute on the

    second object.

    collectionCondition() can be used to apply a compound filter to a second object that is available through

    a direct reference; for example, it can be used to specify match conditions for both the department and

    region for the selected identities manager.

    subquery() functions similarly to Join in that it allows a condition to be checked on a separate object

    connected to the central object through a single value; the primary differences is that multiple

    subqueries can be performed on the same table while a join can only be done once per filter.

    Method Operator Description and Examples

    join(String property, String joinProperty)

    Creates a connection between two objects based on the named properties; property is the name of the attribute on the primary object and joinProperty is the fully-qualified property name to join to on the second object.

    Example: Filter.join("department", "Bundle.name")

    This joins to the Bundle object based on its name matching the (Identitys) department.

    collectionCondition (String property, Filter compoundFilter )

    Allows a separate filter string to be specified that will be executed against the specified property. This is useful for a multi-valued property that is another object, such as Link, when multiple query criteria need to be imposed against attributes of that object to find the ones that should be used as filters against the primary object.

    Example: Filter adPrivileged = Filter.and(Filter.eq("application.name", "AD"),

    Filter.eq("privileged", "true"));

    Filter.collectionCondition("links", adPrivileged);

    This example returns Identities with a privileged AD account. Stating these criteria together in a collection condition prevents Identities with a non-privileged AD account but a privileged account on another system from being returned from the query.

  • Filters and Filter Strings Page 13 of 22

    NOTE: This method only applies and only works when the filter specified is a compound filter (involving an and or or condition). NOTE: If any Identity has more than one account on the application and one of them is privileged, this will return that Identitys name twice. To get only one returned record per Identity, use the setDistinct() method on the QueryOptions object to which this filter is added (e.g. qo.setDistinct(true)).

    subquery(String property, Class subqueryClass, String subqueryProperty, Filter subqueryFilter)

    Subquery runs a specified query on a secondary object, connected to the primary object by the property name and the secondary objects specified property.

    Example: Filter.subquery("department", Bundle.class, "name",

    Filter.ignoreCase(Filter.eq("owner.name", "Walter.Henderson")))

    This joins to the Bundle object based on its name matching the (Identitys) department; the subquery restricts the result set to only Bundles that are owned by Walter.Henderson, so the returned set of Identities from this filter would all be in departments with matching roles that are owned by Walter.Henderson.

    Filter Modifiers

    These two methods on the Filter object modify the Filter object specified as a parameter. Their signatures look

    like: [methodName](Filter filter) (e.g. not(oldFilter)).

    Operator Method Description Example

    not() Negates the specified filter Filter.not(oldFilter)

    ignoreCase() Applies case-insensitivity to the specified filter

    Filter.ignoreCase(Filter.eq(department, accounting)

    Filter Builder Helper Class

    The filter object syntax for accessing multi-valued Identity and account (Link) extended attributes parallels the

    filter string syntax discussed in the filter strings Multi-valued Identity and Account Attributes section. It uses the

    collectionCondition and join methods to connect from the Identity object to its IdentityExternalAttribute entries

    (or Link to LinkExternalAttribute).

    It is possible to build this syntax manually to query these fields. However, SailPoint has provided a helper class

    for specifying these filters that makes it a little less cumbersome. That class is ExternalAttributeFilterBuilder.

    NOTE: In a rule, you must import sailpoint.search.ExternalAttributeFilterBuilder to use this classs methods.

    All of these methods automatically create the required join from the primary table (Identity or Link) to the

    named table (tableName) based on a match between the connecting ID field on the primary object

    (joinProperty) and the objectID attribute on the named table. (The named table will either be

    IdentityExternalAttribute or LinkExternalAttribute.) Both the buildAndFilter() and buildOrFilter() methods

    provide two signatures: one with the final op parameter and one without it. If the op parameter is specified as

    EQ, it forces the comparison to attrName to be an equals evaluation instead of a starts with evaluation; if it is

    omitted or is anything other than EQ, starts with is used.

  • Filters and Filter Strings Page 14 of 22

    ExternalAttributeFilterBuilder Method Usage / Description

    public static Filter buildAndFilter(String tableName, String joinProperty, String attrName, List values, [String op])

    Looks for Identities (or Links) that have records containing all of the values in the list for the named attribute (attrName). Replicates a containsAll comparison. NOTE: The values list may contain as many or as few attribute values as should be in the containsAll list, so this can be used to look for one or more values.

    public static Filter buildOrFilter(String tableName, String joinProperty, String attrName, List values, [String op])

    Looks for Identities (or Links) that have records containing any of the values in the list for the named attribute (attrName). NOTE: Introducing multiple joins during an OR operation will have a negative impact on performance.

    public static Filter buildNullFilters(String tableName, String joinProperty, String attrName)

    Looks for Identities (or Links) with no value for the named attribute (attrName).

    public static Filter buildNotNullFilters(String tableName, String joinProperty, String attrName)

    Looks for Identities (or Links) with any non-null value in the named attribute (attrName).

    This example shows the syntax for manually building a Filter object that mimics a containsAll(R01e, L01e)

    condition for the multi-valued Identity extended attribute costcenter:

    Filter f = Filter.and(Filter.join("id", "IdentityExternalAttribute.objectId"),

    Filter.eq("IdentityExternalAttribute.attributeName", "costcenter"));

    f = Filter.and(f, Filter.eq("IdentityExternalAttribute.value", "R01e"));

    Filter f2 = Filter.and(Filter.join("id", "IdentityExternalAttribute.objectId"),

    Filter.eq("IdentityExternalAttribute.attributeName", "costcenter"));

    f2 = Filter.and(f2, Filter.eq("IdentityExternalAttribute.value", "L01e"));

    f = Filter.and(f, f2);

    Filter containsAll = Filter.collectionCondition("IdentityExternalAttribute", f);

    This example uses the buildAndFilter() method to create the same containsAll(R01e, L01e) filter:

    Filter containsAll = ExternalAttributeFilterBuilder.buildAndFilter("IdentityExternalAt

    tribute", "id", "costcenter", Util.csvToList("R01e, L01e"), "EQ");

    Constants are defined in the ExternalAttributeFilterBuilder class that can be used in these method calls if

    preferred.

    Constant Value Usage

    IDENTITY_EXTERNAL IdentityExternalAttribute Specifies tableName for Identity join

    IDENTITY_JOIN id Specifies joinProperty for Identity join

    LINK_EXTERNAL LinkExternalAttribute Specifies tableName for Link join

    LINK_JOIN links.id Speicfies joinProperty for Link join

    This example shows the same buildAndFilter() method call using the defined constants.

  • Filters and Filter Strings Page 15 of 22

    Filter containsAll = ExternalAttributeFilterBuilder.buildAndFilter(ExternalAttributeFi

    lterBuilder.IDENTITY_EXTERNAL, ExternalAttributeFilterBuilder.IDENTITY_JOIN, "costcent

    er", Util.csvToList("R01e, L01e"), "EQ");

    Adding Multiple Filter Conditions to a Filter Object

    One or more filter conditions will be specified in any Filter object. Filter conditions can be added to the Filter

    object one at a time or several all at once, depending on the query criteria being specified. Some extremely

    complex combinations of and and or relationships are best added piecemeal for readability of the code

    being executed, but most criteria that relate to each other exclusively through and or exclusively through or

    can be added to the Filter all at one time.

    Each method used to add criteria to a filter returns the Filter object including the newly added condition.

    Complex criteria can be built into a filter by adding more conditions to an existing Filter object. This is most

    easily understood by exploring it through examples.

    Adding a Single Criterion

    If only a single filter condition is being used, it is simply specified through its operator method. For example,

    consider a query that will retrieve an AccountGroup based on an application name, reference attribute, and

    native identity that are all known (and stored in variables myApp, myRefAttr, and myNativeIdent). Start with a

    basic filter that could return multiple account groups, based solely on the application:

    Filter myFilter = Filter.eq("application.name", myApp);

    Adding Filters with And

    A second filter condition can be added to this existing filter using this syntax:

    myFilter = Filter.and(myFilter, Filter.eq("referenceAttribute", myRefAttr));

    This can be repeated as many times as necessary to append additional and conditions.

    myFilter = Filter.and(myFilter, Filter.eq("referenceAttribute", myRefAttr));

    myFilter = Filter.and(myFilter, Filter.ignoreCase(Filter.eq("nativeIdentity",

    myNativeIdent)));

    Notice that an existing Filter object can have additional criteria added to it without having to create a new Filter

    object to hold the combined criteria. It is also possible to create a separate new Filter object as additional

    criteria are added; this can be useful if the original criterion is still needed as a stand-alone Filter.

    Filter newFilter = Filter.and(myFilter, Filter.eq("referenceAttribute", myRefAttr));

    The and() method offers another signature that can accept a List of Filter objects like this:

    List filters = new ArrayList ();

    filters.add(myFilter);

    filters.add(Filter.eq("referenceAttribute", myRefAttr));

    filters.add(Filter.ignoreCase(Filter.eq("nativeIdentity", myNativeIdent)));

    myFilter = Filter.and(filters);

  • Filters and Filter Strings Page 16 of 22

    In custom Java code, multiple filters can be added to an and grouping at one time. This cannot be used in a

    rule since beanshell cannot process methods with variable arguments.

    myFilter = Filter.and(myFilter,

    Filter.eq("referenceAttribute", myRefAttr),

    Filter.ignoreCase(Filter.eq("nativeIdentity", myNativeIdent)));

    However, beanshell can use the array syntax to add multiple conditions to the filter in a single statement like

    this:

    myFilter = Filter.and(new Filter[] { myFilter,

    Filter.eq("referenceAttribute", myRefAttr),

    Filter.ignoreCase(Filter.eq("nativeIdentity", myNativeIdent)) });

    This builds the 3 filter conditions into an array and passes the array to the and method.

    Adding Filters with Or

    The or syntax mirrors the and, offering the same signatures: two Filter objects, a List of Filter objects, and

    (for custom Java code only, not beanshell) a variable number of Filter objects. Examples are shown below.

    Two Filters: Filter f = Filter.or(Filter.eq("bundles.id", roleId), Filter.eq("assignedRoles.id", roleId));

    List of Filters: List appsList = new ArrayList(); for (String app : includedAppIds) {

    appsList.add(Filter.eq("links.application.id", app));

    }

    Filter f = (Filter.or(appsList));

    Multiple Filters (Java only): Filter f = Filter.or(Filter.ne("department", "Accounting"), Filter.like("firstname","A,Filter.MatchMode.START),

    Filter.eq("region", myRegion));

    Multiple Filters (beanshell): Filter f1 = Filter.or(new Filter[] { Filter.ne("department","Accounting"),

    Filter.like("firstname","A",Filter.MatchMode.START),

    Filter.eq("region","Europe") });

    Adding Filters with Different Relationships

    Filter specification gets a little more complicated when some conditions are ord together while others are

    anded. The way to do this is to specify the more closely tied filter conditions into one filter together first and

    then add the combination filter to the more loosely associated criteria.

    For example, consider these query criteria for selecting an Identity (written in pseudocode):

    (Last Name = Smith) OR (Department = Finance AND Manager = Catherine.Simmons)

    The Department and Manager components jointly identify a single selection criterion so they must be grouped

    in a filter first. That filter can then be grouped with the Last Name component.

    Filter f = Filter.and(Filter.eq("department", "Finance"),

  • Filters and Filter Strings Page 17 of 22

    Filter.eq("manager.name", "Catherine.Simmons"));

    f = Filter.or(f, Filter.eq("lastname","Smith"));

    Alternatively, this can be expressed in a single statement, as shown below.

    Filter f = Filter.or(

    Filter.and(Filter.eq("department", "Finance"),

    Filter.eq("manager.name", "Catherine.Simmons")),

    Filter.eq("lastname", "Smith"));

    Complex filter criteria may require more statements to build them into a Filter object. It is a good practice to

    minimize the complexity of each statement for readability and maintainability.

  • Filters and Filter Strings Page 18 of 22

    QueryOptions Objects

    The QueryOptions object contains a variety of options that can affect the running of a query. Methods on the

    QueryOptions object allow specification of:

    Filter objects to restrict the results

    Attributes for ordering and grouping the returned results

    Options for ignoring case or requiring distinct results

    Limits on the number of records to return

    Location in an ordered list of the first record to return (used for paged results)

    Instructions on whether to apply configured scoping to the query and on how to extend scopes

    A pre-written HQL (Hibernate) query (supersedes any Filters specified)

    The methods for these specifications are outlined in the IdentityIQ Javadocs. More information on the Scoping-

    related options is provided in the Scoping technical white paper on Compass. The Filter-specific methods are

    further discussed below.

    Adding a Filter to QueryOptions

    Filters can be added to QueryOptions through its addFilter() method.

    QueryOptions ops = new QueryOptions();

    ops.addFilter(Filter.eq("application.name", myApp));

    The filter can be built as it is added to the QueryOptions object, as shown above, or it can be built first and

    added after it is complete.

    Filter myFilter = Filter.and(Filter.eq("application.name", myApp),

    Filter.eq("referenceAttribute", myRefAttr));

    QueryOptions ops = new QueryOptions();

    ops.addFilter(myFilter);

    When multiple separate filters are added to one QueryOptions object, they are anded together when the

    query runs.

    QueryOptions qo = new QueryOptions();

    qo.addFilter(Filter.eq("application.name", myApp));

    qo.addFilter(Filter.eq("referenceAttribute", myRefAttr));

    Custom java code can use the QueryOptions constructor or its add() method to add one or more filters. Rules

    cannot use these because beanshell cannot process variable arguments.

    QueryOptions ops = new QueryOptions(Filter.eq("application.name", myApp));

    or

    QueryOptions qo = new QueryOptions();

    qo.add(Filter.eq("application.name", myApp), Filter.eq("referenceAttribute",

    myRefAttr));

  • Filters and Filter Strings Page 19 of 22

    Multiple filters can be added at one time to a QueryOptions object in beanshell by building a list of filters and

    using the setFilters() method. This replaces any existing filters in the QueryOptions object.

    List filters = new ArrayList();

    filters.add(Filter.eq("application.name", myApp));

    filters.add(Filter.eq("referenceAttribute", myRefAttr));

    QueryOptions qo = new QueryOptions();

    qo.setFilters(filters);

    Passing QueryOptions to a SailPointContext Method

    Once all the desired options are included in the QueryOptions object, the query can be executed. All IdentityIQ

    rules include a parameter called context that is a SailPointContext object. SailPointContext offers two different

    methods for executing queries, both of which take a QueryOptions object as a parameter.

    SailPointContext Method Description

    public Iterator search (Class cls, QueryOptions options, List properties)

    Returns an iterator of the requested properties from the objects matching the query e.g. context.search(Identity.class, qo, id, name) returns an iterator of the ids and names from the Identity objects matching the query terms in the qo QueryOptions object

    public List getObjects (Class cls, QueryOptions options)

    Returns a list of objects (of the specified class) matching the query criteria

    The example below queries for an accountGroup object based on the specified filter and prints the names of all

    the returned account groups.

    import sailpoint.object.*;

    String myApp = "ADAM";

    String myRefAttr = "groups";

    Filter myFilter = Filter.and(Filter.eq("application.name", myApp),

    Filter.eq("referenceAttribute", myRefAttr));

    QueryOptions qo = new QueryOptions();

    qo.addFilter(myFilter);

    List myAcctGrps = context.getObjects(AccountGroup.class, qo);

    if (null != myAcctGrps) {

    for (AccountGroup acctGrp : myAcctGrps) {

    System.out.println("Account Group Name = "+ acctGrp.getName());

    // You have to be careful with other code, but this can be

    // important for performance.

    context.decache();

    }

    }

    NOTE: It is a best practice, for performance reasons, to decache occasionally when looping over a large number

    of objects.

  • Filters and Filter Strings Page 20 of 22

    This next example uses the contexts search method to return an iterator that contains the names of the

    account groups, rather than a list of full objects, and then prints those names.

    import sailpoint.object.*;

    String myApp = "ADAM";

    String myRefAttr = "groups";

    Filter myFilter = Filter.and(Filter.eq("application.name", myApp),

    Filter.eq("referenceAttribute", myRefAttr));

    QueryOptions qo = new QueryOptions();

    qo.addFilter(myFilter);

    List props = new ArrayList();

    props.add("name");

    Iterator names = context.search(AccountGroup.class, qo, props);

    if (null != names) {

    while (names.hasNext()) {

    String name = (String) names.next()[0];

    System.out.println("Account Group name = " + name);

    }

    }

    NOTE: It is a best practice to avoid breaking out of loops when iterating over search results. Doing so can leave

    open database cursors. Two examples of what not to do are shown below.

    // Dont do this!

    Boolean quitLooping = false;

    if (null != names && !quitLooping) {

    while (names.hasNext()) {

    String name = (String) names.next()[0];

    System.out.println("Account Group name = " + name);

    // Do not break out of a loop before getting

    // to the end of the search results like this.

    if (Special Group.equals(name)) {

    break;

    }

    // Do not break out using a loop condition like this either.

    if (Special Group.equals(name)) {

    quitLooping = true;

    }

    }

    }

    Other Commonly Used QueryOptions/SailPointContext Features

    Ordering with QueryOptions

    After filters, ordering is one of the most frequently used features of QueryOptions. This is an example of the Java

    code that applies ordering to a search. This example orders results by lastname, then firstname, then ID.

  • Filters and Filter Strings Page 21 of 22

    List ordering = new ArrayList();

    ordering.add(new QueryOptions.Ordering("lastname", true));

    ordering.add(new QueryOptions.Ordering("firstname", true));

    ordering.add(new QueryOptions.Ordering("id", true));

    QueryOptions queryOps = new QueryOptions();

    queryOps.setOrderings(ordering);

    Like filters, ordering can only be based on persistent object attributes.

    Counting Objects with QueryOptions and SailPointContext

    It can often be helpful to get a count of objects returned by a set of query criteria. A built-in method in the

    SailPointContext countObjects makes that easy to do. CountObjects signature is:

    public int countObjects (Class cls, QueryOptions options)

    The code below illustrates how to pass a queryOptions object to this method; the method returns an integer

    count of the objects meeting the criteria in that queryOptions.

    QueryOptions qo = new QueryOptions();

    // ... add filters to the query options as described above ...

    int total = ctx.countObjects(CertificationItem.class, qo);

    // total now contains the number of records returned by the query.

  • Filters and Filter Strings Page 22 of 22

    Document Revision History

    Revision Date Written/Edited By Comments

    July 2012 Jennifer Mitchell Initial Creation; current IdentityIQ version: 5.5p4