diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index 5a9bece4a80..3583056e4d3 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.path.*; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.provisioning.api.*; import com.evolveum.midpoint.repo.api.PreconditionViolationException; @@ -1249,57 +1250,20 @@ public Integer countObjects(Class type, ObjectQuery or @Override @Deprecated - public PrismObject findShadowOwner(String accountOid, Task task, OperationResult parentResult) - throws ObjectNotFoundException, SecurityViolationException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException { + public PrismObject findShadowOwner( + String accountOid, Task task, OperationResult parentResult) + throws ObjectNotFoundException, SecurityViolationException, SchemaException, + ConfigurationException, ExpressionEvaluationException, CommunicationException { Validate.notEmpty(accountOid, "Account oid must not be null or empty."); Validate.notNull(parentResult, "Result type must not be null."); - enterModelMethod(); - - PrismObject user; - - LOGGER.trace("Listing account shadow owner for account with oid {}.", new Object[]{accountOid}); - - OperationResult result = parentResult.createSubresult(LIST_ACCOUNT_SHADOW_OWNER); - result.addParam("accountOid", accountOid); - - try { - - user = cacheRepositoryService.listAccountShadowOwner(accountOid, result); - result.recordSuccess(); - } catch (ObjectNotFoundException ex) { - LoggingUtils.logException(LOGGER, "Account with oid {} doesn't exists", ex, accountOid); - result.recordFatalError("Account with oid '" + accountOid + "' doesn't exists", ex); - throw ex; - } catch (RuntimeException | Error ex) { - LoggingUtils.logException(LOGGER, "Couldn't list account shadow owner from repository" - + " for account with oid {}", ex, accountOid); - result.recordFatalError("Couldn't list account shadow owner for account with oid '" - + accountOid + "'.", ex); - throw ex; - } finally { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(result.dump(false)); - } - exitModelMethod(); - result.cleanupResult(); - } - - if (user != null) { - try { - user = user.cloneIfImmutable(); - schemaTransformer.applySchemasAndSecurity(user, null, null,null, task, result); - } catch (SchemaException | SecurityViolationException | ConfigurationException | - ExpressionEvaluationException | ObjectNotFoundException | CommunicationException ex) { - LoggingUtils.logException(LOGGER, "Couldn't list account shadow owner from repository" - + " for account with oid {}", ex, accountOid); - result.recordFatalError("Couldn't list account shadow owner for account with oid '" - + accountOid + "'.", ex); - throw ex; - } - } - - return user; + ObjectQuery query = prismContext.queryFor(UserType.class) + .item(UserType.F_LINK_REF) + .ref(accountOid) + .build(); + SearchResultList> prismObjects = + searchObjects(UserType.class, query, null, task, parentResult); + return MiscUtil.extractSingleton(prismObjects); } @Override diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/util/mock/MockFactory.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/util/mock/MockFactory.java index 7980f3c35da..d8ebe565910 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/util/mock/MockFactory.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/util/mock/MockFactory.java @@ -6,11 +6,18 @@ */ package com.evolveum.midpoint.model.impl.util.mock; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import javax.xml.namespace.QName; + +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Objectable; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; @@ -24,33 +31,25 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.jetbrains.annotations.NotNull; - -import javax.xml.namespace.QName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; public class MockFactory { public static ProvisioningService createProvisioningService() { return new ProvisioningService() { @Override - public PrismObject getObject(Class type, String oid, Collection> options, Task task, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { + public PrismObject getObject(Class type, String oid, Collection> options, Task task, OperationResult parentResult) { return null; } @Override - public String addObject(PrismObject object, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws ObjectAlreadyExistsException, SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException { + public String addObject(PrismObject object, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) { return null; } @Override - public int synchronize(ResourceShadowDiscriminator shadowCoordinates, Task task, TaskPartitionDefinitionType taskPartition, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException { + public int synchronize(ResourceShadowDiscriminator shadowCoordinates, Task task, TaskPartitionDefinitionType taskPartition, OperationResult parentResult) { return 0; } @@ -61,77 +60,77 @@ public void processAsynchronousUpdates(ResourceShadowDiscriminator shadowCoordin @NotNull @Override - public SearchResultList> searchObjects(Class type, ObjectQuery query, Collection> options, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { - return new SearchResultList(new ArrayList<>(0)); + public SearchResultList> searchObjects(Class type, ObjectQuery query, Collection> options, Task task, OperationResult parentResult) { + return new SearchResultList<>(new ArrayList<>(0)); } @Override - public Integer countObjects(Class type, ObjectQuery query, Collection> options, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { + public Integer countObjects(Class type, ObjectQuery query, Collection> options, Task task, OperationResult parentResult) { return null; } @Override - public SearchResultMetadata searchObjectsIterative(Class type, ObjectQuery query, Collection> options, ResultHandler handler, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { + public SearchResultMetadata searchObjectsIterative(Class type, ObjectQuery query, Collection> options, ResultHandler handler, Task task, OperationResult parentResult) { return null; } @Override - public String modifyObject(Class type, String oid, Collection modifications, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException, ObjectAlreadyExistsException, ExpressionEvaluationException { + public String modifyObject(Class type, String oid, Collection modifications, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) { return null; } @Override - public PrismObject deleteObject(Class type, String oid, ProvisioningOperationOptions option, OperationProvisioningScriptsType scripts, Task task, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException { + public PrismObject deleteObject(Class type, String oid, ProvisioningOperationOptions option, OperationProvisioningScriptsType scripts, Task task, OperationResult parentResult) { return null; } @Override - public Object executeScript(String resourceOid, ProvisioningScriptType script, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectAlreadyExistsException, ExpressionEvaluationException { + public Object executeScript(String resourceOid, ProvisioningScriptType script, Task task, OperationResult parentResult) { return null; } @Override - public OperationResult testResource(String resourceOid, Task task) throws ObjectNotFoundException { + public OperationResult testResource(String resourceOid, Task task) { return null; } @Override - public Set discoverConnectors(ConnectorHostType hostType, OperationResult parentResult) throws CommunicationException { + public Set discoverConnectors(ConnectorHostType hostType, OperationResult parentResult) { return null; } @Override - public List getConnectorOperationalStatus(String resourceOid, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + public List getConnectorOperationalStatus(String resourceOid, Task task, OperationResult parentResult) { return null; } @Override - public List> listResourceObjects(String resourceOid, QName objectClass, ObjectPaging paging, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { + public List> listResourceObjects(String resourceOid, QName objectClass, ObjectPaging paging, Task task, OperationResult parentResult) { return null; } @Override - public void refreshShadow(PrismObject shadow, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, SecurityViolationException, ExpressionEvaluationException { + public void refreshShadow(PrismObject shadow, ProvisioningOperationOptions options, Task task, OperationResult parentResult) { } @Override - public void applyDefinition(ObjectDelta delta, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + public void applyDefinition(ObjectDelta delta, Task task, OperationResult parentResult) { } @Override - public void applyDefinition(ObjectDelta delta, Objectable object, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + public void applyDefinition(ObjectDelta delta, Objectable object, Task task, OperationResult parentResult) { } @Override - public void applyDefinition(PrismObject object, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + public void applyDefinition(PrismObject object, Task task, OperationResult parentResult) { } @Override - public void applyDefinition(Class type, ObjectQuery query, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + public void applyDefinition(Class type, ObjectQuery query, Task task, OperationResult parentResult) { } @@ -151,7 +150,7 @@ public void postInit(OperationResult parentResult) { } @Override - public ConstraintsCheckingResult checkConstraints(RefinedObjectClassDefinition shadowDefinition, PrismObject shadowObject, PrismObject shadowObjectOld, ResourceType resourceType, String shadowOid, ResourceShadowDiscriminator resourceShadowDiscriminator, ConstraintViolationConfirmer constraintViolationConfirmer, ConstraintsCheckingStrategyType strategy, Task task, OperationResult parentResult) throws CommunicationException, ObjectAlreadyExistsException, SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException { + public ConstraintsCheckingResult checkConstraints(RefinedObjectClassDefinition shadowDefinition, PrismObject shadowObject, PrismObject shadowObjectOld, ResourceType resourceType, String shadowOid, ResourceShadowDiscriminator resourceShadowDiscriminator, ConstraintViolationConfirmer constraintViolationConfirmer, ConstraintsCheckingStrategyType strategy, Task task, OperationResult parentResult) { return null; } @@ -166,7 +165,7 @@ public void exitConstraintsCheckerCache() { } @Override - public ItemComparisonResult compare(Class type, String oid, ItemPath path, T expectedValue, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, EncryptionException { + public ItemComparisonResult compare(Class type, String oid, ItemPath path, T expectedValue, Task task, OperationResult result) { return null; } @@ -186,12 +185,12 @@ public static RepositoryService createRepositoryService() { return new RepositoryService() { @Override @NotNull - public PrismObject getObject(Class type, String oid, Collection> options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { + public PrismObject getObject(Class type, String oid, Collection> options, OperationResult parentResult) { throw new UnsupportedOperationException(); } @Override - public String getVersion(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { + public String getVersion(Class type, String oid, OperationResult parentResult) { return null; } @@ -201,77 +200,72 @@ public int countContainers(Class type, ObjectQuery } @Override - public String addObject(PrismObject object, RepoAddOptions options, OperationResult parentResult) throws ObjectAlreadyExistsException, SchemaException { + public String addObject(PrismObject object, RepoAddOptions options, OperationResult parentResult) { return null; } @NotNull @Override - public SearchResultList> searchObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException { - return new SearchResultList(new ArrayList<>(0)); + public SearchResultList> searchObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) { + return new SearchResultList<>(new ArrayList<>(0)); } @Override - public SearchResultList searchContainers(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException { - return new SearchResultList(new ArrayList<>(0)); + public SearchResultList searchContainers(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) { + return new SearchResultList<>(new ArrayList<>(0)); } @Override - public SearchResultMetadata searchObjectsIterative(Class type, ObjectQuery query, ResultHandler handler, Collection> options, boolean strictlySequential, OperationResult parentResult) throws SchemaException { + public SearchResultMetadata searchObjectsIterative(Class type, ObjectQuery query, ResultHandler handler, Collection> options, boolean strictlySequential, OperationResult parentResult) { return null; } @Override - public int countObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException { + public int countObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) { return 0; } @Override - public int countObjects(Class type, ObjectQuery query, OperationResult parentResult) throws SchemaException { + public int countObjects(Class type, ObjectQuery query, OperationResult parentResult) { return 0; } @Override - public boolean isAnySubordinate(String upperOrgOid, Collection lowerObjectOids) throws SchemaException { + public boolean isAnySubordinate(String upperOrgOid, Collection lowerObjectOids) { return false; } @Override - public boolean isDescendant(PrismObject object, String orgOid) throws SchemaException { + public boolean isDescendant(PrismObject object, String orgOid) { return false; } @Override - public boolean isAncestor(PrismObject object, String oid) throws SchemaException { + public boolean isAncestor(PrismObject object, String oid) { return false; } @NotNull @Override - public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, OperationResult parentResult) { return null; } @NotNull @Override - public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, RepoModifyOptions options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, RepoModifyOptions options, OperationResult parentResult) { return null; } @NotNull @Override - public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, ModificationPrecondition precondition, RepoModifyOptions options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, PreconditionViolationException { + public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, ModificationPrecondition precondition, RepoModifyOptions options, OperationResult parentResult) { return null; } @NotNull @Override - public DeleteObjectResult deleteObject(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException { - return null; - } - - @Override - public PrismObject listAccountShadowOwner(String accountOid, OperationResult parentResult) throws ObjectNotFoundException { + public DeleteObjectResult deleteObject(Class type, String oid, OperationResult parentResult) { return null; } @@ -281,17 +275,12 @@ public PrismObject searchShadowOwner(String shadowOid, } @Override - public List> listResourceObjectShadows(String resourceOid, Class resourceObjectShadowType, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { - return null; - } - - @Override - public long advanceSequence(String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { + public long advanceSequence(String oid, OperationResult parentResult) { return 0; } @Override - public void returnUnusedValuesToSequence(String oid, Collection unusedValues, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { + public void returnUnusedValuesToSequence(String oid, Collection unusedValues, OperationResult parentResult) { } @@ -316,7 +305,7 @@ public RepositoryQueryDiagResponse executeQueryDiagnostics(RepositoryQueryDiagRe } @Override - public boolean selectorMatches(ObjectSelectorType objectSelector, PrismObject object, ObjectFilterExpressionEvaluator filterEvaluator, Trace logger, String logMessagePrefix) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { + public boolean selectorMatches(ObjectSelectorType objectSelector, PrismObject object, ObjectFilterExpressionEvaluator filterEvaluator, Trace logger, String logMessagePrefix) { return false; } @@ -331,7 +320,7 @@ public FullTextSearchConfigurationType getFullTextSearchConfiguration() { } @Override - public void postInit(OperationResult result) throws SchemaException { + public void postInit(OperationResult result) { } @@ -351,7 +340,7 @@ public boolean hasConflict(ConflictWatcher watcher, OperationResult result) { } @Override - public void addDiagnosticInformation(Class type, String oid, DiagnosticInformationType information, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + public void addDiagnosticInformation(Class type, String oid, DiagnosticInformationType information, OperationResult parentResult) { } @@ -395,7 +384,7 @@ public void unregisterNotificationListener(ResourceEventListener listener) { } @Override - public void notifyEvent(ResourceEventDescription eventDescription, Task task, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, GenericConnectorException, ObjectAlreadyExistsException, ExpressionEvaluationException, PolicyViolationException { + public void notifyEvent(ResourceEventDescription eventDescription, Task task, OperationResult parentResult) throws GenericConnectorException { } diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/AccountOperationListener.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/AccountOperationListener.java index a73cda7b8c0..d60ae19a054 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/AccountOperationListener.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/AccountOperationListener.java @@ -7,31 +7,35 @@ package com.evolveum.midpoint.notifications.impl; +import javax.annotation.PostConstruct; + +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + import com.evolveum.midpoint.notifications.api.NotificationManager; import com.evolveum.midpoint.notifications.api.OperationStatus; import com.evolveum.midpoint.notifications.impl.events.ResourceObjectEventImpl; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; import com.evolveum.midpoint.provisioning.api.ResourceOperationDescription; import com.evolveum.midpoint.provisioning.api.ResourceOperationListener; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; - /** * Converts provisioning events into notification events. */ @@ -42,6 +46,7 @@ public class AccountOperationListener implements ResourceOperationListener { private static final String DOT_CLASS = AccountOperationListener.class.getName() + "."; + @Autowired private PrismContext prismContext; @Autowired private LightweightIdentifierGenerator lightweightIdentifierGenerator; @Autowired private ChangeNotificationDispatcher provisioningNotificationDispatcher; @Autowired private NotificationManager notificationManager; @@ -138,9 +143,9 @@ private void executeNotifyAny(OperationStatus status, ResourceOperationDescripti @NotNull private ResourceObjectEventImpl createRequest(OperationStatus status, - ResourceOperationDescription operationDescription, - Task task, - OperationResult result) { + ResourceOperationDescription operationDescription, + Task task, + OperationResult result) { ResourceObjectEventImpl event = new ResourceObjectEventImpl(lightweightIdentifierGenerator, operationDescription, status); @@ -173,10 +178,17 @@ private PrismObject findRequestee(String shadowOid, Task task, Operati return task.getRequestee(); } else if (shadowOid != null) { try { - PrismObject user = cacheRepositoryService.listAccountShadowOwner(shadowOid, result); + ObjectQuery query = prismContext.queryFor(UserType.class) + .item(UserType.F_LINK_REF) + .ref(shadowOid) + .build(); + SearchResultList> prismObjects = + cacheRepositoryService.searchObjects(UserType.class, query, null, result); + PrismObject user = MiscUtil.extractSingleton(prismObjects); + LOGGER.trace("listAccountShadowOwner for shadow {} yields {}", shadowOid, user); return user; - } catch (ObjectNotFoundException e) { + } catch (SchemaException e) { LOGGER.trace("There's a problem finding account {}", shadowOid, e); return null; } diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java index a3ad10082e3..27a849ec943 100644 --- a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java +++ b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java @@ -7,42 +7,20 @@ package com.evolveum.midpoint.repo.api; import java.util.Collection; -import java.util.List; -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.repo.api.perf.PerformanceMonitor; import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.repo.api.perf.PerformanceMonitor; import com.evolveum.midpoint.repo.api.query.ObjectFilterExpressionEvaluator; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.RepositoryDiag; -import com.evolveum.midpoint.schema.RepositoryQueryDiagRequest; -import com.evolveum.midpoint.schema.RepositoryQueryDiagResponse; -import com.evolveum.midpoint.schema.ResultHandler; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.SearchResultMetadata; -import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.xml.ns._public.common.common_3.DiagnosticInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FullTextSearchConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSelectorType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** *

Identity Repository Interface.

@@ -51,7 +29,7 @@ *
  • Status: public
  • *
  • Stability: stable
  • * - * @version 3.1.1 + * * @author Radovan Semancik *

    * This service provides repository for objects that are commonly found @@ -125,6 +103,7 @@ *

  • TODO: task coordination
  • * *

    + * @version 3.1.1 */ public interface RepositoryService { @@ -141,7 +120,6 @@ public interface RepositoryService { String SEARCH_OBJECTS = CLASS_NAME_WITH_DOT + "searchObjects"; String SEARCH_CONTAINERS = CLASS_NAME_WITH_DOT + "searchContainers"; String COUNT_CONTAINERS = CLASS_NAME_WITH_DOT + "countContainers"; - String LIST_RESOURCE_OBJECT_SHADOWS = CLASS_NAME_WITH_DOT + "listResourceObjectShadows"; String MODIFY_OBJECT = CLASS_NAME_WITH_DOT + "modifyObject"; String COUNT_OBJECTS = CLASS_NAME_WITH_DOT + "countObjects"; String GET_VERSION = CLASS_NAME_WITH_DOT + "getVersion"; @@ -160,7 +138,6 @@ public interface RepositoryService { String OP_DELETE_OBJECT = "deleteObject"; String OP_COUNT_OBJECTS = "countObjects"; String OP_MODIFY_OBJECT = "modifyObject"; - String OP_LIST_RESOURCE_OBJECT_SHADOWS = "listResourceObjectShadows"; String OP_GET_VERSION = "getVersion"; String OP_IS_ANY_SUBORDINATE = "isAnySubordinate"; String OP_ADVANCE_SEQUENCE = "advanceSequence"; @@ -168,31 +145,23 @@ public interface RepositoryService { String OP_EXECUTE_QUERY_DIAGNOSTICS = "executeQueryDiagnostics"; String OP_GET_OBJECT = "getObject"; String OP_SEARCH_SHADOW_OWNER = "searchShadowOwner"; - String OP_LIST_ACCOUNT_SHADOW_OWNER = "listAccountShadowOwner"; String OP_SEARCH_OBJECTS = "searchObjects"; String OP_SEARCH_OBJECTS_ITERATIVE = "searchObjectsIterative"; String OP_FETCH_EXT_ITEMS = "fetchExtItems"; /** * Returns object for provided OID. - * + *

    * Must fail if object with the OID does not exists. * - * @param oid - * OID of the object to get - * @param parentResult - * parent OperationResult (in/out) + * @param oid OID of the object to get + * @param parentResult parent OperationResult (in/out) * @return Object fetched from repository - * - * @throws ObjectNotFoundException - * requested object does not exist - * @throws SchemaException - * error dealing with storage schema - * @throws IllegalArgumentException - * wrong OID format, etc. + * @throws ObjectNotFoundException requested object does not exist + * @throws SchemaException error dealing with storage schema + * @throws IllegalArgumentException wrong OID format, etc. */ - @NotNull - PrismObject getObject(Class type, String oid, Collection> options, + @NotNull PrismObject getObject(Class type, String oid, Collection> options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException; @@ -203,24 +172,18 @@ PrismObject getObject(Class type, String oid, Colle /** * Returns object version for provided OID. - * + *

    * Must fail if object with the OID does not exists. - * + *

    * This is a supposed to be a very lightweight and cheap operation. It is used to support * efficient caching of expensive objects. * - * @param oid - * OID of the object to get - * @param parentResult - * parent OperationResult (in/out) + * @param oid OID of the object to get + * @param parentResult parent OperationResult (in/out) * @return Object version - * - * @throws ObjectNotFoundException - * requested object does not exist - * @throws SchemaException - * error dealing with storage schema - * @throws IllegalArgumentException - * wrong OID format, etc. + * @throws ObjectNotFoundException requested object does not exist + * @throws SchemaException error dealing with storage schema + * @throws IllegalArgumentException wrong OID format, etc. */ String getVersion(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException; @@ -252,23 +215,16 @@ int countContainers(Class type, ObjectQuery query, * Note: no need for explicit type parameter here. The object parameter contains the information. *

    * - * @param object - * object to create - * @param parentResult - * parent OperationResult (in/out) + * @param object object to create + * @param parentResult parent OperationResult (in/out) * @return OID assigned to the created object - * - * @throws ObjectAlreadyExistsException - * object with specified identifiers already exists, cannot add - * @throws SchemaException - * error dealing with storage schema, e.g. schema violation - * @throws IllegalArgumentException - * wrong OID format, etc. + * @throws ObjectAlreadyExistsException object with specified identifiers already exists, cannot add + * @throws SchemaException error dealing with storage schema, e.g. schema violation + * @throws IllegalArgumentException wrong OID format, etc. */ String addObject(PrismObject object, RepoAddOptions options, OperationResult parentResult) throws ObjectAlreadyExistsException, SchemaException; - /** *

    Search for objects in the repository.

    *

    If no search criteria specified, list of all objects of specified type is returned.

    @@ -284,21 +240,15 @@ String addObject(PrismObject object, RepoAddOptions op * specified in the query. *

    * - * @param query - * search query - * @param parentResult - * parent OperationResult (in/out) + * @param query search query + * @param parentResult parent OperationResult (in/out) * @return all objects of specified type that match search criteria (subject - * to paging) - * - * @throws IllegalArgumentException - * wrong object type - * @throws SchemaException - * unknown property used in search query + * to paging) + * @throws IllegalArgumentException wrong object type + * @throws SchemaException unknown property used in search query */ - @NotNull - SearchResultList> searchObjects(Class type, ObjectQuery query, + @NotNull SearchResultList> searchObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException; @@ -325,46 +275,38 @@ SearchResultList searchContainers(Class type, Ob * specified in the query. *

    * - * @param query - * search query - * @param handler - * result handler - * @param strictlySequential - * takes care not to skip any object nor to process objects more than once; see below - * @param parentResult - * parent OperationResult (in/out) + * @param query search query + * @param handler result handler + * @param strictlySequential takes care not to skip any object nor to process objects more than once; see below + * @param parentResult parent OperationResult (in/out) * @return all objects of specified type that match search criteria (subject to paging) - * - * @throws IllegalArgumentException - * wrong object type - * @throws SchemaException - * unknown property used in search query - * + * @throws IllegalArgumentException wrong object type + * @throws SchemaException unknown property used in search query + *

    * A note related to iteration method: - * + *

    * There are three iteration methods (see IterationMethodType): * - SINGLE_TRANSACTION: Fetches objects in single DB transaction. Not supported for all DBMSs. * - SIMPLE_PAGING: Uses the "simple paging" method: takes objects (e.g.) numbered 0 to 49, then 50 to 99, - * then 100 to 149, and so on. The disadvantage is that if the order of objects is changed - * during operation (e.g. by inserting/deleting some of them) then some objects can be - * processed multiple times, where others can be skipped. + * then 100 to 149, and so on. The disadvantage is that if the order of objects is changed + * during operation (e.g. by inserting/deleting some of them) then some objects can be + * processed multiple times, where others can be skipped. * - STRICTLY_SEQUENTIAL_PAGING: Uses the "strictly sequential paging" method: sorting returned objects by OID. This - * is (almost) reliable in such a way that no object would be skipped. However, custom - * paging cannot be used in this mode. - * + * is (almost) reliable in such a way that no object would be skipped. However, custom + * paging cannot be used in this mode. + *

    * If GetOperationOptions.iterationMethod is specified, it is used without any further considerations. * Otherwise, the repository configuration determines whether to use SINGLE_TRANSACTION or a paging. In the latter case, * strictlySequential flag determines between SIMPLE_PAGING (if false) and STRICTLY_SEQUENTIAL_PAGING (if true). - * + *

    * If explicit GetOperationOptions.iterationMethod is not provided, and paging is prescribed, and strictlySequential flag * is true and client-provided paging conflicts with the paging used by the iteration method, a warning is issued, and * iteration method is switched to SIMPLE_PAGING. - * + *

    * Sources of conflicts: - * - ordering is specified - * - offset is specified + * - ordering is specified + * - offset is specified * (limit is not a problem) - * */ SearchResultMetadata searchObjectsIterative(Class type, ObjectQuery query, @@ -380,23 +322,19 @@ SearchResultMetadata searchObjectsIterative(Class type * specified in the query. *

    * - * @param query - * search query - * @param parentResult - * parent OperationResult (in/out) + * @param query search query + * @param parentResult parent OperationResult (in/out) * @return count of objects of specified type that match search criteria (subject - * to paging) - * - * @throws IllegalArgumentException - * wrong object type - * @throws SchemaException - * unknown property used in search query + * to paging) + * @throws IllegalArgumentException wrong object type + * @throws SchemaException unknown property used in search query */ int countObjects(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException; - @Deprecated // use the version with options instead + @Deprecated + // use the version with options instead int countObjects(Class type, ObjectQuery query, OperationResult parentResult) throws SchemaException; @@ -421,34 +359,25 @@ int countObjects(Class type, ObjectQuery query, Operat * underlying schema of the storage system or the schema enforced by the * implementation. *

    - * + *

    * TODO: optimistic locking - * + *

    * Note: the precondition is checked only if actual modification is going to take place * (not e.g. if the list of modifications is empty). * - * @param parentResult - * parent OperationResult (in/out) - * - * @throws ObjectNotFoundException - * specified object does not exist - * @throws SchemaException - * resulting object would violate the schema - * @throws ObjectAlreadyExistsException - * if resulting object would have name which already exists in another object of the same type - * @throws IllegalArgumentException - * wrong OID format, described change is not applicable + * @param parentResult parent OperationResult (in/out) + * @throws ObjectNotFoundException specified object does not exist + * @throws SchemaException resulting object would violate the schema + * @throws ObjectAlreadyExistsException if resulting object would have name which already exists in another object of the same type + * @throws IllegalArgumentException wrong OID format, described change is not applicable */ - @NotNull - ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, OperationResult parentResult) + @NotNull ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException; - @NotNull - ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, RepoModifyOptions options, OperationResult parentResult) + @NotNull ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, RepoModifyOptions options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException; - @NotNull - ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, + @NotNull ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, ModificationPrecondition precondition, RepoModifyOptions options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, PreconditionViolationException; @@ -458,51 +387,12 @@ ModifyObjectResult modifyObject(Class type, String * Must fail if object with specified OID does not exists. Should be atomic. *

    * - * @param oid - * OID of object to delete - * @param parentResult - * parent OperationResult (in/out) - * - * @throws ObjectNotFoundException - * specified object does not exist - * @throws IllegalArgumentException - * wrong OID format, described change is not applicable + * @param oid OID of object to delete + * @param parentResult parent OperationResult (in/out) + * @throws ObjectNotFoundException specified object does not exist + * @throws IllegalArgumentException wrong OID format, described change is not applicable */ - @NotNull - DeleteObjectResult deleteObject(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException; - - /** - *

    Returns the User object representing owner of specified account (account - * shadow).

    - *

    - * May return null if there is no owner specified for the account. - *

    - * May only be called with OID of AccountShadow object. - *

    - * Implements the backward "owns" association between account shadow and - * user. Forward association is implemented by property "account" of user - * object. - *

    - * This is a "list" operation even though it may return at most one owner. - * However the operation implies searching the repository for an owner, - * which may be less efficient that following a direct association. Hence it - * is called "list" to indicate that there may be non-negligible overhead. - *

    - * - * @param accountOid - * OID of account shadow - * @param parentResult - * parentResult parent OperationResult (in/out) - * @return User object representing owner of specified account - * - * @throws ObjectNotFoundException - * specified object does not exist - * @throws IllegalArgumentException - * wrong OID format - */ - @Deprecated - PrismObject listAccountShadowOwner(String accountOid, OperationResult parentResult) - throws ObjectNotFoundException; + @NotNull DeleteObjectResult deleteObject(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException; /** *

    Returns the object representing owner of specified shadow.

    @@ -527,51 +417,14 @@ PrismObject listAccountShadowOwner(String accountOid, OperationResult * will not be able to do proper cleanup. *

    * - * @param shadowOid - * OID of shadow - * @param parentResult - * parentResult parent OperationResult (in/out) + * @param shadowOid OID of shadow + * @param parentResult parentResult parent OperationResult (in/out) * @return Object representing owner of specified account (subclass of FocusType) - * - * @throws IllegalArgumentException - * wrong OID format + * @throws IllegalArgumentException wrong OID format */ PrismObject searchShadowOwner(String shadowOid, Collection> options, OperationResult parentResult); /** - *

    Search for resource object shadows of a specified type that belong to the - * specified resource.

    - *

    - * Returns a list of such object shadows or empty list - * if nothing was found. - *

    - * Implements the backward "has" association between resource and resource - * object shadows. Forward association is implemented by property "resource" - * of resource object shadow. - *

    - * May only be called with OID of Resource object. - *

    - * - * @param resourceOid - * OID of resource definition (ResourceType) - * @param parentResult - * parentResult parent OperationResult (in/out) - * @return resource object shadows of a specified type from specified - * resource - * - * @throws ObjectNotFoundException - * specified object does not exist - * @throws SchemaException - * found object is not type of {@link ShadowType} - * @throws IllegalArgumentException - * wrong OID format - */ - List> listResourceObjectShadows(String resourceOid, - Class resourceObjectShadowType, OperationResult parentResult) throws ObjectNotFoundException, - SchemaException; - - /** - * * This operation is guaranteed to be atomic. If two threads or even two nodes request a value from * the same sequence at the same time then different values will be returned. * @@ -584,7 +437,6 @@ List> listResourceObjectShadows(String res long advanceSequence(String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException; /** - * * The sequence may ignore the values, e.g. if value re-use is disabled or when the list of * unused values is full. In such a case the values will be ignored silently and no error is indicated. * @@ -600,14 +452,14 @@ List> listResourceObjectShadows(String res RepositoryDiag getRepositoryDiag(); /** - * Runs a short, non-descructive repository self test. + * Runs a short, non-destructive repository self test. * This methods should never throw a (checked) exception. All the results * should be recorded under the provided result structure (including fatal errors). - * + *

    * This should implement ONLY self-tests that are IMPLEMENTATION-SPECIFIC. It must not * implement self-tests that are generic and applies to all repository implementations. * Such self-tests must be implemented in higher layers. - * + *

    * If the repository has no self-tests then the method should return immediately * without changing the result structure. It must not throw an exception in this case. */ @@ -617,14 +469,14 @@ List> listResourceObjectShadows(String res * Checks a closure for consistency, repairing any problems found. * This methods should never throw a (checked) exception. All the results * should be in the returned result structure (including fatal errors). - * + *

    * The current implementation expects closure to be of reasonable size - so * it could be fetched into main memory as well as recomputed online * (perhaps up to ~250K entries). In future, this method will be reimplemented. - * + *

    * BEWARE, this method locks out the M_ORG_CLOSURE table, so org-related operations * would wait until it completes. - * + *

    * TODO this method is SQL service specific; it should be generalized/fixed somehow. */ void testOrgClosureConsistency(boolean repairIfNecessary, OperationResult testResult); diff --git a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java index d63f0765517..0d5a7d7e53b 100644 --- a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java +++ b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java @@ -6,6 +6,26 @@ */ package com.evolveum.midpoint.repo.cache; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + +import static com.evolveum.midpoint.repo.cache.RepositoryCache.PassReasonType.*; +import static com.evolveum.midpoint.schema.GetOperationOptions.*; +import static com.evolveum.midpoint.schema.SelectorOptions.findRootOptions; +import static com.evolveum.midpoint.schema.cache.CacheType.*; +import static com.evolveum.midpoint.schema.util.TraceUtil.isAtLeastMinimal; +import static com.evolveum.midpoint.schema.util.TraceUtil.isAtLeastNormal; + +import java.util.Objects; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.PreDestroy; + +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + import com.evolveum.midpoint.CacheInvalidationContext; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContext; @@ -31,35 +51,16 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PreDestroy; -import java.util.Objects; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import static com.evolveum.midpoint.repo.cache.RepositoryCache.PassReasonType.*; -import static com.evolveum.midpoint.schema.GetOperationOptions.*; -import static com.evolveum.midpoint.schema.SelectorOptions.findRootOptions; -import static com.evolveum.midpoint.schema.cache.CacheType.*; -import static com.evolveum.midpoint.schema.util.TraceUtil.isAtLeastMinimal; -import static com.evolveum.midpoint.schema.util.TraceUtil.isAtLeastNormal; -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; /** * Read-through write-through per-session repository cache. - * + *

    * TODO doc * TODO logging perf measurements * * @author Radovan Semancik - * */ -@Component(value="cacheRepositoryService") +@Component(value = "cacheRepositoryService") public class RepositoryCache implements RepositoryService, Cacheable { private static final Trace LOGGER = TraceManager.getTrace(RepositoryCache.class); @@ -73,7 +74,6 @@ public class RepositoryCache implements RepositoryService, Cacheable { private static final String SEARCH_OBJECTS = CLASS_NAME_WITH_DOT + "searchObjects"; private static final String SEARCH_CONTAINERS = CLASS_NAME_WITH_DOT + "searchContainers"; private static final String COUNT_CONTAINERS = CLASS_NAME_WITH_DOT + "countContainers"; - private static final String LIST_RESOURCE_OBJECT_SHADOWS = CLASS_NAME_WITH_DOT + "listResourceObjectShadows"; private static final String MODIFY_OBJECT = CLASS_NAME_WITH_DOT + "modifyObject"; private static final String COUNT_OBJECTS = CLASS_NAME_WITH_DOT + "countObjects"; private static final String GET_VERSION = CLASS_NAME_WITH_DOT + "getVersion"; @@ -1070,7 +1070,7 @@ public int countObjects(Class type, ObjectQuery query, @NotNull public ModifyObjectResult modifyObject(Class type, String oid, Collection modifications, - OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { return modifyObject(type, oid, modifications, null, parentResult); } @@ -1362,45 +1362,6 @@ private PassReason getPassReason(Collection return new PassReason(UNSUPPORTED_OPTION, cloned.toString()); } - @Override - @Deprecated - public PrismObject listAccountShadowOwner(String accountOid, OperationResult parentResult) - throws ObjectNotFoundException { - OperationResult result = parentResult.subresult(LIST_ACCOUNT_SHADOW_OWNER) - .addParam("accountOid", accountOid) - .build(); - Long startTime = repoOpStart(); - try { - return repositoryService.listAccountShadowOwner(accountOid, result); - } catch (Throwable t) { - result.recordFatalError(t); - throw t; - } finally { - repoOpEnd(startTime); - result.computeStatusIfUnknown(); - } - } - - @Override - public List> listResourceObjectShadows(String resourceOid, - Class resourceObjectShadowType, OperationResult parentResult) throws ObjectNotFoundException, - SchemaException { - OperationResult result = parentResult.subresult(LIST_RESOURCE_OBJECT_SHADOWS) - .addParam("resourceOid", resourceOid) - .addParam("resourceObjectShadowType", resourceObjectShadowType) - .build(); - Long startTime = repoOpStart(); - try { - return repositoryService.listResourceObjectShadows(resourceOid, resourceObjectShadowType, result); - } catch (Throwable t) { - result.recordFatalError(t); - throw t; - } finally { - repoOpEnd(startTime); - result.computeStatusIfUnknown(); - } - } - @Override public String getVersion(Class type, String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { @@ -1754,7 +1715,6 @@ public void unregister() { cacheRegistry.unregisterCacheableService(this); } - @Override public ConflictWatcher createAndRegisterConflictWatcher(@NotNull String oid) { return repositoryService.createAndRegisterConflictWatcher(oid); @@ -1914,10 +1874,12 @@ enum PassReasonType { private static final class PassReason { private final PassReasonType type; private final String comment; + private PassReason(PassReasonType type) { this.type = type; this.comment = null; } + private PassReason(PassReasonType type, String comment) { this.type = type; this.comment = comment; @@ -1976,14 +1938,14 @@ public Object getObject() { public Collection getStateInformation() { List rv = new ArrayList<>(); rv.add(new SingleCacheStateInformationType(prismContext) - .name(LocalObjectCache.class.getName()) - .size(LocalObjectCache.getTotalSize(LOCAL_OBJECT_CACHE_INSTANCE))); + .name(LocalObjectCache.class.getName()) + .size(LocalObjectCache.getTotalSize(LOCAL_OBJECT_CACHE_INSTANCE))); rv.add(new SingleCacheStateInformationType(prismContext) - .name(LocalQueryCache.class.getName()) - .size(LocalQueryCache.getTotalSize(LOCAL_QUERY_CACHE_INSTANCE))); + .name(LocalQueryCache.class.getName()) + .size(LocalQueryCache.getTotalSize(LOCAL_QUERY_CACHE_INSTANCE))); rv.add(new SingleCacheStateInformationType(prismContext) - .name(LocalVersionCache.class.getName()) - .size(LocalVersionCache.getTotalSize(LOCAL_VERSION_CACHE_INSTANCE))); + .name(LocalVersionCache.class.getName()) + .size(LocalVersionCache.getTotalSize(LOCAL_VERSION_CACHE_INSTANCE))); rv.addAll(globalObjectCache.getStateInformation()); rv.addAll(globalVersionCache.getStateInformation()); rv.addAll(globalQueryCache.getStateInformation()); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java deleted file mode 100644 index e17a518a4a5..00000000000 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.repo.sql; - -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; - -import java.io.File; -import java.util.Collection; -import java.util.List; - -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; -import org.testng.annotations.Test; - -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.util.PrismTestUtil; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; - -/** - * @author lazyman - */ -@ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -public class ListAccountShadowOwnerTest extends BaseSQLRepoTest { - - @Test - public void listExistingOwner() throws Exception { - OperationResult result = new OperationResult("List owner"); - - //insert sample data - final File OBJECTS_FILE = new File(FOLDER_BASIC, "objects.xml"); - List> elements = prismContext.parserFor(OBJECTS_FILE).parseObjects(); - for (PrismObject object : elements) { - repositoryService.addObject(object, null, result); - } - - //look for account owner - PrismObject user = repositoryService.listAccountShadowOwner("1234", result); - - assertNotNull("No owner for account 1234", user); - PrismProperty name = user.findProperty(ObjectType.F_NAME); - AssertJUnit.assertNotNull(name); - AssertJUnit.assertEquals("atestuserX00003", ((PolyString) name.getRealValue()).getOrig()); - } - - @Test - public void listNonExistingOwner() throws Exception { - OperationResult result = new OperationResult("LIST OWNER"); - - PrismObject user = repositoryService.listAccountShadowOwner("12345", result); - AssertJUnit.assertNull(user); - } - - @Test - public void testLinkUnlink() throws Exception { - // GIVEN - OperationResult result = new OperationResult("testLinkUnlink"); - PrismObject user = PrismTestUtil.parseObject(new File(FOLDER_BASIC, "user.xml")); - String userOid = repositoryService.addObject(user, null, result); - assertNotNull("User oid is null", userOid); - AssertJUnit.assertEquals("user oid is not equal to returned value", userOid, user.getOid()); - PrismObject account = PrismTestUtil.parseObject(new File(FOLDER_BASIC, "account-shadow.xml")); - String accountOid = repositoryService.addObject(account, null, result); - assertNotNull("Account oid is null, couldn't add account or what?", account); - AssertJUnit.assertEquals("account oid is not equal to returned value", accountOid, account.getOid()); - // precondition - PrismObject accountOwnerOid = repositoryService.listAccountShadowOwner(accountOid, result); - assertNull("Account has owner and should not have (precondition)", accountOwnerOid); - - // WHEN (link account) - Collection modifications = prismContext.deltaFactory().reference().createModificationAddCollection(UserType.class, - UserType.F_LINK_REF, account); - repositoryService.modifyObject(UserType.class, userOid, modifications, result); - // THEN - accountOwnerOid = repositoryService.listAccountShadowOwner(accountOid, result); - assertEquals("listAccountShadowOwner returned wrong value", userOid, accountOwnerOid); - - // WHEN (unlink account) - modifications = prismContext.deltaFactory().reference().createModificationDeleteCollection(UserType.class, UserType.F_LINK_REF, - account); - repositoryService.modifyObject(UserType.class, userOid, modifications, result); - // THEN - accountOwnerOid = repositoryService.listAccountShadowOwner(accountOid, result); - assertNull("listAccountShadowOwner returned non-null value after unlink", accountOwnerOid); - } - - private void assertEquals(String string, String userOid, PrismObject accountOwner) { - AssertJUnit.assertEquals(string, userOid, accountOwner != null ? accountOwner.getOid() : null); - } -} diff --git a/repo/repo-sql-impl-test/testng-integration.xml b/repo/repo-sql-impl-test/testng-integration.xml index 0384c9c4fde..4e0c2af25a1 100644 --- a/repo/repo-sql-impl-test/testng-integration.xml +++ b/repo/repo-sql-impl-test/testng-integration.xml @@ -29,7 +29,6 @@ - diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java index e1ff5ae17a9..e89e2930a17 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java @@ -13,25 +13,12 @@ import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; - import javax.xml.namespace.QName; -import com.evolveum.midpoint.repo.api.*; -import com.evolveum.midpoint.repo.sql.perf.SqlPerformanceMonitorImpl; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -42,42 +29,20 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; import com.evolveum.midpoint.common.crypto.CryptoUtil; -import com.evolveum.midpoint.prism.ConsistencyCheckScope; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ItemDeltaCollectionsUtil; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.AllFilter; -import com.evolveum.midpoint.prism.query.NoneFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; -import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.*; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.repo.api.*; import com.evolveum.midpoint.repo.api.query.ObjectFilterExpressionEvaluator; -import com.evolveum.midpoint.repo.sql.helpers.BaseHelper; -import com.evolveum.midpoint.repo.sql.helpers.ObjectRetriever; -import com.evolveum.midpoint.repo.sql.helpers.ObjectUpdater; -import com.evolveum.midpoint.repo.sql.helpers.OrgClosureManager; -import com.evolveum.midpoint.repo.sql.helpers.SequenceHelper; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.LabeledString; -import com.evolveum.midpoint.schema.RelationRegistry; -import com.evolveum.midpoint.schema.RepositoryDiag; -import com.evolveum.midpoint.schema.RepositoryQueryDiagRequest; -import com.evolveum.midpoint.schema.RepositoryQueryDiagResponse; -import com.evolveum.midpoint.schema.ResultHandler; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.SearchResultMetadata; -import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.repo.sql.helpers.*; +import com.evolveum.midpoint.repo.sql.perf.SqlPerformanceMonitorImpl; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.internals.InternalsConfig; @@ -88,22 +53,17 @@ import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** * @author lazyman - * + *

    * Note: don't autowire this class - because of Spring AOP use it couldn't be found by implementation class; only by its interface. */ @Repository @@ -120,7 +80,6 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito private static final int RESTART_LIMIT = 1000; private static final Trace LOGGER = TraceManager.getTrace(SqlRepositoryServiceImpl.class); - private static final Trace LOGGER_PERFORMANCE = TraceManager.getTrace(PERFORMANCE_LOG_NAME); private static final int MAX_CONFLICT_WATCHERS = 10; // just a safeguard (watchers per thread should be at most 1-2) public static final int MAX_CONSTRAINT_NAME_LENGTH = 40; @@ -139,7 +98,6 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito @Autowired private OrgClosureManager closureManager; @Autowired private BaseHelper baseHelper; @Autowired private MatchingRuleRegistry matchingRuleRegistry; - @Autowired private MidpointConfiguration midpointConfiguration; @Autowired private PrismContext prismContext; @Autowired private RelationRegistry relationRegistry; @Autowired private SystemConfigurationChangeDispatcher systemConfigurationChangeDispatcher; @@ -219,8 +177,9 @@ private RV executeAttempts(String oid, String operationName, Class type, } } - private RV executeAttemptsNoSchemaException(String oid, String operationName, Class type, String operationVerb, OperationResult subResult, - ResultSupplier supplier) throws ObjectNotFoundException { + private RV executeAttemptsNoSchemaException( + String oid, String operationName, Class type, String operationVerb, + OperationResult subResult, ResultSupplier supplier) throws ObjectNotFoundException { try { return executeAttempts(oid, operationName, type, operationVerb, subResult, supplier); } catch (SchemaException e) { @@ -228,7 +187,8 @@ private RV executeAttemptsNoSchemaException(String oid, String operationNam } } - private RV executeQueryAttemptsNoSchemaException(ObjectQuery query, String operationName, Class type, String operationVerb, OperationResult subResult, + private RV executeQueryAttemptsNoSchemaException(ObjectQuery query, + String operationName, Class type, String operationVerb, OperationResult subResult, Supplier emptyQueryResultSupplier, ResultQueryBasedSupplier supplier) { try { return executeQueryAttempts(query, operationName, type, operationVerb, subResult, emptyQueryResultSupplier, supplier); @@ -279,29 +239,7 @@ public PrismObject searchShadowOwner(String shadowOid, return executeAttempts(shadowOid, OP_SEARCH_SHADOW_OWNER, FocusType.class, "searching shadow owner", subResult, () -> objectRetriever.searchShadowOwnerAttempt(shadowOid, options, subResult) ); - } catch (ObjectNotFoundException|SchemaException e) { - throw new AssertionError("Should not occur; exception should have been treated in searchShadowOwnerAttempt.", e); - } - } - - @Override - @Deprecated - public PrismObject listAccountShadowOwner(String accountOid, OperationResult result) - throws ObjectNotFoundException { - Validate.notEmpty(accountOid, "Oid must not be null or empty."); - Validate.notNull(result, "Operation result must not be null."); - - LOGGER.debug("Selecting account shadow owner for account {}.", new Object[]{accountOid}); - - OperationResult subResult = result.subresult(LIST_ACCOUNT_SHADOW) - .addParam("accountOid", accountOid) - .build(); - - try { - return executeAttempts(accountOid, OP_LIST_ACCOUNT_SHADOW_OWNER, UserType.class, "listing account shadow owner", - subResult, () -> objectRetriever.listAccountShadowOwnerAttempt(accountOid, subResult) - ); - } catch (ObjectNotFoundException|SchemaException e) { + } catch (ObjectNotFoundException | SchemaException e) { throw new AssertionError("Should not occur; exception should have been treated in searchShadowOwnerAttempt.", e); } } @@ -363,7 +301,7 @@ public SearchResultList searchContainers(Class t .build(); return executeQueryAttempts(query, "searchContainers", type, "searching", result, - () -> new SearchResultList<>(new ArrayList(0)), + () -> new SearchResultList<>(new ArrayList<>(0)), (q) -> objectRetriever.searchContainersAttempt(type, q, options, result)); } @@ -525,7 +463,7 @@ public int countObjects(Class type, ObjectQuery query, } public int countObjects(Class type, ObjectQuery query, - Collection> options, OperationResult result) { + Collection> options, OperationResult result) { Validate.notNull(type, "Object type must not be null."); Validate.notNull(result, "Operation result must not be null."); @@ -654,41 +592,6 @@ public ModifyObjectResult modifyObject(Class type, } } - @Override - public List> listResourceObjectShadows(String resourceOid, - Class resourceObjectShadowType, OperationResult result) throws ObjectNotFoundException, SchemaException { - Validate.notEmpty(resourceOid, "Resource oid must not be null or empty."); - Validate.notNull(resourceObjectShadowType, "Resource object shadow type must not be null."); - Validate.notNull(result, "Operation result must not be null."); - - LOGGER.debug("Listing resource object shadows '{}' for resource '{}'.", - new Object[]{resourceObjectShadowType.getSimpleName(), resourceOid}); - OperationResult subResult = result.subresult(LIST_RESOURCE_OBJECT_SHADOWS) - .addParam("oid", resourceOid) - .addParam("resourceObjectShadowType", resourceObjectShadowType) - .build(); - - final String operation = "listing resource object shadows"; - int attempt = 1; - - SqlPerformanceMonitorImpl pm = getPerformanceMonitor(); - long opHandle = pm.registerOperationStart(OP_LIST_RESOURCE_OBJECT_SHADOWS, ShadowType.class); - - // TODO executeAttempts - try { - while (true) { - try { - return objectRetriever.listResourceObjectShadowsAttempt(resourceOid, resourceObjectShadowType, subResult); - } catch (RuntimeException ex) { - attempt = baseHelper.logOperationAttempt(resourceOid, operation, attempt, ex, subResult); - pm.registerOperationNewAttempt(opHandle, attempt); - } - } - } finally { - pm.registerOperationFinish(opHandle, attempt); - } - } - @Override public RepositoryDiag getRepositoryDiag() { LOGGER.debug("Getting repository diagnostics."); @@ -740,7 +643,6 @@ public void execute(Connection connection) throws SQLException { details.add(new LabeledString(DETAILS_TRANSACTION_ISOLATION, getTransactionIsolation(connection, config))); - Properties info = connection.getClientInfo(); if (info == null) { return; @@ -760,9 +662,9 @@ public void execute(Connection connection) throws SQLException { SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) sessionFactory; // we try to override configuration which was read from sql repo configuration with // real configuration from session factory - if(sessionFactoryImpl.getDialect() != null) { - for(int i =0; i String getVersion(Class type, String oid, Opera Validate.notNull(oid, "Object oid must not be null."); Validate.notNull(parentResult, "Operation result must not be null."); - LOGGER.debug("Getting version for {} with oid '{}'.", new Object[]{type.getSimpleName(), oid}); + LOGGER.debug("Getting version for {} with oid '{}'.", new Object[] { type.getSimpleName(), oid }); OperationResult subResult = parentResult.subresult(GET_VERSION) .addQualifier(type.getSimpleName()) @@ -932,11 +834,20 @@ public SearchResultMetadata searchObjectsIterative(Class< SearchResultMetadata rv = null; // todo what about returning values from other search methods? switch (iterationMethod) { - case SINGLE_TRANSACTION: rv = searchObjectsIterativeBySingleTransaction(type, query, handler, options, subResult); break; - case SIMPLE_PAGING: objectRetriever.searchObjectsIterativeByPaging(type, query, handler, options, subResult); break; - case STRICTLY_SEQUENTIAL_PAGING: objectRetriever.searchObjectsIterativeByPagingStrictlySequential(type, query, handler, options, subResult); break; - case FETCH_ALL: objectRetriever.searchObjectsIterativeByFetchAll(type, query, handler, options, subResult); break; - default: throw new AssertionError("iterationMethod: " + iterationMethod); + case SINGLE_TRANSACTION: + rv = searchObjectsIterativeBySingleTransaction(type, query, handler, options, subResult); + break; + case SIMPLE_PAGING: + objectRetriever.searchObjectsIterativeByPaging(type, query, handler, options, subResult); + break; + case STRICTLY_SEQUENTIAL_PAGING: + objectRetriever.searchObjectsIterativeByPagingStrictlySequential(type, query, handler, options, subResult); + break; + case FETCH_ALL: + objectRetriever.searchObjectsIterativeByFetchAll(type, query, handler, options, subResult); + break; + default: + throw new AssertionError("iterationMethod: " + iterationMethod); } return rv; } @@ -991,12 +902,13 @@ private SearchResultMetadata searchObjectsIterativeBySing } @Override - public boolean isAnySubordinate(String upperOrgOid, Collection lowerObjectOids) throws SchemaException { + public boolean isAnySubordinate(String upperOrgOid, Collection lowerObjectOids) { Validate.notNull(upperOrgOid, "upperOrgOid must not be null."); Validate.notNull(lowerObjectOids, "lowerObjectOids must not be null."); - if (LOGGER.isTraceEnabled()) - LOGGER.trace("Querying for subordination upper {}, lower {}", new Object[]{upperOrgOid, lowerObjectOids}); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Querying for subordination upper {}, lower {}", new Object[] { upperOrgOid, lowerObjectOids }); + } if (lowerObjectOids.isEmpty()) { // trivial case @@ -1022,7 +934,6 @@ public boolean isAnySubordinate(String upperOrgOid, Collection lowerObje } } - @Override public long advanceSequence(String oid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { @@ -1034,8 +945,7 @@ public long advanceSequence(String oid, OperationResult parentResult) throws Obj .addParam("oid", oid) .build(); - if (LOGGER.isTraceEnabled()) - LOGGER.trace("Advancing sequence {}", oid); + if (LOGGER.isTraceEnabled()) { LOGGER.trace("Advancing sequence {}", oid); } // TODO executeAttempts int attempt = 1; @@ -1056,7 +966,6 @@ public long advanceSequence(String oid, OperationResult parentResult) throws Obj } } - @Override public void returnUnusedValuesToSequence(String oid, Collection unusedValues, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { @@ -1194,17 +1103,17 @@ public boolean selectorMatches(ObjectSelectorType objectS } @Override - public boolean isDescendant(PrismObject object, String orgOid) throws SchemaException { + public boolean isDescendant(PrismObject object, String orgOid) { List objParentOrgRefs = object.asObjectable().getParentOrgRef(); List objParentOrgOids = new ArrayList<>(objParentOrgRefs.size()); - for (ObjectReferenceType objParentOrgRef: objParentOrgRefs) { + for (ObjectReferenceType objParentOrgRef : objParentOrgRefs) { objParentOrgOids.add(objParentOrgRef.getOid()); } return isAnySubordinate(orgOid, objParentOrgOids); } @Override - public boolean isAncestor(PrismObject object, String oid) throws SchemaException { + public boolean isAncestor(PrismObject object, String oid) { if (object.getOid() == null) { return false; } @@ -1319,7 +1228,8 @@ public void addDiagnosticInformation(Class type, Strin // TODO replace by something in system configuration (postponing until this feature is used more) - private static final Map DIAG_INFO_CLEANUP_POLICY = new HashMap<>(); + private static final Map DIAG_INFO_CLEANUP_POLICY = new HashMap<>(); + static { DIAG_INFO_CLEANUP_POLICY.put(SchemaConstants.TASK_THREAD_DUMP_URI, 5); DIAG_INFO_CLEANUP_POLICY.put(null, 2); @@ -1344,7 +1254,7 @@ private boolean pruneDiagnosticInformation(Class type, List oldToPrune = oldInformationList.stream() .filter(i -> infoType.equals(i.getType())) .collect(Collectors.toList()); - int pruneToSize = limit > 0 ? limit-1 : 0; + int pruneToSize = limit > 0 ? limit - 1 : 0; if (oldToPrune.size() > pruneToSize) { oldToPrune.sort(Comparator.nullsFirst(Comparator.comparing(i -> XmlTypeConverter.toDate(i.getTimestamp())))); List toDelete = oldToPrune.subList(0, oldToPrune.size() - pruneToSize); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java index 63355be0884..75ab55fdec2 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java @@ -7,6 +7,23 @@ package com.evolveum.midpoint.repo.sql.helpers; +import static org.apache.commons.lang3.ArrayUtils.getLength; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + +import java.util.*; +import java.util.stream.Collectors; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.xml.namespace.QName; + +import org.hibernate.*; +import org.hibernate.query.NativeQuery; +import org.hibernate.query.Query; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + import com.evolveum.midpoint.common.crypto.CryptoUtil; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemName; @@ -42,22 +59,6 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; -import org.hibernate.*; -import org.hibernate.query.NativeQuery; -import org.hibernate.query.Query; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.xml.namespace.QName; -import java.util.*; -import java.util.stream.Collectors; - -import static org.apache.commons.lang3.ArrayUtils.getLength; -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; /** * @author lazyman, mederly @@ -66,7 +67,6 @@ public class ObjectRetriever { public static final String CLASS_DOT = ObjectRetriever.class.getName() + "."; - public static final String OPERATION_GET_OBJECT_INTERNAL = CLASS_DOT + "getObjectInternal"; private static final Trace LOGGER = TraceManager.getTrace(ObjectRetriever.class); private static final Trace LOGGER_PERFORMANCE = TraceManager.getTrace(SqlRepositoryServiceImpl.PERFORMANCE_LOG_NAME); @@ -232,7 +232,7 @@ public PrismObject searchShadowOwnerAttempt(String shad query.setParameter("oid", shadowOid); query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer()); - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List focuses = query.list(); LOGGER.trace("Found {} focuses, transforming data to JAXB types.", focuses != null ? focuses.size() : 0); @@ -257,8 +257,7 @@ public PrismObject searchShadowOwnerAttempt(String shad return owner; } - public PrismObject listAccountShadowOwnerAttempt(String accountOid, OperationResult result) - throws ObjectNotFoundException { + public PrismObject listAccountShadowOwnerAttempt(String accountOid, OperationResult result) { LOGGER_PERFORMANCE.debug("> list account shadow owner oid={}", accountOid); PrismObject userType = null; Session session = null; @@ -268,7 +267,7 @@ public PrismObject listAccountShadowOwnerAttempt(String accountOid, Op query.setParameter("oid", accountOid); query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer()); - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List users = query.list(); LOGGER.trace("Found {} users, transforming data to JAXB types.", users != null ? users.size() : 0); @@ -333,8 +332,8 @@ public int countObjectsAttempt(Class type, ObjectQuery return count; } - //TODO copied from QueryInterpreter, remove if full support for searching AssignmentHolderType is implemented MID-5579 + /** * Both ObjectType and AssignmentHolderType are mapped to RObject. So when searching for AssignmentHolderType it is not sufficient to * query this table. This method hacks this situation a bit by introducing explicit type filter for AssignmentHolderType. @@ -391,7 +390,7 @@ public SearchResultList> searchObjectsAtte QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); rQuery = engine.interpret(query, type, options, false, session); - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List queryResult = rQuery.list(); LOGGER.trace("Found {} objects, translating to JAXB.", queryResult != null ? queryResult.size() : 0); @@ -456,21 +455,21 @@ public SearchResultList searchContainersAttempt(Cla RQuery rQuery = engine.interpret(query, type, options, false, session); if (cases) { - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List items = rQuery.list(); LOGGER.trace("Found {} items (cases), translating to JAXB.", items.size()); - Map> campaignsCache = new HashMap<>(); + Map> campaignsCache = new HashMap<>(); for (GetContainerableResult item : items) { @SuppressWarnings({ "raw", "unchecked" }) C value = (C) caseHelper.updateLoadedCertificationCase(item, campaignsCache, options, session, result); list.add(value); } } else if (workItems) { - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List items = rQuery.list(); LOGGER.trace("Found {} work items, translating to JAXB.", items.size()); - Map> casesCache = new HashMap<>(); - Map> campaignsCache = new HashMap<>(); + Map> casesCache = new HashMap<>(); + Map> campaignsCache = new HashMap<>(); for (GetCertificationWorkItemResult item : items) { //LOGGER.trace("- {}", item); @SuppressWarnings({ "raw", "unchecked" }) @@ -479,17 +478,17 @@ public SearchResultList searchContainersAttempt(Cla } } else { assert caseWorkItems; - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List items = rQuery.list(); LOGGER.trace("Found {} items (case work items), translating to JAXB.", items.size()); - Map> casesCache = new HashMap<>(); + Map> casesCache = new HashMap<>(); for (GetContainerableIdOnlyResult item : items) { try { @SuppressWarnings({ "raw", "unchecked" }) C value = (C) caseManagementHelper.updateLoadedCaseWorkItem(item, casesCache, options, session, result); list.add(value); - } catch (ObjectNotFoundException|DtoTranslationException e) { + } catch (ObjectNotFoundException | DtoTranslationException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't retrieve case work item for {}", e, item); } } @@ -745,7 +744,7 @@ private Collection> getIndexOnlyExtensi } private void applyShadowAttributeDefinitions(Class anyValueType, - PrismObject object, Session session) throws SchemaException { + PrismObject object, Session session) throws SchemaException { PrismContainer attributes = object.findContainer(ShadowType.F_ATTRIBUTES); @@ -753,7 +752,7 @@ private void applyShadowAttributeDefinitions(Class anyValue query.setParameter("oid", object.getOid()); query.setParameter("ownerType", RObjectExtensionType.ATTRIBUTES); - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({ "unchecked", "raw" }) List identifiers = query.list(); if (identifiers == null || identifiers.isEmpty()) { return; @@ -785,7 +784,7 @@ private MutableItemDefinition createDynamicDefinition(RExtItem extItem, ItemN RItemKind rValType = extItem.getKind(); MutableItemDefinition def; if (rValType == RItemKind.PROPERTY) { - def = prismContext.definitionFactory().createPropertyDefinition(name, type); + def = prismContext.definitionFactory().createPropertyDefinition(name, type); } else if (rValType == RItemKind.REFERENCE) { def = prismContext.definitionFactory().createReferenceDefinition(name, type); } else { @@ -797,40 +796,6 @@ private MutableItemDefinition createDynamicDefinition(RExtItem extItem, ItemN return def; } - public List> listResourceObjectShadowsAttempt( - String resourceOid, Class resourceObjectShadowType, OperationResult result) - throws ObjectNotFoundException, SchemaException { - - LOGGER_PERFORMANCE.debug("> list resource object shadows {}, for resource oid={}", - resourceObjectShadowType.getSimpleName(), resourceOid); - List> list = new ArrayList<>(); - Session session = null; - try { - session = baseHelper.beginReadOnlyTransaction(); - Query query = session.getNamedQuery("listResourceObjectShadows"); - query.setParameter("oid", resourceOid); - query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer()); - - @SuppressWarnings({"unchecked", "raw"}) - List shadows = query.list(); - LOGGER.debug("Query returned {} shadows, transforming to JAXB types.", shadows != null ? shadows.size() : 0); - - if (shadows != null) { - for (GetObjectResult shadow : shadows) { - PrismObject prismObject = updateLoadedObject(shadow, resourceObjectShadowType, null, null, null, session, result); - list.add(prismObject); - } - } - session.getTransaction().commit(); - } catch (SchemaException | RuntimeException ex) { - baseHelper.handleGeneralException(ex, session, result); - } finally { - baseHelper.cleanupSessionAndResult(session, result); - } - - return list; - } - private void validateObjectType(PrismObject prismObject, Class type) throws SchemaException { if (prismObject == null || !type.isAssignableFrom(prismObject.getCompileTimeClass())) { @@ -847,7 +812,7 @@ private void validateObjectType(PrismObject prismObjec } public String getVersionAttempt(Class type, String oid, OperationResult result) - throws ObjectNotFoundException, SchemaException { + throws ObjectNotFoundException { LOGGER_PERFORMANCE.debug("> get version {}, oid={}", type.getSimpleName(), oid); String version = null; @@ -874,8 +839,7 @@ public String getVersionAttempt(Class type, String oid } public void searchObjectsIterativeAttempt(Class type, ObjectQuery query, ResultHandler handler, - Collection> options, OperationResult result, Set retrievedOids) - throws SchemaException { + Collection> options, OperationResult result, Set retrievedOids) { Set newlyRetrievedOids = new HashSet<>(); Session session = null; try { @@ -945,7 +909,8 @@ public void searchObjectsIterativeByPaging(Class type, remaining = paging.getMaxSize() != null ? paging.getMaxSize() : repositoryService.countObjects(type, query, options, result) - offset; } -main: while (remaining > 0) { + main: + while (remaining > 0) { paging.setOffset(offset); paging.setMaxSize(remaining < batchSize ? remaining : batchSize); @@ -974,23 +939,23 @@ public void searchObjectsIterativeByPaging(Class type, /** * Strictly-sequential version of paged search. - * + *

    * Assumptions: - * - During processing of returned object(s), any objects can be added, deleted or modified. - * + * - During processing of returned object(s), any objects can be added, deleted or modified. + *

    * Guarantees: - * - We return each object that existed in the moment of search start: - * - exactly once if it was not deleted in the meanwhile, - * - at most once otherwise. - * - However, we may or may not return any objects that were added during the processing. - * + * - We return each object that existed in the moment of search start: + * - exactly once if it was not deleted in the meanwhile, + * - at most once otherwise. + * - However, we may or may not return any objects that were added during the processing. + *

    * Constraints: - * - There can be no ordering prescribed. We use our own ordering. - * - We also disallow any explicit paging - except for maxSize setting. - * - * Implementation is very simple - we fetch objects ordered by OID, and remember last OID fetched. - * Obviously no object will be present in output more than once. - * Objects that are not deleted will be there exactly once, provided their oid is not changed. + * - There can be no ordering prescribed. We use our own ordering. + * - We also disallow any explicit paging - except for maxSize setting. + *

    + * Implementation is very simple - we fetch objects ordered by OID, and remember last OID fetched. + * Obviously no object will be present in output more than once. + * Objects that are not deleted will be there exactly once, provided their oid is not changed. */ public void searchObjectsIterativeByPagingStrictlySequential( Class type, ObjectQuery query, ResultHandler handler, @@ -1017,7 +982,8 @@ public void searchObjectsIterativeByPagingStrictlySequent ObjectPaging paging = prismContext.queryFactory().createPaging(); pagedQuery.setPaging(paging); -main: for (;;) { + main: + for (; ; ) { paging.setCookie(lastOid != null ? lastOid : NULL_OID_MARKER); paging.setMaxSize(Math.min(batchSize, defaultIfNull(maxSize, Integer.MAX_VALUE))); @@ -1145,7 +1111,7 @@ void attachDiagDataIfRequested(PrismValue value, byte[] fullObject, Collection item, byte[] fullObject, Collection> options) { + private void attachDiagDataIfRequested(Item item, byte[] fullObject, Collection> options) { if (GetOperationOptions.isAttachDiagData(SelectorOptions.findRootOptions(options))) { item.setUserData(RepositoryService.KEY_DIAG_DATA, new RepositoryObjectDiagnosticData(getLength(fullObject))); }