Skip to content

Commit

Permalink
repo-sqale: fixed modification of pendingOperation/1/..., tests
Browse files Browse the repository at this point in the history
Modification of the whole container for count column was already
supported, but the resolver for delta was not found for modifications
going inside - now it correctly ignores such a modification.
This also fixed TestMultiResource from model-intests (among others).
  • Loading branch information
virgo47 committed Jul 29, 2021
1 parent 6c836b5 commit 9758b33
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
4 changes: 3 additions & 1 deletion model/model-intest/testng-integration-sqale.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
TODO: subclass of the above, but more is failing, probably because of missing RAW support?
<class name="com.evolveum.midpoint.model.intest.TestModelServiceContractCaching"/>
-->
<!--
<class name="com.evolveum.midpoint.model.intest.TestModelCrudService"/>
<class name="com.evolveum.midpoint.model.intest.TestPreviewChanges"/>
<class name="com.evolveum.midpoint.model.intest.multi.TestMultiResource"/>
<class name="com.evolveum.midpoint.model.intest.multi.TestMultiAccount"/>
<class name="com.evolveum.midpoint.model.intest.multi.TestMultiConnectorResources"/>
<!--
<class name="com.evolveum.midpoint.model.intest.TestUserTemplate"/>
<class name="com.evolveum.midpoint.model.intest.TestUserTemplateWithRanges"/>
<class name="com.evolveum.midpoint.model.intest.orgstruct.TestOrgStruct"/>
Expand All @@ -59,7 +59,9 @@
<class name="com.evolveum.midpoint.model.intest.TestTolerantAttributes"/>
<class name="com.evolveum.midpoint.model.intest.TestScriptHooks"/>
<class name="com.evolveum.midpoint.model.intest.TestEntitlements"/>
-->
<class name="com.evolveum.midpoint.model.intest.TestCaseIgnore"/>
<!--
<class name="com.evolveum.midpoint.model.intest.TestIntent"/>
<class name="com.evolveum.midpoint.model.intest.gensync.TestEditSchema"/>
<class name="com.evolveum.midpoint.model.intest.gensync.TestRoleEntitlement"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public DelegatingItemDeltaProcessor(SqaleUpdateContext<?, ?, ?> context) {

@Override
public void process(ItemDelta<?, ?> modification) throws RepositoryException, SchemaException {
QName itemName = resolvePath(modification.getPath());
QName itemName = resolvePath(modification);
if (itemName == null) {
// This may indicate forgotten mapping, but normally it means that the item is simply
// not externalized and there is nothing to, update is only in fullObject.
Expand All @@ -65,7 +65,8 @@ public void process(ItemDelta<?, ?> modification) throws RepositoryException, Sc
// It's a similar case like the fast return after resolving the path.
}

private QName resolvePath(ItemPath path) {
private QName resolvePath(ItemDelta<?, ?> modification) {
ItemPath path = modification.getPath();
while (!path.isSingleName()) {
ItemName firstName = path.firstName();
path = path.rest();
Expand All @@ -79,7 +80,8 @@ private QName resolvePath(ItemPath path) {
if (!(relationResolver instanceof SqaleItemRelationResolver)) {
// Again, programmers fault.
throw new IllegalArgumentException("Relation resolver for " + firstName
+ " in mapping " + mapping + " does not support delta modifications!");
+ " in mapping " + mapping + " does not support delta modifications. "
+ "Used modification: " + modification);
}

ItemPath subcontextPath = firstName;
Expand All @@ -96,6 +98,9 @@ private QName resolvePath(ItemPath path) {
//noinspection unchecked,rawtypes
subcontext = ((SqaleItemRelationResolver) relationResolver)
.resolve(this.context, subcontextPath);
if (subcontext == null) {
return null; // this means "ignore"
}
context.addSubcontext(subcontextPath, subcontext);
}
context = subcontext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.NumberPath;

import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.sqale.SqaleQueryContext;
import com.evolveum.midpoint.repo.sqale.update.SqaleUpdateContext;
import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext;
import com.evolveum.midpoint.repo.sqlbase.mapping.ItemRelationResolver;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;

/**
Expand All @@ -23,7 +24,7 @@
* @param <R> row type of {@link Q}
*/
public class CountMappingResolver<Q extends FlexibleRelationalPathBase<R>, R>
implements ItemRelationResolver<Q, R, Q, R> {
implements SqaleItemRelationResolver<Q, R, Q, R> {

private final Function<Q, NumberPath<Integer>> rootToCount;

Expand All @@ -41,4 +42,10 @@ public ResolutionResult<Q, R> resolve(SqlQueryContext<?, Q, R> context) {
public Predicate createExistsPredicate(SqaleQueryContext<?, Q, R> context) {
return rootToCount.apply(context.path()).gt(0);
}

@Override
public SqaleUpdateContext<?, ?, ?> resolve(
SqaleUpdateContext<?, Q, R> context, ItemPath itemPath) {
return null; // indicates ignore
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public interface SqaleItemRelationResolver<
* The information about the resolved item is captured in the instance resolver already
* in a manner that is specific for various types of resolution (JOIN or nested mapping).
* Optional {@link ItemPath} is provided for cases when container ID is necessary.
*
* Return value `null` indicates that the modification using the resolver should be ignored
* by the repository.
*/
SqaleUpdateContext<?, ?, ?> resolve(SqaleUpdateContext<?, Q, R> context, ItemPath itemPath);
}
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,39 @@ public void test150PendingOperationCountColumn() throws Exception {
}

@Test
public void test151PendingOperationCountStoresZeroForEmptyContainer() throws Exception {
public void test151PendingOperationItemModification() throws Exception {
OperationResult result = createOperationResult();

given("delta changing property inside existing pending operation container");
Long cid = repositoryService.getObject(ShadowType.class, shadow1Oid, null, result)
.asObjectable().getPendingOperation().get(0).getId();
ObjectDelta<ShadowType> delta = prismContext.deltaFor(ShadowType.class)
.item(ShadowType.F_PENDING_OPERATION, cid, PendingOperationType.F_COMPLETION_TIMESTAMP)
.add(MiscUtil.asXMLGregorianCalendar(2L))
.asObjectDelta(shadow1Oid);

when("modifyObject is called");
repositoryService.modifyObject(
ShadowType.class, shadow1Oid, delta.getModifications(), result);

then("operation is successful");
assertThatOperationResult(result).isSuccess();

and("serialized form (fullObject) is updated");
ShadowType shadowObject = repositoryService
.getObject(ShadowType.class, shadow1Oid, null, result)
.asObjectable();
assertThat(shadowObject.getPendingOperation()).hasSize(1);
assertThat(shadowObject.getPendingOperation().get(0).getCompletionTimestamp())
.isEqualTo(MiscUtil.asXMLGregorianCalendar(2L));

and("externalized column is still having (the same) count");
MShadow row = selectObjectByOid(QShadow.class, shadow1Oid);
assertThat(row.pendingOperationCount).isEqualTo(1);
}

@Test
public void test152PendingOperationCountStoresZeroForEmptyContainer() throws Exception {
OperationResult result = createOperationResult();

given("delta clearing the pending operation container for shadow 1");
Expand Down

0 comments on commit 9758b33

Please sign in to comment.