From 0fbaf28da5bd0aef71cc955957910cc1813b89a1 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 16 Aug 2018 16:37:21 +0200 Subject: [PATCH] Fix pendingOperationsCount update (MID-4831) --- .../midpoint/repo/sql/ModifyTest.java | 95 ++++++++++++++++--- .../repo/sql/helpers/ObjectDeltaUpdater.java | 31 ++++++ 2 files changed, 113 insertions(+), 13 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java index 9ec1b7cbce1..fbbde3e64db 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java @@ -18,6 +18,7 @@ import static com.evolveum.midpoint.prism.SerializationOptions.createSerializeForExport; import static com.evolveum.midpoint.schema.GetOperationOptions.createRawCollection; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; @@ -34,6 +35,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.hibernate.Session; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -94,19 +96,6 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationDescriptionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; @@ -1008,4 +997,84 @@ public void test210ModifyObjectCollection() throws Exception { assertTrue("Filters differ", filterExpectedParsed.equals(filterFromRepoParsed, false)); } + /** + * Add shadow pendingOperations; MID-4831 + */ + @Test + public void test250AddShadowPendingOperations() throws Exception { + final String TEST_NAME = "test250AddShadowPendingOperations"; + TestUtil.displayTestTitle(TEST_NAME); + + // GIVEN + OperationResult result = new OperationResult(TEST_NAME); + + PrismObject shadow = prismContext.createObjectable(ShadowType.class) + .name("shadow1") + .oid("000-aaa-bbb-ccc") + .asPrismObject(); + repositoryService.addObject(shadow, null, result); + + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_NAME).eqPoly("shadow1") + .and().exists(ShadowType.F_PENDING_OPERATION) + .build(); + + List> objectsBefore = repositoryService.searchObjects(ShadowType.class, query, null, result); + assertEquals("Wrong # of shadows found (before)", 0, objectsBefore.size()); + + // WHEN + + List> itemDeltas = DeltaBuilder.deltaFor(ShadowType.class, prismContext) + .item(ShadowType.F_PENDING_OPERATION).add(new PendingOperationType(prismContext).executionStatus(COMPLETED)) + .asItemDeltas(); + repositoryService.modifyObject(ShadowType.class, shadow.getOid(), itemDeltas, getModifyOptions(), result); + + // THEN + + List> objectsAfter = repositoryService.searchObjects(ShadowType.class, query, null, result); + assertEquals("Wrong # of shadows found (after)", 1, objectsAfter.size()); + display("object found (after)", objectsAfter.get(0)); + } + + /** + * Delete shadow pendingOperations; MID-4831 + */ + @Test + public void test260DeleteShadowPendingOperations() throws Exception { + final String TEST_NAME = "test260DeleteShadowPendingOperations"; + TestUtil.displayTestTitle(TEST_NAME); + + // GIVEN + OperationResult result = new OperationResult(TEST_NAME); + + PrismObject shadow = prismContext.createObjectable(ShadowType.class) + .name("shadow2") + .oid("000-aaa-bbb-ddd") + .beginPendingOperation() + .executionStatus(COMPLETED) + .end() + .asPrismObject(); + repositoryService.addObject(shadow, null, result); + + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_NAME).eqPoly("shadow2") + .and().exists(ShadowType.F_PENDING_OPERATION) + .build(); + List> objectsBefore = repositoryService.searchObjects(ShadowType.class, query, null, result); + assertEquals("Wrong # of shadows found (before)", 1, objectsBefore.size()); + display("object found (before)", objectsBefore.get(0)); + + // WHEN + + List> itemDeltas = DeltaBuilder.deltaFor(ShadowType.class, prismContext) + .item(ShadowType.F_PENDING_OPERATION).replace() + .asItemDeltas(); + repositoryService.modifyObject(ShadowType.class, shadow.getOid(), itemDeltas, getModifyOptions(), result); + + // THEN + + List> objectsAfter = repositoryService.searchObjects(ShadowType.class, query, null, result); + assertEquals("Wrong # of shadows found (after)", 0, objectsAfter.size()); + } + } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectDeltaUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectDeltaUpdater.java index d3a77e415f7..8de6060ea1e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectDeltaUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectDeltaUpdater.java @@ -121,6 +121,8 @@ public RObject modifyObject(Class type, String oid, ManagedType mainEntityType = entityRegistry.getJaxbMapping(type); + boolean modifiesShadowPendingOperation = false; + for (ItemDelta delta : processedModifications) { ItemPath path = delta.getPath(); @@ -176,6 +178,10 @@ public RObject modifyObject(Class type, String oid, continue; } + if (isShadowPendingOperation(object, delta)) { + modifiesShadowPendingOperation = true; + } + Attribute attribute = findAttribute(attributeStep, nameLocalPart, path, segments, nameSegment); if (attribute == null) { // there's no table/column that needs update @@ -198,8 +204,13 @@ public RObject modifyObject(Class type, String oid, } } + // the following will apply deltas to prismObject handleObjectCommonAttributes(type, processedModifications, prismObject, object, idGenerator); + if (modifiesShadowPendingOperation) { + handleShadowPendingOperation(object, prismObject); + } + LOGGER.trace("Entity changes applied"); return object; @@ -313,6 +324,26 @@ private void handleOperationResult(Object bean, ItemDelta delta) { } } + + private boolean isShadowPendingOperation(RObject object, ItemDelta delta) { + return object instanceof RShadow && new ItemPath(ShadowType.F_PENDING_OPERATION).equals(delta.getPath()); + } + + private void handleShadowPendingOperation(RObject bean, PrismObject prismObject) throws SchemaException { + if (!(bean instanceof RShadow)) { + throw new SystemException("Bean is not instance of " + RShadow.class + ", shouldn't happen"); + } + RShadow shadow = (RShadow) bean; + + T objectable = prismObject.asObjectable(); + if (!(objectable instanceof ShadowType)) { + throw new SystemException("PrismObject is not instance of " + ShadowType.class + ", shouldn't happen"); + } + ShadowType shadowType = (ShadowType) objectable; + + shadow.setPendingOperationCount(shadowType.getPendingOperation().size()); + } + private void handleObjectCommonAttributes(Class type, Collection modifications, PrismObject prismObject, RObject object, PrismIdentifierGenerator idGenerator) throws SchemaException {