diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.html index 3b5e28b758e..9afb3943214 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.html @@ -142,6 +142,7 @@

+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.java index 324bd7b9e6b..ee1cae5b8f8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAbout.java @@ -18,12 +18,16 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.model.api.ModelPublicConstants; import com.evolveum.midpoint.schema.LabeledString; import com.evolveum.midpoint.schema.ProvisioningDiag; import com.evolveum.midpoint.schema.RepositoryDiag; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.AuthorizationConstants; +import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.logging.LoggingUtils; @@ -32,9 +36,10 @@ import com.evolveum.midpoint.web.application.AuthorizationAction; import com.evolveum.midpoint.web.application.PageDescriptor; import com.evolveum.midpoint.web.component.AjaxButton; -import com.evolveum.midpoint.web.page.admin.home.PageAdminHome; - +import com.evolveum.midpoint.web.page.login.PageLogin; +import com.evolveum.midpoint.web.security.SecurityUtils; import org.apache.commons.lang.StringUtils; +import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; @@ -64,6 +69,7 @@ public class PageAbout extends PageAdminConfiguration { private static final String OPERATION_TEST_REPOSITORY = DOT_CLASS + "testRepository"; private static final String OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE = DOT_CLASS + "testRepositoryCheckOrgClosure"; private static final String OPERATION_GET_REPO_DIAG = DOT_CLASS + "getRepoDiag"; + private static final String OPERATION_SUBMIT_REINDEX = DOT_CLASS + "submitReindex"; private static final String OPERATION_GET_PROVISIONING_DIAG = DOT_CLASS + "getProvisioningDiag"; private static final String ID_BUILD = "build"; @@ -73,6 +79,7 @@ public class PageAbout extends PageAdminConfiguration { private static final String ID_LIST_SYSTEM_ITEMS = "listSystemItems"; private static final String ID_TEST_REPOSITORY = "testRepository"; private static final String ID_TEST_REPOSITORY_CHECK_ORG_CLOSURE = "testRepositoryCheckOrgClosure"; + private static final String ID_REINDEX_REPOSITORY_OBJECTS = "reindexRepositoryObjects"; private static final String ID_TEST_PROVISIONING = "testProvisioning"; private static final String ID_IMPLEMENTATION_SHORT_NAME = "implementationShortName"; private static final String ID_IMPLEMENTATION_DESCRIPTION = "implementationDescription"; @@ -229,6 +236,16 @@ public void onClick(AjaxRequestTarget target) { }; add(testRepositoryCheckOrgClosure); + AjaxButton reindexRepositoryObjects = new AjaxButton(ID_REINDEX_REPOSITORY_OBJECTS, + createStringResource("PageAbout.button.reindexRepositoryObjects")) { + + @Override + public void onClick(AjaxRequestTarget target) { + reindexRepositoryObjectsPerformed(target); + } + }; + add(reindexRepositoryObjects); + AjaxButton testProvisioning = new AjaxButton(ID_TEST_PROVISIONING, createStringResource("PageAbout.button.testProvisioning")) { @@ -306,7 +323,7 @@ private void testRepositoryPerformed(AjaxRequestTarget target) { } private void testRepositoryCheckOrgClosurePerformed(AjaxRequestTarget target) { - OperationResult result = new OperationResult(OPERATION_GET_PROVISIONING_DIAG); + OperationResult result = new OperationResult(OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE); try { Task task = createSimpleTask(OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE); getModelDiagnosticService().repositoryTestOrgClosureConsistency(task, true, result); @@ -320,6 +337,32 @@ private void testRepositoryCheckOrgClosurePerformed(AjaxRequestTarget target) { target.add(getFeedbackPanel()); } + private void reindexRepositoryObjectsPerformed(AjaxRequestTarget target) { + OperationResult result = new OperationResult(OPERATION_SUBMIT_REINDEX); + try { + TaskManager taskManager = getTaskManager(); + Task task = taskManager.createTaskInstance(); + MidPointPrincipal user = SecurityUtils.getPrincipalUser(); + if (user == null) { + throw new RestartResponseException(PageLogin.class); + } else { + task.setOwner(user.getUser().asPrismObject()); + } + getSecurityEnforcer().authorize(AuthorizationConstants.AUTZ_ALL_URL, null, null, null, null, null, result); + task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI); + task.setHandlerUri(ModelPublicConstants.REINDEX_TASK_HANDLER_URI); + task.setName("Reindex repository objects"); + taskManager.switchToBackground(task, result); + result.setBackgroundTaskOid(task.getOid()); + } catch (SecurityViolationException|SchemaException|RuntimeException e) { + result.recordFatalError(e); + } finally { + result.computeStatusIfUnknown(); + } + showResult(result); + target.add(getFeedbackPanel()); + } + private void testProvisioningPerformed(AjaxRequestTarget target) { Task task = createSimpleTask(OPERATION_TEST_REPOSITORY); diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index eca42922774..24f02eec332 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -880,6 +880,7 @@ OrgUnitBrowser.title=Choose new parent for org. unit PageAbout.allRightsReserved=©2014 Evolveum. PageAbout.button.testProvisioning=Provisioning self test PageAbout.button.testRepositoryCheckOrgClosure=Check and repair org closure consistency +PageAbout.button.reindexRepositoryObjects=Reindex repository objects PageAbout.button.testRepository=Repository self test PageAbout.message.couldntObtainJvmParams=Couldn't obtain JVM parameters from JMX. PageAbout.midPointRevision=${git.describe} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeTaskHandler.java index 71f96452335..3495baa5746 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeTaskHandler.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.prism.xml.ns._public.query_3.QueryType; @@ -80,19 +81,22 @@ public abstract class AbstractSearchIterativeTaskHandler handlers = Collections.synchronizedMap(new HashMap()); - @Autowired(required=true) + @Autowired protected TaskManager taskManager; - @Autowired(required=true) + @Autowired protected ModelObjectResolver modelObjectResolver; @Autowired @Qualifier("cacheRepositoryService") protected RepositoryService repositoryService; - @Autowired(required = true) + @Autowired protected PrismContext prismContext; - + + @Autowired + protected SecurityEnforcer securityEnforcer; + private static final transient Trace LOGGER = TraceManager.getTrace(AbstractSearchIterativeTaskHandler.class); protected AbstractSearchIterativeTaskHandler(String taskName, String taskOperationPrefix) { @@ -164,7 +168,16 @@ public TaskRunResult runInternal(Task coordinatorTask) { TaskRunResult runResult = new TaskRunResult(); runResult.setOperationResult(opResult); - H resultHandler = createHandler(runResult, coordinatorTask, opResult); + H resultHandler = null; + try { + resultHandler = createHandler(runResult, coordinatorTask, opResult); + } catch (SecurityViolationException|SchemaException|RuntimeException e) { + LOGGER.error("{}: Error while creating a result handler: {}", taskName, e.getMessage(), e); + opResult.recordFatalError("Error while creating a result handler: " + e.getMessage(), e); + runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR); + runResult.setProgress(coordinatorTask.getProgress()); + return runResult; + } if (resultHandler == null) { // the error should already be in the runResult return runResult; @@ -428,7 +441,7 @@ protected boolean useRepositoryDirectly(H resultHandler, TaskRunResult runResult protected abstract Class getType(Task task); protected abstract H createHandler(TaskRunResult runResult, Task coordinatorTask, - OperationResult opResult); + OperationResult opResult) throws SchemaException, SecurityViolationException; /** * Used to properly initialize the "run", which is kind of task instance. The result handler is already created at this stage. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java index 058742a4b87..da9d23de071 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java @@ -20,10 +20,12 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.schema.result.OperationConstants; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskCategory; import com.evolveum.midpoint.task.api.TaskRunResult; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; @@ -64,7 +66,9 @@ private void initialize() { } @Override - protected ReindexResultHandler createHandler(TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { + protected ReindexResultHandler createHandler(TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) + throws SchemaException, SecurityViolationException { + securityEnforcer.authorize(AuthorizationConstants.AUTZ_ALL_URL, null, null, null, null, null, opResult); return new ReindexResultHandler(coordinatorTask, ReindexTaskHandler.class.getName(), "reindex", "reindex", taskManager, repositoryService); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java index 8c969f10f5b..74dcbc0eac7 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.repo.api.RepoAddOptions; +import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; @@ -91,7 +92,11 @@ public class CertificationTest extends BaseSQLRepoTest { private String campaign2Oid; private PrismObjectDefinition campaignDef; - @Test + protected RepoModifyOptions getModifyOptions() { + return null; + } + + @Test public void test100AddCampaignNonOverwrite() throws Exception { PrismObject campaign = prismContext.parseObject(CAMPAIGN_1_FILE); campaignDef = campaign.getDefinition(); @@ -488,11 +493,16 @@ public void test900DeleteCampaign() throws Exception { } protected void executeAndCheckModification(List> modifications, OperationResult result, int versionDelta) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, IOException { - PrismObject before = getFullCampaign(campaign1Oid, result); + RepoModifyOptions modifyOptions = getModifyOptions(); + if (RepoModifyOptions.isExecuteIfNoChanges(modifyOptions) && versionDelta == 0) { + versionDelta = 1; + } + + PrismObject before = getFullCampaign(campaign1Oid, result); int expectedVersion = Integer.parseInt(before.getVersion()) + versionDelta; List savedModifications = (List) CloneUtil.cloneCollectionMembers(modifications); - repositoryService.modifyObject(AccessCertificationCampaignType.class, campaign1Oid, modifications, result); + repositoryService.modifyObject(AccessCertificationCampaignType.class, campaign1Oid, modifications, modifyOptions, result); checkCampaign(campaign1Oid, result, before, savedModifications, expectedVersion); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTestReindex.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTestReindex.java new file mode 100644 index 00000000000..d17e9f7dc4c --- /dev/null +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTestReindex.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.sql; + +import com.evolveum.midpoint.repo.api.RepoModifyOptions; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +/** + * The same as CertificationTest but with "executeIfNoChanges" (a.k.a. "reindex") option set. + * Certification cases have very special treatment in this respect. + * + * @author mederly + */ +@ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class CertificationTestReindex extends CertificationTest { + + protected RepoModifyOptions getModifyOptions() { + return RepoModifyOptions.createExecuteIfNoChanges(); + } + +} diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTest.java index 9998f8745e5..d4819cf5d30 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTest.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepoAddOptions; +import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; @@ -63,7 +64,11 @@ public class LookupTableTest extends BaseSQLRepoTest { private String tableOid; - @Test + protected RepoModifyOptions getModifyOptions() { + return null; + } + + @Test public void test100AddTableNonOverwrite() throws Exception { PrismObject table = prismContext.parseObject(new File(TEST_DIR, "table-1.xml")); OperationResult result = new OperationResult("test100AddTableNonOverwrite"); @@ -247,9 +252,13 @@ private void checkTable(String tableOid, PrismObject expectedOb } protected void executeAndCheckModification(List> modifications, OperationResult result, int versionDelta) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, IOException { - PrismObject before = getFullTable(tableOid, result); + RepoModifyOptions modifyOptions = getModifyOptions(); + if (RepoModifyOptions.isExecuteIfNoChanges(modifyOptions) && versionDelta == 0) { + versionDelta = 1; + } + PrismObject before = getFullTable(tableOid, result); - repositoryService.modifyObject(LookupTableType.class, tableOid, modifications, result); + repositoryService.modifyObject(LookupTableType.class, tableOid, modifications, modifyOptions, result); checkTable(tableOid, result, before, modifications, Integer.parseInt(before.getVersion()) + versionDelta); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTestReindex.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTestReindex.java new file mode 100644 index 00000000000..29eb0ff395f --- /dev/null +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/LookupTableTestReindex.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.sql; + +import com.evolveum.midpoint.repo.api.RepoModifyOptions; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +/** + * The same as LookupTableTest but with "executeIfNoChanges" (a.k.a. "reindex") option set. + * Although this flag causes no special behavior for lookup table rows, it's better to check. + * + * @author mederly + */ +@ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class LookupTableTestReindex extends LookupTableTest { + + protected RepoModifyOptions getModifyOptions() { + return RepoModifyOptions.createExecuteIfNoChanges(); + } + +} 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 17694287b11..ebd90f987f1 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 @@ -16,39 +16,8 @@ package com.evolveum.midpoint.repo.sql; -import java.io.File; -import java.io.IOException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import javax.xml.datatype.XMLGregorianCalendar; -import javax.xml.namespace.QName; - -import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import org.hibernate.Session; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; - import com.evolveum.midpoint.common.SynchronizationUtils; -import com.evolveum.midpoint.prism.PrismContainer; -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.PrismReferenceDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -58,10 +27,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.repo.sql.data.common.any.ROExtDate; -import com.evolveum.midpoint.repo.sql.data.common.any.ROExtLong; -import com.evolveum.midpoint.repo.sql.data.common.any.ROExtString; -import com.evolveum.midpoint.repo.sql.data.common.any.RValueType; +import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.repo.sql.testing.SqlRepoTestUtil; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; @@ -74,22 +40,25 @@ 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.MetadataType; -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.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.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.xml.sax.SAXException; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static org.testng.AssertJUnit.assertEquals; + /** * @author lazyman */ @@ -102,6 +71,10 @@ public void setup() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); } + + protected RepoModifyOptions getModifyOptions() { + return null; + } private static final Trace LOGGER = TraceManager.getTrace(ModifyTest.class); private static final File TEST_DIR = new File("src/test/resources/modify"); @@ -144,7 +117,7 @@ public void test020ModifyNotExistingUser() throws Exception { UserType.class, prismContext); OperationResult result = new OperationResult("MODIFY"); - repositoryService.modifyObject(UserType.class, "1234", deltas, result); + repositoryService.modifyObject(UserType.class, "1234", deltas, getModifyOptions(), result); } @Test(enabled = false) @@ -168,7 +141,7 @@ public void test030ModifyUserOnNonExistingAccountTest() throws Exception { Collection deltas = DeltaConvertor.toModifications(modification, UserType.class, prismContext); - repositoryService.modifyObject(UserType.class, oid, deltas, result); + repositoryService.modifyObject(UserType.class, oid, deltas, getModifyOptions(), result); PropertyDelta.applyTo(deltas, userOld); @@ -195,7 +168,7 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { String userOid = user.getOid(); String oid = repositoryService.addObject(user, null, result); - AssertJUnit.assertEquals(userOid, oid); + assertEquals(userOid, oid); PrismObject userOld = repositoryService.getObject(UserType.class, oid, null, result); @@ -206,7 +179,7 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { Collection deltas = DeltaConvertor.toModifications(modification, UserType.class, prismContext); - repositoryService.modifyObject(UserType.class, oid, deltas, result); + repositoryService.modifyObject(UserType.class, oid, deltas, getModifyOptions(), result); PropertyDelta.applyTo(deltas, userOld); @@ -246,13 +219,13 @@ public void test032ModifyTaskObjectRef() throws Exception { ReferenceDelta delta = new ReferenceDelta(def, prismContext); delta.addValueToAdd(new PrismReferenceValue("1", ResourceType.COMPLEX_TYPE)); modifications.add(delta); - repositoryService.modifyObject(TaskType.class, taskOid, modifications, result); + repositoryService.modifyObject(TaskType.class, taskOid, modifications, getModifyOptions(), result); System.out.println("GET"); getTask = repositoryService.getObject(TaskType.class, taskOid, null, result); taskType = getTask.asObjectable(); AssertJUnit.assertNotNull(taskType.getObjectRef()); objectRef = taskType.getObjectRef(); - AssertJUnit.assertEquals("1", objectRef.getOid()); + assertEquals("1", objectRef.getOid()); SqlRepoTestUtil.assertVersionProgress(lastVersion, getTask.getVersion()); lastVersion = getTask.getVersion(); @@ -263,7 +236,7 @@ public void test032ModifyTaskObjectRef() throws Exception { delta.addValueToDelete(new PrismReferenceValue("1", ResourceType.COMPLEX_TYPE)); delta.addValueToAdd(new PrismReferenceValue("2", ResourceType.COMPLEX_TYPE)); modifications.add(delta); - repositoryService.modifyObject(TaskType.class, taskOid, modifications, result); + repositoryService.modifyObject(TaskType.class, taskOid, modifications, getModifyOptions(), result); checkReference(taskOid); @@ -271,7 +244,7 @@ public void test032ModifyTaskObjectRef() throws Exception { taskType = getTask.asObjectable(); AssertJUnit.assertNotNull(taskType.getObjectRef()); objectRef = taskType.getObjectRef(); - AssertJUnit.assertEquals("2", objectRef.getOid()); + assertEquals("2", objectRef.getOid()); LOGGER.info(PrismTestUtil.serializeObjectToString(taskType.asPrismObject())); SqlRepoTestUtil.assertVersionProgress(lastVersion, getTask.getVersion()); lastVersion = getTask.getVersion(); @@ -281,7 +254,7 @@ public void test032ModifyTaskObjectRef() throws Exception { delta.addValueToDelete(new PrismReferenceValue("2", ResourceType.COMPLEX_TYPE)); delta.addValueToAdd(new PrismReferenceValue("1", ResourceType.COMPLEX_TYPE)); modifications.add(delta); - repositoryService.modifyObject(TaskType.class, taskOid, modifications, result); + repositoryService.modifyObject(TaskType.class, taskOid, modifications, getModifyOptions(), result); checkReference(taskOid); @@ -289,7 +262,7 @@ public void test032ModifyTaskObjectRef() throws Exception { taskType = getTask.asObjectable(); AssertJUnit.assertNotNull(taskType.getObjectRef()); objectRef = taskType.getObjectRef(); - AssertJUnit.assertEquals("1", objectRef.getOid()); + assertEquals("1", objectRef.getOid()); SqlRepoTestUtil.assertVersionProgress(lastVersion, getTask.getVersion()); lastVersion = getTask.getVersion(); } @@ -330,8 +303,8 @@ public void testModifyUserAddRole() throws Exception { repositoryService.addObject(roleLdap, null, parentResult); RoleType ldapRole = repositoryService.getObject(RoleType.class, ldapRoleOid, null, parentResult).asObjectable(); - AssertJUnit.assertEquals("Expected that the role has one approver.", 1, ldapRole.getApproverRef().size()); - AssertJUnit.assertEquals("Actual approved not equals to expected one.", userToModifyOid, ldapRole.getApproverRef().get(0).getOid()); + assertEquals("Expected that the role has one approver.", 1, ldapRole.getApproverRef().size()); + assertEquals("Actual approved not equals to expected one.", userToModifyOid, ldapRole.getApproverRef().get(0).getOid()); ObjectModificationType modification = PrismTestUtil.parseAtomicValue(new File(TEST_DIR + "/modify-user-add-roles.xml"), ObjectModificationType.COMPLEX_TYPE); @@ -340,10 +313,10 @@ public void testModifyUserAddRole() throws Exception { ObjectDelta delta = DeltaConvertor.createObjectDelta(modification, UserType.class, prismContext); - repositoryService.modifyObject(UserType.class, userToModifyOid, delta.getModifications(), parentResult); + repositoryService.modifyObject(UserType.class, userToModifyOid, delta.getModifications(), getModifyOptions(), parentResult); UserType modifiedUser = repositoryService.getObject(UserType.class, userToModifyOid, null, parentResult).asObjectable(); - AssertJUnit.assertEquals("wrong number of assignments", 3, modifiedUser.getAssignment().size()); + assertEquals("wrong number of assignments", 3, modifiedUser.getAssignment().size()); } @@ -368,7 +341,7 @@ public void testModifyDeleteObjectChangeFromAccount() throws Exception { System.out.println("\nDelta"); System.out.println(d.debugDump()); - repositoryService.modifyObject(ShadowType.class, oid, d.getModifications(), parentResult); + repositoryService.modifyObject(ShadowType.class, oid, d.getModifications(), getModifyOptions(), parentResult); PrismObject afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); AssertJUnit.assertNull(afterModify.asObjectable().getObjectChange()); @@ -413,7 +386,7 @@ public void testModifyAccountMetadata() throws Exception { Collection accountRefDeltas = ReferenceDelta.createModificationAddCollection( UserType.F_LINK_REF, user.getDefinition(), accountRef); - repositoryService.modifyObject(ShadowType.class, oid, accountRefDeltas, parentResult); + repositoryService.modifyObject(ShadowType.class, oid, accountRefDeltas, getModifyOptions(), parentResult); PrismObject afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); System.out.println("\nAfter modify"); @@ -428,7 +401,7 @@ public void testModifyAccountMetadata() throws Exception { .createXMLGregorianCalendar(System.currentTimeMillis())); modifications.add(pdelta); - repositoryService.modifyObject(ShadowType.class, oid, modifications, parentResult); + repositoryService.modifyObject(ShadowType.class, oid, modifications, getModifyOptions(), parentResult); afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); @@ -443,7 +416,7 @@ public void testModifyAccountMetadata() throws Exception { createSynchronizationSituationDelta(repoShadow, SynchronizationSituationType.LINKED); syncSituationDeltas.add(syncSituationDelta); - repositoryService.modifyObject(ShadowType.class, oid, syncSituationDeltas, parentResult); + repositoryService.modifyObject(ShadowType.class, oid, syncSituationDeltas, getModifyOptions(), parentResult); // AssertJUnit.assertNull(afterModify.asObjectable().getObjectChange()); afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); @@ -474,7 +447,7 @@ public void testExtensionModify() throws Exception { lootDelta.setValueToReplace(new PrismPropertyValue(456)); modifications.add(lootDelta); - repositoryService.modifyObject(UserType.class, oid, modifications, result); + repositoryService.modifyObject(UserType.class, oid, modifications, getModifyOptions(), result); //check read after modify operation user = prismContext.parseObject(userFile); @@ -503,14 +476,14 @@ public void testModifyAccountSynchronizationSituation() throws Exception { // createSynchronizationSituationDelta(account, SynchronizationSituationType.LINKED); // syncSituationDeltas.add(syncSituationDelta); - repositoryService.modifyObject(ShadowType.class, account.getOid(), syncSituationDeltas, result); + repositoryService.modifyObject(ShadowType.class, account.getOid(), syncSituationDeltas, getModifyOptions(), result); PrismObject afterFirstModify = repositoryService.getObject(ShadowType.class, account.getOid(), null, result); AssertJUnit.assertNotNull(afterFirstModify); ShadowType afterFirstModifyType = afterFirstModify.asObjectable(); - AssertJUnit.assertEquals(1, afterFirstModifyType.getSynchronizationSituationDescription().size()); + assertEquals(1, afterFirstModifyType.getSynchronizationSituationDescription().size()); SynchronizationSituationDescriptionType description = afterFirstModifyType.getSynchronizationSituationDescription().get(0); - AssertJUnit.assertEquals(SynchronizationSituationType.LINKED, description.getSituation()); + assertEquals(SynchronizationSituationType.LINKED, description.getSituation()); // timestamp = XmlTypeConverter.createXMLGregorianCalendar(System.currentTimeMillis()); @@ -524,17 +497,17 @@ public void testModifyAccountSynchronizationSituation() throws Exception { // ShadowType.F_SYNCHRONIZATION_TIMESTAMP, afterFirstModify.getDefinition(), timestamp); // syncSituationDeltas.add(syncTimestap); - repositoryService.modifyObject(ShadowType.class, account.getOid(), syncSituationDeltas, result); + repositoryService.modifyObject(ShadowType.class, account.getOid(), syncSituationDeltas, getModifyOptions(), result); PrismObject afterSecondModify = repositoryService.getObject(ShadowType.class, account.getOid(), null, result); AssertJUnit.assertNotNull(afterSecondModify); ShadowType afterSecondModifyType = afterSecondModify.asObjectable(); - AssertJUnit.assertEquals(1, afterSecondModifyType.getSynchronizationSituationDescription().size()); + assertEquals(1, afterSecondModifyType.getSynchronizationSituationDescription().size()); description = afterSecondModifyType.getSynchronizationSituationDescription().get(0); AssertJUnit.assertNull(description.getSituation()); XMLGregorianCalendar afterModifytimestamp = afterSecondModifyType.getSynchronizationTimestamp(); AssertJUnit.assertNotNull(afterModifytimestamp); - AssertJUnit.assertEquals(afterSecondModifyType.getSynchronizationTimestamp(), description.getTimestamp()); + assertEquals(afterSecondModifyType.getSynchronizationTimestamp(), description.getTimestamp()); LessFilter filter = LessFilter.createLess(ShadowType.F_SYNCHRONIZATION_TIMESTAMP, afterSecondModify.findProperty( ShadowType.F_SYNCHRONIZATION_TIMESTAMP).getDefinition(), afterModifytimestamp, true); @@ -542,7 +515,7 @@ public void testModifyAccountSynchronizationSituation() throws Exception { List> shadows = repositoryService.searchObjects(ShadowType.class, query, null, result); AssertJUnit.assertNotNull(shadows); - AssertJUnit.assertEquals(1, shadows.size()); + assertEquals(1, shadows.size()); System.out.println("shadow: " + shadows.get(0).debugDump()); } @@ -564,7 +537,7 @@ public void modifyRoleAddInducements() throws Exception { Collection deltas = DeltaConvertor.toModifications(modification, RoleType.class, prismContext); - repositoryService.modifyObject(RoleType.class, oid, deltas, result); + repositoryService.modifyObject(RoleType.class, oid, deltas, getModifyOptions(), result); result.recomputeStatus(); AssertJUnit.assertTrue(result.isSuccess()); @@ -574,9 +547,23 @@ public void modifyRoleAddInducements() throws Exception { AssertJUnit.assertTrue(result.isSuccess()); PrismContainer container = role.findContainer(RoleType.F_INDUCEMENT); - AssertJUnit.assertEquals(2, container.size()); + assertEquals(2, container.size()); AssertJUnit.assertNotNull(container.getValue(2L)); AssertJUnit.assertNotNull(container.getValue(3L)); - } + + // modify role once more to check version progress + String version = role.getVersion(); + repositoryService.modifyObject(RoleType.class, oid, new ArrayList(), getModifyOptions(), result); + result.recomputeStatus(); + AssertJUnit.assertTrue(result.isSuccess()); + role = repositoryService.getObject(RoleType.class, oid, null, result); + result.recomputeStatus(); + AssertJUnit.assertTrue(result.isSuccess()); + if (RepoModifyOptions.isExecuteIfNoChanges(getModifyOptions())) { + SqlRepoTestUtil.assertVersionProgress(version, role.getVersion()); + } else { + assertEquals("Version has changed", version, role.getVersion()); + } + } } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTestReindex.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTestReindex.java new file mode 100644 index 00000000000..12637a7c24e --- /dev/null +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTestReindex.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.sql; + +import com.evolveum.midpoint.repo.api.RepoModifyOptions; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +/** + * The same as ModifyTest but with "executeIfNoChanges" (a.k.a. "reindex") option set. + * Although this option should do no harm in objects other than certification cases and lookup tables, + * it is better to check. + * + * @author mederly + */ +@ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class ModifyTestReindex extends ModifyTest { + + @Override + protected RepoModifyOptions getModifyOptions() { + return RepoModifyOptions.createExecuteIfNoChanges(); + } +} diff --git a/repo/repo-sql-impl-test/testng-integration.xml b/repo/repo-sql-impl-test/testng-integration.xml index 864619d9575..599974ddf6f 100644 --- a/repo/repo-sql-impl-test/testng-integration.xml +++ b/repo/repo-sql-impl-test/testng-integration.xml @@ -32,6 +32,7 @@ + @@ -42,7 +43,9 @@ + + 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 e66d678127b..7911c74192e 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 @@ -513,7 +513,7 @@ public void modifyObject(Class type, String oid, try { while (true) { try { - objectUpdater.modifyObjectAttempt(type, oid, modifications, subResult); + objectUpdater.modifyObjectAttempt(type, oid, modifications, options, subResult); return; } catch (RuntimeException ex) { attempt = baseHelper.logOperationAttempt(oid, operation, attempt, ex, subResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java index b58321ebb7a..ffd7bbfa0eb 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java @@ -119,7 +119,8 @@ // doesn't work; generates SQL of "delete from m_acc_cert_case_reference where owner_owner_oid=? and owner_id=? and owner_owner_oid=? and reference_type=? and relation=? and targetOid=?" //@NamedQuery(name = "delete.campaignCaseReferences", query = "delete RCertCaseReference r where r.ownerOid = :oid and r.id = :id"), @NamedQuery(name = "resolveReferences", query = "select o.oid, o.name from RObject as o where o.oid in (:oid)"), - @NamedQuery(name = "get.campaignCase", query = "select c.fullObject from RAccessCertificationCase c where c.ownerOid=:ownerOid and c.id=:id") + @NamedQuery(name = "get.campaignCase", query = "select c.fullObject from RAccessCertificationCase c where c.ownerOid=:ownerOid and c.id=:id"), + @NamedQuery(name = "get.campaignCases", query = "select c.fullObject from RAccessCertificationCase c where c.ownerOid=:ownerOid") }) @QueryEntity( anyElements = { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/CertificationCaseHelper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/CertificationCaseHelper.java index 6e1da7082cc..cbf59ce7b67 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/CertificationCaseHelper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/CertificationCaseHelper.java @@ -23,13 +23,15 @@ import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.ItemPathSegment; -import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.repo.sql.data.common.RAccessCertificationCampaign; import com.evolveum.midpoint.repo.sql.data.common.RObject; import com.evolveum.midpoint.repo.sql.data.common.container.RAccessCertificationCase; import com.evolveum.midpoint.repo.sql.data.common.container.RCertCaseReference; -import com.evolveum.midpoint.repo.sql.query.QueryException; -import com.evolveum.midpoint.repo.sql.util.*; +import com.evolveum.midpoint.repo.sql.util.DtoTranslationException; +import com.evolveum.midpoint.repo.sql.util.GetContainerableResult; +import com.evolveum.midpoint.repo.sql.util.PrismIdentifierGenerator; +import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; @@ -50,10 +52,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Contains methods specific to handle certification cases. @@ -160,15 +159,15 @@ public Collection filterCampaignCase } public void updateCampaignCases(Session session, String campaignOid, - Collection modifications) throws SchemaException, ObjectNotFoundException, DtoTranslationException { - if (modifications.isEmpty()) { + Collection modifications, RepoModifyOptions modifyOptions) throws SchemaException, ObjectNotFoundException, DtoTranslationException { + if (modifications.isEmpty() && !RepoModifyOptions.isExecuteIfNoChanges(modifyOptions)) { return; } List casesAddedOrDeleted = addOrDeleteCases(session, campaignOid, modifications); LOGGER.trace("Cases added/deleted (null means REPLACE operation) = {}", casesAddedOrDeleted); - updateCasesContent(session, campaignOid, modifications, casesAddedOrDeleted); + updateCasesContent(session, campaignOid, modifications, casesAddedOrDeleted, modifyOptions); } protected List addOrDeleteCases(Session session, String campaignOid, Collection modifications) throws SchemaException, DtoTranslationException { @@ -225,7 +224,9 @@ protected List addOrDeleteCases(Session session, String campaignOid, Colle return replacePresent ? null : affectedIds; } - private void updateCasesContent(Session session, String campaignOid, Collection modifications, List casesAddedOrDeleted) throws SchemaException, ObjectNotFoundException, DtoTranslationException { + private void updateCasesContent(Session session, String campaignOid, Collection modifications, + List casesAddedOrDeleted, RepoModifyOptions modifyOptions) throws SchemaException, ObjectNotFoundException, DtoTranslationException { + Set casesModified = new HashSet<>(); for (ItemDelta delta : modifications) { ItemPath deltaPath = delta.getPath(); if (deltaPath.size() > 1) { @@ -255,9 +256,30 @@ private void updateCasesContent(Session session, String campaignOid, Collection< RAccessCertificationCase rCase = RAccessCertificationCase.toRepo(campaignOid, aCase, prismContext); session.merge(rCase); - LOGGER.trace("Access certification case " + rCase + " merged."); + LOGGER.trace("Access certification case {} merged", rCase); + casesModified.add(aCase.getId()); } } + + // refresh campaign cases, if requested + if (RepoModifyOptions.isExecuteIfNoChanges(modifyOptions)) { + Query query = session.getNamedQuery("get.campaignCases"); + query.setString("ownerOid", campaignOid); + List cases = query.list(); + for (Object o : cases) { + if (!(o instanceof byte[])) { + throw new IllegalStateException("Certification case: expected byte[], got " + o.getClass()); + } + byte[] fullObject = (byte[]) o; + AccessCertificationCaseType aCase = RAccessCertificationCase.createJaxb(fullObject, prismContext, false); + Long id = aCase.getId(); + if (id != null && casesAddedOrDeleted != null && !casesAddedOrDeleted.contains(id) && !casesModified.contains(id)) { + RAccessCertificationCase rCase = RAccessCertificationCase.toRepo(campaignOid, aCase, prismContext); + session.merge(rCase); + LOGGER.trace("Access certification case {} refreshed", rCase); + } + } + } } private long checkPathSanity(ItemPath deltaPath, List casesAddedOrDeleted) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index f0df4ee601d..581b981e716 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.repo.api.RepoAddOptions; +import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.sql.SerializationRelatedException; import com.evolveum.midpoint.repo.sql.SqlRepositoryConfiguration; @@ -64,10 +65,7 @@ import java.lang.reflect.Method; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * @author lazyman, mederly @@ -342,8 +340,8 @@ public void deleteObjectAttempt(Class type, String oid } public void modifyObjectAttempt(Class type, String oid, - Collection modifications, - OperationResult result) throws ObjectNotFoundException, + Collection modifications, + RepoModifyOptions modifyOptions, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, SerializationRelatedException { // clone - because some certification and lookup table related methods manipulate this collection and even their constituent deltas @@ -367,7 +365,7 @@ public void modifyObjectAttempt(Class type, String oid Collection lookupTableModifications = lookupTableHelper.filterLookupTableModifications(type, modifications); Collection campaignCaseModifications = caseHelper.filterCampaignCaseModifications(type, modifications); - if (!modifications.isEmpty()) { + if (!modifications.isEmpty() || RepoModifyOptions.isExecuteIfNoChanges(modifyOptions)) { // JpegPhoto (RFocusPhoto) is a special kind of entity. First of all, it is lazily loaded, because photos are really big. // Each RFocusPhoto naturally belongs to one RFocus, so it would be appropriate to set orphanRemoval=true for focus-photo @@ -385,7 +383,7 @@ public void modifyObjectAttempt(Class type, String oid Collection> options; boolean containsFocusPhotoModification = FocusType.class.isAssignableFrom(type) && containsPhotoModification(modifications); if (containsFocusPhotoModification) { - options = Arrays.asList(SelectorOptions.create(FocusType.F_JPEG_PHOTO, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE))); + options = Collections.singletonList(SelectorOptions.create(FocusType.F_JPEG_PHOTO, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE))); } else { options = null; } @@ -434,7 +432,7 @@ public void modifyObjectAttempt(Class type, String oid lookupTableHelper.updateLookupTableData(session, oid, lookupTableModifications); } if (AccessCertificationCampaignType.class.isAssignableFrom(type)) { - caseHelper.updateCampaignCases(session, oid, campaignCaseModifications); + caseHelper.updateCampaignCases(session, oid, campaignCaseModifications, modifyOptions); } LOGGER.trace("Before commit...");