use of org.forgerock.openam.entitlement.PrivilegeEvaluatorContext in project OpenAM by OpenRock.
the class PrivilegeEvaluator method evaluate.
/**
* Responsible for the core evaluation of policies associated with the request resource.
*
* @param realm
* the evaluation realm
*
* @return a list of applicable entitlements
*
* @throws EntitlementException
*/
private List<Entitlement> evaluate(String realm) throws EntitlementException {
final Debug debug = PolicyConstants.DEBUG;
// Search for relevant policies.
final SubjectAttributesManager sam = SubjectAttributesManager.getInstance(adminSubject, realm);
final Set<String> subjectIndexes = sam.getSubjectSearchFilter(subject, applicationName);
final PrivilegeIndexStore indexStore = PrivilegeIndexStore.getInstance(adminSubject, realm);
final Iterator<IPrivilege> policyIterator = indexStore.search(realm, indexes, subjectIndexes, recursive);
int totalCount = 0;
IPrivilege policy;
// First collect policies to be evaluated locally.
final Set<IPrivilege> localBatch = new HashSet<IPrivilege>(2 * TASKS_PER_THREAD);
while (totalCount < TASKS_PER_THREAD && policyIterator.hasNext()) {
policy = policyIterator.next();
if (policy instanceof ReferralPrivilege) {
// We want to ignore referrals - deprecated.
continue;
}
if (debug.messageEnabled()) {
debug.message("[PolicyEval] PolicyEvaluator.evaluate");
debug.message("[PolicyEval] search result: privilege=" + policy.getName());
}
localBatch.add(policy);
totalCount++;
}
// Define an evaluation context.
final PrivilegeEvaluatorContext context = new PrivilegeEvaluatorContext(realm, normalisedResourceName, applicationName);
final Object appToken = AppTokenHandler.getAndClear();
// Submit additional policies to be executed by worker threads.
final Set<IPrivilege> threadBatch = new HashSet<IPrivilege>(2 * TASKS_PER_THREAD);
boolean tasksSubmitted = false;
while (policyIterator.hasNext()) {
tasksSubmitted = true;
policy = policyIterator.next();
if (policy instanceof ReferralPrivilege) {
// We want to ignore referrals - deprecated.
continue;
}
if (debug.messageEnabled()) {
debug.message("[PolicyEval] PolicyEvaluator.evaluate");
debug.message("[PolicyEval] search result: privilege=" + policy.getName());
}
threadBatch.add(policy);
totalCount++;
if (threadBatch.size() == TASKS_PER_THREAD) {
final Set<IPrivilege> copiedBatch = new HashSet<IPrivilege>(threadBatch);
threadPool.submit(new PrivilegeTask(this, copiedBatch, isMultiThreaded, appToken, context));
threadBatch.clear();
}
}
if (!threadBatch.isEmpty()) {
// Submit any remaining policies.
threadPool.submit(new PrivilegeTask(this, threadBatch, isMultiThreaded, appToken, context));
}
// Submit the local policies.
final Runnable localTask = new PrivilegeTask(this, localBatch, tasksSubmitted, appToken, context);
localTask.run();
// Wait for submitted threads to complete evaluation.
if (tasksSubmitted) {
if (isMultiThreaded) {
receiveEvalResults(totalCount);
} else {
boolean isDone = false;
while (!resultQ.isEmpty() && !isDone) {
entitlementCombiner.add(resultQ.remove(0));
isDone = entitlementCombiner.isDone();
}
}
} else if (eException == null) {
boolean isDone = false;
while (!resultQ.isEmpty() && !isDone) {
entitlementCombiner.add(resultQ.remove(0));
isDone = entitlementCombiner.isDone();
}
}
if (eException != null) {
// Throw caught exception.
throw eException;
}
return entitlementCombiner.getResults();
}
Aggregations