Example usage for javax.persistence QueryTimeoutException getQuery

List of usage examples for javax.persistence QueryTimeoutException getQuery

Introduction

In this page you can find the example usage for javax.persistence QueryTimeoutException getQuery.

Prototype

public Query getQuery() 

Source Link

Document

Returns the query that caused this exception.

Usage

From source file:org.ejbca.core.model.era.RaMasterApiSessionBean.java

@SuppressWarnings("unchecked")
@Override//from w ww.  ja v  a 2 s.  c om
public RaEndEntitySearchResponse searchForEndEntities(AuthenticationToken authenticationToken,
        RaEndEntitySearchRequest request) {
    final RaEndEntitySearchResponse response = new RaEndEntitySearchResponse();
    final List<Integer> authorizedLocalCaIds = new ArrayList<>(
            caSession.getAuthorizedCaIds(authenticationToken));
    // Only search a subset of the requested CAs if requested
    if (!request.getCaIds().isEmpty()) {
        authorizedLocalCaIds.retainAll(request.getCaIds());
    }
    if (authorizedLocalCaIds.isEmpty()) {
        // Empty response since there were no authorized CAs
        if (log.isDebugEnabled()) {
            log.debug("Client '" + authenticationToken
                    + "' was not authorized to any of the requested CAs and the search request will be dropped.");
        }
        return response;
    }
    // Check Certificate Profile authorization
    final List<Integer> authorizedCpIds = new ArrayList<>(
            certificateProfileSession.getAuthorizedCertificateProfileIds(authenticationToken, 0));
    final boolean accessAnyCpAvailable = authorizedCpIds
            .containsAll(certificateProfileSession.getCertificateProfileIdToNameMap().keySet());
    if (!request.getCpIds().isEmpty()) {
        authorizedCpIds.retainAll(request.getCpIds());
    }
    if (authorizedCpIds.isEmpty()) {
        // Empty response since there were no authorized Certificate Profiles
        if (log.isDebugEnabled()) {
            log.debug("Client '" + authenticationToken
                    + "' was not authorized to any of the requested CPs and the search request will be dropped.");
        }
        return response;
    }
    // Check End Entity Profile authorization
    final Collection<Integer> authorizedEepIds = new ArrayList<>(endEntityProfileSession
            .getAuthorizedEndEntityProfileIds(authenticationToken, AccessRulesConstants.VIEW_END_ENTITY));
    final boolean accessAnyEepAvailable = authorizedEepIds
            .containsAll(endEntityProfileSession.getEndEntityProfileIdToNameMap().keySet());
    if (!request.getEepIds().isEmpty()) {
        authorizedEepIds.retainAll(request.getEepIds());
    }
    if (authorizedEepIds.isEmpty()) {
        // Empty response since there were no authorized End Entity Profiles
        if (log.isDebugEnabled()) {
            log.debug("Client '" + authenticationToken
                    + "' was not authorized to any of the requested EEPs and the search request will be dropped.");
        }
        return response;
    }
    final String subjectDnSearchString = request.getSubjectDnSearchString();
    final String subjectAnSearchString = request.getSubjectAnSearchString();
    final String usernameSearchString = request.getUsernameSearchString();
    final StringBuilder sb = new StringBuilder("SELECT a.username FROM UserData a WHERE (a.caId IN (:caId))");
    if (!subjectDnSearchString.isEmpty() || !subjectAnSearchString.isEmpty()
            || !usernameSearchString.isEmpty()) {
        sb.append(" AND (");
        boolean firstAppended = false;
        if (!subjectDnSearchString.isEmpty()) {
            sb.append("a.subjectDN LIKE :subjectDN");
            firstAppended = true;
        }
        if (!subjectAnSearchString.isEmpty()) {
            if (firstAppended) {
                sb.append(" OR ");
            } else {
                firstAppended = true;
            }
            sb.append("a.subjectAltName LIKE :subjectAltName");
        }
        if (!usernameSearchString.isEmpty()) {
            if (firstAppended) {
                sb.append(" OR ");
            } else {
                firstAppended = true;
            }
            sb.append("a.username LIKE :username");
        }
        sb.append(")");
    }

    if (request.isModifiedAfterUsed()) {
        sb.append(" AND (a.timeModified > :modifiedAfter)");
    }
    if (request.isModifiedBeforeUsed()) {
        sb.append(" AND (a.timeModified < :modifiedBefore)");
    }
    if (!request.getStatuses().isEmpty()) {
        sb.append(" AND (a.status IN (:status))");
    }
    // Don't constrain results to certain end entity profiles if root access is available and "any" CP is requested
    if (!accessAnyCpAvailable || !request.getCpIds().isEmpty()) {
        sb.append(" AND (a.certificateProfileId IN (:certificateProfileId))");
    }
    // Don't constrain results to certain end entity profiles if root access is available and "any" EEP is requested
    if (!accessAnyEepAvailable || !request.getEepIds().isEmpty()) {
        sb.append(" AND (a.endEntityProfileId IN (:endEntityProfileId))");
    }
    final Query query = entityManager.createQuery(sb.toString());
    query.setParameter("caId", authorizedLocalCaIds);
    if (!accessAnyCpAvailable || !request.getCpIds().isEmpty()) {
        query.setParameter("certificateProfileId", authorizedCpIds);
    }
    if (!accessAnyEepAvailable || !request.getEepIds().isEmpty()) {
        query.setParameter("endEntityProfileId", authorizedEepIds);
    }
    if (log.isDebugEnabled()) {
        log.debug(" CA IDs: " + Arrays.toString(authorizedLocalCaIds.toArray()));
        if (!accessAnyCpAvailable || !request.getCpIds().isEmpty()) {
            log.debug(" certificateProfileId: " + Arrays.toString(authorizedCpIds.toArray()));
        } else {
            log.debug(" certificateProfileId: Any (even deleted) profile(s) due to root access.");
        }
        if (!accessAnyEepAvailable || !request.getEepIds().isEmpty()) {
            log.debug(" endEntityProfileId: " + Arrays.toString(authorizedEepIds.toArray()));
        } else {
            log.debug(" endEntityProfileId: Any (even deleted) profile(s) due to root access.");
        }
    }
    if (!subjectDnSearchString.isEmpty()) {
        if (request.isSubjectDnSearchExact()) {
            query.setParameter("subjectDN", subjectDnSearchString);
        } else {
            query.setParameter("subjectDN", "%" + subjectDnSearchString + "%");
        }
    }
    if (!subjectAnSearchString.isEmpty()) {
        if (request.isSubjectAnSearchExact()) {
            query.setParameter("subjectAltName", subjectAnSearchString);
        } else {
            query.setParameter("subjectAltName", "%" + subjectAnSearchString + "%");
        }
    }
    if (!usernameSearchString.isEmpty()) {
        if (request.isUsernameSearchExact()) {
            query.setParameter("username", usernameSearchString);
        } else {
            query.setParameter("username", "%" + usernameSearchString + "%");
        }
    }
    if (request.isModifiedAfterUsed()) {
        query.setParameter("modifiedAfter", request.getModifiedAfter());
    }
    if (request.isModifiedBeforeUsed()) {
        query.setParameter("modifiedBefore", request.getModifiedBefore());
    }
    if (!request.getStatuses().isEmpty()) {
        query.setParameter("status", request.getStatuses());
    }
    final int maxResults = Math.min(getGlobalCesecoreConfiguration().getMaximumQueryCount(),
            request.getMaxResults());
    query.setMaxResults(maxResults);
    /* Try to use the non-portable hint (depends on DB and JDBC driver) to specify how long in milliseconds the query may run. Possible behaviors:
     * - The hint is ignored
     * - A QueryTimeoutException is thrown
     * - A PersistenceException is thrown (and the transaction which don't have here is marked for roll-back)
     */
    final long queryTimeout = getGlobalCesecoreConfiguration().getMaximumQueryTimeout();
    if (queryTimeout > 0L) {
        query.setHint("javax.persistence.query.timeout", String.valueOf(queryTimeout));
    }
    final List<String> usernames;
    try {
        usernames = query.getResultList();
        for (final String username : usernames) {
            response.getEndEntities().add(endEntityAccessSession.findUser(username));
        }
        response.setMightHaveMoreResults(usernames.size() == maxResults);
        if (log.isDebugEnabled()) {
            log.debug("Certificate search query: " + sb.toString() + " LIMIT " + maxResults + " \u2192 "
                    + usernames.size() + " results. queryTimeout=" + queryTimeout + "ms");
        }
    } catch (QueryTimeoutException e) {
        log.info("Requested search query by " + authenticationToken + " took too long. Query was "
                + e.getQuery().toString() + ". " + e.getMessage());
        response.setMightHaveMoreResults(true);
    } catch (PersistenceException e) {
        log.info("Requested search query by " + authenticationToken + " failed, possibly due to timeout. "
                + e.getMessage());
        response.setMightHaveMoreResults(true);
    }
    return response;
}