Skip to content

Commit

Permalink
Record operation result times for QObjectMapping
Browse files Browse the repository at this point in the history
Signed-off-by: Tony Tkáčik <tonydamage@gmail.com>
  • Loading branch information
tonydamage committed Jan 10, 2024
1 parent f7399ea commit 3cfc72d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.evolveum.midpoint.repo.sqale;

import com.evolveum.midpoint.schema.result.OperationResult;

public class SqaleOperationResult implements AutoCloseable {
private static ThreadLocal<OperationResult> CURRENT_OPERATION_RESULT = new ThreadLocal<>();

public static OperationResult get() {
var maybe = CURRENT_OPERATION_RESULT.get();
if (maybe != null) {
return maybe;
}
// Nullables (for operations we are not tracking)
return new OperationResult("temporary");
}

public static OperationResult set(OperationResult result) {
CURRENT_OPERATION_RESULT.set(result);
return result;
}

public static void free() {
CURRENT_OPERATION_RESULT.remove();
}

public static OperationResult createSubresult(String name) {
return get().createSubresult(name);
}

public static SqaleOperationResult with(OperationResult result) {
set(result);
return new SqaleOperationResult();
}

@Override
public void close() {
free();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public SqaleRepositoryService(
.build();

PrismObject<T> object = null;
try {
try (var sqResult = SqaleOperationResult.with(operationResult)) {
object = executeGetObject(type, oidUuid, options);
return object;
} catch (ObjectNotFoundException e) {
Expand Down Expand Up @@ -597,52 +597,53 @@ private <T extends ObjectType> ModifyObjectResult<T> modifyObjectInternal(
@Nullable RepoModifyOptions options,
@NotNull OperationResult operationResult)
throws SchemaException, PreconditionViolationException, RepositoryException {
try (var sqaleResult = SqaleOperationResult.with(operationResult)){
if (options == null) {
options = new RepoModifyOptions();
}

if (options == null) {
options = new RepoModifyOptions();
}

PrismObject<T> prismObject = updateContext.getPrismObject();
//noinspection ConstantConditions
logger.debug("Modify object type '{}', oid={}, reindex={}",
prismObject.getCompileTimeClass().getSimpleName(),
prismObject.getOid(),
options.isForceReindex());

if (modifications.isEmpty() && !RepoModifyOptions.isForceReindex(options)) {
logger.debug("Modification list is empty, nothing was modified.");
operationResult.recordStatus(OperationResultStatus.SUCCESS,
"Modification list is empty, nothing was modified.");
return new ModifyObjectResult<>(modifications);
}
PrismObject<T> prismObject = updateContext.getPrismObject();
//noinspection ConstantConditions
logger.debug("Modify object type '{}', oid={}, reindex={}",
prismObject.getCompileTimeClass().getSimpleName(),
prismObject.getOid(),
options.isForceReindex());

if (modifications.isEmpty() && !RepoModifyOptions.isForceReindex(options)) {
logger.debug("Modification list is empty, nothing was modified.");
operationResult.recordStatus(OperationResultStatus.SUCCESS,
"Modification list is empty, nothing was modified.");
return new ModifyObjectResult<>(modifications);
}

checkModifications(modifications);
logTraceModifications(modifications);
checkModifications(modifications);
logTraceModifications(modifications);

if (precondition != null && !precondition.holds(prismObject)) {
// will be rolled back automatically
throw new PreconditionViolationException(
"Modification precondition does not hold for " + prismObject);
}
invokeConflictWatchers(w -> w.beforeModifyObject(prismObject));
PrismObject<T> originalObject = prismObject.clone(); // for result later
if (precondition != null && !precondition.holds(prismObject)) {
// will be rolled back automatically
throw new PreconditionViolationException(
"Modification precondition does not hold for " + prismObject);
}
invokeConflictWatchers(w -> w.beforeModifyObject(prismObject));
PrismObject<T> originalObject = prismObject.clone(); // for result later

boolean reindex = options.isForceReindex();
boolean reindex = options.isForceReindex();

if (reindex) {
// UpdateTables is false, we want only to process modifications on fullObject
// do not modify nested items.
modifications = updateContext.execute(modifications, false);
replaceObject(updateContext, updateContext.getPrismObject());
} else {
modifications = updateContext.execute(modifications);
}
logger.trace("OBJECT after:\n{}", prismObject.debugDumpLazily());
if (reindex) {
// UpdateTables is false, we want only to process modifications on fullObject
// do not modify nested items.
modifications = updateContext.execute(modifications, false);
replaceObject(updateContext, updateContext.getPrismObject());
} else {
modifications = updateContext.execute(modifications);
}
logger.trace("OBJECT after:\n{}", prismObject.debugDumpLazily());

if (!modifications.isEmpty()) {
invokeConflictWatchers((w) -> w.afterModifyObject(prismObject.getOid()));
if (!modifications.isEmpty()) {
invokeConflictWatchers((w) -> w.afterModifyObject(prismObject.getOid()));
}
return new ModifyObjectResult<>(originalObject, prismObject, modifications);
}
return new ModifyObjectResult<>(originalObject, prismObject, modifications);
}

private <T extends ObjectType> void replaceObject(
Expand Down Expand Up @@ -932,7 +933,7 @@ private <T extends ObjectType> int executeCountObjects(
.addParam(OperationResult.PARAM_OPTIONS, String.valueOf(options))
.build();

try {
try (var sqaleResult = SqaleOperationResult.with(operationResult)) {
logSearchInputParameters(type, query, "Search objects");

query = ObjectQueryUtil.simplifyQuery(query);
Expand Down Expand Up @@ -987,7 +988,7 @@ public <T extends ObjectType> SearchResultMetadata searchObjectsIterative(
.addParam(OperationResult.PARAM_QUERY, query)
.build();

try {
try (var sqaleResult = SqaleOperationResult.with(operationResult)) {
logSearchInputParameters(type, query, "Iterative search objects");

query = ObjectQueryUtil.simplifyQuery(query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.PathSet;
import com.evolveum.midpoint.prism.path.UniformItemPath;
import com.evolveum.midpoint.repo.sqale.SqaleOperationResult;
import com.evolveum.midpoint.repo.sqale.mapping.ReferenceNameResolver;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleMappingMixin;
import com.evolveum.midpoint.repo.sqale.qmodel.common.*;
Expand Down Expand Up @@ -96,6 +97,12 @@ public class QObjectMapping<S extends ObjectType, Q extends QObject<R>, R extend
return Objects.requireNonNull(instance);
}

private static String DOT_NAME = QObjectMapping.class.getName() + ".";
private static String PARSE_FULL_OBJECT = DOT_NAME + "parseFullObject";
private static String FETCH_CHILDREN = DOT_NAME + "fetchChildren";
private static String PARSE_CHILDREN = DOT_NAME + "parseChildren";


protected QObjectMapping(
@NotNull String tableName,
@NotNull String defaultAliasName,
Expand Down Expand Up @@ -210,6 +217,7 @@ public S toSchemaObjectCompleteSafe(
Collection<SelectorOptions<GetOperationOptions>> options,
@NotNull JdbcSession jdbcSession,
boolean forceFull) {
var result = SqaleOperationResult.createSubresult(PARSE_FULL_OBJECT);
try {
return toSchemaObjectComplete(tuple, entityPath, options, jdbcSession, forceFull);
} catch (SchemaException e) {
Expand All @@ -225,6 +233,8 @@ public S toSchemaObjectCompleteSafe(
} catch (SchemaException ex) {
throw new RepositoryMappingException("Schema exception [" + ex + "] while handling schema exception: " + e, e);
}
} finally {
result.close();
}
}

Expand Down Expand Up @@ -418,16 +428,16 @@ public boolean isIncluded(Collection<SelectorOptions<GetOperationOptions>> optio
if (includedByDefault) {
var retrieveOptions = SelectorOptions.findOptionsForPath(options, UniformItemPath.from(this.getPath()));
if (retrieveOptions.stream().anyMatch(o -> RetrieveOption.EXCLUDE.equals(o.getRetrieve()))) {
// THere is at least one exclude for options
// There is at least one exclude for options
return false;
}
return true;
}
return SelectorOptions.hasToFetchPathNotRetrievedByDefault(getPath(), options);
}

public Multimap<UUID, PrismValue> fetchChildren(List<UUID> oidList, JdbcSession jdbcSession) throws SchemaException {
Multimap<UUID, PrismValue> ret = HashMultimap.create();
public Multimap<UUID, Object> fetchChildren(List<UUID> oidList, JdbcSession jdbcSession) throws SchemaException {
Multimap<UUID, Object> ret = HashMultimap.create();

var q = mapping.createAlias();
var query = jdbcSession.newQuery()
Expand All @@ -437,16 +447,18 @@ public Multimap<UUID, PrismValue> fetchChildren(List<UUID> oidList, JdbcSession
for (var row : query.fetch()) {
// All assignments should have full object present / legacy assignments should be kept
if (mapping.hasFullObject(row)) {
ret.put(mapping.getOwner(row), mapping.toSchemaObjectEmbedded(row));
ret.put(mapping.getOwner(row), row);
}
}
return ret;
}

public void applyToSchemaObject(S target, Collection<PrismValue> values) throws SchemaException {
public void applyToSchemaObject(S target, Collection<Object> values) throws SchemaException {
var container = target.asPrismObject().findOrCreateItem(getPath(), (Class) mapping.getPrismItemType());
container.setIncomplete(false);
for (var containerable : values) {
for (var val : values) {
IR row = (IR) val;
var containerable = mapping.toSchemaObjectEmbedded(row);
// FIXME: Some better addition method should be necessary.
((Item) container).addIgnoringEquivalents(containerable);
}
Expand All @@ -473,24 +485,35 @@ public ResultListRowTransformer<S, Q, R> createRowTransformer(SqlQueryContext<S,
@Override
public void beforeTransformation(List<Tuple> tuples, Q entityPath) throws SchemaException {
// get uuids?
var oidList = tuples.stream().map(t -> t.get(entityPath.oid)).collect(Collectors.toList());
for (var mapping : mappingToData.entrySet()) {
mapping.setValue(mapping.getKey().fetchChildren(oidList, jdbcSession));
var result = SqaleOperationResult.createSubresult(FETCH_CHILDREN);
try {
var oidList = tuples.stream().map(t -> t.get(entityPath.oid)).collect(Collectors.toList());
for (var mapping : mappingToData.entrySet()) {
mapping.setValue(mapping.getKey().fetchChildren(oidList, jdbcSession));
}
} finally {
result.close();
}

}

@Override
public S transform(Tuple tuple, Q entityPath) {
// Parsing full object
S baseObject = toSchemaObjectCompleteSafe(tuple, entityPath, options, jdbcSession, false);
var uuid = tuple.get(entityPath.oid);
for (var entry : mappingToData.entrySet()) {
var mapping = entry.getKey();
try {
mapping.applyToSchemaObject(baseObject, entry.getValue().get(uuid));
} catch (SchemaException e) {
throw new SystemException(e);
var childrenResult = SqaleOperationResult.createSubresult(PARSE_CHILDREN);
try {
for (var entry : mappingToData.entrySet()) {
var mapping = entry.getKey();
try {
mapping.applyToSchemaObject(baseObject, entry.getValue().get(uuid));
} catch (SchemaException e) {
throw new SystemException(e);
}
}
} finally {
childrenResult.close();
}
resolveReferenceNames(baseObject, jdbcSession, options);
return baseObject;
Expand Down

0 comments on commit 3cfc72d

Please sign in to comment.