[OPENAM-5623] CTS uses inefficient search for coreTokenId= Created: 05/Mar/15  Updated: 20/Nov/16  Resolved: 12/Mar/15

Status: Resolved
Project: OpenAM
Component/s: CTS
Affects Version/s: 12.0.0
Fix Version/s: 12.0.1, 13.0.0

Type: Bug Priority: Major
Reporter: Ian Packer [X] (Inactive) Assignee: Peter Major [X] (Inactive)
Resolution: Fixed Votes: 0
Labels: EDISON, release-notes
Remaining Estimate: Not Specified
Time Spent: 3h
Original Estimate: Not Specified

Target Version/s:
Sprint: Sprint 78 - Sustaining
Support Ticket IDs:

 Description   

The CTS codebase regularly looks up tokens by ID from the directory server

Usually, since the coreTokenID is the RDN of the entry and the base below this is known, this is done as a very efficient search similar to the following:

[05/Jan/2015:20:39:21 +0000] SEARCH REQ conn=10 op=187 msgID=188 base="coreTokenId=-6105011964828865040,ou=famrecords,ou=openam-session,ou=tokens,dc=openam,dc=forgerock,dc=org" scope=baseObject filter="(objectClass=*)" attrs="ALL"

It seems there may be a few places where tokens are looked up differently, using a search similar to the following:

[05/Mar/2015:11:00:49 +0000] SEARCH REQ conn=9 op=340246 msgID=340247 base="ou=famrecords,ou=openam-session,ou=tokens,dc=openam,dc=forgerock,dc=org" scope=wholeSubtree filter="(&(objectClass=frCoreToken)(&(coreTokenId=2560815068138090132)))" attrs="coreTokenId"

coreTokenId is not indexed as part of cts-indices.ldif, or mentioned in the documentation for setting up CTS:

[root@openam sfha]# grep -i coreTokenId cts-indices.ldif  -c
0

So in a system with lots of tokens this search could be a significant performance hit.

The optimal solution is probably not to index this attribute, but to change these searches to use the baseObject search instead.

This might be a new problem in 12.0.0 as I cannot find any examples of this search in 11.

hasSession in CTSOperations.java looks like one possible candidate:

 /**
     * Checks whether the CTS store contains the session.
     * @param session The requested session.
     * @return Whether the session is in the CTS store.
     */
    public boolean hasSession(Session session) throws SessionException {
        String tokenId = idFactory.toSessionTokenId(session.getID());
        boolean found = false;
        try {
            Collection<PartialToken> tokens = cts.attributeQuery(new TokenFilterBuilder()
                    .returnAttribute(CoreTokenField.TOKEN_ID)
                    .withAttribute(CoreTokenField.TOKEN_ID, tokenId)
                    .build());
            found = !tokens.isEmpty();
        } catch (CoreTokenException e) {
            if (debug.messageEnabled()) {
                debug.message("Could not find token: " + tokenId, e);
            }
        }
        return found;
    }


 Comments   
Comment by Peter Major [X] (Inactive) [ 06/Mar/15 ]

After discussing this issue with Rob, it appears that this hasSession check is actually now redundant, because update operations are still performing crosstalk (in the early versions it was using CTS for updates as well, but that approach had some problems). The solution will be to simply remove hasSession.
For future versions it may be beneficial to implement a doesTokenExist method that uses the preferred approach of performing an LDAP search with base scope though if the need arises.

Comment by Peter Major [X] (Inactive) [ 12/Mar/15 ]

Fixed with R12984 and R1986

Generated at Sat Oct 24 00:31:32 UTC 2020 using Jira 7.13.12#713012-sha1:6e07c38070d5191bbf7353952ed38f111754533a.