From ab5109c732e18d134f7c0541b51f3041e2b30d45 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 10 Oct 2016 17:33:57 +0200 Subject: [PATCH 1/5] Fixing endless loop (stack overflow) in consistency (MID-3451) --- .../icf/dummy/connector/DummyConnector.java | 38 ++++++-- .../icf/dummy/resource/BreakMode.java | 1 + .../icf/dummy/resource/ConflictException.java | 40 ++++++++ .../icf/dummy/resource/DummyAccount.java | 6 +- .../icf/dummy/resource/DummyGroup.java | 6 +- .../icf/dummy/resource/DummyObject.java | 32 ++++--- .../icf/dummy/resource/DummyResource.java | 96 ++++++++++++------- .../model/impl/lens/ChangeExecutor.java | 56 ++++++----- .../model/impl/lens/TestDependencies.java | 5 +- .../midpoint/model/intest/TestActivation.java | 13 +-- .../midpoint/model/intest/TestIteration.java | 3 +- .../midpoint/model/intest/TestMapping.java | 15 +-- .../model/intest/TestModelCrudService.java | 23 ++--- .../model/intest/TestMultiResource.java | 3 +- .../midpoint/model/intest/TestPassword.java | 3 +- .../model/intest/TestStrangeCases.java | 50 ++++++++++ .../AbstractSynchronizationStoryTest.java | 5 +- .../resources/common/resource-dummy-red.xml | 12 +++ .../test/AbstractModelIntegrationTest.java | 55 +++++------ .../api/ProvisioningOperationOptions.java | 61 ++++++++---- .../consistency/api/ErrorHandler.java | 18 +--- .../impl/CommunicationExceptionHandler.java | 12 ++- .../impl/ConfigurationExceptionHandler.java | 12 ++- .../consistency/impl/GenericErrorHandler.java | 12 ++- .../impl/ObjectAlreadyExistHandler.java | 14 ++- .../impl/ObjectNotFoundHandler.java | 14 ++- .../impl/SchemaExceptionHandler.java | 12 ++- .../impl/SecurityViolationHandler.java | 12 ++- .../provisioning/impl/ShadowCache.java | 56 ++++++++--- .../impl/dummy/AbstractDummyTest.java | 15 +-- .../dummy/TestDummyUuidNonUniqueName.java | 5 +- .../midpoint/test/DummyResourceContoller.java | 15 +-- .../testing/consistency/ConsistencyTest.java | 4 +- 33 files changed, 497 insertions(+), 227 deletions(-) create mode 100644 icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/ConflictException.java diff --git a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java index df61fee7842..5f36812d9f5 100644 --- a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java +++ b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java @@ -71,6 +71,7 @@ import org.identityconnectors.framework.spi.operations.TestOp; import org.identityconnectors.framework.spi.operations.UpdateAttributeValuesOp; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyAttributeDefinition; import com.evolveum.icf.dummy.resource.DummyDelta; @@ -268,6 +269,8 @@ public Uid create(final ObjectClass objectClass, final Set createAttr throw new ConnectorIOException(e.getMessage(), e); } catch (SchemaViolationException e) { throw new InvalidAttributeValueException(e); + } catch (ConflictException e) { + throw new AlreadyExistsException(e); } String id; @@ -505,6 +508,9 @@ public Uid update(ObjectClass objectClass, Uid uid, Set replaceAttrib } catch (SchemaViolationException e) { log.info("update::exception "+e); throw new InvalidAttributeValueException(e.getMessage(), e); + } catch (ConflictException e) { + log.info("update::exception "+e); + throw new AlreadyExistsException(e); } log.info("update::end"); @@ -698,6 +704,9 @@ public Uid addAttributeValues(ObjectClass objectClass, Uid uid, Set v } catch (SchemaViolationException e) { log.info("addAttributeValues::exception "+e); throw new InvalidAttributeValueException(e.getMessage(), e); + } catch (ConflictException e) { + log.info("addAttributeValues::exception "+e); + throw new AlreadyExistsException(e); } return uid; @@ -874,6 +883,9 @@ public Uid removeAttributeValues(ObjectClass objectClass, Uid uid, Set createAttributes) throws ConnectException, FileNotFoundException, SchemaViolationException { + private DummyAccount convertToAccount(Set createAttributes) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { log.ok("Create attributes: {0}", createAttributes); String userName = Utils.getMandatoryStringAttribute(createAttributes, Name.NAME); if (configuration.getUpCaseName()) { @@ -1725,7 +1751,7 @@ private DummyAccount convertToAccount(Set createAttributes) throws Co return newAccount; } - private DummyGroup convertToGroup(Set createAttributes) throws ConnectException, FileNotFoundException, SchemaViolationException { + private DummyGroup convertToGroup(Set createAttributes) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { String icfName = Utils.getMandatoryStringAttribute(createAttributes,Name.NAME); if (configuration.getUpCaseName()) { icfName = StringUtils.upperCase(icfName); @@ -1774,7 +1800,7 @@ private DummyGroup convertToGroup(Set createAttributes) throws Connec return newGroup; } - private DummyPrivilege convertToPriv(Set createAttributes) throws ConnectException, FileNotFoundException { + private DummyPrivilege convertToPriv(Set createAttributes) throws ConnectException, FileNotFoundException, ConflictException { String icfName = Utils.getMandatoryStringAttribute(createAttributes,Name.NAME); if (configuration.getUpCaseName()) { icfName = StringUtils.upperCase(icfName); @@ -1807,7 +1833,7 @@ private DummyPrivilege convertToPriv(Set createAttributes) throws Con return newPriv; } - private DummyOrg convertToOrg(Set createAttributes) throws ConnectException, FileNotFoundException { + private DummyOrg convertToOrg(Set createAttributes) throws ConnectException, FileNotFoundException, ConflictException { String icfName = Utils.getMandatoryStringAttribute(createAttributes,Name.NAME); if (configuration.getUpCaseName()) { icfName = StringUtils.upperCase(icfName); @@ -1879,7 +1905,7 @@ private Date getDate(Attribute attr) { } - private void changePassword(final DummyAccount account, Attribute attr) throws ConnectException, FileNotFoundException, SchemaViolationException { + private void changePassword(final DummyAccount account, Attribute attr) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { final String[] passwdArray = { null }; if (attr.getValue() != null && !attr.getValue().isEmpty()) { Object passwdObject = attr.getValue().get(0); diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/BreakMode.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/BreakMode.java index 057596b9b8d..22c45cd5fcd 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/BreakMode.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/BreakMode.java @@ -25,6 +25,7 @@ public enum BreakMode { NETWORK, IO, SCHEMA, + CONFLICT, // results in AlreadyExists exceptions GENERIC, UNSUPPORTED, RUNTIME; diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/ConflictException.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/ConflictException.java new file mode 100644 index 00000000000..617b93588ab --- /dev/null +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/ConflictException.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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.icf.dummy.resource; + +/** + * @author semancik + * + */ +public class ConflictException extends Exception { + + public ConflictException() { + super(); + } + + public ConflictException(String message, Throwable cause) { + super(message, cause); + } + + public ConflictException(String message) { + super(message); + } + + public ConflictException(Throwable cause) { + super(cause); + } + +} diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyAccount.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyAccount.java index af9c7b191b5..3b6262b86f9 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyAccount.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyAccount.java @@ -55,7 +55,7 @@ public String getPassword() { return password; } - public void setPassword(String password) throws ConnectException, FileNotFoundException, SchemaViolationException { + public void setPassword(String password) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); this.password = password; } @@ -64,13 +64,13 @@ public Boolean isLockout() { return lockout; } - public void setLockout(boolean lockout) throws ConnectException, FileNotFoundException, SchemaViolationException { + public void setLockout(boolean lockout) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); this.lockout = lockout; } @Override - protected DummyObjectClass getObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyObjectClass getObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return resource.getAccountObjectClass(); } diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyGroup.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyGroup.java index 708f9c94cb5..e3445bf5542 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyGroup.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * 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. @@ -48,7 +48,7 @@ public Collection getMembers() { return getAttributeValues(ATTR_MEMBERS_NAME, String.class); } - public void addMember(String newMember) throws SchemaViolationException, ConnectException, FileNotFoundException { + public void addMember(String newMember) throws SchemaViolationException, ConnectException, FileNotFoundException, ConflictException { addAttributeValue(ATTR_MEMBERS_NAME, newMember); } @@ -60,7 +60,7 @@ public boolean containsMember(String member) { return members.contains(member); // TODO ok? what about case ignoring scenarios? } - public void removeMember(String newMember) throws SchemaViolationException, ConnectException, FileNotFoundException { + public void removeMember(String newMember) throws SchemaViolationException, ConnectException, FileNotFoundException, ConflictException { removeAttributeValue(ATTR_MEMBERS_NAME, newMember); } diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java index d29a58f21af..9364fca652b 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * 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. @@ -88,7 +88,7 @@ public Boolean isEnabled() { return enabled; } - public void setEnabled(Boolean enabled) throws ConnectException, FileNotFoundException, SchemaViolationException { + public void setEnabled(Boolean enabled) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); this.enabled = enabled; } @@ -97,7 +97,7 @@ public Date getValidFrom() { return validFrom; } - public void setValidFrom(Date validFrom) throws ConnectException, FileNotFoundException, SchemaViolationException { + public void setValidFrom(Date validFrom) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); this.validFrom = validFrom; } @@ -106,7 +106,7 @@ public Date getValidTo() { return validTo; } - public void setValidTo(Date validTo) throws ConnectException, FileNotFoundException, SchemaViolationException { + public void setValidTo(Date validTo) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); this.validTo = validTo; } @@ -143,13 +143,13 @@ public String getAttributeValue(String attrName) { return getAttributeValue(attrName,String.class); } - public void replaceAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void replaceAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { Collection values = new ArrayList(1); values.add(value); replaceAttributeValues(name, values); } - public void replaceAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void replaceAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); Set currentValues = attributes.get(name); if (currentValues == null) { @@ -163,7 +163,7 @@ public void replaceAttributeValues(String name, Collection values) throw recordModify(); } - public void replaceAttributeValues(String name, Object... values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void replaceAttributeValues(String name, Object... values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); Set currentValues = attributes.get(name); if (currentValues == null) { @@ -181,13 +181,13 @@ public void replaceAttributeValues(String name, Object... values) throws SchemaV recordModify(); } - public void addAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void addAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { Collection values = new ArrayList(1); values.add(value); addAttributeValues(name, values); } - public void addAttributeValues(String name, Collection valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void addAttributeValues(String name, Collection valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); Set currentValues = attributes.get(name); if (currentValues == null) { @@ -200,7 +200,7 @@ public void addAttributeValues(String name, Collection valuesToAdd) thro recordModify(); } - public void addAttributeValues(String name, String... valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void addAttributeValues(String name, String... valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); Set currentValues = attributes.get(name); if (currentValues == null) { @@ -213,7 +213,7 @@ public void addAttributeValues(String name, String... valuesToAdd) throws Schema recordModify(); } - private void addAttributeValue(String attrName, Set currentValues, Object valueToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + private void addAttributeValue(String attrName, Set currentValues, Object valueToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); if (resource != null && !resource.isTolerateDuplicateValues()) { for (Object currentValue: currentValues) { @@ -236,13 +236,13 @@ private void addAttributeValue(String attrName, Set currentValues, Objec currentValues.add(valueToAdd); } - public void removeAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void removeAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { Collection values = new ArrayList(); values.add(value); removeAttributeValues(name, values); } - public void removeAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException { + public void removeAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkModifyBreak(); Set currentValues = attributes.get(name); if (currentValues == null) { @@ -335,7 +335,7 @@ private void checkIfExist(Collection valuesToDelete, Set current } } - protected void checkModifyBreak() throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void checkModifyBreak() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { if (resource == null) { return; } @@ -351,6 +351,8 @@ protected void checkModifyBreak() throws ConnectException, FileNotFoundException throw new FileNotFoundException("IO error (simulated error)"); } else if (modifyBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (modifyBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (modifyBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -416,7 +418,7 @@ public DummyAttributeDefinition getAttributeDefinition(String attrName) { return null; } - abstract protected DummyObjectClass getObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException; + abstract protected DummyObjectClass getObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException; abstract protected DummyObjectClass getObjectClassNoExceptions(); diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyResource.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyResource.java index 7907d7e0b13..e70e3f3c416 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyResource.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyResource.java @@ -362,7 +362,7 @@ public void recordGroupMembersReadCount() { traceOperation("groupMembersRead", groupMembersReadCount); } - public DummyObjectClass getAccountObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyObjectClass getAccountObjectClass() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { if (schemaBreakMode == BreakMode.NONE) { return accountObjectClass; } else if (schemaBreakMode == BreakMode.NETWORK) { @@ -371,6 +371,8 @@ public DummyObjectClass getAccountObjectClass() throws ConnectException, FileNot throw new FileNotFoundException("The schema file not found (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error fetching schema (simulated error)"); @@ -405,7 +407,7 @@ public void addAuxiliaryObjectClass(String name, DummyObjectClass objectClass) { auxiliaryObjectClassMap.put(name, objectClass); } - public Collection listAccounts() throws ConnectException, FileNotFoundException, SchemaViolationException { + public Collection listAccounts() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (getBreakMode == BreakMode.NONE) { return accounts.values(); @@ -415,6 +417,8 @@ public Collection listAccounts() throws ConnectException, FileNotF throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -429,7 +433,7 @@ public Collection listAccounts() throws ConnectException, FileNotF } } - private T getObjectByName(Map map, String name) throws ConnectException, FileNotFoundException, SchemaViolationException { + private T getObjectByName(Map map, String name) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { if (!enforceUniqueName) { throw new IllegalStateException("Attempt to search object by name while resource is in non-unique name mode"); } @@ -441,6 +445,8 @@ private T getObjectByName(Map map, String name throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -455,23 +461,23 @@ private T getObjectByName(Map map, String name } } - public DummyAccount getAccountByUsername(String username) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyAccount getAccountByUsername(String username) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectByName(accounts, username); } - public DummyGroup getGroupByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyGroup getGroupByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectByName(groups, name); } - public DummyPrivilege getPrivilegeByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyPrivilege getPrivilegeByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectByName(privileges, name); } - public DummyOrg getOrgByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyOrg getOrgByName(String name) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectByName(orgs, name); } - private T getObjectById(Class expectedClass, String id) throws ConnectException, FileNotFoundException, SchemaViolationException { + private T getObjectById(Class expectedClass, String id) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { if (getBreakMode == BreakMode.NONE) { DummyObject dummyObject = allObjects.get(id); if (dummyObject == null) { @@ -487,6 +493,8 @@ private T getObjectById(Class expectedClass, String i throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -501,23 +509,23 @@ private T getObjectById(Class expectedClass, String i } } - public DummyAccount getAccountById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyAccount getAccountById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectById(DummyAccount.class, id); } - public DummyGroup getGroupById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyGroup getGroupById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectById(DummyGroup.class, id); } - public DummyPrivilege getPrivilegeById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyPrivilege getPrivilegeById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectById(DummyPrivilege.class, id); } - public DummyOrg getOrgById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException { + public DummyOrg getOrgById(String id) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return getObjectById(DummyOrg.class, id); } - public Collection listGroups() throws ConnectException, FileNotFoundException, SchemaViolationException { + public Collection listGroups() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (getBreakMode == BreakMode.NONE) { return groups.values(); @@ -527,6 +535,8 @@ public Collection listGroups() throws ConnectException, FileNotFound throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -541,7 +551,7 @@ public Collection listGroups() throws ConnectException, FileNotFound } } - public Collection listPrivileges() throws ConnectException, FileNotFoundException, SchemaViolationException { + public Collection listPrivileges() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (getBreakMode == BreakMode.NONE) { return privileges.values(); @@ -551,6 +561,8 @@ public Collection listPrivileges() throws ConnectException, File throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -565,7 +577,7 @@ public Collection listPrivileges() throws ConnectException, File } } - public Collection listOrgs() throws ConnectException, FileNotFoundException, SchemaViolationException { + public Collection listOrgs() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (getBreakMode == BreakMode.NONE) { return orgs.values(); @@ -575,6 +587,8 @@ public Collection listOrgs() throws ConnectException, FileNotFoundExce throw new FileNotFoundException("IO error (simulated error)"); } else if (schemaBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (schemaBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (schemaBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -589,7 +603,7 @@ public Collection listOrgs() throws ConnectException, FileNotFoundExce } } - private synchronized String addObject(Map map, T newObject) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + private synchronized String addObject(Map map, T newObject) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (addBreakMode == BreakMode.NONE) { // just go on @@ -599,6 +613,8 @@ private synchronized String addObject(Map map, throw new FileNotFoundException("IO error during add (simulated error)"); } else if (addBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation during add (simulated error)"); + } else if (addBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict during add (simulated error)"); } else if (addBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error during add (simulated error)"); @@ -656,7 +672,7 @@ private synchronized String addObject(Map map, } - private synchronized void deleteObjectByName(Class type, Map map, String name) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + private synchronized void deleteObjectByName(Class type, Map map, String name) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (deleteBreakMode == BreakMode.NONE) { // go on @@ -666,6 +682,8 @@ private synchronized void deleteObjectByName(Class ty throw new FileNotFoundException("IO error (simulated error)"); } else if (deleteBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (deleteBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict during (simulated error)"); } else if (deleteBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -701,23 +719,23 @@ private synchronized void deleteObjectByName(Class ty } } - public void deleteAccountById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException { + public void deleteAccountById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException, ConflictException { deleteObjectById(DummyAccount.class, accounts, id); } - public void deleteGroupById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException { + public void deleteGroupById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException, ConflictException { deleteObjectById(DummyGroup.class, groups, id); } - public void deletePrivilegeById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException { + public void deletePrivilegeById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException, ConflictException { deleteObjectById(DummyPrivilege.class, privileges, id); } - public void deleteOrgById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException { + public void deleteOrgById(String id) throws ConnectException, FileNotFoundException, ObjectDoesNotExistException, SchemaViolationException, ConflictException { deleteObjectById(DummyOrg.class, orgs, id); } - private synchronized void deleteObjectById(Class type, Map map, String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + private synchronized void deleteObjectById(Class type, Map map, String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (deleteBreakMode == BreakMode.NONE) { // go on @@ -727,6 +745,8 @@ private synchronized void deleteObjectById(Class type throw new FileNotFoundException("IO error (simulated error)"); } else if (deleteBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (deleteBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (deleteBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -772,7 +792,7 @@ private synchronized void deleteObjectById(Class type } } - private void renameObject(Class type, Map map, String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + private void renameObject(Class type, Map map, String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { checkBlockOperations(); if (modifyBreakMode == BreakMode.NONE) { // go on @@ -780,8 +800,10 @@ private void renameObject(Class type, Map m throw new ConnectException("Network error (simulated error)"); } else if (modifyBreakMode == BreakMode.IO) { throw new FileNotFoundException("IO error (simulated error)"); - } else if (schemaBreakMode == BreakMode.SCHEMA) { + } else if (modifyBreakMode == BreakMode.SCHEMA) { throw new SchemaViolationException("Schema violation (simulated error)"); + } else if (modifyBreakMode == BreakMode.CONFLICT) { + throw new ConflictException("Conflict (simulated error)"); } else if (modifyBreakMode == BreakMode.GENERIC) { // The connector will react with generic exception throw new IllegalArgumentException("Generic error (simulated error)"); @@ -817,18 +839,18 @@ private void renameObject(Class type, Map m } } - public String addAccount(DummyAccount newAccount) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + public String addAccount(DummyAccount newAccount) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { if (generateAccountDescriptionOnCreate && newAccount.getAttributeValue(DummyAccount.ATTR_DESCRIPTION_NAME) == null) { newAccount.addAttributeValue(DummyAccount.ATTR_DESCRIPTION_NAME, "Description of " + newAccount.getName()); } return addObject(accounts, newAccount); } - public void deleteAccountByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + public void deleteAccountByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { deleteObjectByName(DummyAccount.class, accounts, id); } - public void renameAccount(String id, String oldUsername, String newUsername) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException { + public void renameAccount(String id, String oldUsername, String newUsername) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException, ConflictException { renameObject(DummyAccount.class, accounts, id, oldUsername, newUsername); for (DummyGroup group : groups.values()) { if (group.containsMember(oldUsername)) { @@ -838,7 +860,7 @@ public void renameAccount(String id, String oldUsername, String newUsername) thr } } - public void changeDescriptionIfNeeded(DummyAccount account) throws SchemaViolationException { + public void changeDescriptionIfNeeded(DummyAccount account) throws SchemaViolationException, ConflictException { if (generateAccountDescriptionOnCreate) { try { account.replaceAttributeValue(DummyAccount.ATTR_DESCRIPTION_NAME, "Updated description of " + account.getName()); @@ -848,39 +870,39 @@ public void changeDescriptionIfNeeded(DummyAccount account) throws SchemaViolati } } - public String addGroup(DummyGroup newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException { + public String addGroup(DummyGroup newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException, ConflictException { return addObject(groups, newGroup); } - public void deleteGroupByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + public void deleteGroupByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { deleteObjectByName(DummyGroup.class, groups, id); } - public void renameGroup(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + public void renameGroup(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { renameObject(DummyGroup.class, groups, id, oldName, newName); } - public String addPrivilege(DummyPrivilege newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException { + public String addPrivilege(DummyPrivilege newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException, ConflictException { return addObject(privileges, newGroup); } - public void deletePrivilegeByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + public void deletePrivilegeByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { deleteObjectByName(DummyPrivilege.class, privileges, id); } - public void renamePrivilege(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + public void renamePrivilege(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { renameObject(DummyPrivilege.class, privileges, id, oldName, newName); } - public String addOrg(DummyOrg newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException { + public String addOrg(DummyOrg newGroup) throws ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, SchemaViolationException, ConflictException { return addObject(orgs, newGroup); } - public void deleteOrgByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException { + public void deleteOrgByName(String id) throws ObjectDoesNotExistException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { deleteObjectByName(DummyOrg.class, orgs, id); } - public void renameOrg(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException { + public void renameOrg(String id, String oldName, String newName) throws ObjectDoesNotExistException, ObjectAlreadyExistsException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { renameObject(DummyOrg.class, orgs, id, oldName, newName); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java index 7bf433b1538..b5a16364ee8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java @@ -719,7 +719,7 @@ private void updateSituationInShadow(Task task, Utils.setRequestee(task, focusContext); ProvisioningOperationOptions options = ProvisioningOperationOptions .createCompletePostponed(false); - options.setDoDiscovery(false); + options.setDoNotDiscovery(true); String changedOid = provisioning.modifyObject(ShadowType.class, projectionOid, syncSituationDeltas, null, options, task, result); // modifyProvisioningObject(AccountShadowType.class, accountRef, @@ -1051,6 +1051,31 @@ private ProvisioningOperationOptions copyFromModelOptions(ModelExecuteOptions op provisioningOptions.setOverwrite(options.getOverwrite()); return provisioningOptions; } + + private ProvisioningOperationOptions getProvisioningOptions(LensContext context, + ModelExecuteOptions modelOptions) { + if (modelOptions == null && context != null) { + modelOptions = context.getOptions(); + } + ProvisioningOperationOptions provisioningOptions = copyFromModelOptions(modelOptions); + + if (context != null && context.getChannel() != null) { + + if (context.getChannel().equals(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECON))) { + // TODO: this is probably wrong. We should not have special case + // for recon channel! This should be handled by the provisioning task + // setting the right options there. + provisioningOptions.setCompletePostponed(false); + } + + if (context.getChannel().equals(SchemaConstants.CHANGE_CHANNEL_DISCOVERY_URI)) { + // We want to avoid endless loops in error handling. + provisioningOptions.setDoNotDiscovery(true); + } + } + + return provisioningOptions; + } private void logDeltaExecution(ObjectDelta objectDelta, LensContext context, ResourceType resource, OperationResult result, Task task) { @@ -1122,14 +1147,8 @@ private void executeAddition(Object } else if (objectTypeToAdd instanceof NodeType) { throw new UnsupportedOperationException("NodeType cannot be added using model interface"); } else if (ObjectTypes.isManagedByProvisioning(objectTypeToAdd)) { - ProvisioningOperationOptions provisioningOptions = copyFromModelOptions(options); - - // TODO: this is probably wrong. We should not have special case - // for a channel! - if (context != null && context.getChannel() != null && context.getChannel() - .equals(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECON))) { - provisioningOptions.setCompletePostponed(false); - } + + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); oid = addProvisioningObject(objectToAdd, context, objectContext, provisioningOptions, resource, task, result); @@ -1184,14 +1203,7 @@ private void executeDeletion(Object } else if (NodeType.class.isAssignableFrom(objectTypeClass)) { taskManager.deleteNode(oid, result); } else if (ObjectTypes.isClassManagedByProvisioning(objectTypeClass)) { - if (options == null) { - options = context.getOptions(); - } - ProvisioningOperationOptions provisioningOptions = copyFromModelOptions(options); - if (context != null && context.getChannel() != null && context.getChannel() - .equals(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECON))) { - provisioningOptions.setCompletePostponed(false); - } + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); try { deleteProvisioningObject(objectTypeClass, oid, context, objectContext, provisioningOptions, resource, task, result); @@ -1250,14 +1262,7 @@ private void executeModification(Ob } else if (NodeType.class.isAssignableFrom(objectTypeClass)) { throw new UnsupportedOperationException("NodeType is not modifiable using model interface"); } else if (ObjectTypes.isClassManagedByProvisioning(objectTypeClass)) { - if (options == null && context != null) { - options = context.getOptions(); - } - ProvisioningOperationOptions provisioningOptions = copyFromModelOptions(options); - if (context != null && context.getChannel() != null && context.getChannel() - .equals(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECON))) { - provisioningOptions.setCompletePostponed(false); - } + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); String oid = modifyProvisioningObject(objectTypeClass, change.getOid(), change.getModifications(), context, objectContext, provisioningOptions, resource, task, result); @@ -1441,6 +1446,7 @@ private String modifyProvisioningOb ProvisioningOperationTypeType.MODIFY, resource, task, result); } Utils.setRequestee(task, context); + LOGGER.info("MOD options {}", options); String changedOid = provisioning.modifyObject(objectTypeClass, oid, modifications, scripts, options, task, result); Utils.clearRequestee(task); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestDependencies.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestDependencies.java index b2685f1ec6d..6a44f0d2117 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestDependencies.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestDependencies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * 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. @@ -31,6 +31,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.model.api.PolicyViolationException; import com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest; @@ -96,7 +97,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti initDummy("z", initTask, initResult); // depends on X (circular) } - private void initDummy(String name, Task initTask, OperationResult initResult) throws FileNotFoundException, ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, SchemaViolationException { + private void initDummy(String name, Task initTask, OperationResult initResult) throws FileNotFoundException, ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, SchemaViolationException, ConflictException { String resourceOid = getDummyOid(name); DummyResourceContoller resourceCtl = DummyResourceContoller.create(name.toUpperCase()); resourceCtl.extendSchemaPirate(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java index c8a08ef6f74..9d3c6966bf8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java @@ -44,6 +44,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.SchemaViolationException; @@ -2033,29 +2034,29 @@ public void test610EnableUser1() throws Exception { // TODO check real state of the account and shadow } - private void assertDummyActivationEnabledState(String userId, Boolean expectedEnabled) throws SchemaViolationException { + private void assertDummyActivationEnabledState(String userId, Boolean expectedEnabled) throws SchemaViolationException, ConflictException { assertDummyActivationEnabledState(null, userId, expectedEnabled); } - private void assertDummyActivationEnabledState(String instance, String userId, Boolean expectedEnabled) throws SchemaViolationException { + private void assertDummyActivationEnabledState(String instance, String userId, Boolean expectedEnabled) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(instance, userId); assertNotNull("No dummy account "+userId, account); assertEquals("Wrong enabled flag in dummy '"+instance+"' account "+userId, expectedEnabled, account.isEnabled()); } - private void assertDummyEnabled(String userId) throws SchemaViolationException { + private void assertDummyEnabled(String userId) throws SchemaViolationException, ConflictException { assertDummyActivationEnabledState(userId, true); } - private void assertDummyDisabled(String userId) throws SchemaViolationException { + private void assertDummyDisabled(String userId) throws SchemaViolationException, ConflictException { assertDummyActivationEnabledState(userId, false); } - private void assertDummyEnabled(String instance, String userId) throws SchemaViolationException { + private void assertDummyEnabled(String instance, String userId) throws SchemaViolationException, ConflictException { assertDummyActivationEnabledState(instance, userId, true); } - private void assertDummyDisabled(String instance, String userId) throws SchemaViolationException { + private void assertDummyDisabled(String instance, String userId) throws SchemaViolationException, ConflictException { assertDummyActivationEnabledState(instance, userId, false); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java index 5b4af5e53e8..51e8e2647eb 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java @@ -49,6 +49,7 @@ import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.DummySyncStyle; @@ -770,7 +771,7 @@ public void test262JupiterCleanup() throws Exception { cleanUpJupiter(TEST_NAME); } - protected void cleanUpJupiter(String TEST_NAME) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, SchemaViolationException { + protected void cleanUpJupiter(String TEST_NAME) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, SchemaViolationException, ConflictException { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java index 4941b6f2717..6e12a3c7f5e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * 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. @@ -31,6 +31,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.SchemaViolationException; @@ -1250,27 +1251,27 @@ public void test149ModifyUserUnassignAccountDummy() throws Exception { private void assertAccountShip(PrismObject userJack, String expectedFullName, String expectedShip, - DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { assertAccount(userJack, expectedFullName, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, expectedShip, true, resourceCtl, task); } private void assertAccountShip(PrismObject userJack, String expectedFullName, String expectedShip, - boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { assertAccount(userJack, expectedFullName, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, expectedShip, expectedEnabled, resourceCtl, task); } private void assertAccountLocation(PrismObject userJack, String expectedFullName, String expectedShip, - DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { assertAccount(userJack, expectedFullName, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, expectedShip, true, resourceCtl, task); } private void assertAccountRename(PrismObject userJack, String name, String expectedFullName, - DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { assertAccount(userJack, name, expectedFullName, null, null, true, resourceCtl, task); } private void assertAccount(PrismObject userJack, String name, String expectedFullName, String shipAttributeName, String expectedShip, - boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { // ship inbound mapping is used, it is strong String accountOid = getSingleLinkOid(userJack); @@ -1303,7 +1304,7 @@ private void assertAccount(PrismObject userJack, String name, String e } private void assertAccount(PrismObject userJack, String expectedFullName, String attributeName, String expectedShip, - boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + boolean expectedEnabled, DummyResourceContoller resourceCtl, Task task) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { assertAccount(userJack, "jack", expectedFullName, attributeName, expectedShip, expectedEnabled, resourceCtl, task); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelCrudService.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelCrudService.java index 73de732b4fb..0ff6ff63231 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelCrudService.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelCrudService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * 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. @@ -36,6 +36,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.model.api.PolicyViolationException; import com.evolveum.midpoint.model.impl.ModelCrudService; @@ -156,9 +157,7 @@ public void test100ModifyUserAddAccount() throws Exception { } @Test - public void test119ModifyUserDeleteAccount() throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, - IOException, JAXBException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, - PolicyViolationException, SecurityViolationException, SchemaViolationException { + public void test119ModifyUserDeleteAccount() throws Exception { TestUtil.displayTestTile(this, "test119ModifyUserDeleteAccount"); // GIVEN @@ -198,9 +197,7 @@ public void test119ModifyUserDeleteAccount() throws SchemaException, ObjectNotFo } @Test - public void test120AddAccount() throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, - IOException, JAXBException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, - PolicyViolationException, SecurityViolationException, SchemaViolationException { + public void test120AddAccount() throws Exception { TestUtil.displayTestTile(this, "test120AddAccount"); // GIVEN @@ -233,9 +230,7 @@ public void test120AddAccount() throws SchemaException, ObjectNotFoundException, } @Test - public void test121ModifyUserAddAccountRef() throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, - FileNotFoundException, JAXBException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, - PolicyViolationException, SecurityViolationException, SchemaViolationException { + public void test121ModifyUserAddAccountRef() throws Exception { TestUtil.displayTestTile(this, "test121ModifyUserAddAccountRef"); // GIVEN @@ -271,9 +266,7 @@ public void test121ModifyUserAddAccountRef() throws SchemaException, ObjectNotFo @Test - public void test128ModifyUserDeleteAccountRef() throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, - IOException, JAXBException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, - PolicyViolationException, SecurityViolationException, SchemaViolationException { + public void test128ModifyUserDeleteAccountRef() throws Exception { TestUtil.displayTestTile(this, "test128ModifyUserDeleteAccountRef"); // GIVEN @@ -311,9 +304,7 @@ public void test128ModifyUserDeleteAccountRef() throws SchemaException, ObjectNo } @Test - public void test129DeleteAccount() throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, - FileNotFoundException, JAXBException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, - PolicyViolationException, SecurityViolationException, ConsistencyViolationException, SchemaViolationException { + public void test129DeleteAccount() throws Exception { TestUtil.displayTestTile(this, "test129DeleteAccount"); // GIVEN diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java index 9f2dfa8edff..d59d44bf085 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java @@ -29,6 +29,7 @@ import org.testng.annotations.Test; import com.evolveum.icf.dummy.resource.BreakMode; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.model.api.PolicyViolationException; @@ -1661,7 +1662,7 @@ public void test400DavidAndGoliathAssignRole() throws Exception { PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 2); } - private void assertDavidGoliath(String userOid, String ou, String name, boolean userEnabled, boolean davidEnabled, boolean goliathEnabled) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException { + private void assertDavidGoliath(String userOid, String ou, String name, boolean userEnabled, boolean davidEnabled, boolean goliathEnabled) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException { PrismObject userAfter = getUser(userOid); display("User after", userAfter); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestPassword.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestPassword.java index 46768e002bc..bc67458c777 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestPassword.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestPassword.java @@ -38,6 +38,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.model.api.PolicyViolationException; @@ -894,7 +895,7 @@ public void test330RemoveEmployeeNumber() throws Exception { } - private void assertDummyPassword(String userId, String expectedClearPassword) throws SchemaViolationException { + private void assertDummyPassword(String userId, String expectedClearPassword) throws SchemaViolationException, ConflictException { assertDummyPassword(null, userId, expectedClearPassword); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java index 62599e3d82c..712afde1139 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java @@ -76,6 +76,7 @@ import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -536,6 +537,55 @@ public void test214ModifyUserJackBrokenPassword() throws Exception { // The change should be propagated here normally assertDummyAccount(RESOURCE_DUMMY_RED_NAME, "jack", "Cpt. Jack Sparrow", true); } + + /** + * Cause modification that will be mapped to the account and that will cause + * conflict (AlreadyExistsException). Make sure that midpoint does not end up + * in endless loop. + * MID-3451 + */ + @Test + public void test220ModifyUserJackBrokenConflict() throws Exception { + final String TEST_NAME = "test220ModifyUserJackBrokenConflict"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + dummyAuditService.clear(); + + dummyResource.setModifyBreakMode(BreakMode.CONFLICT); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + modifyUserReplace(USER_JACK_OID, UserType.F_LOCALITY, task, result, + PrismTestUtil.createPolyString("High seas")); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("Result", result); + TestUtil.assertPartialError(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + PrismAsserts.assertPropertyValue(userJack, UserType.F_LOCALITY, + PrismTestUtil.createPolyString("High seas")); + + assertLinks(userJack, 2); + String accountJackRedOidAfter = getLinkRefOid(userJack, RESOURCE_DUMMY_RED_OID); + assertNotNull(accountJackRedOidAfter); + + // The change was not propagated here because of schema violation error + assertDefaultDummyAccount("jack", "Jack Sparrow", true); + assertDefaultDummyAccountAttribute("jack", + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, "Caribbean"); + + // The change should be propagated here normally + assertDummyAccount(RESOURCE_DUMMY_RED_NAME, "jack", "Cpt. Jack Sparrow", true); + assertDummyAccountAttribute(RESOURCE_DUMMY_RED_NAME, "jack", + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, "High seas"); + } // Lets test various extension magic and border cases now. This is maybe quite hight in the architecture for // this test, but we want to make sure that none of the underlying components will screw the things up. diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java index a3eb26060ce..15537e2fe83 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java @@ -38,6 +38,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.SchemaViolationException; @@ -1080,12 +1081,12 @@ protected OperationResult waitForSyncTaskNextRun(PrismObject resou } private PrismObject checkWallyAccount(PrismObject resource, DummyResource dummy, String resourceDesc, - String expectedFullName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, FileNotFoundException, SchemaViolationException { + String expectedFullName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { return checkWallyAccount(resource, dummy, resourceDesc, expectedFullName, null, null); } private PrismObject checkWallyAccount(PrismObject resource, DummyResource dummy, String resourceDesc, - String expectedFullName, String shipName, String quote) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, FileNotFoundException, SchemaViolationException { + String expectedFullName, String shipName, String quote) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { PrismObject accountShadowWally = findAccountByUsername(ACCOUNT_WALLY_DUMMY_USERNAME, resource); display("Account shadow wally ("+resourceDesc+")", accountShadowWally); assertEquals("Wrong resourceRef in wally account ("+resourceDesc+")", resource.getOid(), diff --git a/model/model-intest/src/test/resources/common/resource-dummy-red.xml b/model/model-intest/src/test/resources/common/resource-dummy-red.xml index 8795b08f240..d438450377d 100644 --- a/model/model-intest/src/test/resources/common/resource-dummy-red.xml +++ b/model/model-intest/src/test/resources/common/resource-dummy-red.xml @@ -118,6 +118,18 @@ + + ri:location + Location + + strong + + + $user/locality + + + + ri:ship Ship diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 4aa3b43fa53..d25e03cbcaf 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.model.test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyGroup; import com.evolveum.icf.dummy.resource.DummyResource; @@ -2561,7 +2562,7 @@ protected void checkDummyTransportMessagesAtLeast(String name, int expectedCount assertTrue("Number of messages recorded in dummy transport '" + name + "' (" + messages.size() + ") is not at least " + expectedCount, messages.size() >= expectedCount); } - protected DummyAccount getDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException { + protected DummyAccount getDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException, ConflictException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getAccountByUsername(username); @@ -2572,7 +2573,7 @@ protected DummyAccount getDummyAccount(String dummyInstanceName, String username } } - protected DummyAccount getDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException { + protected DummyAccount getDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException, ConflictException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getAccountById(id); @@ -2583,11 +2584,11 @@ protected DummyAccount getDummyAccountById(String dummyInstanceName, String id) } } - protected void assertDefaultDummyAccount(String username, String fullname, boolean active) throws SchemaViolationException { + protected void assertDefaultDummyAccount(String username, String fullname, boolean active) throws SchemaViolationException, ConflictException { assertDummyAccount(null, username, fullname, active); } - protected DummyAccount assertDummyAccount(String dummyInstanceName, String username, String fullname, Boolean active) throws SchemaViolationException { + protected DummyAccount assertDummyAccount(String dummyInstanceName, String username, String fullname, Boolean active) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy("+dummyInstanceName+") account for username "+username, account); assertEquals("Wrong fullname for dummy("+dummyInstanceName+") account "+username, fullname, account.getAttributeValue("fullname")); @@ -2595,41 +2596,41 @@ protected DummyAccount assertDummyAccount(String dummyInstanceName, String usern return account; } - protected void assertDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException { + protected void assertDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy(" + dummyInstanceName + ") account for username " + username, account); } - protected void assertDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException { + protected void assertDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccountById(dummyInstanceName, id); assertNotNull("No dummy("+dummyInstanceName+") account for id "+id, account); } - protected void assertNoDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException { + protected void assertNoDummyAccountById(String dummyInstanceName, String id) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccountById(dummyInstanceName, id); assertNull("Dummy(" + dummyInstanceName + ") account for id " + id + " exists while not expecting it", account); } - protected void assertDummyAccountActivation(String dummyInstanceName, String username, Boolean active) throws SchemaViolationException { + protected void assertDummyAccountActivation(String dummyInstanceName, String username, Boolean active) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy("+dummyInstanceName+") account for username "+username, account); assertEquals("Wrong activation for dummy(" + dummyInstanceName + ") account " + username, active, account.isEnabled()); } - protected void assertNoDummyAccount(String username) throws SchemaViolationException { + protected void assertNoDummyAccount(String username) throws SchemaViolationException, ConflictException { assertNoDummyAccount(null, username); } - protected void assertNoDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException { + protected void assertNoDummyAccount(String dummyInstanceName, String username) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNull("Dummy account for username " + username + " exists while not expecting it (" + dummyInstanceName + ")", account); } - protected void assertDefaultDummyAccountAttribute(String username, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException { + protected void assertDefaultDummyAccountAttribute(String username, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException, ConflictException { assertDummyAccountAttribute(null, username, attributeName, expectedAttributeValues); } - protected void assertDummyAccountAttribute(String dummyInstanceName, String username, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException { + protected void assertDummyAccountAttribute(String dummyInstanceName, String username, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username "+username, account); Set values = account.getAttributeValues(attributeName, Object.class); @@ -2648,7 +2649,7 @@ protected void assertDummyAccountAttribute(String dummyInstanceName, String user } } - protected void assertNoDummyAccountAttribute(String dummyInstanceName, String username, String attributeName) throws SchemaViolationException { + protected void assertNoDummyAccountAttribute(String dummyInstanceName, String username, String attributeName) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username "+username, account); Set values = account.getAttributeValues(attributeName, Object.class); @@ -2659,7 +2660,7 @@ protected void assertNoDummyAccountAttribute(String dummyInstanceName, String us ". Values found: " + values); } - protected void assertDummyAccountAttributeGenerated(String dummyInstanceName, String username) throws SchemaViolationException { + protected void assertDummyAccountAttributeGenerated(String dummyInstanceName, String username) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username "+username, account); Integer generated = account.getAttributeValue(DummyAccount.ATTR_INTERNAL_ID, Integer.class); @@ -2668,7 +2669,7 @@ protected void assertDummyAccountAttributeGenerated(String dummyInstanceName, St } } - protected DummyGroup getDummyGroup(String dummyInstanceName, String name) throws SchemaViolationException { + protected DummyGroup getDummyGroup(String dummyInstanceName, String name) throws SchemaViolationException, ConflictException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getGroupByName(name); @@ -2679,15 +2680,15 @@ protected DummyGroup getDummyGroup(String dummyInstanceName, String name) throws } } - protected void assertDummyGroup(String username, String description) throws SchemaViolationException { + protected void assertDummyGroup(String username, String description) throws SchemaViolationException, ConflictException { assertDummyGroup(null, username, description, null); } - protected void assertDummyGroup(String username, String description, Boolean active) throws SchemaViolationException { + protected void assertDummyGroup(String username, String description, Boolean active) throws SchemaViolationException, ConflictException { assertDummyGroup(null, username, description, active); } - protected void assertDummyGroup(String dummyInstanceName, String groupname, String description, Boolean active) throws SchemaViolationException { + protected void assertDummyGroup(String dummyInstanceName, String groupname, String description, Boolean active) throws SchemaViolationException, ConflictException { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNotNull("No dummy("+dummyInstanceName+") group for name "+groupname, group); assertEquals("Wrong fullname for dummy(" + dummyInstanceName + ") group " + groupname, description, @@ -2697,16 +2698,16 @@ protected void assertDummyGroup(String dummyInstanceName, String groupname, Stri } } - protected void assertNoDummyGroup(String groupname) throws SchemaViolationException { + protected void assertNoDummyGroup(String groupname) throws SchemaViolationException, ConflictException { assertNoDummyGroup(null, groupname); } - protected void assertNoDummyGroup(String dummyInstanceName, String groupname) throws SchemaViolationException { + protected void assertNoDummyGroup(String dummyInstanceName, String groupname) throws SchemaViolationException, ConflictException { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNull("Dummy group '" + groupname + "' exists while not expecting it (" + dummyInstanceName + ")", group); } - protected void assertDummyGroupAttribute(String dummyInstanceName, String groupname, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException { + protected void assertDummyGroupAttribute(String dummyInstanceName, String groupname, String attributeName, Object... expectedAttributeValues) throws SchemaViolationException, ConflictException { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNotNull("No dummy group for groupname "+groupname, group); Set values = group.getAttributeValues(attributeName, Object.class); @@ -2723,27 +2724,27 @@ protected void assertDummyGroupAttribute(String dummyInstanceName, String groupn } } - protected void assertDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void assertDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); DummyGroup group = dummyResource.getGroupByName(dummyGroupName); IntegrationTestTools.assertGroupMember(group, accountId); } - protected void assertDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void assertDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { assertDummyGroupMember(null, dummyGroupName, accountId); } - protected void assertNoDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void assertNoDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); DummyGroup group = dummyResource.getGroupByName(dummyGroupName); IntegrationTestTools.assertNoGroupMember(group, accountId); } - protected void assertNoDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void assertNoDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { assertNoDummyGroupMember(null, dummyGroupName, accountId); } - protected void assertDummyAccountNoAttribute(String dummyInstanceName, String username, String attributeName) throws SchemaViolationException { + protected void assertDummyAccountNoAttribute(String dummyInstanceName, String username, String attributeName) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username "+username, account); Set values = account.getAttributeValues(attributeName, Object.class); @@ -3287,7 +3288,7 @@ protected void assertPasswordMetadata(PrismObject user, boolean create } } - protected void assertDummyPassword(String instance, String userId, String expectedClearPassword) throws SchemaViolationException { + protected void assertDummyPassword(String instance, String userId, String expectedClearPassword) throws SchemaViolationException, ConflictException { DummyAccount account = getDummyAccount(instance, userId); assertNotNull("No dummy account "+userId, account); assertEquals("Wrong password in dummy '"+instance+"' account "+userId, expectedClearPassword, account.getPassword()); diff --git a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java index a1a723f7cb7..23222a9beeb 100644 --- a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java +++ b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java @@ -19,25 +19,23 @@ import java.io.Serializable; public class ProvisioningOperationOptions implements Serializable { - private static final long serialVersionUID = -6960273605308871338L; /** * Avoid any smart processing of the data except for schema application. Do not synchronize the data, do not apply * any expressions, etc. */ - Boolean raw; + private Boolean raw; - Boolean completePostponed; + private Boolean completePostponed; - Boolean force; + private Boolean force; - Boolean postpone; + private Boolean postpone; - // TODO: align with GetOperationOptions, the option there is doNotDiscovery - Boolean doDiscovery; + private Boolean doNotDiscovery; - Boolean overwrite; + private Boolean overwrite; public Boolean getCompletePostponed() { return completePostponed; @@ -112,27 +110,27 @@ public static ProvisioningOperationOptions createPostpone(boolean postpone) { return opts; } - public Boolean getDoDiscovery() { - return doDiscovery; + public Boolean getDoNotDiscovery() { + return doNotDiscovery; } - public void setDoDiscovery(Boolean doDiscovery) { - this.doDiscovery = doDiscovery; + public void setDoNotDiscovery(Boolean doDiscovery) { + this.doNotDiscovery = doDiscovery; } - public static boolean isDoDiscovery(ProvisioningOperationOptions options){ + public static boolean isDoNotDiscovery(ProvisioningOperationOptions options){ if (options == null) { return false; } - if (options.doDiscovery == null) { + if (options.doNotDiscovery == null) { return false; } - return options.doDiscovery; + return options.doNotDiscovery; } - public static ProvisioningOperationOptions createDoDiscovery(boolean doDiscovery) { + public static ProvisioningOperationOptions createDoNotDiscovery(boolean doDiscovery) { ProvisioningOperationOptions opts = new ProvisioningOperationOptions(); - opts.setDoDiscovery(doDiscovery); + opts.setDoNotDiscovery(doDiscovery); return opts; } @@ -185,5 +183,32 @@ public static ProvisioningOperationOptions createRaw() { return opts; } - + @Override + public String toString() { + StringBuilder sb = new StringBuilder("ProvisioningOperationOptions("); + appendFlag(sb, "raw", raw); + appendFlag(sb, "completePostponed", completePostponed); + appendFlag(sb, "force", force); + appendFlag(sb, "postpone", postpone); + appendFlag(sb, "doNotDiscovery", doNotDiscovery); + appendFlag(sb, "overwrite", overwrite); + if (sb.charAt(sb.length() - 1) == ',') { + sb.deleteCharAt(sb.length() - 1); + } + sb.append(")"); + return sb.toString(); + } + + private void appendFlag(StringBuilder sb, String name, Boolean val) { + if (val == null) { + return; + } else if (val) { + sb.append(name); + sb.append(","); + } else { + sb.append(name); + sb.append("=false,"); + } + } + } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/api/ErrorHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/api/ErrorHandler.java index e4fccdd8947..8b7dc1049d7 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/api/ErrorHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/api/ErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * 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. @@ -71,19 +71,9 @@ protected boolean isPostpone(ResourceType resource){ return resource.getConsistency().isPostpone(); } - protected boolean isDoDiscovery(ResourceType resource){ - if (resource.getConsistency() == null){ - return true; - } - - if (resource.getConsistency().isDiscovery() == null){ - return true; - } - - return resource.getConsistency().isDiscovery(); - } - - public abstract T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException; + public abstract T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) + throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException; protected Collection createAttemptModification(T shadow, diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/CommunicationExceptionHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/CommunicationExceptionHandler.java index b660bf49a32..1aacb7762b7 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/CommunicationExceptionHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/CommunicationExceptionHandler.java @@ -87,10 +87,20 @@ public void setCacheRepositoryService(RepositoryService repositoryService) { } @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException { + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof CommunicationException) { + throw (CommunicationException)ex; + } else { + throw new CommunicationException(ex.getMessage(), ex); + } + } + Validate.notNull(shadow, "Shadow must not be null."); OperationResult operationResult = parentResult.createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.CommunicationExceptionHandler.handleError." + op.name()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java index 41b87901466..cef29545fae 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java @@ -54,10 +54,20 @@ public class ConfigurationExceptionHandler extends ErrorHandler { private RepositoryService cacheRepositoryService; @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException { + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof ConfigurationException) { + throw (ConfigurationException)ex; + } else { + throw new ConfigurationException(ex.getMessage(), ex); + } + } + ObjectDelta delta = null; switch (op) { case ADD: diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java index 4af7194d0c9..54c4aeaa962 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java @@ -74,10 +74,20 @@ public class GenericErrorHandler extends ErrorHandler{ @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof GenericFrameworkException) { + throw (GenericFrameworkException)ex; + } else { + throw new GenericFrameworkException(ex.getMessage(), ex); + } + } + // OperationResult result = OperationResult.createOperationResult(shadow.getResult()); String operation = (shadow.getFailedOperationType() == null ? "null" : shadow.getFailedOperationType().name()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java index 5784d4f7cfb..2443cfe079d 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java @@ -63,12 +63,18 @@ public class ObjectAlreadyExistHandler extends ErrorHandler { private static final Trace LOGGER = TraceManager.getTrace(ObjectAlreadyExistHandler.class); @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { - if (!isDoDiscovery(shadow.getResource())){ - throw new ObjectAlreadyExistsException(); + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof ObjectAlreadyExistsException) { + throw (ObjectAlreadyExistsException)ex; + } else { + throw new ObjectAlreadyExistsException(ex.getMessage(), ex); + } } LOGGER.trace("Start to hanlde ObjectAlreadyExitsException."); @@ -113,7 +119,7 @@ public T handleError(T shadow, FailedOperation op, Except } if (compensate){ - throw new ObjectAlreadyExistsException(ex.getMessage(), ex); + throw new ObjectAlreadyExistsException(ex.getMessage(), ex); } return shadow; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java index 563fb1fb48a..eccd0cc93df 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java @@ -95,12 +95,18 @@ public void setCacheRepositoryService(RepositoryService repositoryService) { } @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { - if (!isDoDiscovery(shadow.getResource())){ - throw new ObjectNotFoundException(ex.getMessage(), ex); + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof ObjectNotFoundException) { + throw (ObjectNotFoundException)ex; + } else { + throw new ObjectNotFoundException(ex.getMessage(), ex); + } } OperationResult result = parentResult @@ -182,7 +188,7 @@ public T handleError(T shadow, FailedOperation op, Except try { ProvisioningOperationOptions options = new ProvisioningOperationOptions(); options.setCompletePostponed(false); - options.setDoDiscovery(false); + options.setDoNotDiscovery(true); provisioningService.modifyObject(ShadowType.class, oid, modifications, null, options, task, result); parentResult.recordHandledError( diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SchemaExceptionHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SchemaExceptionHandler.java index e030b22e7a7..484b7ba39a3 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SchemaExceptionHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SchemaExceptionHandler.java @@ -51,10 +51,20 @@ public class SchemaExceptionHandler extends ErrorHandler{ private RepositoryService cacheRepositoryService; @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof SchemaException) { + throw (SchemaException)ex; + } else { + throw new SchemaException(ex.getMessage(), ex); + } + } + ObjectDelta delta = null; switch (op) { case ADD: diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SecurityViolationHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SecurityViolationHandler.java index 238bfaec5c8..fa8b8c924aa 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SecurityViolationHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/SecurityViolationHandler.java @@ -51,10 +51,20 @@ public class SecurityViolationHandler extends ErrorHandler{ private RepositoryService cacheRepositoryService; @Override - public T handleError(T shadow, FailedOperation op, Exception ex, boolean compensate, + public T handleError(T shadow, FailedOperation op, Exception ex, + boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { + if (!doDiscovery) { + parentResult.recordFatalError(ex); + if (ex instanceof SecurityViolationException) { + throw (SecurityViolationException)ex; + } else { + throw new SecurityViolationException(ex.getMessage(), ex); + } + } + ObjectDelta delta = null; switch(op){ case ADD : diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index a24967700d4..a2f28a4be40 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -319,7 +319,7 @@ public PrismObject getShadow(String oid, PrismObject rep try { resourceShadow = handleError(ctx, ex, repositoryShadow, FailedOperation.GET, null, - isCompensate(rootOptions), parentResult); + isDoDiscovery(resource, rootOptions), isCompensate(rootOptions), parentResult); if (parentResult.getStatus() == OperationResultStatus.FATAL_ERROR) { // We are going to return an object. Therefore this cannot // be fatal error, as at least some information @@ -348,9 +348,36 @@ public PrismObject getShadow(String oid, PrismObject rep } private boolean isCompensate(GetOperationOptions rootOptions) { - return GetOperationOptions.isDoNotDiscovery(rootOptions) ? false : true; + return !GetOperationOptions.isDoNotDiscovery(rootOptions); } + private boolean isCompensate(ProvisioningOperationOptions options) { + return ProvisioningOperationOptions.isCompletePostponed(options); + } + + private boolean isDoDiscovery(ResourceType resource, GetOperationOptions rootOptions) { + return !GetOperationOptions.isDoNotDiscovery(rootOptions) && isDoDiscovery(resource); + } + + private boolean isDoDiscovery(ResourceType resource, ProvisioningOperationOptions options) { + return !ProvisioningOperationOptions.isDoNotDiscovery(options) && isDoDiscovery(resource); + } + + private boolean isDoDiscovery (ResourceType resource) { + if (resource == null) { + return true; + } + if (resource.getConsistency() == null) { + return true; + } + + if (resource.getConsistency().isDiscovery() == null) { + return true; + } + + return resource.getConsistency().isDiscovery(); + } + public abstract String afterAddOnResource(ProvisioningContext ctx, PrismObject shadow, OperationResult parentResult) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ConfigurationException, CommunicationException; @@ -372,7 +399,8 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr try { ctx.assertDefinition(); } catch (SchemaException e) { - handleError(ctx, e, shadow, FailedOperation.ADD, null, true, parentResult); + handleError(ctx, e, shadow, FailedOperation.ADD, null, + isDoDiscovery(resource, options), true, parentResult); return null; } @@ -385,7 +413,8 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr SchemaException e = new SchemaException( "Attempt to add shadow without any attributes: " + shadow); parentResult.recordFatalError(e); - handleError(ctx, e, shadow, FailedOperation.ADD, null, true, parentResult); + handleError(ctx, e, shadow, FailedOperation.ADD, null, + isDoDiscovery(resource, options), true, parentResult); return null; } @@ -399,7 +428,7 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr } catch (Exception ex) { shadow = handleError(ctx, ex, shadow, FailedOperation.ADD, null, - ProvisioningOperationOptions.isCompletePostponed(options), parentResult); + isDoDiscovery(resource, options), isCompensate(options), parentResult); return shadow.getOid(); } @@ -491,7 +520,7 @@ public String modifyShadow(PrismObject repoShadow, String oid, new Object[] { ex.getClass(), ex.getMessage(), ex }); try { repoShadow = handleError(ctx, ex, repoShadow, FailedOperation.MODIFY, modifications, - ProvisioningOperationOptions.isCompletePostponed(options), parentResult); + isDoDiscovery(ctx.getResource(), options), isCompensate(options), parentResult); parentResult.computeStatus(); } catch (ObjectAlreadyExistsException e) { parentResult.recordFatalError( @@ -558,7 +587,7 @@ public void deleteShadow(PrismObject shadow, ProvisioningOperationOp } catch (Exception ex) { try { handleError(ctx, ex, shadow, FailedOperation.DELETE, null, - ProvisioningOperationOptions.isCompletePostponed(options), parentResult); + isDoDiscovery(ctx.getResource(), options), isCompensate(options), parentResult); } catch (ObjectAlreadyExistsException e) { e.printStackTrace(); } @@ -702,12 +731,12 @@ protected ResourceType getResource(ResourceShadowDiscriminator coords, Operation @SuppressWarnings("rawtypes") protected PrismObject handleError(ProvisioningContext ctx, Exception ex, PrismObject shadow, FailedOperation op, Collection modifications, - boolean compensate, OperationResult parentResult) throws SchemaException, + boolean doDiscovery, boolean compensate, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException { // do not set result in the shadow in case of get operation, it will - // resilted to misleading information + // resulted to misleading information // by get operation we do not modify the result in the shadow, so only // fetch result in this case needs to be set if (FailedOperation.GET != op) { @@ -722,12 +751,13 @@ protected PrismObject handleError(ProvisioningContext ctx, Exception throw new SystemException(ex.getMessage(), ex); } - LOGGER.debug("Handling provisioning exception {}:{}", + LOGGER.debug("Handling provisioning exception {}: {}", new Object[] { ex.getClass(), ex.getMessage() }); - LOGGER.trace("Handling provisioning exception {}:{}", - new Object[] { ex.getClass(), ex.getMessage(), ex }); + LOGGER.trace("Handling provisioning exception {}: {}\ndoDiscovery={}, compensate={}", + new Object[] { ex.getClass(), ex.getMessage(), + doDiscovery, compensate, ex }); - return handler.handleError(shadow.asObjectable(), op, ex, compensate, ctx.getTask(), parentResult) + return handler.handleError(shadow.asObjectable(), op, ex, doDiscovery, compensate, ctx.getTask(), parentResult) .asPrismObject(); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java index 02d1549c830..5dba0d948af 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java @@ -37,6 +37,7 @@ import org.testng.AssertJUnit; import org.w3c.dom.Element; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyAttributeDefinition; import com.evolveum.icf.dummy.resource.DummyGroup; @@ -324,7 +325,7 @@ protected void assertSchemaSanity(ResourceSchema resourceSchema, ResourceType re dummyResourceCtl.assertDummyResourceSchemaSanityExtended(resourceSchema, resourceType); } - protected DummyAccount getDummyAccount(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyAccount getDummyAccount(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getAccountByUsername(icfName); @@ -333,7 +334,7 @@ protected DummyAccount getDummyAccount(String icfName, String icfUid) throws Con } } - protected DummyAccount getDummyAccountAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyAccount getDummyAccountAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getAccountByUsername(icfName); @@ -345,7 +346,7 @@ protected DummyAccount getDummyAccountAssert(String icfName, String icfUid) thro } } - protected DummyGroup getDummyGroup(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyGroup getDummyGroup(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getGroupByName(icfName); @@ -354,7 +355,7 @@ protected DummyGroup getDummyGroup(String icfName, String icfUid) throws Connect } } - protected DummyGroup getDummyGroupAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyGroup getDummyGroupAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getGroupByName(icfName); @@ -366,7 +367,7 @@ protected DummyGroup getDummyGroupAssert(String icfName, String icfUid) throws C } } - protected DummyPrivilege getDummyPrivilege(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyPrivilege getDummyPrivilege(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getPrivilegeByName(icfName); @@ -375,7 +376,7 @@ protected DummyPrivilege getDummyPrivilege(String icfName, String icfUid) throws } } - protected DummyPrivilege getDummyPrivilegeAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected DummyPrivilege getDummyPrivilegeAssert(String icfName, String icfUid) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { // if (isNameUnique()) { if (isIcfNameUidSame()) { return dummyResource.getPrivilegeByName(icfName); @@ -387,7 +388,7 @@ protected DummyPrivilege getDummyPrivilegeAssert(String icfName, String icfUid) } } - protected void assertDummyAccountAttributeValues(String accountName, String accountUid, String attributeName, T... expectedValues) throws ConnectException, FileNotFoundException, SchemaViolationException { + protected void assertDummyAccountAttributeValues(String accountName, String accountUid, String attributeName, T... expectedValues) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { DummyAccount dummyAccount = getDummyAccountAssert(accountName, accountUid); assertNotNull("No account '"+accountName+"'", dummyAccount); assertDummyAttributeValues(dummyAccount, attributeName, expectedValues); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java index 60ce88fae8d..ff8b937d1c1 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Evolveum + * Copyright (c) 2013-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.prism.PrismObject; @@ -123,7 +124,7 @@ public void test600AddAccountAlreadyExist() throws Exception { // DO nothing. This test is meaningless in non-unique environment } - private String addFettucini(final String TEST_NAME, File file, String oid, String expectedFullName) throws SchemaException, ObjectAlreadyExistsException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, IOException, SchemaViolationException { + private String addFettucini(final String TEST_NAME, File file, String oid, String expectedFullName) throws SchemaException, ObjectAlreadyExistsException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, IOException, SchemaViolationException, ConflictException { // GIVEN Task task = taskManager.createTaskInstance(TestDummy.class.getName() + "." + TEST_NAME); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java index e90c559d526..5305b7964fa 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java @@ -30,6 +30,7 @@ import org.apache.commons.lang.StringUtils; +import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyAttributeDefinition; import com.evolveum.icf.dummy.resource.DummyGroup; @@ -147,7 +148,7 @@ public void populateWithDefaultSchema() { /** * Extend schema in piratey fashion. Arr! This is used in many tests. Lots of attributes, various combination of types, etc. */ - public void extendSchemaPirate() throws ConnectException, FileNotFoundException, SchemaViolationException { + public void extendSchemaPirate() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { populateWithDefaultSchema(); DummyObjectClass accountObjectClass = dummyResource.getAccountObjectClass(); addAttrDef(accountObjectClass, DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, String.class, false, true); @@ -174,9 +175,9 @@ public void extendSchemaPirate() throws ConnectException, FileNotFoundException, } /** - * Extend dummy schema to look like AD + * Extend dummy schema to look like AD */ - public void extendSchemaAd() throws ConnectException, FileNotFoundException, SchemaViolationException { + public void extendSchemaAd() throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { DummyObjectClass accountObjectClass = dummyResource.getAccountObjectClass(); addAttrDef(accountObjectClass, DUMMY_ACCOUNT_ATTRIBUTE_AD_GIVEN_NAME_NAME, String.class, false, false); addAttrDef(accountObjectClass, DUMMY_ACCOUNT_ATTRIBUTE_AD_SN_NAME, String.class, false, false); @@ -357,13 +358,13 @@ public void assertRefinedSchemaSanity(RefinedResourceSchema refinedSchema) { } - public DummyOrg addOrgTop() throws ConnectException, FileNotFoundException, ObjectAlreadyExistsException, SchemaViolationException { + public DummyOrg addOrgTop() throws ConnectException, FileNotFoundException, ObjectAlreadyExistsException, SchemaViolationException, ConflictException { DummyOrg org = new DummyOrg(ORG_TOP_NAME); dummyResource.addOrg(org); return org; } - public DummyAccount addAccount(String userId, String fullName) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException { + public DummyAccount addAccount(String userId, String fullName) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException, ConflictException { DummyAccount account = new DummyAccount(userId); account.setEnabled(true); account.addAttributeValues(DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, fullName); @@ -371,7 +372,7 @@ public DummyAccount addAccount(String userId, String fullName) throws ObjectAlre return account; } - public void addAccount(String userId, String fullName, String location) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException { + public void addAccount(String userId, String fullName, String location) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException, ConflictException { assertExtendedSchema(); DummyAccount account = new DummyAccount(userId); account.setEnabled(true); @@ -380,7 +381,7 @@ public void addAccount(String userId, String fullName, String location) throws O dummyResource.addAccount(account); } - public void addGroup(String name) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException { + public void addGroup(String name) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException, ConflictException { assertExtendedSchema(); DummyGroup group = new DummyGroup(name); group.setEnabled(true); diff --git a/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java b/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java index b86cb6a5229..7f16ff4261b 100644 --- a/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java +++ b/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java @@ -1562,7 +1562,9 @@ public void test280ModifyObjectCommunicationProblemWeakMapping() throws Exceptio requestToExecuteChanges(REQUEST_USER_MODIFY_WEAK_MAPPING_COMMUNICATION_PROBLEM, USER_JOHN_WEAK_OID, UserType.class, task, null, parentResult); - checkNormalizedShadowBasic(accountOid, "john", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), task, parentResult); + // TODO: [RS] not 100% sure about this. But if you do not expect an error you should not set doNotDiscovery. Server is still not running. + checkNormalizedShadowBasic(accountOid, "john", true, null, task, parentResult); +// checkNormalizedShadowBasic(accountOid, "john", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), task, parentResult); } From aaa10763c9b925273bc21227828d9bc1fec5b785 Mon Sep 17 00:00:00 2001 From: honchar Date: Mon, 10 Oct 2016 23:58:53 +0200 Subject: [PATCH 2/5] implemented provider for AuditEventRecordType --- .../data/BaseSortableDataProvider.java | 6 + .../admin/reports/PageAuditLogViewer.java | 86 +--------- .../reports/dto/AuditEventRecordProvider.java | 155 ++++++++++++++++++ .../web/security/MidPointApplication.java | 7 + 4 files changed, 170 insertions(+), 84 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java index d52cafa22b9..32603b06bf7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.web.component.data; +import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelInteractionService; @@ -116,6 +117,11 @@ protected WorkflowService getWorkflowService() { return application.getWorkflowService(); } + protected AuditService getAuditService() { + MidPointApplication application = (MidPointApplication) MidPointApplication.get(); + return application.getAuditService(); + } + protected WorkflowManager getWorkflowManager() { MidPointApplication application = (MidPointApplication) MidPointApplication.get(); return application.getWorkflowManager(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java index 57e18c51b23..415bd084918 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java @@ -11,6 +11,7 @@ import com.evolveum.midpoint.web.component.util.ListDataProvider; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.page.admin.configuration.PageAdminConfiguration; +import com.evolveum.midpoint.web.page.admin.reports.dto.AuditEventRecordProvider; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; @@ -43,8 +44,6 @@ public class PageAuditLogViewer extends PageBase{ private static final String ID_FROM = "fromField"; private static final String ID_MAIN_FORM = "mainForm"; - private static final String AUDIT_RECORDS_QUERY = "from RAuditEventRecord as aer where 1=1 and "; - private static final String AUDIT_RECORDS_QUERY_COUNT = "select count(*) from RAuditEventRecord as aer where 1=1 and "; public PageAuditLogViewer(){ initLayout(); @@ -85,23 +84,7 @@ public void detach() { } private void initTable(Form mainForm){ - IModel> model = new IModel>() { - @Override - public List getObject() { - return getAuditEventRecordList(); - } - - @Override - public void setObject(List auditEventRecord) { - - } - - @Override - public void detach() { - - } - }; - ListDataProvider provider = new ListDataProvider(PageAuditLogViewer.this, model); + AuditEventRecordProvider provider = new AuditEventRecordProvider(PageAuditLogViewer.this); BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, initColumns(), UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER, @@ -113,24 +96,6 @@ public void detach() { mainForm.add(table); } - private List getAuditEventRecordList(){ - String parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY); - List auditRecords = getAuditService().listRecords(parameterQuery + " order by aer.timestamp asc", params); - if (auditRecords == null){ - auditRecords = new ArrayList<>(); - } - List auditRecordList = new ArrayList<>(); - for (AuditEventRecord record : auditRecords){ - AuditEventRecordType newRecord = getAuditEventRecordType(record); - auditRecordList.add(newRecord); - } -// parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT); -// long count = getAuditService().countObjects(parameterQuery, params); -// if (count != 0){ -// -// } - return auditRecordList; - } private List, String>> initColumns() { List, String>> columns = new ArrayList<>(); @@ -145,51 +110,4 @@ private List, String>> initColumns( return columns; } - private AuditEventRecordType getAuditEventRecordType(AuditEventRecord record){ - AuditEventRecordType newRecord = new AuditEventRecordType(); - newRecord.setTimestamp(MiscUtil.asXMLGregorianCalendar(new Date(record.getTimestamp()))); - //TODO fill in others fields - return newRecord; - } - - private String generateFullQuery(String query){ - if (params.get("from") != null) { - query += "(aer.timestamp >= :from) and "; - } else { - params.remove("from"); - } - if (params.get("to") != null) { - query += "(aer.timestamp <= :to) and "; - } else { - params.remove("to"); - } - if (params.get("eventType") != null) { - query += "(aer.eventType = :eventType) and "; - } else { - params.remove("eventType"); - } - if (params.get("eventStage") != null) { - query += "(aer.eventStage = :eventStage) and "; - } else { - params.remove("eventStage"); - } - if (params.get("outcome") != null) { - query += "(aer.outcome = :outcome) and "; - } else { - params.remove("outcome"); - } - if (params.get("initiatorName") != null) { - query += "(aer.initiatorName = :initiatorName) and "; - } else { - params.remove("initiatorName"); - } - if (params.get("targetName") != null) { - query += "(aer.targetName = :targetName) and "; - } else { - params.remove("targetName"); - } - - query = query.substring(0, query.length()-5); // remove trailing and -return query; - } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java new file mode 100644 index 00000000000..030a320839f --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java @@ -0,0 +1,155 @@ +package com.evolveum.midpoint.web.page.admin.reports.dto; + +import com.evolveum.midpoint.audit.api.AuditEventRecord; +import com.evolveum.midpoint.web.component.data.BaseSortableDataProvider; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; +import org.apache.wicket.Component; +import org.apache.wicket.model.IModel; + +import java.util.*; + +/** + * Created by honchar. + */ +public class AuditEventRecordProvider extends BaseSortableDataProvider { + private IModel> model; + + private String auditEventQuery; + private Map parameters = new HashMap<>(); + + private static final String AUDIT_RECORDS_QUERY_CORE = "from RAuditEventRecord as aer where 1=1 and "; + private static final String AUDIT_RECORDS_QUERY_COUNT = "select count(*) "; + private static final String AUDIT_RECORDS_ORDER_BY = " order by aer.timestamp asc"; + private static final String SET_FIRST_RESULT_PARAMETER = "setFirstResult"; + private static final String SET_MAX_RESULTS_PARAMETER = "setMaxResults"; + + public AuditEventRecordProvider(Component component){ + this(component, AUDIT_RECORDS_QUERY_CORE, new HashMap()); + } + + public AuditEventRecordProvider(Component component, String auditEventQuery, Map parameters ){ + super(component); + this.auditEventQuery = auditEventQuery; + this.parameters = parameters; + + initModel(); + } + + + private void initModel(){ + model = new IModel>() { + @Override + public List getObject() { + return listRecords(auditEventQuery, true); + } + + @Override + public void setObject(List auditEventRecordTypes) { + + } + + @Override + public void detach() { + + } + }; + } + + @Override + public Iterator internalIterator(long first, long count) { + if (parameters.containsKey(SET_FIRST_RESULT_PARAMETER)){ + parameters.remove(SET_FIRST_RESULT_PARAMETER); + } + parameters.put(SET_FIRST_RESULT_PARAMETER, ((Long) first).intValue()); + if (parameters.containsKey(SET_MAX_RESULTS_PARAMETER)){ + parameters.remove(SET_MAX_RESULTS_PARAMETER); + } + parameters.put(SET_MAX_RESULTS_PARAMETER, ((Long) count).intValue()); + + List recordsList = listRecords(auditEventQuery, true); + return recordsList.iterator(); + } + + + @Override + protected int internalSize(){ + String query = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT + auditEventQuery, false); + long count = getAuditService().countObjects(query, parameters); + + return ((Long)count).intValue(); + } + + private List listRecords(String query, boolean orderBy){ + String parameterQuery = generateFullQuery(query, orderBy); + List auditRecords = getAuditService().listRecords(parameterQuery, parameters); + if (auditRecords == null){ + auditRecords = new ArrayList<>(); + } + List auditRecordList = new ArrayList<>(); + for (AuditEventRecord record : auditRecords){ + auditRecordList.add(record.createAuditEventRecordType()); + } + + return auditRecordList; + } + + public String getAuditEventQuery() { + return auditEventQuery; + } + + public void setAuditEventQuery(String auditEventQuery) { + this.auditEventQuery = auditEventQuery; + } + + private String generateFullQuery(String query, boolean orderBy){ + if (parameters.get("from") != null) { + query += "(aer.timestamp >= :from) and "; + } else { + parameters.remove("from"); + } + if (parameters.get("to") != null) { + query += "(aer.timestamp <= :to) and "; + } else { + parameters.remove("to"); + } + if (parameters.get("eventType") != null) { + query += "(aer.eventType = :eventType) and "; + } else { + parameters.remove("eventType"); + } + if (parameters.get("eventStage") != null) { + query += "(aer.eventStage = :eventStage) and "; + } else { + parameters.remove("eventStage"); + } + if (parameters.get("outcome") != null) { + query += "(aer.outcome = :outcome) and "; + } else { + parameters.remove("outcome"); + } + if (parameters.get("initiatorName") != null) { + query += "(aer.initiatorName = :initiatorName) and "; + } else { + parameters.remove("initiatorName"); + } + if (parameters.get("targetName") != null) { + query += "(aer.targetName = :targetName) and "; + } else { + parameters.remove("targetName"); + } + + query = query.substring(0, query.length()-5); // remove trailing and + if (orderBy){ + query += AUDIT_RECORDS_ORDER_BY; + } + return query; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java index 968737ea039..6f0ee8b37be 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java @@ -33,6 +33,7 @@ import java.util.Properties; import java.util.Set; +import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.model.common.expression.ExpressionFactory; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -190,6 +191,8 @@ public class MidPointApplication extends AuthenticatedWebApplication { transient ExpressionFactory expressionFactory; @Autowired transient TaskManager taskManager; + @Autowired + transient AuditService auditService; @Autowired transient private RepositoryService repositoryService; // temporary @Autowired @@ -322,6 +325,10 @@ public TaskManager getTaskManager() { return taskManager; } + public AuditService getAuditService() { + return auditService; + } + public RepositoryService getRepositoryService() { return repositoryService; } From 0eba3dcbd4cd88c2b498095e2046e177b6c28315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zkan=20Bayraktar?= Date: Tue, 11 Oct 2016 08:36:00 +0200 Subject: [PATCH 3/5] filter parameters are added to the audit log viewer page --- .../admin/reports/PageAuditLogViewer.html | 16 +- .../admin/reports/PageAuditLogViewer.java | 395 ++++++++++-------- .../localization/Midpoint.properties | 8 + 3 files changed, 241 insertions(+), 178 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.html index 5a70fbc3209..70b9a823910 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.html @@ -20,11 +20,21 @@
- - -
+ + + + + + + + +
+
+ +
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java index 57e18c51b23..ab450a04b1a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java @@ -1,195 +1,240 @@ package com.evolveum.midpoint.web.page.admin.reports; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.util.ListModel; + import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.security.api.AuthorizationConstants; -import com.evolveum.midpoint.util.MiscUtil; 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.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.input.DatePanel; -import com.evolveum.midpoint.web.component.util.ListDataProvider; +import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.page.admin.configuration.PageAdminConfiguration; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; -import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.model.IModel; - -import javax.xml.datatype.XMLGregorianCalendar; -import java.sql.Timestamp; -import java.util.*; /** * Created by honchar. */ @PageDescriptor(url = "/admin/auditLogViewer", action = { - @AuthorizationAction(actionUri = PageAdminReports.AUTH_REPORTS_ALL, - label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, - description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_AUDIT_LOG_VIEWER_URL, - label = "PageAuditLogViewer.auth.auditLogViewer.label", - description = "PageAuditLogViewer.auth.auditLogViewer.description")}) + @AuthorizationAction(actionUri = PageAdminReports.AUTH_REPORTS_ALL, + label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, + description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_AUDIT_LOG_VIEWER_URL, + label = "PageAuditLogViewer.auth.auditLogViewer.label", + description = "PageAuditLogViewer.auth.auditLogViewer.description")}) public class PageAuditLogViewer extends PageBase{ - private List auditEventRecordList; - - Map params = new HashMap<>(); - - private static final String ID_PARAMETERS_PANEL = "parametersPanel"; - private static final String ID_TABLE = "table"; - private static final String ID_FROM = "fromField"; - private static final String ID_MAIN_FORM = "mainForm"; - - private static final String AUDIT_RECORDS_QUERY = "from RAuditEventRecord as aer where 1=1 and "; - private static final String AUDIT_RECORDS_QUERY_COUNT = "select count(*) from RAuditEventRecord as aer where 1=1 and "; - - public PageAuditLogViewer(){ - initLayout(); - } - private void initLayout(){ - Form mainForm = new Form(ID_MAIN_FORM); - add(mainForm); - - initParametersPanel(mainForm); - initTable(mainForm); - } - - private void initParametersPanel(Form mainForm){ - WebMarkupContainer parametersPanel = new WebMarkupContainer(ID_PARAMETERS_PANEL); - parametersPanel.setOutputMarkupId(true); - mainForm.add(parametersPanel); - - - final DatePanel from = new DatePanel(ID_FROM, - new IModel() { - @Override - public XMLGregorianCalendar getObject() { - return null; - } - - @Override - public void setObject(XMLGregorianCalendar date) { - - } - - @Override - public void detach() { - - } - }); - from.setOutputMarkupId(true); - parametersPanel.add(from); - } - - private void initTable(Form mainForm){ - IModel> model = new IModel>() { - @Override - public List getObject() { - return getAuditEventRecordList(); - } - - @Override - public void setObject(List auditEventRecord) { - - } - - @Override - public void detach() { - - } - }; - ListDataProvider provider = new ListDataProvider(PageAuditLogViewer.this, model); - BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, - initColumns(), - UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER, - (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER)) { - - }; - table.setShowPaging(true); - table.setOutputMarkupId(true); - mainForm.add(table); - } - - private List getAuditEventRecordList(){ - String parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY); - List auditRecords = getAuditService().listRecords(parameterQuery + " order by aer.timestamp asc", params); - if (auditRecords == null){ - auditRecords = new ArrayList<>(); - } - List auditRecordList = new ArrayList<>(); - for (AuditEventRecord record : auditRecords){ - AuditEventRecordType newRecord = getAuditEventRecordType(record); - auditRecordList.add(newRecord); - } -// parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT); -// long count = getAuditService().countObjects(parameterQuery, params); -// if (count != 0){ -// -// } - return auditRecordList; - } - - private List, String>> initColumns() { - List, String>> columns = new ArrayList<>(); - - IColumn column; - column = new PropertyColumn( - createStringResource("PageAuditLogViewer.column.time"), "timestamp"); - columns.add(column); - - //TODO add columns - - return columns; - } - - private AuditEventRecordType getAuditEventRecordType(AuditEventRecord record){ - AuditEventRecordType newRecord = new AuditEventRecordType(); - newRecord.setTimestamp(MiscUtil.asXMLGregorianCalendar(new Date(record.getTimestamp()))); - //TODO fill in others fields - return newRecord; - } - - private String generateFullQuery(String query){ - if (params.get("from") != null) { - query += "(aer.timestamp >= :from) and "; - } else { - params.remove("from"); - } - if (params.get("to") != null) { - query += "(aer.timestamp <= :to) and "; - } else { - params.remove("to"); - } - if (params.get("eventType") != null) { - query += "(aer.eventType = :eventType) and "; - } else { - params.remove("eventType"); - } - if (params.get("eventStage") != null) { - query += "(aer.eventStage = :eventStage) and "; - } else { - params.remove("eventStage"); - } - if (params.get("outcome") != null) { - query += "(aer.outcome = :outcome) and "; - } else { - params.remove("outcome"); - } - if (params.get("initiatorName") != null) { - query += "(aer.initiatorName = :initiatorName) and "; - } else { - params.remove("initiatorName"); - } - if (params.get("targetName") != null) { - query += "(aer.targetName = :targetName) and "; - } else { - params.remove("targetName"); - } - - query = query.substring(0, query.length()-5); // remove trailing and -return query; - } + private List auditEventRecordList; + + Map params = new HashMap<>(); + + private static final String ID_PARAMETERS_PANEL = "parametersPanel"; + private static final String ID_TABLE = "table"; + private static final String ID_FROM = "fromField"; + private static final String ID_TO = "toField"; + private static final String ID_INITIATOR = "initiatorField"; + private static final String ID_CHANNEL = "channelField"; + private static final String ID_PROPERTY = "propertyField"; + private static final String ID_MAIN_FORM = "mainForm"; + private static final String ID_SEARCH_BUTTON = "searchButton"; + + private static final String AUDIT_RECORDS_QUERY = "from RAuditEventRecord as aer where 1=1 and "; + private static final String AUDIT_RECORDS_QUERY_COUNT = "select count(*) from RAuditEventRecord as aer where 1=1 and "; + + private IModel fromModel; + private IModel toModel; + private IModel initiatorModel; + private IModel channelModel; + private IModel channelListModel; + private IModel propertyModel; + + public PageAuditLogViewer(){ + fromModel = new Model(); + toModel = new Model(); + initiatorModel = new Model(); + channelModel = new Model(); + channelListModel = new ListModel(new WebComponentUtil().getChannelList()); + propertyModel = new Model(); + initLayout(); + } + private void initLayout(){ + Form mainForm = new Form(ID_MAIN_FORM); + mainForm.setOutputMarkupId(true); + add(mainForm); + + initParametersPanel(mainForm); + initTable(mainForm); + } + + private void initParametersPanel(Form mainForm){ + WebMarkupContainer parametersPanel = new WebMarkupContainer(ID_PARAMETERS_PANEL); + parametersPanel.setOutputMarkupId(true); + mainForm.add(parametersPanel); + + final DatePanel from = new DatePanel(ID_FROM, fromModel); + from.setOutputMarkupId(true); + parametersPanel.add(from); + + final DatePanel to = new DatePanel(ID_TO, toModel); + to.setOutputMarkupId(true); + parametersPanel.add(to); + + final TextPanel initiator = new TextPanel(ID_INITIATOR, initiatorModel); + initiator.setOutputMarkupId(true); + parametersPanel.add(initiator); + + final DropDownChoicePanel channel = new DropDownChoicePanel(ID_CHANNEL, channelModel, channelListModel); + channel.setOutputMarkupId(true); + parametersPanel.add(channel); + + final TextPanel property = new TextPanel(ID_PROPERTY, propertyModel); + property.setOutputMarkupId(true); + parametersPanel.add(property); + + AjaxButton ajaxButton = new AjaxButton(ID_SEARCH_BUTTON, createStringResource("BasicSearchPanel.search")) { + @Override + public void onClick(AjaxRequestTarget arg0) { + Form mainForm = (Form)get(ID_MAIN_FORM); + initTable(mainForm); + arg0.add(mainForm); + // TODO Auto-generated method stub + } + }; + ajaxButton.setOutputMarkupId(true); + parametersPanel.add(ajaxButton); + } + + private void initTable(Form mainForm){ + IModel> model = new IModel>() { + @Override + public List getObject() { + return getAuditEventRecordList(); + } + + @Override + public void setObject(List auditEventRecord) { + + } + + @Override + public void detach() { + + } + }; + ListDataProvider provider = new ListDataProvider(PageAuditLogViewer.this, model); + BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, + initColumns(), + UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER, + (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER)) { + + }; + table.setShowPaging(true); + table.setOutputMarkupId(true); + mainForm.add(table); + } + + private List getAuditEventRecordList(){ + String parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY); + List auditRecords = getAuditService().listRecords(parameterQuery + " order by aer.timestamp asc", params); + if (auditRecords == null){ + auditRecords = new ArrayList<>(); + } + List auditRecordList = new ArrayList<>(); + for (AuditEventRecord record : auditRecords){ + AuditEventRecordType newRecord = getAuditEventRecordType(record); + auditRecordList.add(newRecord); + } + // parameterQuery = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT); + // long count = getAuditService().countObjects(parameterQuery, params); + // if (count != 0){ + // + // } + return auditRecordList; + } + + private List, String>> initColumns() { + List, String>> columns = new ArrayList<>(); + + IColumn timeColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.time"), "timestamp"); + columns.add(timeColumn); + IColumn initiatorColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.initiatorRef"), "initiatorRef"); + columns.add(initiatorColumn); + IColumn taskIdentifierColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.taskIdentifier"), "taskIdentifier"); + columns.add(taskIdentifierColumn); + IColumn channelColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.channel"), "channel"); + columns.add(channelColumn); + IColumn deltaColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.delta"), "delta"); + columns.add(deltaColumn); + + //TODO add columns + + return columns; + } + + private AuditEventRecordType getAuditEventRecordType(AuditEventRecord record){ + AuditEventRecordType recordType = record.createAuditEventRecordType(); + // AuditEventRecordType newRecord = new AuditEventRecordType(); + // newRecord.setTimestamp(MiscUtil.asXMLGregorianCalendar(new Date(record.getTimestamp()))); + // TODO fill in others fields + return recordType; + } + + private String generateFullQuery(String query){ + if (params.get("from") != null) { + query += "(aer.timestamp >= :from) and "; + } else { + params.remove("from"); + } + if (params.get("to") != null) { + query += "(aer.timestamp <= :to) and "; + } else { + params.remove("to"); + } + if (params.get("eventType") != null) { + query += "(aer.eventType = :eventType) and "; + } else { + params.remove("eventType"); + } + if (params.get("eventStage") != null) { + query += "(aer.eventStage = :eventStage) and "; + } else { + params.remove("eventStage"); + } + if (params.get("outcome") != null) { + query += "(aer.outcome = :outcome) and "; + } else { + params.remove("outcome"); + } + if (params.get("initiatorName") != null) { + query += "(aer.initiatorName = :initiatorName) and "; + } else { + params.remove("initiatorName"); + } + if (params.get("targetName") != null) { + query += "(aer.targetName = :targetName) and "; + } else { + params.remove("targetName"); + } + + query = query.substring(0, query.length()-5); // remove trailing and + return query; + } } diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 59288846f1b..51ebcb9edab 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3340,4 +3340,12 @@ PageAuditLogViewer.title=Audit Log Viewer PageAuditLogViewer.menuName=Audit Log Viewer PageAuditLogViewer.timeLabel=Time PageAuditLogViewer.fromLabel=from +PageAuditLogViewer.toLabel=to +PageAuditLogViewer.initiatorLabel=initiator +PageAuditLogViewer.channelLabel=channel +PageAuditLogViewer.propertyLabel=property PageAuditLogViewer.column.time=Time +PageAuditLogViewer.column.initiatorRef=Initiator +PageAuditLogViewer.column.taskIdentifier=Task Identifier +PageAuditLogViewer.column.channel=Channel +PageAuditLogViewer.column.delta=Delta \ No newline at end of file From 367ed4d7672059b7162f40c6da939719a874e07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zkan=20Bayraktar?= Date: Tue, 11 Oct 2016 09:25:00 +0200 Subject: [PATCH 4/5] fix the error about the table on the audit log viewer page --- .../admin/reports/PageAuditLogViewer.java | 88 ++++--------------- 1 file changed, 16 insertions(+), 72 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java index 8e983bf1ce0..9b41ed418da 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.web.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.input.DatePanel; import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; +import com.evolveum.midpoint.web.component.input.TextPanel; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.page.admin.configuration.PageAdminConfiguration; import com.evolveum.midpoint.web.page.admin.reports.dto.AuditEventRecordProvider; @@ -43,6 +44,7 @@ label = "PageAuditLogViewer.auth.auditLogViewer.label", description = "PageAuditLogViewer.auth.auditLogViewer.description")}) public class PageAuditLogViewer extends PageBase{ + private List auditEventRecordList; Map params = new HashMap<>(); @@ -57,7 +59,6 @@ public class PageAuditLogViewer extends PageBase{ private static final String ID_MAIN_FORM = "mainForm"; private static final String ID_SEARCH_BUTTON = "searchButton"; - private IModel fromModel; private IModel toModel; private IModel initiatorModel; @@ -74,6 +75,7 @@ public PageAuditLogViewer(){ propertyModel = new Model(); initLayout(); } + private void initLayout(){ Form mainForm = new Form(ID_MAIN_FORM); mainForm.setOutputMarkupId(true); @@ -87,7 +89,7 @@ private void initParametersPanel(Form mainForm){ WebMarkupContainer parametersPanel = new WebMarkupContainer(ID_PARAMETERS_PANEL); parametersPanel.setOutputMarkupId(true); mainForm.add(parametersPanel); - + final DatePanel from = new DatePanel(ID_FROM, fromModel); from.setOutputMarkupId(true); parametersPanel.add(from); @@ -99,15 +101,15 @@ private void initParametersPanel(Form mainForm){ final TextPanel initiator = new TextPanel(ID_INITIATOR, initiatorModel); initiator.setOutputMarkupId(true); parametersPanel.add(initiator); - + final DropDownChoicePanel channel = new DropDownChoicePanel(ID_CHANNEL, channelModel, channelListModel); channel.setOutputMarkupId(true); parametersPanel.add(channel); - + final TextPanel property = new TextPanel(ID_PROPERTY, propertyModel); property.setOutputMarkupId(true); parametersPanel.add(property); - + AjaxButton ajaxButton = new AjaxButton(ID_SEARCH_BUTTON, createStringResource("BasicSearchPanel.search")) { @Override public void onClick(AjaxRequestTarget arg0) { @@ -122,26 +124,18 @@ public void onClick(AjaxRequestTarget arg0) { } private void initTable(Form mainForm){ - IModel> model = new IModel>() { - @Override - public List getObject() { - return getAuditEventRecordList(); - } - - @Override - public void setObject(List auditEventRecord) { - - } + AuditEventRecordProvider provider = new AuditEventRecordProvider(PageAuditLogViewer.this); + BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, + initColumns(), + UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER, + (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER)); + table.setShowPaging(true); + table.setOutputMarkupId(true); + mainForm.add(table); + } - private void initTable(Form mainForm){ - AuditEventRecordProvider provider = new AuditEventRecordProvider(PageAuditLogViewer.this); - BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, - initColumns(), - UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER, - (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_AUDIT_LOG_VIEWER)) { private List, String>> initColumns() { List, String>> columns = new ArrayList<>(); - IColumn timeColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.time"), "timestamp"); columns.add(timeColumn); IColumn initiatorColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.initiatorRef"), "initiatorRef"); @@ -152,57 +146,7 @@ private List, String>> initColumns( columns.add(channelColumn); IColumn deltaColumn = new PropertyColumn(createStringResource("PageAuditLogViewer.column.delta"), "delta"); columns.add(deltaColumn); - - return columns; } - private AuditEventRecordType getAuditEventRecordType(AuditEventRecord record){ - AuditEventRecordType recordType = record.createAuditEventRecordType(); - // AuditEventRecordType newRecord = new AuditEventRecordType(); - // newRecord.setTimestamp(MiscUtil.asXMLGregorianCalendar(new Date(record.getTimestamp()))); - // TODO fill in others fields - return recordType; - } - - private String generateFullQuery(String query){ - if (params.get("from") != null) { - query += "(aer.timestamp >= :from) and "; - } else { - params.remove("from"); - } - if (params.get("to") != null) { - query += "(aer.timestamp <= :to) and "; - } else { - params.remove("to"); - } - if (params.get("eventType") != null) { - query += "(aer.eventType = :eventType) and "; - } else { - params.remove("eventType"); - } - if (params.get("eventStage") != null) { - query += "(aer.eventStage = :eventStage) and "; - } else { - params.remove("eventStage"); - } - if (params.get("outcome") != null) { - query += "(aer.outcome = :outcome) and "; - } else { - params.remove("outcome"); - } - if (params.get("initiatorName") != null) { - query += "(aer.initiatorName = :initiatorName) and "; - } else { - params.remove("initiatorName"); - } - if (params.get("targetName") != null) { - query += "(aer.targetName = :targetName) and "; - } else { - params.remove("targetName"); - } - - return columns; - } - } From ad8ea89b79e4783c0d7a89be56779710963a1fe4 Mon Sep 17 00:00:00 2001 From: honchar Date: Tue, 11 Oct 2016 09:55:03 +0200 Subject: [PATCH 5/5] provider for AuditEventRecordType changed --- .../reports/dto/AuditEventRecordProvider.java | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java index 030a320839f..a398100b94a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java @@ -57,14 +57,15 @@ public void detach() { @Override public Iterator internalIterator(long first, long count) { - if (parameters.containsKey(SET_FIRST_RESULT_PARAMETER)){ - parameters.remove(SET_FIRST_RESULT_PARAMETER); + Map queryParameters = getParameters(); + if (queryParameters.containsKey(SET_FIRST_RESULT_PARAMETER)){ + queryParameters.remove(SET_FIRST_RESULT_PARAMETER); } - parameters.put(SET_FIRST_RESULT_PARAMETER, ((Long) first).intValue()); - if (parameters.containsKey(SET_MAX_RESULTS_PARAMETER)){ - parameters.remove(SET_MAX_RESULTS_PARAMETER); + queryParameters.put(SET_FIRST_RESULT_PARAMETER, ((Long) first).intValue()); + if (queryParameters.containsKey(SET_MAX_RESULTS_PARAMETER)){ + queryParameters.remove(SET_MAX_RESULTS_PARAMETER); } - parameters.put(SET_MAX_RESULTS_PARAMETER, ((Long) count).intValue()); + queryParameters.put(SET_MAX_RESULTS_PARAMETER, ((Long) count).intValue()); List recordsList = listRecords(auditEventQuery, true); return recordsList.iterator(); @@ -73,15 +74,17 @@ public Iterator internalIterator(long first, long count) { @Override protected int internalSize(){ + Map queryParameters = getParameters(); String query = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT + auditEventQuery, false); - long count = getAuditService().countObjects(query, parameters); + long count = getAuditService().countObjects(query, queryParameters); return ((Long)count).intValue(); } private List listRecords(String query, boolean orderBy){ + Map queryParameters = getParameters(); String parameterQuery = generateFullQuery(query, orderBy); - List auditRecords = getAuditService().listRecords(parameterQuery, parameters); + List auditRecords = getAuditService().listRecords(parameterQuery, queryParameters); if (auditRecords == null){ auditRecords = new ArrayList<>(); } @@ -102,40 +105,41 @@ public void setAuditEventQuery(String auditEventQuery) { } private String generateFullQuery(String query, boolean orderBy){ - if (parameters.get("from") != null) { + Map queryParameters = getParameters(); + if (queryParameters.get("from") != null) { query += "(aer.timestamp >= :from) and "; } else { - parameters.remove("from"); + queryParameters.remove("from"); } - if (parameters.get("to") != null) { + if (queryParameters.get("to") != null) { query += "(aer.timestamp <= :to) and "; } else { - parameters.remove("to"); + queryParameters.remove("to"); } - if (parameters.get("eventType") != null) { + if (queryParameters.get("eventType") != null) { query += "(aer.eventType = :eventType) and "; } else { - parameters.remove("eventType"); + queryParameters.remove("eventType"); } - if (parameters.get("eventStage") != null) { + if (queryParameters.get("eventStage") != null) { query += "(aer.eventStage = :eventStage) and "; } else { - parameters.remove("eventStage"); + queryParameters.remove("eventStage"); } - if (parameters.get("outcome") != null) { + if (queryParameters.get("outcome") != null) { query += "(aer.outcome = :outcome) and "; } else { - parameters.remove("outcome"); + queryParameters.remove("outcome"); } - if (parameters.get("initiatorName") != null) { + if (queryParameters.get("initiatorName") != null) { query += "(aer.initiatorName = :initiatorName) and "; } else { - parameters.remove("initiatorName"); + queryParameters.remove("initiatorName"); } - if (parameters.get("targetName") != null) { + if (queryParameters.get("targetName") != null) { query += "(aer.targetName = :targetName) and "; } else { - parameters.remove("targetName"); + queryParameters.remove("targetName"); } query = query.substring(0, query.length()-5); // remove trailing and