Skip to content

Commit

Permalink
Fix handling exceptions in search post-processing
Browse files Browse the repository at this point in the history
When an exception occurred during "applyDefinition" for provisioning
objects (resources, shadows) after they were fetched from the
repository, it was not handled correctly. It caused the whole
search operation to fail.

This is now fixed.

However, it is questionable if we want to support this mode of operation
(i.e. searching for more object types e.g. resources + connectors
in a single query) in the long term.
  • Loading branch information
mederly committed Aug 23, 2022
1 parent 735008d commit 3bad047
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public class ModelController implements ModelService, TaskService, CaseService,
// Constants for OperationResult
private static final String CLASS_NAME_WITH_DOT = ModelController.class.getName() + ".";
private static final String RESOLVE_REFERENCE = CLASS_NAME_WITH_DOT + "resolveReference";
private static final String OP_APPLY_PROVISIONING_DEFINITION = CLASS_NAME_WITH_DOT + "applyProvisioningDefinition";

private static final Trace LOGGER = TraceManager.getTrace(ModelController.class);

Expand Down Expand Up @@ -940,13 +941,15 @@ public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Cla
executeResolveOptions(object.asObjectable(), options, task, result);
}

// postprocessing objects that weren't handled by their correct provider (e.g. searching for ObjectType, and retrieving tasks, resources, shadows)
// currently only resources and shadows are handled in this way
// Post-processing objects that weren't handled by their correct provider (e.g. searching for ObjectType,
// and retrieving tasks, resources, shadows). Currently, only resources and shadows are handled in this way.
//
// TODO generalize this approach somehow (something like "postprocess" in task/provisioning interface)
// TODO ... or consider abandoning this functionality altogether (it is more a hack than a serious design!)
if (searchProvider == ObjectTypes.ObjectManager.REPOSITORY && !GetOperationOptions.isRaw(rootOptions)) {
for (PrismObject<T> object : list) {
if (object.asObjectable() instanceof ResourceType || object.asObjectable() instanceof ShadowType) {
provisioning.applyDefinition(object, task, result);
applyProvisioningDefinition(object, task, result);
}
}
}
Expand Down Expand Up @@ -985,6 +988,26 @@ public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Cla
return list;
}

private <T extends ObjectType> void applyProvisioningDefinition(
PrismObject<T> object, Task task, OperationResult parentResult) {
OperationResult result = parentResult.subresult(OP_APPLY_PROVISIONING_DEFINITION)
.setMinor()
.addParam(OperationResult.PARAM_OBJECT, object)
.build();
try {
provisioning.applyDefinition(object, task, result);
} catch (Throwable t) {
LoggingUtils.logExceptionAsWarning(
LOGGER, "Couldn't apply definition to {} (returning with fetchResult set)", t, object);
result.recordPartialError(t); // This is not a fatal error: something is retrieved, but not the whole object
object.asObjectable().setFetchResult(
result.createBeanReduced());
// Intentionally not re-throwing the exception
} finally {
result.close();
}
}

private class ContainerOperationContext<T extends Containerable> {
final boolean isCertCase;
final boolean isCaseMgmtWorkItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,11 @@ public void test357SearchResourceWrongConnectorOid() throws Exception {
assertEquals("Expected partial error in fetchResult", OperationResultStatusType.PARTIAL_ERROR, fetchResult.getStatus());
}

@Test(enabled = false)
/**
* It is a bit questionable if we want to support this mode of operation (asking for resources by specifying type
* of {@link AssignmentHolderType}).
*/
@Test
public void test358SearchResourceWrongConnectorOidUseTypeFilter() throws Exception {
Task task = getTestTask();
OperationResult result = task.getResult();
Expand Down

0 comments on commit 3bad047

Please sign in to comment.