Skip to content

Commit

Permalink
optimize lookuptable loading
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed May 27, 2021
1 parent f8fb14b commit 78c6ef0
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 99 deletions.
Expand Up @@ -13,16 +13,16 @@
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.VirtualContainerItemSpecificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.VirtualContainersSpecificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author katka
Expand Down Expand Up @@ -55,6 +55,11 @@ public class WrapperContext {

private MetadataItemProcessingSpec metadataItemProcessingSpec;

//to avoid duplicate loading of the same lookuptable, maybe later we will need this
//for different types of objects
@Experimental
private Map<String, LookupTableType> lookupTableCache = new HashMap();

public WrapperContext(Task task, OperationResult result) {
this.task = task;
this.result = result != null ? result : new OperationResult("temporary"); // TODO !!!
Expand Down Expand Up @@ -181,6 +186,14 @@ public boolean isMetadata() {
return isMetadata;
}

public void rememberLookuptable(LookupTableType lookupTableType) {
lookupTableCache.put(lookupTableType.getOid(), lookupTableType);
}

public LookupTableType getLookuptableFromCache(String oid) {
return lookupTableCache.get(oid);
}

public WrapperContext clone() {
WrapperContext ctx = new WrapperContext(task,result);
ctx.setAuthzPhase(authzPhase);
Expand All @@ -196,6 +209,7 @@ public WrapperContext clone() {
ctx.setObject(object);
ctx.setMetadata(isMetadata);
ctx.setMetadataItemProcessingSpec(metadataItemProcessingSpec);
ctx.lookupTableCache = lookupTableCache;
return ctx;
}
}
Expand Up @@ -13,6 +13,7 @@

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType;
Expand Down Expand Up @@ -185,43 +186,13 @@ public static <O extends ObjectType> String runTask(TaskType taskToRun, Task ope
} catch (ObjectAlreadyExistsException | ObjectNotFoundException | SchemaException
| ExpressionEvaluationException | CommunicationException | ConfigurationException
| PolicyViolationException | SecurityViolationException e) {
// TODO Auto-generated catch block
// error(pageBase.getString("pageUsers.message.nothingSelected") + e.getMessage());
parentResult.recordFatalError(pageBase.createStringResource("WebModelUtils.couldntRunTask", e.getMessage()).getString(), e);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't run task " + e.getMessage(), e);
return null;
}

}

public static void runTask(Collection<TaskType> tasksToRun, Task operationalTask, OperationResult parentResult, PageBase pageBase) {
// try {

for (TaskType taskToRun : tasksToRun) {
runTask(tasksToRun, operationalTask, parentResult, pageBase);
}

// }
// ObjectDelta<TaskType> delta = ObjectDelta.createAddDelta(taskToRun.asPrismObject());
// pageBase.getPrismContext().adopt(delta);
// pageBase.getModelService().executeChanges(WebComponentUtil.createDeltaCollection(delta), null,
// operationalTask, parentResult);
// parentResult.recordInProgress();
// parentResult.setBackgroundTaskOid(delta.getOid());
// pageBase.showResult(parentResult);
// return delta.getOid();
// } catch (ObjectAlreadyExistsException | ObjectNotFoundException | SchemaException
// | ExpressionEvaluationException | CommunicationException | ConfigurationException
// | PolicyViolationException | SecurityViolationException e) {
// // TODO Auto-generated catch block
//// error(pageBase.getString("pageUsers.message.nothingSelected") + e.getMessage());
// parentResult.recordFatalError(pageBase.createStringResource("WebModelUtils.couldntRunTask", e.getMessage()).getString(), e);
// LoggingUtils.logUnexpectedException(LOGGER, "Couldn't run task " + e.getMessage(), e);
// return null;
// }

}

public static <O extends ObjectType> PrismObject<O> loadObject(PrismReferenceValue objectRef, QName expectedTargetType, PageBase pageBase, Task task, OperationResult result) {
if (objectRef == null) {
return null;
Expand All @@ -241,7 +212,7 @@ public static <T extends ObjectType> PrismObject<T> loadObject(Referencable obje
PageBase page) {
Task task = page.createSimpleTask(OPERATION_LOAD_OBJECT);
OperationResult result = task.getResult();
Class<T> type = page.getPrismContext().getSchemaRegistry().determineClassForType(objectReference.getType());
Class<T> type = ObjectTypes.getObjectTypeClassIfKnown(objectReference.getType());
return loadObject(type, objectReference.getOid(), null, page, task, result);
}

Expand Down Expand Up @@ -325,67 +296,6 @@ public static <T extends ObjectType> PrismObject<T> loadObject(Class<T> type, St
return object;
}

//TODO consider using modelServiceLocator instead of PageBase in other methods.. Do we even need it? What about showResult? Should it be
// here or directly in the page? Consider usability and readabiltiy
@Nullable
// public static <T extends ObjectType> PrismObject<T> loadObject(ObjectReferenceType objectReference,
// ModelServiceLocator page, Task task, OperationResult result) {
// Class<T> type = page.getPrismContext().getSchemaRegistry().determineClassForType(objectReference.getType());
// String oid = objectReference.getOid();
// Collection<SelectorOptions<GetOperationOptions>> options = null;
// LOGGER.debug("Loading {} with oid {}, options {}", type.getSimpleName(), oid, options);
//
// OperationResult subResult;
// if (result != null) {
// subResult = result.createMinorSubresult(OPERATION_LOAD_OBJECT);
// } else {
// subResult = new OperationResult(OPERATION_LOAD_OBJECT);
// }
// PrismObject<T> object = null;
// try {
// if (options == null) {
// options = SelectorOptions.createCollection(GetOperationOptions.createResolveNames());
// } else {
// GetOperationOptions getOpts = SelectorOptions.findRootOptions(options);
// if (getOpts == null) {
// options.add(new SelectorOptions<>(GetOperationOptions.createResolveNames()));
// } else {
// getOpts.setResolveNames(Boolean.TRUE);
// }
// }
// object = page.getModelService().getObject(type, oid, options, task, subResult);
// } catch (AuthorizationException e) {
// // Not authorized to access the object. This is probably caused by a reference that
// // point to an object that the current user cannot read. This is no big deal.
// // Just do not display that object.
// subResult.recordHandledError(e);
// LOGGER.debug("User {} is not authorized to read {} {}",
// task.getOwner() != null ? task.getOwner().getName() : null, type.getSimpleName(), oid);
// return null;
// } catch (ObjectNotFoundException e) {
// // Object does not exist. It was deleted in the meanwhile, or not created yet. This could happen quite often.
// subResult.recordHandledError(e);
// LOGGER.debug("{} {} does not exist", type.getSimpleName(), oid, e);
// return null;
//
// } catch (Exception ex) {
// subResult.recordFatalError("WebModelUtils.couldntLoadObject", ex);
// LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load object", ex);
// } finally {
// subResult.computeStatus();
// }
// // TODO reconsider this part: until recently, the condition was always 'false'
// if (WebComponentUtil.showResultInPage(subResult)) {
// if (page instanceof PageBase) {
// ((PageBase)page).showResult(subResult);
// }
// }
//
// LOGGER.debug("Loaded {} with result {}", object, subResult);
//
// return object;
// }

public static boolean isNoFetch(Collection<SelectorOptions<GetOperationOptions>> options) {
if (options == null) {
return false;
Expand Down
Expand Up @@ -82,16 +82,26 @@ protected LookupTableType getPredefinedValues(PrismProperty<T> item, WrapperCont
if (valueEnumerationRef == null) {
return null;
}

String lookupTableOid = valueEnumerationRef.getOid();
LookupTableType lookupTableType = wrapperContext.getLookuptableFromCache(lookupTableOid);
if (lookupTableType != null) {
LOGGER.trace("Loading lookuptable from cache");
return lookupTableType;
}

//TODO: task and result from context
Task task = wrapperContext.getTask();
OperationResult result = wrapperContext.getResult().createSubresult(OPERATION_LOAD_LOOKUP_TABLE);
Collection<SelectorOptions<GetOperationOptions>> options = WebModelServiceUtils
.createLookupTableRetrieveOptions(schemaService);

try {
PrismObject<LookupTableType> lookupTable = getModelService().getObject(LookupTableType.class, valueEnumerationRef.getOid(), options, task, result);
PrismObject<LookupTableType> lookupTable = getModelService().getObject(LookupTableType.class, lookupTableOid, options, task, result);
result.computeStatusIfUnknown();
return lookupTable.asObjectable();
lookupTableType = lookupTable.asObjectable();
wrapperContext.rememberLookuptable(lookupTableType);
return lookupTableType;
} catch (ObjectNotFoundException | SchemaException | SecurityViolationException | CommunicationException
| ConfigurationException | ExpressionEvaluationException e) {
LOGGER.error("Cannot load lookup table for {} ", item);
Expand All @@ -100,7 +110,6 @@ protected LookupTableType getPredefinedValues(PrismProperty<T> item, WrapperCont
}

return null;

}

@Override
Expand Down

0 comments on commit 78c6ef0

Please sign in to comment.