From 15dd458eb9696f744dfa36bf179a2aa2b564d86a Mon Sep 17 00:00:00 2001 From: kate Date: Tue, 3 Apr 2018 14:39:14 +0200 Subject: [PATCH 01/43] induced entitlements panel, columns are fixed --- .../AbstractRoleAssignmentPanel.java | 43 +++--- .../component/assignment/AssignmentPanel.java | 2 +- .../assignment/InducedEntitlementsPanel.java | 131 ++++++++++++++++++ .../component/data/SelectableDataTable.java | 2 +- 4 files changed, 152 insertions(+), 26 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index 154bc354350..9fc06c3e323 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -231,6 +231,25 @@ public void populateItem(Item, String>(createStringResource("AssignmentType.tenant")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> item, String componentId, + final IModel> rowModel) { + item.add(new Label(componentId, getTenantLabelModel(rowModel.getObject()))); + } + }); + columns.add(new AbstractColumn, String>(createStringResource("AssignmentType.orgReferenceShorten")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> item, String componentId, + final IModel> rowModel) { + item.add(new Label(componentId, getOrgRefLabelModel(rowModel.getObject()))); + } + }); + return columns; } @@ -308,30 +327,6 @@ protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentD return new AbstractRoleAssignmentDetailsPanel(ID_ASSIGNMENT_DETAILS, form, model); } - @Override - protected List, String>> initBasicColumns() { - List, String>> columns = super.initBasicColumns(); - columns.add(new AbstractColumn, String>(createStringResource("AssignmentType.tenant")){ - private static final long serialVersionUID = 1L; - - @Override - public void populateItem(Item>> item, String componentId, - final IModel> rowModel) { - item.add(new Label(componentId, getTenantLabelModel(rowModel.getObject()))); - } - }); - columns.add(new AbstractColumn, String>(createStringResource("AssignmentType.orgReferenceShorten")){ - private static final long serialVersionUID = 1L; - - @Override - public void populateItem(Item>> item, String componentId, - final IModel> rowModel) { - item.add(new Label(componentId, getOrgRefLabelModel(rowModel.getObject()))); - } - }); - return columns; - } - private IModel getTenantLabelModel(ContainerValueWrapper assignmentContainer){ if (assignmentContainer == null || assignmentContainer.getContainerValue() == null){ return Model.of(""); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java index 68ca698b1e4..5d020439caa 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java @@ -224,7 +224,7 @@ protected AssignmentsTabStorage getAssignmentsStorage() { protected abstract ObjectQuery createObjectQuery(); - protected List, String>> initBasicColumns() { + private List, String>> initBasicColumns() { List, String>> columns = new ArrayList<>(); columns.add(new CheckBoxHeaderColumn<>()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java index a30b6f77094..81fe813e430 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java @@ -1,19 +1,33 @@ package com.evolveum.midpoint.web.component.assignment; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ValueStatus; import com.evolveum.midpoint.web.session.AssignmentsTabStorage; import com.evolveum.midpoint.web.session.UserProfileStorage; +import com.evolveum.midpoint.web.util.ExpressionUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; +import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import javax.jws.WebParam; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -24,6 +38,9 @@ public class InducedEntitlementsPanel extends InducementsPanel{ private static final long serialVersionUID = 1L; + private static final Trace LOGGER = TraceManager.getTrace(InducedEntitlementsPanel.class); + private static final String DOT_CLASS = InducedEntitlementsPanel.class.getName() + "."; + private static final String OPERATION_LOAD_SHADOW_DISPLAY_NAME = DOT_CLASS + "loadShadowDisplayName"; public InducedEntitlementsPanel(String id, IModel> inducementContainerWrapperModel){ super(id, inducementContainerWrapperModel); @@ -49,6 +66,40 @@ private AssignmentsTabStorage getInducedEntitlementsTabStorage(){ return getParentPage().getSessionStorage().getInducedEntitlementsTabStorage(); } + @Override + protected List, String>> initColumns() { + List, String>> columns = new ArrayList<>(); + columns.add(new AbstractColumn, String>(createStringResource("ConstructionType.kind")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> item, String componentId, + final IModel> rowModel) { + item.add(new Label(componentId, getKindLabelModel(rowModel.getObject()))); + } + }); + columns.add(new AbstractColumn, String>(createStringResource("ConstructionType.intent")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> item, String componentId, + final IModel> rowModel) { + item.add(new Label(componentId, getIntentLabelModel(rowModel.getObject()))); + } + }); + columns.add(new AbstractColumn, String>(createStringResource("ConstructionType.association")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> item, String componentId, + final IModel> rowModel) { + item.add(new Label(componentId, getAssociationLabelModel(rowModel.getObject()))); + } + }); + + return columns; + } + @Override protected ObjectQuery createObjectQuery() { ObjectQuery query = super.createObjectQuery(); @@ -91,4 +142,84 @@ protected boolean isRelationVisible() { protected List getObjectTypesList(){ return Arrays.asList(ObjectTypes.RESOURCE); } + + private IModel getKindLabelModel(ContainerValueWrapper assignmentWrapper){ + if (assignmentWrapper == null){ + return Model.of(""); + } + AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); + ConstructionType construction = assignment.getConstruction(); + if (construction == null || construction.getKind() == null){ + return Model.of(""); + } + return WebComponentUtil.createLocalizedModelForEnum(construction.getKind(), InducedEntitlementsPanel.this); + + } + + private IModel getIntentLabelModel(ContainerValueWrapper assignmentWrapper){ + if (assignmentWrapper == null){ + return Model.of(""); + } + AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); + ConstructionType construction = assignment.getConstruction(); + if (construction == null || construction.getIntent() == null){ + return Model.of(""); + } + return Model.of(construction.getIntent()); + + } + + private IModel getAssociationLabelModel(ContainerValueWrapper assignmentWrapper){ + if (assignmentWrapper == null){ + return Model.of(""); + } + AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); + ConstructionType construction = assignment.getConstruction(); + if (construction == null || construction.getAssociation() == null){ + return Model.of(""); + } + StringBuilder sb = new StringBuilder(); + for (ResourceObjectAssociationType association : construction.getAssociation()){ + if (association.getOutbound() == null || association.getOutbound().getExpression() == null){ + continue; + } + ObjectReferenceType shadowRefValue = ExpressionUtil.getShadowRefValue(association.getOutbound().getExpression()); + if (shadowRefValue == null || StringUtils.isEmpty(shadowRefValue.getOid())){ + continue; + } + String shadowDisplayName = WebComponentUtil.getDisplayNameOrName(shadowRefValue, getPageBase(), OPERATION_LOAD_SHADOW_DISPLAY_NAME); + if (sb.length() == 0){ + sb.append(createStringResource("ExpressionValuePanel.shadowRefValueTitle").getString() + ":"); + } + if (StringUtils.isNotEmpty(shadowDisplayName)){ + sb.append("\n"); + sb.append(shadowDisplayName); + } + } + return Model.of(sb.toString()); + + } + + @Override + protected List> postSearch(List> assignments) { + //TODO fix post search filtering + List> filteredAssignments = new ArrayList<>(); + assignments.forEach(assignmentWrapper -> { + AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); + if (assignment.getConstruction() != null && assignment.getConstruction().getAssociation() != null){ + List associations = assignment.getConstruction().getAssociation(); + associations.forEach(association -> { + if (association.getOutbound() != null && association.getOutbound().getExpression() != null){ + ObjectReferenceType shadowRef = ExpressionUtil.getShadowRefValue(association.getOutbound().getExpression()); + if (shadowRef != null || (shadowRef == null && ValueStatus.ADDED.equals(assignmentWrapper.getStatus()))){ + filteredAssignments.add(assignmentWrapper); + return; + } + } + }); + } + }); +// return filteredAssignments; + return assignments; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableDataTable.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableDataTable.java index 1bcfe9e89a3..c7779144282 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableDataTable.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableDataTable.java @@ -60,7 +60,7 @@ public SelectableRowItem(String id, int index, IModel model) { @Override protected Item> newCellItem(String id, int index, IModel> model) { Item item = super.newCellItem(id, index, model); - item.add(new AttributeModifier("style", "max-width: 250px; word-wrap: break-word;")); + item.add(new AttributeModifier("style", "word-wrap: break-word;")); return item; } From 20117d0675b5d0f944ad58d2be168ecf13a855f4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 4 Apr 2018 20:16:57 +0200 Subject: [PATCH 02/43] Add searchOptions extension property (MID-3293) This property can be used e.g. to specify 'distinct' option to be used when searching for objects in iterative tasks. Added samples how to use distinct in iterative tasks and bulk actions. See also https://wiki.evolveum.com/display/midPoint/Redundant+objects+processing+elimination+HOWTO. --- .../schema/constants/SchemaConstants.java | 1 + .../xml/ns/public/model/extension-3.xsd | 14 +++ .../ObjectIntegrityCheckTaskHandler.java | 4 +- .../AbstractSearchIterativeTaskHandler.java | 18 ++-- .../bulk-actions/script-users-distinct.xml | 87 +++++++++++++++++++ .../tasks/task-user-recompute-distinct.xml | 71 +++++++++++++++ 6 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 samples/tasks/bulk-actions/script-users-distinct.xml create mode 100644 samples/tasks/task-user-recompute-distinct.xml diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 4302afd2f8d..77e7306086b 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -358,6 +358,7 @@ public abstract class SchemaConstants { public static final QName MODEL_EXTENSION_OBJECT_TYPE = new QName(NS_MODEL_EXTENSION, "objectType"); public static final QName MODEL_EXTENSION_OBJECT_QUERY = new QName(NS_MODEL_EXTENSION, "objectQuery"); + public static final QName MODEL_EXTENSION_SEARCH_OPTIONS = new QName(NS_MODEL_EXTENSION, "searchOptions"); public static final QName MODEL_EXTENSION_ITERATION_METHOD = new QName(NS_MODEL_EXTENSION, "iterationMethod"); public static final QName MODEL_EXTENSION_OBJECT_DELTA = new QName(NS_MODEL_EXTENSION, "objectDelta"); public static final QName MODEL_EXTENSION_WORKER_THREADS = new QName(NS_MODEL_EXTENSION, "workerThreads"); diff --git a/infra/schema/src/main/resources/xml/ns/public/model/extension-3.xsd b/infra/schema/src/main/resources/xml/ns/public/model/extension-3.xsd index 85330e2fc37..88d8dcd451b 100644 --- a/infra/schema/src/main/resources/xml/ns/public/model/extension-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/model/extension-3.xsd @@ -141,6 +141,20 @@ + + + + Options to be used for object search (if supported by particular task handler). + + + Search options + + 0 + 1 + + + + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ObjectIntegrityCheckTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ObjectIntegrityCheckTaskHandler.java index 492fecbd3c7..172ebb1790e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ObjectIntegrityCheckTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ObjectIntegrityCheckTaskHandler.java @@ -94,7 +94,9 @@ protected ObjectQuery createQuery(ObjectIntegrityCheckResultHandler handler, Tas protected Collection> createSearchOptions( ObjectIntegrityCheckResultHandler resultHandler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { - return SelectorOptions.createCollection(GetOperationOptions.createAttachDiagData()); + Collection> optionsFromTask = createSearchOptionsFromTask(resultHandler, + runResult, coordinatorTask, opResult); + return SelectorOptions.updateRootOptions(optionsFromTask, opt -> opt.setAttachDiagData(true), GetOperationOptions::new); } @Override diff --git a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java index b53bdd6d8aa..bd6b88ca1f4 100644 --- a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java +++ b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java @@ -17,16 +17,14 @@ import static com.evolveum.midpoint.prism.PrismProperty.getRealValue; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.function.Function; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.schema.util.TaskWorkStateTypeUtil; import com.evolveum.midpoint.task.api.*; import com.evolveum.midpoint.util.exception.*; @@ -490,10 +488,10 @@ protected ObjectQuery createQuery(H handler, TaskRunResult runResult, Task coord // useful e.g. to specify noFetch options for shadow-related queries protected Collection> createSearchOptions(H resultHandler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { - return null; + return createSearchOptionsFromTask(resultHandler, runResult, coordinatorTask, opResult); } - // as provisioning service does not allow searches without specifying resource or objectclass/kind, we need to be able to contact repository directly + // as provisioning service does not allow searches without specifying resource or objectclass/kind, we need to be able to contact repository directly // for some specific tasks protected boolean useRepositoryDirectly(H resultHandler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { return false; @@ -522,7 +520,13 @@ protected ObjectQuery createQueryFromTask(H handler, TaskRunResult runResult, Ta return query != null ? query : new ObjectQuery(); } - protected ObjectQuery createQueryFromTaskIfExists(H handler, TaskRunResult runResult, Task task, OperationResult opResult) throws SchemaException { + protected Collection> createSearchOptionsFromTask(H resultHandler, TaskRunResult runResult, + Task coordinatorTask, OperationResult opResult) { + SelectorQualifiedGetOptionsType opts = getRealValue(coordinatorTask.getExtensionProperty(SchemaConstants.MODEL_EXTENSION_SEARCH_OPTIONS)); + return MiscSchemaUtil.optionsTypeToOptions(opts); + } + + protected ObjectQuery createQueryFromTaskIfExists(H handler, TaskRunResult runResult, Task task, OperationResult opResult) throws SchemaException { Class objectType = getType(task); LOGGER.trace("Object type = {}", objectType); diff --git a/samples/tasks/bulk-actions/script-users-distinct.xml b/samples/tasks/bulk-actions/script-users-distinct.xml new file mode 100644 index 00000000000..6aa2c299958 --- /dev/null +++ b/samples/tasks/bulk-actions/script-users-distinct.xml @@ -0,0 +1,87 @@ + + + + script users (distinct) + runnable + + + + c:UserType + + + + assignment + + + + targetRef + + + + targetRef + + + + targetRef + + + + targetRef + + + + targetRef + + + + + + + + + + + true + + + + + execute-script + + script + + + log.info('Hello {}', input) + + + + + + + + + BulkActions + http://midpoint.evolveum.com/xml/ns/public/model/scripting/handler-3 + single + \ No newline at end of file diff --git a/samples/tasks/task-user-recompute-distinct.xml b/samples/tasks/task-user-recompute-distinct.xml new file mode 100644 index 00000000000..20c8cc2f730 --- /dev/null +++ b/samples/tasks/task-user-recompute-distinct.xml @@ -0,0 +1,71 @@ + + + + + + User Recompute (distinct) + + + + + assignment + + + + targetRef + + + + targetRef + + + + targetRef + + + + targetRef + + + + targetRef + + + + + + + + UserType + + + + + + runnable + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/recompute/handler-3 + single + From cefb11f11bac7cd5c3449b4ef34d7e54fd641a0c Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 4 Apr 2018 20:26:01 +0200 Subject: [PATCH 03/43] Upgrade CXF from 3.2.1 to 3.2.4 (MID-4353) --- build-system/pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build-system/pom.xml b/build-system/pom.xml index 90db6a74dd3..3ea5ce2a29a 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -49,7 +49,7 @@ 2.6 3.7 1.2 - 3.2.1 + 3.2.4 3.2.0 2.2.0 2.4.7 @@ -63,7 +63,8 @@ 1.0.1 1.7.25 1.2.3 - 1.5.8.e1 + 1.5.8.e1 4.3.14.RELEASE 4.2.4.RELEASE 3.5.0 From 557f26665a89ceb7b067461ede7d0027b11351c9 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 4 Apr 2018 20:49:31 +0200 Subject: [PATCH 04/43] Fix hashed password notifications (MID-4566) This is only a PRELIMINARY fix. It expects that the password stored in the primary delta is not hashed even after model execution. To be discussed further. --- .../notifications/api/events/ModelEvent.java | 4 ++ .../impl/notifiers/UserPasswordNotifier.java | 38 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java index 3508e7d825f..3bd8df25494 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java @@ -149,6 +149,10 @@ public boolean isCategoryType(EventCategoryType eventCategoryType) { return eventCategoryType == EventCategoryType.MODEL_EVENT; } + public ObjectDelta getFocusPrimaryDelta() { + return getFocusContext() != null ? getFocusContext().getPrimaryDelta() : null; + } + public List> getFocusDeltas() { List> retval = new ArrayList<>(); Class c = modelContext.getFocusClass(); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java index ecd5a818b67..cbe3fc1797c 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java @@ -40,6 +40,8 @@ import java.util.List; +import static java.util.Collections.singletonList; + /** * @author mederly */ @@ -76,23 +78,38 @@ protected boolean checkApplicability(Event event, GeneralNotifierType generalNot LOGGER.trace("Operation was not successful, exiting."); return false; } + return getPasswordFromEvent((ModelEvent) event) != null; // logging is done in the called method + } - ModelEvent modelEvent = (ModelEvent) event; + private String getPasswordFromEvent(ModelEvent modelEvent) { if (modelEvent.getFocusDeltas().isEmpty()) { LOGGER.trace("No user deltas in event, exiting."); - return false; + return null; } - if (getPasswordFromDeltas(modelEvent.getFocusDeltas()) != null) { - LOGGER.trace("Found password in user delta(s), continuing."); - return true; + String password = getPasswordFromDeltas(modelEvent.getFocusDeltas()); + if (password != null) { + LOGGER.trace("Found password in user executed delta(s), continuing."); + return password; + } + //noinspection unchecked + ObjectDelta focusPrimaryDelta = (ObjectDelta) modelEvent.getFocusPrimaryDelta(); + if (focusPrimaryDelta == null) { + LOGGER.trace("No password in executed delta(s) and no primary delta, exiting."); + return null; + } + password = getPasswordFromDeltas(singletonList(focusPrimaryDelta)); + if (password != null) { + LOGGER.trace("Found password in user primary delta, continuing."); + return password; } else { - LOGGER.trace("No password in user delta(s), exiting."); - return false; + LOGGER.trace("No password in executed delta(s) nor in primary delta, exiting."); + return null; } } private String getPasswordFromDeltas(List> deltas) { try { + //noinspection unchecked return midpointFunctions.getPlaintextUserPasswordFromDeltas((List) deltas); } catch (EncryptionException e) { LoggingUtils.logException(LOGGER, "Couldn't decrypt password from user deltas: {}", e, DebugUtil.debugDump(deltas)); @@ -107,15 +124,12 @@ protected String getSubject(Event event, GeneralNotifierType generalNotifierType @Override protected String getBody(Event event, GeneralNotifierType generalNotifierType, String transport, Task task, OperationResult result) { - - ModelEvent modelEvent = (ModelEvent) event; - List> deltas = modelEvent.getFocusDeltas(); - return "Password for user " + notificationsUtil.getObjectType(event.getRequestee(), false, result).getName() + " is: " + getPasswordFromDeltas(deltas); + return "Password for user " + notificationsUtil.getObjectType(event.getRequestee(), false, result).getName() + + " is: " + getPasswordFromEvent((ModelEvent) event); } @Override protected Trace getLogger() { return LOGGER; } - } From 2bdb2a6a0ff14579a497ab56c78af913b00d8907 Mon Sep 17 00:00:00 2001 From: kate Date: Thu, 5 Apr 2018 11:40:50 +0200 Subject: [PATCH 05/43] induced entitlements filter fixes --- .../AbstractRoleAssignmentPanel.java | 4 -- .../ConstructionAssociationPanel.java | 6 ++- .../assignment/InducedEntitlementsPanel.java | 47 +++++++++---------- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index 9fc06c3e323..b9ca2e932e8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -206,7 +206,6 @@ protected void addSelectedAssignmentsPerformed(AjaxReques constructionType.setResourceRef(ref); constructionType.setKind(kind); constructionType.setIntent(intent); - initAssociationContainer(constructionType); assignmentType.setConstruction(constructionType); } else { assignmentType.setTargetRef(ref); @@ -218,9 +217,6 @@ protected void addSelectedAssignmentsPerformed(AjaxReques reloadSavePreviewButtons(target); } - protected void initAssociationContainer(ConstructionType constructionType){ - } - protected List, String>> initColumns() { List, String>> columns = new ArrayList<>(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java index 0128cb7d22d..10be52569db 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java @@ -237,11 +237,13 @@ public List load() { PrismContainerValue associationValue = ((ContainerValueWrapper) associationValueWrapper).getContainerValue(); ResourceObjectAssociationType assoc = (ResourceObjectAssociationType) associationValue.asContainerable(); if (assoc == null || assoc.getOutbound() == null || assoc.getOutbound().getExpression() == null - || ExpressionUtil.getShadowRefValue(assoc.getOutbound().getExpression()) == null) { + || (ExpressionUtil.getShadowRefValue(assoc.getOutbound().getExpression()) == null + && !ValueStatus.ADDED.equals(((ContainerValueWrapper) associationValueWrapper).getStatus()))) { return; } QName assocRef = ItemPathUtil.getOnlySegmentQName(assoc.getRef()); - if (defName != null && defName.equals(assocRef)) { + if ((defName != null && defName.equals(assocRef)) + || (assocRef == null && ValueStatus.ADDED.equals(((ContainerValueWrapper) associationValueWrapper).getStatus()))) { shadowsList.add(ExpressionUtil.getShadowRefValue(assoc.getOutbound().getExpression())); } }); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java index 81fe813e430..89c9d84718d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java @@ -105,11 +105,7 @@ protected ObjectQuery createObjectQuery() { ObjectQuery query = super.createObjectQuery(); ObjectFilter filter = query.getFilter(); ObjectQuery entitlementsQuery = QueryBuilder.queryFor(AssignmentType.class, getParentPage().getPrismContext()) - .block() - .not() - .item(AssignmentType.F_CONSTRUCTION, ConstructionType.F_ASSOCIATION, ResourceObjectAssociationType.F_OUTBOUND, MappingType.F_EXPRESSION) - .isNull() - .endBlock() + .exists(AssignmentType.F_CONSTRUCTION) .build(); if (filter != null){ query.setFilter(AndFilter.createAnd(filter, entitlementsQuery.getFilter())); @@ -130,11 +126,6 @@ protected Class getDefaultNewAssignmentFocusType(){ } @Override - - protected void initAssociationContainer(ConstructionType constructionType){ - constructionType.beginAssociation().beginOutbound().beginExpression(); - } - protected boolean isRelationVisible() { return false; } @@ -202,24 +193,32 @@ private IModel getAssociationLabelModel(ContainerValueWrapper> postSearch(List> assignments) { - //TODO fix post search filtering List> filteredAssignments = new ArrayList<>(); assignments.forEach(assignmentWrapper -> { - AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); - if (assignment.getConstruction() != null && assignment.getConstruction().getAssociation() != null){ - List associations = assignment.getConstruction().getAssociation(); - associations.forEach(association -> { - if (association.getOutbound() != null && association.getOutbound().getExpression() != null){ - ObjectReferenceType shadowRef = ExpressionUtil.getShadowRefValue(association.getOutbound().getExpression()); - if (shadowRef != null || (shadowRef == null && ValueStatus.ADDED.equals(assignmentWrapper.getStatus()))){ - filteredAssignments.add(assignmentWrapper); - return; - } + AssignmentType assignment = assignmentWrapper.getContainerValue().asContainerable(); + if (assignment.getConstruction() != null && assignment.getConstruction().getAssociation() != null) { + List associations = assignment.getConstruction().getAssociation(); + if (associations.size() == 0 && ValueStatus.ADDED.equals(assignmentWrapper.getStatus())){ + filteredAssignments.add(assignmentWrapper); + return; } - }); + associations.forEach(association -> { + if (!filteredAssignments.contains(assignmentWrapper)) { + if (association.getOutbound() == null && ValueStatus.ADDED.equals(assignmentWrapper.getStatus())) { + filteredAssignments.add(assignmentWrapper); + return; + } + if (association.getOutbound() != null && association.getOutbound().getExpression() != null) { + ObjectReferenceType shadowRef = ExpressionUtil.getShadowRefValue(association.getOutbound().getExpression()); + if ((shadowRef != null || ValueStatus.ADDED.equals(assignmentWrapper.getStatus()))) { + filteredAssignments.add(assignmentWrapper); + return; + } + } + } + }); } }); -// return filteredAssignments; - return assignments; + return filteredAssignments; } } From 0b8e00203bf5644f0e033b6b4a49d4bd1f602f32 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 5 Apr 2018 11:37:20 +0200 Subject: [PATCH 06/43] Adapt TestPasswordDefaultHashing to MID-4553 The history storage is now hashed as well. (cherry picked from commit 2df4a0a) --- .../password/security-policy-default-storage-hashing.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/model/model-intest/src/test/resources/password/security-policy-default-storage-hashing.xml b/model/model-intest/src/test/resources/password/security-policy-default-storage-hashing.xml index 55dbc02dd45..444bcb2ea82 100644 --- a/model/model-intest/src/test/resources/password/security-policy-default-storage-hashing.xml +++ b/model/model-intest/src/test/resources/password/security-policy-default-storage-hashing.xml @@ -23,6 +23,9 @@ hashing + + hashing + From adecade10753409e481f418b9cc79e695a5048a4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 5 Apr 2018 11:42:16 +0200 Subject: [PATCH 07/43] Add tests for user password notifier (MID-4566) Also: Fixed the user password notifier to work with secondary deltas as well (test316UserRecompute). Fixed the notifier to stop expecting full success. This solution is still not complete - we have to find out somehow if the focus update operation(s) were carried out or not. Otherwise we could report password change even if it was not in fact executed. (cherry picked from commit b2ef649) --- ...bstractConfiguredModelIntegrationTest.java | 55 +++- .../intest/password/AbstractPasswordTest.java | 255 +++++++++++------- .../password/TestPasswordDefaultHashing.java | 4 +- .../test/AbstractModelIntegrationTest.java | 10 +- .../notifications/api/events/ModelEvent.java | 4 + .../impl/notifiers/UserPasswordNotifier.java | 30 ++- 6 files changed, 233 insertions(+), 125 deletions(-) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index f6456840ba2..e60e91e6034 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -521,6 +521,7 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final String AUTZ_DRINK_URL = QNameUtil.qNameToUri(AUTZ_DRINK_QNAME); protected static final String NOTIFIER_ACCOUNT_PASSWORD_NAME = "accountPasswordNotifier"; + protected static final String NOTIFIER_USER_PASSWORD_NAME = "userPasswordNotifier"; protected static final String NOTIFIER_ACCOUNT_ACTIVATION_NAME = "accountActivationNotifier"; private static final Trace LOGGER = TraceManager.getTrace(AbstractConfiguredModelIntegrationTest.class); @@ -727,31 +728,45 @@ protected void assertEvaluatedRole(Collection userAfter) throws Exception; @@ -1541,6 +1569,7 @@ public void test314RemovePasswordFail() throws Exception { } finally { setPasswordMinOccurs(null, task, result); } + assertNoUserPasswordNotifications(); } private void setPasswordMinOccurs(Integer value, Task task, OperationResult result) throws CommonException { @@ -1594,7 +1623,9 @@ public void test315RemovePassword() throws Exception { // this one is not changed assertDummyPassword(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_EMPLOYEE_NUMBER_NEW_GOOD); - assertNoPasswordNotifications(); + displayAllNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } /* @@ -1643,8 +1674,9 @@ public void test316UserRecompute() throws Exception { // this one is not changed assertDummyPassword(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_EMPLOYEE_NUMBER_NEW_GOOD); - displayPasswordNotifications(); - assertNoPasswordNotifications(); + displayAccountPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertUserPasswordNotifications(1); } /** @@ -1689,11 +1721,12 @@ public void test318ChangeUserPassword() throws Exception { // this one is not changed assertDummyPassword(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_EMPLOYEE_NUMBER_NEW_GOOD); - displayPasswordNotifications(); - assertPasswordNotifications(2); - assertHasPasswordNotification(null, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); - assertHasPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(2); + assertHasAccountPasswordNotification(null, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); // not BLUE, it already has a password + assertSingleUserPasswordNotification(USER_JACK_USERNAME, USER_PASSWORD_VALID_3); } @Test @@ -1726,7 +1759,8 @@ public void test320ChangeEmployeeNumber() throws Exception { assertDummyPassword(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "emp0000"); - assertSinglePasswordNotification(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "emp0000"); + assertSingleAccountPasswordNotification(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "emp0000"); + assertNoUserPasswordNotifications(); } @Test @@ -1759,7 +1793,8 @@ public void test330RemoveEmployeeNumber() throws Exception { assertDummyPassword(RESOURCE_DUMMY_UGLY_NAME, ACCOUNT_JACK_DUMMY_USERNAME, null); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } /** @@ -1811,7 +1846,8 @@ public void test400AddUserRappWithAssignment() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertSinglePasswordNotification(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertSingleAccountPasswordNotification(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertSingleUserPasswordNotification(USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); } /** @@ -1852,7 +1888,8 @@ public void test401UserRappRecompute() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } /** @@ -1915,8 +1952,9 @@ public void test402AssignRappDummyRed() throws Exception { assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); displayAllNotifications(); - assertSinglePasswordNotificationConditional(RESOURCE_DUMMY_RED_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertSingleAccountPasswordNotificationConditional(RESOURCE_DUMMY_RED_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); assertAccountActivationNotification(RESOURCE_DUMMY_RED_NAME, USER_RAPP_USERNAME); + assertNoUserPasswordNotifications(); } /** @@ -1978,7 +2016,8 @@ public void test403UserRappRecompute() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } /** @@ -2043,7 +2082,8 @@ public void test404InitializeRappDummyRed() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertSingleInitializationPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertSingleAccountInitializationPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertNoUserPasswordNotifications(); } /** @@ -2106,7 +2146,8 @@ public void test405UserRappRecompute() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } /** @@ -2156,7 +2197,8 @@ public void test410AssignRappDummyLifecycle() throws Exception { assertDefaultDummyAccount(USER_RAPP_USERNAME, USER_RAPP_FULLNAME, true); assertDummyPassword(null, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - assertSinglePasswordNotificationConditional(RESOURCE_DUMMY_LIFECYCLE_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertSingleAccountPasswordNotificationConditional(RESOURCE_DUMMY_LIFECYCLE_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertNoUserPasswordNotifications(); } @Test @@ -2232,8 +2274,8 @@ public void test412InitializeRappDummyLifecycle() throws Exception { assertDummyAccountShadowRepo(accountShadow, accountDefaultOid, USER_RAPP_USERNAME); assertShadowLifecycle(accountShadow, null); - assertSingleInitializationPasswordNotification(RESOURCE_DUMMY_LIFECYCLE_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); - + assertSingleAccountInitializationPasswordNotification(RESOURCE_DUMMY_LIFECYCLE_NAME, USER_RAPP_USERNAME, USER_PASSWORD_VALID_1); + assertNoUserPasswordNotifications(); } @Test @@ -2303,7 +2345,8 @@ public void test414UserRappRecompute() throws Exception { assertDummyAccountShadowRepo(accountShadow, accountDefaultOid, USER_RAPP_USERNAME); assertShadowLifecycle(accountShadow, null); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } @Test @@ -2373,7 +2416,8 @@ public void test416UserRappEmployeeTypeWreck() throws Exception { assertDummyAccountShadowRepo(accountShadow, accountDefaultOid, USER_RAPP_USERNAME); assertShadowLifecycle(accountShadow, null); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } // TODO: employeeType->WRECK @@ -2436,8 +2480,9 @@ public void test500JackAssignResourceSouvenir() throws Exception { assertDummyPasswordConditional(RESOURCE_DUMMY_SOUVENIR_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID_3); displayAllNotifications(); - assertSinglePasswordNotificationConditional(RESOURCE_DUMMY_SOUVENIR_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); + assertSingleAccountPasswordNotificationConditional(RESOURCE_DUMMY_SOUVENIR_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); assertAccountActivationNotification(RESOURCE_DUMMY_SOUVENIR_NAME, USER_JACK_USERNAME); + assertNoUserPasswordNotifications(); } /** @@ -2481,7 +2526,9 @@ public void test502JackInitializeAccountSouvenir() throws Exception { assertEquals("Wrong comparison result", ItemComparisonResult.MATCH, comparisonResult); // TODO -// assertSingleInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); +// assertSingleAccountInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); + + assertNoUserPasswordNotifications(); } /** @@ -2522,8 +2569,9 @@ public void test510JackAssignResourceMaverick() throws Exception { assertDummyPasswordConditional(RESOURCE_DUMMY_MAVERICK_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID_3); displayAllNotifications(); - assertSinglePasswordNotificationConditional(RESOURCE_DUMMY_MAVERICK_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); + assertSingleAccountPasswordNotificationConditional(RESOURCE_DUMMY_MAVERICK_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_3); assertAccountActivationNotification(RESOURCE_DUMMY_MAVERICK_NAME, USER_JACK_USERNAME); + assertNoUserPasswordNotifications(); } /** @@ -2566,9 +2614,10 @@ public void test512JackInitializeAccountMaverickAlligator() throws Exception { assertUserPassword(userAfter, USER_PASSWORD_VALID_3); assertDummyPasswordConditional(RESOURCE_DUMMY_MAVERICK_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID_3); + assertNoUserPasswordNotifications(); // TODO -// assertSingleInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); +// assertSingleAccountInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); } /** @@ -2608,7 +2657,8 @@ public void test514JackInitializeAccountMaverickCrododile() throws Exception { assertDummyPassword(RESOURCE_DUMMY_MAVERICK_NAME, ACCOUNT_JACK_DUMMY_USERNAME, PASSWORD_CROCODILE); // TODO -// assertSingleInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); +// assertSingleAccountInitializationPasswordNotification(RESOURCE_DUMMY_PASSWORD_CACHING_NAME, USER_JACK_USERNAME, PASSWORD_Alligator); + assertNoUserPasswordNotifications(); } /** @@ -2646,6 +2696,7 @@ public void test516JackChangePasswordResourceMaverickAlligator() throws Exceptio assertLinks(userAfter, 6); assertDummyPassword(RESOURCE_DUMMY_MAVERICK_NAME, USER_JACK_USERNAME, PASSWORD_CROCODILE); + assertNoUserPasswordNotifications(); } /** @@ -2676,6 +2727,7 @@ public void test518JackChangePasswordResourceMaverickGiantLizard() throws Except assertLinks(userAfter, 6); assertDummyPassword(RESOURCE_DUMMY_MAVERICK_NAME, USER_JACK_USERNAME, PASSWORD_GIANT_LIZARD); + assertNoUserPasswordNotifications(); } /** @@ -2709,7 +2761,8 @@ public void test530JackUnassignResourceSouvenir() throws Exception { display("User after", userAfter); assertAssignments(userAfter, 5); assertAssignedNoAccount(userAfter, RESOURCE_DUMMY_SOUVENIR_OID); - assertLinks(userAfter, 5); + assertLinks(userAfter, 5); + assertNoUserPasswordNotifications(); } /** @@ -2749,6 +2802,7 @@ public void test532JackChangePasswordResourceBlueAlligator() throws Exception { assertLinks(userAfter, 5); assertDummyPassword(RESOURCE_DUMMY_BLUE_NAME, USER_JACK_USERNAME, PASSWORD_ALLIGATOR); + assertNoUserPasswordNotifications(); } /** @@ -2782,6 +2836,7 @@ public void test535ModifyUserJackPasswordAlligator() throws Exception { assertUserPassword(userAfter, PASSWORD_ALLIGATOR); assertDummyPassword(RESOURCE_DUMMY_MAVERICK_NAME, ACCOUNT_JACK_DUMMY_USERNAME, PASSWORD_ALLIGATOR); + assertSingleUserPasswordNotification(USER_JACK_USERNAME, PASSWORD_ALLIGATOR); } /** @@ -2816,29 +2871,30 @@ public void test539JackUnassignResourceMaverick() throws Exception { assertAssignments(userAfter, 4); assertAssignedNoAccount(userAfter, RESOURCE_DUMMY_MAVERICK_OID); assertAssignedNoAccount(userAfter, RESOURCE_DUMMY_SOUVENIR_OID); - assertLinks(userAfter, 4); + assertLinks(userAfter, 4); + assertNoUserPasswordNotifications(); } /** * MID-4507 */ @Test - public void test550JackManyPassowrdChangesClear() throws Exception { - testJackManyPassowrdChanges("test550JackManyPassowrdChangesClear", "TesT550x", null); + public void test550JackManyPasswordChangesClear() throws Exception { + testJackManyPasswordChanges("test550JackManyPasswordChangesClear", "TesT550x", null); } /** * MID-4507 */ @Test - public void test552JackManyPassowrdChangesEncrypted() throws Exception { - testJackManyPassowrdChanges("test552JackManyPassowrdChangesEncrypted", "TesT552x", CredentialsStorageTypeType.ENCRYPTION); + public void test552JackManyPasswordChangesEncrypted() throws Exception { + testJackManyPasswordChanges("test552JackManyPasswordChangesEncrypted", "TesT552x", CredentialsStorageTypeType.ENCRYPTION); } /** * MID-4507 */ - public void testJackManyPassowrdChanges(final String TEST_NAME, String passwordPrefix, CredentialsStorageTypeType storageType) throws Exception { + public void testJackManyPasswordChanges(final String TEST_NAME, String passwordPrefix, CredentialsStorageTypeType storageType) throws Exception { displayTestTitle(TEST_NAME); // GIVEN @@ -2851,12 +2907,12 @@ public void testJackManyPassowrdChanges(final String TEST_NAME, String passwordP assertLinks(userBefore, 4); for (int i = 1; i < 10; i++) { - testJackManyPassowrdChangesAttempt(TEST_NAME, passwordPrefix, storageType, i); + testJackManyPasswordChangesAttempt(TEST_NAME, passwordPrefix, storageType, i); } } - private void testJackManyPassowrdChangesAttempt(String TEST_NAME, String passwordPrefix, CredentialsStorageTypeType storageType, int i) throws Exception { + private void testJackManyPasswordChangesAttempt(String TEST_NAME, String passwordPrefix, CredentialsStorageTypeType storageType, int i) throws Exception { Task task = createTask(TEST_NAME + "-" + i); OperationResult result = task.getResult(); @@ -2917,22 +2973,22 @@ protected void assertDummyPasswordConditionalGenerated(String instance, String u } } - protected void assertSinglePasswordNotificationConditional(String dummyResourceName, String username, String password) { + protected void assertSingleAccountPasswordNotificationConditional(String dummyResourceName, String username, String password) { if (isPasswordEncryption()) { - assertSinglePasswordNotification(dummyResourceName, username, password); + assertSingleAccountPasswordNotification(dummyResourceName, username, password); } } - protected void assertSinglePasswordNotificationConditionalGenerated(String dummyResourceName, String username, String password) { + protected void assertSingleAccountPasswordNotificationConditionalGenerated(String dummyResourceName, String username, String password) { if (isPasswordEncryption()) { - assertSinglePasswordNotification(dummyResourceName, username, password); + assertSingleAccountPasswordNotification(dummyResourceName, username, password); } else { - assertSinglePasswordNotificationGenerated(dummyResourceName, username); + assertSingleAccountPasswordNotificationGenerated(dummyResourceName, username); } } - private void assertSingleInitializationPasswordNotification(String dummyResourceName, String username, String password) { - assertSinglePasswordNotification(dummyResourceName, username, password); + private void assertSingleAccountInitializationPasswordNotification(String dummyResourceName, String username, String password) { + assertSingleAccountPasswordNotification(dummyResourceName, username, password); } protected abstract void assertAccountActivationNotification(String dummyResourceName, String username); @@ -2992,11 +3048,11 @@ public void test900ModifyUserElainePassword() throws Exception { assertUserPassword(userAfter, USER_PASSWORD_VALID_1); - displayPasswordNotifications(); - assertPasswordNotifications(3); - assertHasPasswordNotification(null, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); - assertHasPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); - assertHasPasswordNotification(RESOURCE_DUMMY_BLUE_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(3); + assertHasAccountPasswordNotification(null, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_BLUE_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_1); } @Test @@ -3024,7 +3080,7 @@ public void test902SetPasswordMinAge() throws Exception { new ItemPath(SecurityPolicyType.F_CREDENTIALS, CredentialsPolicyType.F_PASSWORD, PasswordCredentialsPolicyType.F_MIN_AGE), XmlTypeConverter.createDuration("PT10M")); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); } /** @@ -3061,7 +3117,8 @@ public void test904ModifyUserElainePasswordAgain() throws Exception { assertUserPassword(userAfter, USER_PASSWORD_VALID_1); - assertNoPasswordNotifications(); + assertNoAccountPasswordNotifications(); + assertNoUserPasswordNotifications(); } @Test @@ -3091,11 +3148,12 @@ public void test906ModifyUserElainePasswordLater() throws Exception { assertUserPassword(userAfter, USER_PASSWORD_VALID_3); - displayPasswordNotifications(); - assertPasswordNotifications(2); - assertHasPasswordNotification(null, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_3); - assertHasPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_3); + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(2); + assertHasAccountPasswordNotification(null, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_3); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_ELAINE_USERNAME, USER_PASSWORD_VALID_3); // BLUE resource already has a password + assertSingleUserPasswordNotification(USER_ELAINE_USERNAME, USER_PASSWORD_VALID_3); } @@ -3127,6 +3185,7 @@ public void test910AddUserWithNoPasswordFail() throws Exception { } finally { setPasswordMinOccurs(null, task, result); } + assertNoUserPasswordNotifications(); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/TestPasswordDefaultHashing.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/TestPasswordDefaultHashing.java index eac3a5f20d8..0a914f88a2e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/TestPasswordDefaultHashing.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/TestPasswordDefaultHashing.java @@ -69,7 +69,7 @@ protected void assertShadowLifecycle(PrismObject shadow, boolean foc * There is a RED account with a strong password * mapping. The reconcile and the strong mapping would normally try to set the short * password to RED account which would fail on RED account password policy. But not today. - * As we do not have password cleartexct in the user then no password change should happen. + * As we do not have password cleartext in the user then no password change should happen. * And everything should go smoothly. */ @Test @@ -134,7 +134,7 @@ protected void assert31xBluePasswordAfterPasswordChange(PrismObject us protected void assertAccountActivationNotification(String dummyResourceName, String username) { checkDummyTransportMessages(NOTIFIER_ACCOUNT_ACTIVATION_NAME, 1); String body = getDummyTransportMessageBody(NOTIFIER_ACCOUNT_ACTIVATION_NAME, 0); - String expectedPrefix = getExpectedPasswordNotificationBodyPrefix(dummyResourceName, username); + //String expectedPrefix = getExpectedAccountPasswordNotificationBodyPrefix(dummyResourceName, username); if (!body.contains("activat")) { fail("Activation not mentioned in "+dummyResourceName+" dummy account activation notification message : "+body); } 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 f7f0aec07a2..b760b32fe7a 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 @@ -3419,13 +3419,15 @@ protected void checkDummyTransportMessages(String name, int expectedCount) { if (messages != null && !messages.isEmpty()) { LOGGER.error(messages.size() + " unexpected message(s) recorded in dummy transport '" + name + "'"); logNotifyMessages(messages); - assertFalse(messages.size() + " unexpected message(s) recorded in dummy transport '" + name + "'", true); + printNotifyMessages(messages); + fail(messages.size() + " unexpected message(s) recorded in dummy transport '" + name + "'"); } } else { assertNotNull("No messages recorded in dummy transport '" + name + "'", messages); if (expectedCount != messages.size()) { LOGGER.error("Invalid number of messages recorded in dummy transport '" + name + "', expected: "+expectedCount+", actual: "+messages.size()); logNotifyMessages(messages); + printNotifyMessages(messages); assertEquals("Invalid number of messages recorded in dummy transport '" + name + "'", expectedCount, messages.size()); } } @@ -3478,6 +3480,12 @@ private void logNotifyMessages(List messages) { } } + private void printNotifyMessages(List messages) { + for (Message message: messages) { + System.out.println(message); + } + } + protected void checkDummyTransportMessagesAtLeast(String name, int expectedCount) { if (expectedCount == 0) { return; diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java index 3bd8df25494..566e29de140 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/ModelEvent.java @@ -153,6 +153,10 @@ public ObjectDelta getFocusPrimaryDelta() { return getFocusContext() != null ? getFocusContext().getPrimaryDelta() : null; } + public ObjectDelta getFocusSecondaryDelta() { + return getFocusContext() != null ? getFocusContext().getSecondaryDelta() : null; + } + public List> getFocusDeltas() { List> retval = new ArrayList<>(); Class c = modelContext.getFocusClass(); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java index cbe3fc1797c..cd88e326ac3 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/UserPasswordNotifier.java @@ -74,7 +74,7 @@ protected boolean quickCheckApplicability(Event event, GeneralNotifierType gener @Override protected boolean checkApplicability(Event event, GeneralNotifierType generalNotifierType, OperationResult result) { - if (!event.isSuccess()) { + if (!event.isAlsoSuccess()) { // TODO LOGGER.trace("Operation was not successful, exiting."); return false; } @@ -93,18 +93,28 @@ private String getPasswordFromEvent(ModelEvent modelEvent) { } //noinspection unchecked ObjectDelta focusPrimaryDelta = (ObjectDelta) modelEvent.getFocusPrimaryDelta(); - if (focusPrimaryDelta == null) { - LOGGER.trace("No password in executed delta(s) and no primary delta, exiting."); + //noinspection unchecked + ObjectDelta focusSecondaryDelta = (ObjectDelta) modelEvent.getFocusSecondaryDelta(); + if (focusPrimaryDelta == null && focusSecondaryDelta == null) { + LOGGER.trace("No password in executed delta(s) and no primary/secondary deltas, exiting."); return null; } - password = getPasswordFromDeltas(singletonList(focusPrimaryDelta)); - if (password != null) { - LOGGER.trace("Found password in user primary delta, continuing."); - return password; - } else { - LOGGER.trace("No password in executed delta(s) nor in primary delta, exiting."); - return null; + if (focusPrimaryDelta != null) { + password = getPasswordFromDeltas(singletonList(focusPrimaryDelta)); + if (password != null) { + LOGGER.trace("Found password in user primary delta, continuing."); + return password; + } + } + if (focusSecondaryDelta != null) { + password = getPasswordFromDeltas(singletonList(focusSecondaryDelta)); + if (password != null) { + LOGGER.trace("Found password in user secondary delta(s), continuing."); + return password; + } } + LOGGER.trace("No password in executed delta(s) nor in primary/secondary deltas, exiting."); + return null; } private String getPasswordFromDeltas(List> deltas) { From caa1af080494eb4f13625ae304f5cd21ef150b5c Mon Sep 17 00:00:00 2001 From: Viliam Repan Date: Thu, 5 Apr 2018 13:59:21 +0200 Subject: [PATCH 08/43] version update for maven deploy plugin --- pom.xml | 5 +++++ samples/model-client-sample/pom.xml | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/pom.xml b/pom.xml index 9b1c36348ae..78fd80a20d6 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,11 @@ maven-plugin-plugin 3.3 + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + org.eclipse.m2e lifecycle-mapping diff --git a/samples/model-client-sample/pom.xml b/samples/model-client-sample/pom.xml index c205db68a44..6317be9f7ae 100644 --- a/samples/model-client-sample/pom.xml +++ b/samples/model-client-sample/pom.xml @@ -62,6 +62,15 @@ + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + org.apache.maven.plugins From 421bcaa3a198dead9c163a2d4d5f00d8f0ed1de9 Mon Sep 17 00:00:00 2001 From: kate Date: Thu, 5 Apr 2018 14:14:27 +0200 Subject: [PATCH 09/43] MID-4543 Assign construction: kind+intent fields not readonly --- .../evolveum/midpoint/web/component/prism/PrismValuePanel.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index 80faef3e26a..304d15bb312 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -208,6 +208,9 @@ public String getObject() { } private boolean isAccessible(ItemDefinition def, ContainerStatus status) { + if (def.getName().equals(ConstructionType.F_KIND) || def.getName().equals(ConstructionType.F_INTENT)){ + return false; + } switch (status) { case ADDING: if (!def.canAdd()) { From e2d24afe3689ae095f6807e5207a4bb899a539fc Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Thu, 5 Apr 2018 22:39:35 +0200 Subject: [PATCH 10/43] fixing MID-4563 and MID-4562 --- .../web/page/self/PageAccountActivation.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java index f1327e20302..5a20780c467 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java @@ -43,6 +43,7 @@ import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.model.api.AuthenticationEvaluator; import com.evolveum.midpoint.model.api.context.PasswordAuthenticationContext; +import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; @@ -93,6 +94,11 @@ public class PageAccountActivation extends PageBase { public PageAccountActivation(PageParameters params) { UserType user = loadUser(params); + + if (user == null) { + getSession().error(getString("PageAccountActivation.account.activation.failed")); + throw new RestartResponseException(PageLogin.class); + } userModel = new LoadableModel(false) { @@ -119,11 +125,16 @@ private UserType loadUser(PageParameters params){ OperationResult result = new OperationResult(LOAD_USER); return runPrivileged(new Producer() { + private static final long serialVersionUID = 1L; @Override public UserType run() { Collection> options = SelectorOptions.createCollection(UserType.F_LINK_REF, GetOperationOptions.createResolve()); - return WebModelServiceUtils.loadObject(UserType.class, userOid, options, PageAccountActivation.this, task, result).asObjectable(); + PrismObject user = WebModelServiceUtils.loadObject(UserType.class, userOid, options, PageAccountActivation.this, task, result); + if (user == null) { + return null; + } + return user.asObjectable(); } }); @@ -143,7 +154,7 @@ public boolean isVisible() { }); - Form form = new com.evolveum.midpoint.web.component.form.Form<>(ID_MAIN_FORM); + Form form = new com.evolveum.midpoint.web.component.form.Form<>(ID_MAIN_FORM); activationContainer.add(form); Label usernamePanel = new Label(ID_NAME, createStringResource("PageAccountActivation.activate.accounts.label", new PropertyModel<>(userModel, "name.orig"))); @@ -272,6 +283,7 @@ private void propagatePassword(AjaxRequestTarget target, } OperationResult result = runPrivileged(new Producer() { + private static final long serialVersionUID = 1L; @Override public OperationResult run() { @@ -305,7 +317,7 @@ private List getShadowsToActivate(){ if (shadowsToActivate == null || shadowsToActivate.isEmpty()) { return new ArrayList<>(); } - return shadowsToActivate.parallelStream().filter(shadow -> shadow.getLifecycleState().equals(SchemaConstants.LIFECYCLE_PROPOSED)).collect(Collectors.toList()); + return shadowsToActivate.parallelStream().filter(shadow -> SchemaConstants.LIFECYCLE_PROPOSED.equals(shadow.getLifecycleState())).collect(Collectors.toList()); } } From f7387a0c771de374ea4f265d42f74729b4066a61 Mon Sep 17 00:00:00 2001 From: kate Date: Thu, 5 Apr 2018 23:05:02 +0200 Subject: [PATCH 11/43] MID-4521 Policy breach message is not localized in self-service --- .../evolveum/midpoint/web/page/self/PageAssignmentsList.java | 2 +- .../src/main/resources/localization/Midpoint.properties | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java index 06b1181fb47..bda53a579cd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java @@ -260,7 +260,7 @@ private void onSingleUserRequestPerformed(AjaxRequestTarget target) { storage.getRoleCatalog().getAssignmentShoppingCart().clear(); } catch (Exception e) { LoggingUtils.logUnexpectedException(LOGGER, "Could not save assignments ", e); - error("Could not save assignments. Reason: " + e); + error(createStringResource("PageAssignmentsList.saveAssignmentsError").getString() + e.getLocalizedMessage()); target.add(getFeedbackPanel()); } finally { result.recomputeStatus(); diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 7fdc133e23d..9621e10ea6a 100755 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3720,6 +3720,7 @@ PageAssignmentsList.submitButton=Submit PageAssignmentsList.resolveConflicts=Resolve conflicts PageAssignmentsList.commentHere=Comment here... PageAssignmentsList.requestComment=Request comment (optional) +PageAssignmentsList.saveAssignmentsError=Could not save assignments. Reason: AssignmentShoppingCartPanel.treeTitle=Role catalog AssignmentViewType.ROLE_CATALOG_VIEW=Role catalog view AssignmentViewType.ROLE_TYPE=All roles view From 6ebfbcbd02b6c0f7602085b053c12c1ee4a3f7df Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 6 Apr 2018 09:31:14 +0200 Subject: [PATCH 12/43] adding misssing localization key --- .../src/main/resources/localization/Midpoint.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 7fdc133e23d..4457f036f17 100755 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -4023,3 +4023,4 @@ pageAdminFocus.dataProtection=Data protection PageInternals.title.cache=Caches PageInternals.tab.cache=Cache management InternalsCachePanel.button.clearCaches=Clear caches +PageAccountActivation.user.not.found=Unexpected problem occurs. Please contact system administrator. From 140438f1ac54bad8e8b74b40ba9001698f2e9beb Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 6 Apr 2018 09:33:05 +0200 Subject: [PATCH 13/43] fixing typo --- .../evolveum/midpoint/web/page/self/PageAccountActivation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java index 5a20780c467..9377064a57c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAccountActivation.java @@ -236,7 +236,7 @@ public void onClick(AjaxRequestTarget target) { private String getOidFromParameter(PageParameters params){ if (params == null || params.isEmpty()) { - LOGGER.error("No page paraeters found for account activation. No user to activate his/her accounts"); + LOGGER.error("No page parameters found for account activation. No user to activate his/her accounts"); return null; } From 7d7a974afaa23cfc24426a006d180403f6e275a7 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 6 Apr 2018 12:44:42 +0200 Subject: [PATCH 14/43] Fix showing names in 'add' approvals (MID-4512) When approving object creation, the object has an OID but does not exist in repository. This caused problems in task details and task lists pages. Repository change: now we are storing targetName for references in the XML form of stored objects (if set by caller). --- .../web/page/admin/server/dto/TaskDto.java | 10 +++++- .../midpoint/prism/SerializationOptions.java | 2 +- ...opagateTaskObjectReferenceTaskHandler.java | 12 ++----- .../impl/tasks/WfTaskCreationInstruction.java | 3 +- .../midpoint/repo/sql/AddGetObjectTest.java | 31 +++++++++++++------ .../src/test/resources/basic/objects.xml | 2 +- .../repo/sql/helpers/ObjectUpdater.java | 10 +++--- .../task/quartzimpl/TaskQuartzImpl.java | 17 ++-------- 8 files changed, 43 insertions(+), 44 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java index 65955412216..91e745089f1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java @@ -311,7 +311,15 @@ private void fillInObjectRefAttributes(TaskType taskType, TaskDtoProviderOptions } public String getTaskObjectName(TaskType taskType, PageBase pageBase, Task opTask, OperationResult thisOpResult) { - return WebModelServiceUtils.resolveReferenceName(taskType.getObjectRef(), pageBase, opTask, thisOpResult); + OperationResult currentResult; + if (taskType.getWorkflowContext() != null) { + // For workflow-related tasks the task object might not be created yet (MID-4512). The simplest way + // of avoiding displaying the error is to use a separate operation result. + currentResult = new OperationResult(TaskDto.class.getName() + ".getTaskObjectName"); + } else { + currentResult = thisOpResult; + } + return WebModelServiceUtils.resolveReferenceName(taskType.getObjectRef(), pageBase, opTask, currentResult); } private void fillInParentTaskAttributes(TaskType taskType, diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java index c4f7b66aa73..45bf7b5f146 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java @@ -54,7 +54,7 @@ public void setSerializeCompositeObjects(boolean serializeCompositeObjects) { this.serializeCompositeObjects = serializeCompositeObjects; } - public static SerializationOptions createSerializeCompositeObjects(){ + public static SerializationOptions createSerializeCompositeObjects() { SerializationOptions serializationOptions = new SerializationOptions(); serializationOptions.setSerializeCompositeObjects(true); return serializationOptions; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPropagateTaskObjectReferenceTaskHandler.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPropagateTaskObjectReferenceTaskHandler.java index eb155492e6a..015adec87e2 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPropagateTaskObjectReferenceTaskHandler.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPropagateTaskObjectReferenceTaskHandler.java @@ -112,7 +112,7 @@ public TaskRunResult run(Task task) { ObjectReferenceType objectReferenceType = new ObjectReferenceType(); objectReferenceType.setType(type); objectReferenceType.setOid(oid); - + // TODO set also targetName [but it seems that this task handler is not used anymore] if (task.getObjectRef() == null) { task.setObjectRef(objectReferenceType); } else { @@ -123,9 +123,7 @@ public TaskRunResult run(Task task) { try { dependents = wfTask.listDependents(result); dependents.add(wfTask.getParentJob(result)); - } catch (SchemaException e) { - return reportException("Couldn't get dependents from job " + wfTask, task, result, e); - } catch (ObjectNotFoundException e) { + } catch (SchemaException | ObjectNotFoundException e) { return reportException("Couldn't get dependents from job " + wfTask, task, result, e); } @@ -133,13 +131,9 @@ public TaskRunResult run(Task task) { if (dependent.getTask().getObjectRef() == null) { try { dependent.getTask().setObjectRefImmediate(objectReferenceType, result); - } catch (ObjectNotFoundException e) { + } catch (ObjectNotFoundException | SchemaException | ObjectAlreadyExistsException e) { // note we DO NOT return, because we want to set all references we can reportException("Couldn't set object reference on job " + dependent, task, result, e); - } catch (SchemaException e) { - reportException("Couldn't set object reference on job " + dependent, task, result, e); - } catch (ObjectAlreadyExistsException e) { - reportException("Couldn't set object reference on job " + dependent, task, result, e); } } else { LOGGER.warn("object reference in job " + dependent + " is already set, although it shouldn't be"); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java index 53cc5d3bc35..17a4e520269 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java @@ -372,7 +372,8 @@ public Task createTask(WfTaskController taskController, Task parentTask, WfConfi task.setCategory(TaskCategory.WORKFLOW); if (taskObject != null) { - task.setObjectRef(taskObject.getOid(), taskObject.getDefinition().getTypeName()); + //noinspection unchecked + task.setObjectRef(ObjectTypeUtil.createObjectRef(taskObject)); } else if (parentTask != null && parentTask.getObjectRef() != null) { task.setObjectRef(parentTask.getObjectRef().clone()); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java index f1bfbcf9854..126efb4f3ef 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType; @@ -126,10 +127,22 @@ public void addGetDSEESyncDoubleTest() throws Exception { public void simpleAddGetTest() throws Exception { LOGGER.info("===[ simpleAddGetTest ]==="); final File OBJECTS_FILE = new File(FOLDER_BASIC, "objects.xml"); - addGetCompare(OBJECTS_FILE); + List> objects = addGetCompare(OBJECTS_FILE); + + boolean foundAtestuserX00003 = false; + for (PrismObject object : objects) { + // adhoc check whether reference.targetName is preserved + if ("atestuserX00003".equals(PolyString.getOrig(object.getName()))) { + String personaName = PolyString.getOrig(((UserType) object.asObjectable()).getPersonaRef().get(0).getTargetName()); + assertEquals("Wrong personaRef.targetName on atestuserX00003", "u-000", personaName); + foundAtestuserX00003 = true; + break; + } + } + assertTrue("User atestuserX00003 was not found", foundAtestuserX00003); } - private void addGetCompare(File file) throws Exception { + private List> addGetCompare(File file) throws Exception { List> elements = prismContext.parserFor(file).parseObjects(); List oids = new ArrayList<>(); @@ -141,9 +154,9 @@ private void addGetCompare(File file) throws Exception { object.getCompileTimeClass().getSimpleName()}); oids.add(repositoryService.addObject(object, null, result)); } - LOGGER.info("Time to add objects ({}): {}", new Object[]{elements.size(), - (System.currentTimeMillis() - time),}); + LOGGER.info("Time to add objects ({}): {}", elements.size(), System.currentTimeMillis() - time); + List> objectsRead = new ArrayList<>(); int count = 0; elements = prismContext.parserFor(file).parseObjects(); for (int i = 0; i < elements.size(); i++) { @@ -171,10 +184,8 @@ private void addGetCompare(File file) throws Exception { System.out.println("OLD: " + object.findProperty(ObjectType.F_NAME).getValue()); System.out.println("NEW: " + newObject.findProperty(ObjectType.F_NAME).getValue()); + objectsRead.add(newObject); ObjectDelta delta = object.diff(newObject); - if (delta == null) { - continue; - } count += delta.getModifications().size(); if (delta.getModifications().size() > 0) { @@ -186,8 +197,8 @@ private void addGetCompare(File file) throws Exception { continue; } } - LOGGER.error(">>> {} Found {} changes for {}\n{}", new Object[]{(i + 1), - delta.getModifications().size(), newObject.toString(), delta.debugDump(3)}); + LOGGER.error(">>> {} Found {} changes for {}\n{}", (i + 1), + delta.getModifications().size(), newObject.toString(), delta.debugDump(3)); ItemDelta id = (ItemDelta) delta.getModifications().iterator().next(); if (id.isReplace()) { LOGGER.debug("{}", id.getValuesToReplace().iterator().next()); @@ -199,8 +210,8 @@ private void addGetCompare(File file) throws Exception { throw new RuntimeException("Exception during processing of "+object+": "+ex.getMessage(), ex); } } - AssertJUnit.assertEquals("Found changes during add/get test " + count, 0, count); + return objectsRead; } private Integer size(PrismContainerValue value) { diff --git a/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml b/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml index b29cc9482fc..68369d8b5d9 100644 --- a/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml +++ b/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml @@ -164,7 +164,7 @@ - + u-000 Test UserX00003 diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index 48f7b774339..0fd731c5639 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -16,10 +16,7 @@ package com.evolveum.midpoint.repo.sql.helpers; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; @@ -263,7 +260,8 @@ public void updateFullObject(RObject object, PrismObject< // Its' because we're removing some properties during save operation and if save fails, // overwrite attempt (for example using object importer) might try to delete existing object // and then try to save this object one more time. - String xml = prismContext.serializeObjectToString(savedObject, PrismContext.LANG_XML); + SerializationOptions options = SerializationOptions.createSerializeReferenceNames(); + String xml = prismContext.xmlSerializer().options(options).serialize(savedObject); savedObject = prismContext.parseObject(xml); if (FocusType.class.isAssignableFrom(savedObject.getCompileTimeClass())) { @@ -274,7 +272,7 @@ public void updateFullObject(RObject object, PrismObject< savedObject.removeContainer(AccessCertificationCampaignType.F_CASE); } - xml = prismContext.serializeObjectToString(savedObject, PrismContext.LANG_XML); + xml = prismContext.xmlSerializer().options(options).serialize(savedObject); byte[] fullObject = RUtil.getByteArrayFromXml(xml, getConfiguration().isUseZip()); LOGGER.trace("Storing full object\n{}", xml); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java index 0804dd42bc5..9b6723bd058 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java @@ -1547,26 +1547,13 @@ public void setObjectRefImmediate(ObjectReferenceType value, OperationResult par } public void setObjectRefTransient(ObjectReferenceType objectRefType) { - PrismReference objectRef; - try { - objectRef = taskPrism.findOrCreateReference(TaskType.F_OBJECT_REF); - } catch (SchemaException e) { - // This should not happen - throw new IllegalStateException("Internal schema error: " + e.getMessage(), e); - } - objectRef.getValue().setOid(objectRefType.getOid()); - objectRef.getValue().setTargetType(objectRefType.getType()); + taskPrism.asObjectable().setObjectRef(objectRefType != null ? objectRefType.clone() : null); } private ReferenceDelta setObjectRefAndPrepareDelta(ObjectReferenceType value) { setObjectRefTransient(value); - - PrismReferenceValue prismReferenceValue = new PrismReferenceValue(); - prismReferenceValue.setOid(value.getOid()); - prismReferenceValue.setTargetType(value.getType()); - return isPersistent() ? ReferenceDelta.createModificationReplace(TaskType.F_OBJECT_REF, - taskManager.getTaskObjectDefinition(), prismReferenceValue) : null; + taskManager.getTaskObjectDefinition(), value.clone().asReferenceValue()) : null; } @Override From ef4b4cedb0b7233e26cb609c5ec0d709415befd7 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 6 Apr 2018 13:55:02 +0200 Subject: [PATCH 15/43] Add forgotten exception cause (cherry picked from commit 2377d62) --- .../work/segmentation/WorkSegmentationStrategyFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/WorkSegmentationStrategyFactory.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/WorkSegmentationStrategyFactory.java index 369a36d7a35..dfc37ed044a 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/WorkSegmentationStrategyFactory.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/WorkSegmentationStrategyFactory.java @@ -69,7 +69,7 @@ public WorkSegmentationStrategy createStrategy(TaskWorkManagementType configurat PrismContext.class); return constructor.newInstance(configuration, prismContext); } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { - throw new SystemException("Couldn't instantiate work bucket segmentation strategy " + strategyClass + " for " + configuration); + throw new SystemException("Couldn't instantiate work bucket segmentation strategy " + strategyClass + " for " + configuration, e); } } From 33102dcaac169ade322c50127a44b9ba2099656b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 6 Apr 2018 14:43:18 +0200 Subject: [PATCH 16/43] Fix channel for recompute notifications (MID-3476) AbstractSearchIterativeTaskHandler has now a support for setting task channel if none is present. --- .../schema/constants/SchemaConstants.java | 1 + .../model/impl/lens/ContextFactory.java | 4 ++-- .../model/impl/sync/RecomputeTaskHandler.java | 21 +++++++++---------- .../model/intest/sync/TestRecomputeTask.java | 3 +++ .../test/AbstractModelIntegrationTest.java | 11 ++++++++++ .../provisioning/impl/ShadowManager.java | 3 ++- .../AbstractSearchIterativeTaskHandler.java | 11 ++++++++++ 7 files changed, 40 insertions(+), 14 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 77e7306086b..e659f2e883d 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -266,6 +266,7 @@ public abstract class SchemaConstants { public static final QName CHANGE_CHANNEL_RECON = new QName(NS_PROVISIONING_CHANNEL, "reconciliation"); public static final String CHANGE_CHANNEL_RECON_URI = QNameUtil.qNameToUri(CHANGE_CHANNEL_RECON); public static final QName CHANGE_CHANNEL_RECOMPUTE = new QName(NS_PROVISIONING_CHANNEL, "recompute"); + public static final String CHANGE_CHANNEL_RECOMPUTE_URI = QNameUtil.qNameToUri(CHANGE_CHANNEL_RECOMPUTE); public static final QName CHANGE_CHANNEL_DISCOVERY = new QName(NS_PROVISIONING_CHANNEL, "discovery"); public static final String CHANGE_CHANNEL_DISCOVERY_URI = QNameUtil.qNameToUri(CHANGE_CHANNEL_DISCOVERY); public static final QName CHANGE_CHANNEL_IMPORT = new QName(NS_PROVISIONING_CHANNEL, "import"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ContextFactory.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ContextFactory.java index 80c21899f58..e0bf3b7ae5b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ContextFactory.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ContextFactory.java @@ -184,7 +184,7 @@ public LensContext createRecomputeFocusContext( LensFocusContext focusContext = syncContext.createFocusContext(); focusContext.setLoadedObject(focus); focusContext.setOid(focus.getOid()); - syncContext.setChannel(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECOMPUTE)); + syncContext.setChannel(SchemaConstants.CHANGE_CHANNEL_RECOMPUTE_URI); syncContext.setDoReconciliationForAllProjections(ModelExecuteOptions.isReconcile(options)); return syncContext; } @@ -198,7 +198,7 @@ public LensContext createRecomputeProjectionContext( projectionContext.setLoadedObject(shadow); projectionContext.setOid(shadow.getOid()); projectionContext.setDoReconciliation(ModelExecuteOptions.isReconcile(options)); - syncContext.setChannel(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_RECOMPUTE)); + syncContext.setChannel(SchemaConstants.CHANGE_CHANNEL_RECOMPUTE_URI); return syncContext; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java index 3ac36d4e1e1..57f34a8586b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java @@ -17,6 +17,7 @@ import javax.annotation.PostConstruct; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -68,17 +69,10 @@ public class RecomputeTaskHandler extends AbstractSearchIterativeModelTaskHandle public static final String HANDLER_URI = ModelConstants.NS_SYNCHRONIZATION_TASK_PREFIX + "/recompute/handler-3"; - @Autowired - private TaskManager taskManager; - - @Autowired - private PrismContext prismContext; - - @Autowired - private ContextFactory contextFactory; - - @Autowired - private Clockwork clockwork; + @Autowired private TaskManager taskManager; + @Autowired private PrismContext prismContext; + @Autowired private ContextFactory contextFactory; + @Autowired private Clockwork clockwork; private static final transient Trace LOGGER = TraceManager.getTrace(RecomputeTaskHandler.class); @@ -142,4 +136,9 @@ private void recompute(PrismObject focalObject, ModelExecuteOptions o public String getCategoryName(Task task) { return TaskCategory.RECOMPUTATION; } + + @Override + protected String getDefaultChannel() { + return SchemaConstants.CHANGE_CHANNEL_RECOMPUTE_URI; + } } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java index 2b678d2ec09..67fca16e923 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java @@ -322,6 +322,7 @@ public void test120RecomputeByExpression() throws Exception { // GIVEN Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); + prepareNotifications(); // Preconditions assertUsers(6); @@ -367,6 +368,8 @@ public void test120RecomputeByExpression() throws Exception { assertUsers(6); + displayAllNotifications(); + assertSingleDummyTransportMessageContaining("simpleAccountNotifier-SUCCESS", "Channel: " + SchemaConstants.CHANGE_CHANNEL_RECOMPUTE_URI); } /** 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 b760b32fe7a..ab212109336 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 @@ -3443,6 +3443,17 @@ protected void assertSingleDummyTransportMessage(String name, String expectedBod assertEquals("Unexpected notifier "+name+" message body", expectedBody, message.getBody()); } + protected void assertSingleDummyTransportMessageContaining(String name, String expectedSubstring) { + List messages = dummyTransport.getMessages("dummy:" + name); + assertNotNull("No messages recorded in dummy transport '" + name + "'", messages); + if (messages.size() != 1) { + fail("Invalid number of messages recorded in dummy transport '" + name + "', expected: 1, actual: "+messages.size()); + } + Message message = messages.get(0); + assertTrue("Notifier "+name+" message body does not contain text: " + expectedSubstring + ", it is:\n" + message.getBody(), + message.getBody().contains(expectedSubstring)); + } + protected String getDummyTransportMessageBody(String name, int index) { List messages = dummyTransport.getMessages("dummy:" + name); Message message = messages.get(index); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index b836e9829c4..43e95b1b714 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -23,6 +23,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.util.QNameUtil; import org.apache.commons.lang.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -176,7 +177,7 @@ public ResourceOperationDescription createResourceFailureDescription( failureDesc.setObjectDelta(objectDelta); failureDesc.setResource(resource.asPrismObject()); failureDesc.setResult(parentResult); - failureDesc.setSourceChannel(SchemaConstants.CHANGE_CHANNEL_DISCOVERY.getLocalPart()); + failureDesc.setSourceChannel(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_DISCOVERY)); return failureDesc; } diff --git a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java index bd6b88ca1f4..6b77c8f00f3 100644 --- a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java +++ b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/task/AbstractSearchIterativeTaskHandler.java @@ -192,6 +192,13 @@ public TaskWorkBucketProcessingResult run(Task localCoordinatorTask, WorkBucketT OperationResult opResult = runResult.getOperationResult(); opResult.setStatus(OperationResultStatus.IN_PROGRESS); + if (localCoordinatorTask.getChannel() == null) { + String channel = getDefaultChannel(); + if (channel != null) { + localCoordinatorTask.setChannel(channel); + } + } + try { H resultHandler = setupHandler(runResult, localCoordinatorTask, opResult); @@ -310,6 +317,10 @@ public TaskWorkBucketProcessingResult run(Task localCoordinatorTask, WorkBucketT } } + protected String getDefaultChannel() { + return null; + } + private Collection> updateSearchOptionsWithIterationMethod( Collection> searchOptions, Task localCoordinatorTask) { Collection> rv; From f086922a23171c114ccf28bec08d51b9cfc6e9d5 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 6 Apr 2018 16:54:46 +0200 Subject: [PATCH 17/43] Relieve work bucket allocation contention New configuration parameters related to work bucket allocation contention management were added: workAllocationMaxAttempts, workAllocationRetryInterval, workAllocationInitialDelay, workAllocationDefaultFreeBucketWaitInterval. They are part of configuration section. --- .../quartzimpl/TaskManagerConfiguration.java | 45 +++++++++++- .../quartzimpl/TaskManagerQuartzImpl.java | 2 +- .../quartzimpl/execution/JobExecutor.java | 6 ++ .../quartzimpl/work/WorkStateManager.java | 70 ++++++++++++++----- .../task/quartzimpl/TestPartitioning.java | 2 +- .../quartzimpl/TestWorkBucketStrategies.java | 2 +- .../task/quartzimpl/TestWorkDistribution.java | 2 +- .../quartzimpl/TestWorkersManagement.java | 2 +- 8 files changed, 107 insertions(+), 24 deletions(-) diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerConfiguration.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerConfiguration.java index a927d531afd..89434145560 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerConfiguration.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerConfiguration.java @@ -75,6 +75,11 @@ public class TaskManagerConfiguration { private static final String RUN_NOW_KEEPS_ORIGINAL_SCHEDULE_CONFIG_ENTRY = "runNowKeepsOriginalSchedule"; private static final String SCHEDULER_INITIALLY_STOPPED_CONFIG_ENTRY = "schedulerInitiallyStopped"; + private static final String WORK_ALLOCATION_MAX_ATTEMPTS_ENTRY = "workAllocationMaxAttempts"; + private static final String WORK_ALLOCATION_RETRY_INTERVAL_ENTRY = "workAllocationRetryInterval"; + private static final String WORK_ALLOCATION_INITIAL_DELAY_ENTRY = "workAllocationInitialDelay"; + private static final String WORK_ALLOCATION_DEFAULT_FREE_BUCKET_WAIT_INTERVAL_ENTRY = "workAllocationDefaultFreeBucketWaitInterval"; + private static final String MIDPOINT_NODE_ID_PROPERTY = "midpoint.nodeId"; private static final String MIDPOINT_JMX_HOST_NAME_PROPERTY = "midpoint.jmxHostName"; private static final String JMX_PORT_PROPERTY = "com.sun.management.jmxremote.port"; @@ -99,6 +104,11 @@ public class TaskManagerConfiguration { private static final int STALLED_TASKS_REPEATED_NOTIFICATION_INTERVAL_DEFAULT = 3600; private static final boolean RUN_NOW_KEEPS_ORIGINAL_SCHEDULE_DEFAULT = false; + private static final int WORK_ALLOCATION_MAX_ATTEMPTS_DEFAULT = 40; + private static final long WORK_ALLOCATION_RETRY_INTERVAL_DEFAULT = 5000L; + private static final long WORK_ALLOCATION_INITIAL_DELAY_DEFAULT = 5000L; + private static final long WORK_ALLOCATION_DEFAULT_FREE_BUCKET_WAIT_INTERVAL_DEFAULT = 20000L; + private boolean stopOnInitializationFailure; private int threads; private boolean jdbcJobStore; @@ -117,6 +127,11 @@ public class TaskManagerConfiguration { private boolean runNowKeepsOriginalSchedule; private boolean schedulerInitiallyStopped; + private int workAllocationMaxAttempts; + private long workAllocationRetryInterval; + private long workAllocationInitialDelay; + private long workAllocationDefaultFreeBucketWaitInterval; + // JMX credentials for connecting to remote nodes private String jmxUsername; private String jmxPassword; @@ -178,7 +193,11 @@ public class TaskManagerConfiguration { STALLED_TASKS_THRESHOLD_CONFIG_ENTRY, STALLED_TASKS_REPEATED_NOTIFICATION_INTERVAL_CONFIG_ENTRY, RUN_NOW_KEEPS_ORIGINAL_SCHEDULE_CONFIG_ENTRY, - SCHEDULER_INITIALLY_STOPPED_CONFIG_ENTRY + SCHEDULER_INITIALLY_STOPPED_CONFIG_ENTRY, + WORK_ALLOCATION_MAX_ATTEMPTS_ENTRY, + WORK_ALLOCATION_RETRY_INTERVAL_ENTRY, + WORK_ALLOCATION_INITIAL_DELAY_ENTRY, + WORK_ALLOCATION_DEFAULT_FREE_BUCKET_WAIT_INTERVAL_ENTRY ); void checkAllowedKeys(MidpointConfiguration masterConfig) throws TaskManagerConfigurationException { @@ -269,6 +288,12 @@ void setBasicInformation(MidpointConfiguration masterConfig) throws TaskManagerC stalledTasksRepeatedNotificationInterval = c.getInt(STALLED_TASKS_REPEATED_NOTIFICATION_INTERVAL_CONFIG_ENTRY, STALLED_TASKS_REPEATED_NOTIFICATION_INTERVAL_DEFAULT); runNowKeepsOriginalSchedule = c.getBoolean(RUN_NOW_KEEPS_ORIGINAL_SCHEDULE_CONFIG_ENTRY, RUN_NOW_KEEPS_ORIGINAL_SCHEDULE_DEFAULT); schedulerInitiallyStopped = c.getBoolean(SCHEDULER_INITIALLY_STOPPED_CONFIG_ENTRY, false); + + workAllocationMaxAttempts = c.getInt(WORK_ALLOCATION_MAX_ATTEMPTS_ENTRY, WORK_ALLOCATION_MAX_ATTEMPTS_DEFAULT); + workAllocationRetryInterval = c.getLong(WORK_ALLOCATION_RETRY_INTERVAL_ENTRY, WORK_ALLOCATION_RETRY_INTERVAL_DEFAULT); + workAllocationInitialDelay = c.getLong(WORK_ALLOCATION_INITIAL_DELAY_ENTRY, WORK_ALLOCATION_INITIAL_DELAY_DEFAULT); + workAllocationDefaultFreeBucketWaitInterval = c.getLong(WORK_ALLOCATION_DEFAULT_FREE_BUCKET_WAIT_INTERVAL_ENTRY, + WORK_ALLOCATION_DEFAULT_FREE_BUCKET_WAIT_INTERVAL_DEFAULT); } private static final Map schemas = new HashMap<>(); @@ -339,8 +364,6 @@ void setJdbcJobStoreInformation(MidpointConfiguration masterConfig, SqlRepositor /** * Check configuration, except for JDBC JobStore-specific parts. - * - * @throws TaskManagerConfigurationException */ void validateBasicInformation() throws TaskManagerConfigurationException { @@ -525,4 +548,20 @@ public String getDataSource() { public boolean isSchedulerInitiallyStopped() { return schedulerInitiallyStopped; } + + public int getWorkAllocationMaxAttempts() { + return workAllocationMaxAttempts; + } + + public long getWorkAllocationRetryInterval() { + return workAllocationRetryInterval; + } + + public long getWorkAllocationInitialDelay() { + return workAllocationInitialDelay; + } + + public long getWorkAllocationDefaultFreeBucketWaitInterval() { + return workAllocationDefaultFreeBucketWaitInterval; + } } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java index 894225fe840..48c15b6b051 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java @@ -2141,6 +2141,6 @@ public TaskHandler createAndRegisterPartitioningTaskHandler(String handlerUri, F @Override public void setFreeBucketWaitInterval(long value) { - workStateManager.setFreeBucketWaitInterval(value); + workStateManager.setFreeBucketWaitIntervalOverride(value); } } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java index 6eed5dd1f15..b4d3c206ee9 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java @@ -689,6 +689,12 @@ private TaskRunResult executeWorkBucketAwareTaskHandler(WorkBucketAwareTaskHandl } } + try { + workStateManager.executeInitialDelay(task); + } catch (InterruptedException e) { + return createInterruptedTaskRunResult(); + } + TaskWorkBucketProcessingResult runResult = null; for (;;) { WorkBucketType bucket; diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/WorkStateManager.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/WorkStateManager.java index b00ac72553d..6fc6ee7915b 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/WorkStateManager.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/WorkStateManager.java @@ -34,6 +34,9 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskExecutionStatus; import com.evolveum.midpoint.task.api.TaskManager; +import com.evolveum.midpoint.task.quartzimpl.TaskManagerConfiguration; +import com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl; +import com.evolveum.midpoint.task.quartzimpl.TaskQuartzImpl; import com.evolveum.midpoint.task.quartzimpl.work.segmentation.content.WorkBucketContentHandler; import com.evolveum.midpoint.task.quartzimpl.work.segmentation.content.WorkBucketContentHandlerRegistry; import com.evolveum.midpoint.task.quartzimpl.work.segmentation.WorkSegmentationStrategy; @@ -81,12 +84,9 @@ public class WorkStateManager { @Autowired private WorkSegmentationStrategyFactory strategyFactory; @Autowired private WorkBucketContentHandlerRegistry handlerFactory; - private static final int MAX_ATTEMPTS = 40; // temporary - private static final long DELAY_INTERVAL = 5000L; // temporary - private static final long DEFAULT_FREE_BUCKET_WAIT_INTERVAL = 20000L; private static final long DYNAMIC_SLEEP_INTERVAL = 100L; - private long freeBucketWaitInterval = DEFAULT_FREE_BUCKET_WAIT_INTERVAL; + private Long freeBucketWaitIntervalOverride = null; private class Context { Task workerTask; @@ -113,15 +113,15 @@ public void reloadWorkerTask(OperationResult result) throws SchemaException, Obj workerTask = taskManager.getTask(workerTask.getOid(), null, result); } - public boolean canRun() { - return canRunSupplier == null || BooleanUtils.isTrue(canRunSupplier.get()); - } - public TaskWorkManagementType getWorkStateConfiguration() { return isStandalone() ? workerTask.getWorkManagement() : coordinatorTask.getWorkManagement(); } } + public boolean canRun(Supplier canRunSupplier) { + return canRunSupplier == null || BooleanUtils.isTrue(canRunSupplier.get()); + } + /** * Allocates work bucket. If no free work buckets are currently present it tries to create one. * If there is already allocated work bucket for given worker task, it is returned. @@ -172,8 +172,8 @@ private WorkBucketType getWorkBucketMultiNode(Context ctx, long freeBucketWaitTi waitForAvailableBucket: // this cycle exits when something is found OR when a definite 'no more buckets' answer is received for (;;) { -waitForConflictLessUpdate: // this cycle exits when coordinator task update succeeds - for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { + waitForConflictLessUpdate: // this cycle exits when coordinator task update succeeds + for (int attempt = 0; attempt < getMaxAttempts(); attempt++) { TaskWorkStateType coordinatorWorkState = getWorkStateOrNew(ctx.coordinatorTask.getTaskPrismObject()); GetBucketResult response = workStateStrategy.getBucket(coordinatorWorkState); LOGGER.trace("getWorkBucketMultiNode: workStateStrategy returned {} for worker task {}, coordinator {}", response, ctx.workerTask, ctx.coordinatorTask); @@ -215,7 +215,7 @@ private WorkBucketType getWorkBucketMultiNode(Context ctx, long freeBucketWaitTi return null; } //System.out.println("*** No free work bucket -- waiting ***"); - dynamicSleep(Math.min(toWait, freeBucketWaitInterval), ctx); + dynamicSleep(Math.min(toWait, getFreeBucketWaitInterval()), ctx); ctx.reloadCoordinatorTask(result); ctx.reloadWorkerTask(result); if (reclaimWronglyAllocatedBuckets(ctx.coordinatorTask, result)) { @@ -229,8 +229,10 @@ private WorkBucketType getWorkBucketMultiNode(Context ctx, long freeBucketWaitTi throw new AssertionError(response); } } catch (PreconditionViolationException e) { - long delay = (long) (Math.random() * DELAY_INTERVAL); - LOGGER.debug("getWorkBucketMultiNode: conflict; this was attempt #{}; waiting {} ms", attempt, delay, e); + long delay = (long) (Math.random() * getDelayInterval()); + // temporary + LOGGER.info("getWorkBucketMultiNode: conflict; this was attempt #{}; waiting {} ms in {}, worker {}", + attempt, delay, ctx.coordinatorTask, ctx.workerTask, e); dynamicSleep(delay, ctx); ctx.reloadCoordinatorTask(result); ctx.reloadWorkerTask(result); @@ -243,6 +245,27 @@ private WorkBucketType getWorkBucketMultiNode(Context ctx, long freeBucketWaitTi } } + private long getFreeBucketWaitInterval() { + return freeBucketWaitIntervalOverride != null ? freeBucketWaitIntervalOverride : + getConfiguration().getWorkAllocationDefaultFreeBucketWaitInterval(); + } + + private int getMaxAttempts() { + return getConfiguration().getWorkAllocationMaxAttempts(); + } + + private long getDelayInterval() { + return getConfiguration().getWorkAllocationRetryInterval(); + } + + private long getInitialDelay() { + return getConfiguration().getWorkAllocationInitialDelay(); + } + + private TaskManagerConfiguration getConfiguration() { + return ((TaskManagerQuartzImpl) taskManager).getConfiguration(); + } + private void setOrUpdateEstimatedNumberOfBuckets(Task task, WorkSegmentationStrategy workStateStrategy, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException { Integer number = workStateStrategy.estimateNumberOfBuckets(task.getWorkState()); @@ -255,8 +278,12 @@ private void setOrUpdateEstimatedNumberOfBuckets(Task task, WorkSegmentationStra } private void dynamicSleep(long delay, Context ctx) throws InterruptedException { + dynamicSleep(delay, ctx.canRunSupplier); + } + + private void dynamicSleep(long delay, Supplier canRunSupplier) throws InterruptedException { while (delay > 0) { - if (!ctx.canRun()) { + if (!canRun(canRunSupplier)) { throw new InterruptedException(); } Thread.sleep(Math.min(delay, DYNAMIC_SLEEP_INTERVAL)); @@ -556,8 +583,8 @@ private TaskWorkStateType getWorkState(Task task) throws SchemaException { } } - public void setFreeBucketWaitInterval(long freeBucketWaitInterval) { - this.freeBucketWaitInterval = freeBucketWaitInterval; + public void setFreeBucketWaitIntervalOverride(Long value) { + this.freeBucketWaitIntervalOverride = value; } // TODO @@ -593,4 +620,15 @@ public ObjectQuery narrowQueryForWorkBucket(Task workerTask, ObjectQuery query, // TODO update sorting criteria return updatedQuery; } + + public void executeInitialDelay(TaskQuartzImpl task) throws InterruptedException { + if (task.getWorkManagement() != null && task.getWorkManagement().getTaskKind() == TaskKindType.WORKER) { + long delay = (long) (Math.random() * getInitialDelay()); + if (delay != 0) { + // temporary info level logging + LOGGER.info("executeInitialDelay: waiting {} ms in {}", delay, task); + dynamicSleep(delay, task::canRun); + } + } + } } diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestPartitioning.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestPartitioning.java index 860cd67a77a..e4aa7b24a5f 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestPartitioning.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestPartitioning.java @@ -95,7 +95,7 @@ protected String coordinatorTaskOid(String TEST_NAME) { @PostConstruct public void initialize() throws Exception { super.initialize(); - workStateManager.setFreeBucketWaitInterval(1000L); + workStateManager.setFreeBucketWaitIntervalOverride(1000L); DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkBucketStrategies.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkBucketStrategies.java index b4d5a8378b0..5447ade1f66 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkBucketStrategies.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkBucketStrategies.java @@ -106,7 +106,7 @@ protected String coordinatorTaskOid(String TEST_NAME) { @PostConstruct public void initialize() throws Exception { super.initialize(); - workStateManager.setFreeBucketWaitInterval(1000L); + workStateManager.setFreeBucketWaitIntervalOverride(1000L); DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkDistribution.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkDistribution.java index 0ffc8693b0c..0a446bf88b4 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkDistribution.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkDistribution.java @@ -114,7 +114,7 @@ protected String coordinatorTaskOid(String TEST_NAME) { @PostConstruct public void initialize() throws Exception { super.initialize(); - workStateManager.setFreeBucketWaitInterval(1000L); + workStateManager.setFreeBucketWaitIntervalOverride(1000L); DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkersManagement.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkersManagement.java index 1b4eacedf62..7abad172208 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkersManagement.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestWorkersManagement.java @@ -102,7 +102,7 @@ protected String coordinatorTaskOid(String TEST_NAME) { @PostConstruct public void initialize() throws Exception { super.initialize(); - workStateManager.setFreeBucketWaitInterval(1000L); + workStateManager.setFreeBucketWaitIntervalOverride(1000L); DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } From b0917739cb1dd6dbed0cd8afec93be93db64cd21 Mon Sep 17 00:00:00 2001 From: Viliam Repan Date: Mon, 9 Apr 2018 10:26:20 +0200 Subject: [PATCH 18/43] class loading configuration for custom drivers fix for ninja --- tools/ninja/pom.xml | 3 +++ .../main/java/com/evolveum/midpoint/ninja/util/NinjaUtils.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/ninja/pom.xml b/tools/ninja/pom.xml index 21e7eb5d981..33b24e8a8c6 100644 --- a/tools/ninja/pom.xml +++ b/tools/ninja/pom.xml @@ -250,6 +250,9 @@ repackage + + ZIP + diff --git a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/util/NinjaUtils.java b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/util/NinjaUtils.java index 36d046adda1..800bf5d9071 100644 --- a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/util/NinjaUtils.java +++ b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/util/NinjaUtils.java @@ -70,7 +70,7 @@ public static JCommander setupCommandLineParser() { } JCommander jc = builder.build(); - jc.setProgramName("java [-cp ] -jar ninja.jar"); + jc.setProgramName("java [-Dloader.path=] -jar ninja.jar"); jc.setColumnSize(150); jc.setAtFileCharset(Charset.forName(base.getCharset())); From 75ee434b2020df0f10b42f59301a5bbfb290163c Mon Sep 17 00:00:00 2001 From: kate Date: Mon, 9 Apr 2018 10:43:39 +0200 Subject: [PATCH 19/43] MID-4494 Localization warnings after login (self service dashboard) --- .../web/page/self/component/DashboardSearchPanel.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/component/DashboardSearchPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/component/DashboardSearchPanel.java index c44a607078c..f832046dec1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/component/DashboardSearchPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/component/DashboardSearchPanel.java @@ -43,6 +43,11 @@ public class DashboardSearchPanel extends BasePanel { public DashboardSearchPanel(String id) { super(id); + } + + @Override + protected void onInitialize(){ + super.onInitialize(); SEARCH_TYPES = Arrays.asList( createStringResource("PageDashboard.search.users").getString(), createStringResource("PageDashboard.search.resources").getString(), From 94bb35445a8e388addbc224fa7e67ed04a73a5ba Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Mon, 9 Apr 2018 13:38:17 +0430 Subject: [PATCH 20/43] optimize map iterations using entry-sets. --- .../web/component/DropDownMultiChoice.java | 8 +++--- .../web/security/MidPointApplication.java | 16 +++++------ .../prism/marshaller/ItemPathHolder.java | 7 ++--- .../midpoint/prism/xml/XsdTypeMapper.java | 14 +++++----- .../util/aspect/ProfilingDataManager.java | 8 +++--- .../stringpolicy/ValuePolicyProcessor.java | 27 ++++++++++--------- .../impl/api/transports/MailTransport.java | 2 +- .../schema/xjc/schema/SchemaProcessor.java | 16 +++++------ 8 files changed, 51 insertions(+), 47 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/DropDownMultiChoice.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/DropDownMultiChoice.java index 74c6ca85398..215e9d3906f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/DropDownMultiChoice.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/DropDownMultiChoice.java @@ -71,11 +71,11 @@ private void appendOptions(StringBuilder sb) { } sb.append('{'); - Iterator keys = map.keySet().iterator(); + Iterator> keys = map.entrySet().iterator(); while (keys.hasNext()) { - String key = keys.next(); - sb.append(key).append(":"); - sb.append('\'').append(map.get(key)).append('\''); + final Map.Entry key = keys.next(); + sb.append(key.getKey()).append(":"); + sb.append('\'').append(key.getValue()).append('\''); if (keys.hasNext()) { sb.append(",\n"); } 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 327a837345b..92dc6437125 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 @@ -357,18 +357,18 @@ private static List loadLocaleDescriptors(Resource resource) t map.put(key, properties.getProperty(key)); } - for (String key : localeMap.keySet()) { - Map localeDefinition = localeMap.get(key); - if (!localeDefinition.containsKey(key + PROP_NAME) - || !localeDefinition.containsKey(key + PROP_FLAG)) { + for (Map.Entry> entry : localeMap.entrySet()) { + Map localeDefinition = entry.getValue(); + if (!localeDefinition.containsKey(entry + PROP_NAME) + || !localeDefinition.containsKey(entry + PROP_FLAG)) { continue; } LocaleDescriptor descriptor = new LocaleDescriptor( - localeDefinition.get(key + PROP_NAME), - localeDefinition.get(key + PROP_FLAG), - localeDefinition.get(key + PROP_DEFAULT), - WebComponentUtil.getLocaleFromString(key) + localeDefinition.get(entry + PROP_NAME), + localeDefinition.get(entry + PROP_FLAG), + localeDefinition.get(entry + PROP_DEFAULT), + WebComponentUtil.getLocaleFromString(entry.getKey()) ); locales.add(descriptor); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java index f786dfe18f4..8fdd483080f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java @@ -543,17 +543,18 @@ public ItemPathHolder transposedPath(List parentPath) { private void addExplicitNsDeclarations(StringBuilder sb) { if (explicitNamespaceDeclarations != null) { - for (String prefix : explicitNamespaceDeclarations.keySet()) { + for (Map.Entry prefix : explicitNamespaceDeclarations.entrySet()) { sb.append("declare "); + final String declaration = explicitNamespaceDeclarations.get(prefix); if (prefix.equals("")) { sb.append("default namespace '"); - sb.append(explicitNamespaceDeclarations.get(prefix)); + sb.append(declaration); sb.append("'; "); } else { sb.append("namespace "); sb.append(prefix); sb.append("='"); - sb.append(explicitNamespaceDeclarations.get(prefix)); + sb.append(declaration); sb.append("'; "); } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XsdTypeMapper.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XsdTypeMapper.java index 43862c35b6a..206650d1377 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XsdTypeMapper.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XsdTypeMapper.java @@ -152,13 +152,13 @@ public static QName determineQNameWithNs(QName xsdType){ public static Class getXsdToJavaMapping(QName xsdType) { Class clazz = xsdToJavaTypeMap.get(xsdType); if (clazz == null){ - Set keys = xsdToJavaTypeMap.keySet(); - for (Iterator iterator = keys.iterator(); iterator.hasNext();){ - QName key = iterator.next(); - if (QNameUtil.match(key, xsdType)){ - return xsdToJavaTypeMap.get(key); - } - } + Set> entries = xsdToJavaTypeMap.entrySet(); + for (Map.Entry entry : entries) { + QName key = entry.getKey(); + if (QNameUtil.match(key, xsdType)){ + return entry.getValue(); + } + } } return xsdToJavaTypeMap.get(xsdType); } diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/aspect/ProfilingDataManager.java b/infra/util/src/main/java/com/evolveum/midpoint/util/aspect/ProfilingDataManager.java index 34ceb5c9929..c5c35b1a70a 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/aspect/ProfilingDataManager.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/aspect/ProfilingDataManager.java @@ -268,10 +268,10 @@ private synchronized void updateOverallStatistics(Map logMap, Subsystem subsystem, boolean afterTest){ - - for(String key: logMap.keySet()){ - if(logMap.get(key) != null && subsystem.equals(logMap.get(key).getSubsystem())){ - logMap.get(key).appendToLogger(afterTest); + for (Map.Entry usage : logMap.entrySet()){ + final MethodUsageStatistics value = usage.getValue(); + if(subsystem.equals(value.getSubsystem())){ + value.appendToLogger(afterTest); } } } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java index e38ec233534..7e3b9cb00bc 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java @@ -554,9 +554,10 @@ private String generateAttempt(ValuePolicyType policy, int defaultLength, boolea * first in password */ Map> mustBeFirst = new HashMap<>(); - for (StringLimitType l : lims.keySet()) { - if (l.isMustBeFirst() != null && l.isMustBeFirst()) { - mustBeFirst.put(l, lims.get(l)); + for (Map.Entry> entry : lims.entrySet()) { + final StringLimitType key = entry.getKey(); + if (key.isMustBeFirst() != null && key.isMustBeFirst()) { + mustBeFirst.put(key, entry.getValue()); } } @@ -771,26 +772,28 @@ private Map> cardinalityCounter(Map password, Boolean skipMatchedLims, boolean uniquenessReached, OperationResult op) { HashMap counter = new HashMap<>(); - for (StringLimitType l : lims.keySet()) { + Map> mustBeFirst = new HashMap<>(); + for (Map.Entry> entry : lims.entrySet()) { + final StringLimitType key = entry.getKey(); int counterKey = 1; - List chars = lims.get(l); + List chars = entry.getValue(); int i = 0; if (null != password) { - i = charIntersectionCounter(lims.get(l), password); + i = charIntersectionCounter(entry.getValue(), password); } // If max is exceed then error unable to continue - if (l.getMaxOccurs() != null && i > l.getMaxOccurs()) { - OperationResult o = new OperationResult("Limitation check :" + l.getDescription()); + if (key.getMaxOccurs() != null && i > key.getMaxOccurs()) { + OperationResult o = new OperationResult("Limitation check :" + key.getDescription()); o.recordFatalError( - "Exceeded maximal value for this limitation. " + i + ">" + l.getMaxOccurs()); + "Exceeded maximal value for this limitation. " + i + ">" + key.getMaxOccurs()); op.addSubresult(o); return null; // if max is all ready reached or skip enabled for minimal skip // counting - } else if (l.getMaxOccurs() != null && i == l.getMaxOccurs()) { + } else if (key.getMaxOccurs() != null && i == key.getMaxOccurs()) { continue; // other cases minimum is not reached - } else if ((l.getMinOccurs() == null || i >= l.getMinOccurs()) && !skipMatchedLims) { + } else if ((key.getMinOccurs() == null || i >= key.getMinOccurs()) && !skipMatchedLims) { continue; } for (String s : chars) { @@ -803,9 +806,9 @@ private Map> cardinalityCounter(Map field : fields.entrySet()) { + JFieldVar fieldVar = field.getValue(); + // marks a:rawType fields with @Raw - this has to be executed for any bean, not only for prism containers if (hasAnnotation(classOutline, fieldVar, A_RAW_TYPE) != null) { annotateFieldAsRaw(fieldVar); } @@ -1134,7 +1134,7 @@ private void updateFields(Outline outline) { } allFieldsToBeRemoved.forEach((jDefinedClass, jFieldVars) -> { - jFieldVars.forEach(field -> jDefinedClass.removeField(field)); + jFieldVars.forEach(jDefinedClass::removeField); }); } @@ -1148,8 +1148,8 @@ private void processContainerFields(ClassOutline classOutline, Map fieldsToBeRemoved = new ArrayList<>(); - for (String field : fields.keySet()) { - JFieldVar fieldVar = fields.get(field); + for (Map.Entry field : fields.entrySet()) { + JFieldVar fieldVar = field.getValue(); if (isAuxiliaryField(fieldVar)) { continue; } @@ -1183,8 +1183,8 @@ private void processContainerFields(ClassOutline classOutline, Map fields = sourceClass.implClass.fields(); - for (String field : fields.keySet()) { - JFieldVar fieldVar = fields.get(field); + for (Map.Entry field : fields.entrySet()) { + JFieldVar fieldVar = field.getValue(); if (!isAuxiliaryField(fieldVar) && !hasAnnotationClass(fieldVar, XmlAnyElement.class)) { createFluentFieldMethods(fieldVar, targetClass, sourceClass); } From 6772472dd5a9bcbabd275c33d610371458e46dca Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Mon, 9 Apr 2018 13:50:49 +0430 Subject: [PATCH 21/43] Use URI instead of URL to avoid domain name resolution for maps --- .../connid/ConnectorFactoryConnIdImpl.java | 41 +++++++++++-------- .../sql/testing/TestSqlRepositoryFactory.java | 2 +- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java index 05c8238b987..5792a0fb17a 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.security.Key; import java.util.Arrays; @@ -172,7 +173,7 @@ public class ConnectorFactoryConnIdImpl implements ConnectorFactory { private ConnectorInfoManagerFactory connectorInfoManagerFactory; private ConnectorInfoManager localConnectorInfoManager; - private Set bundleURLs; + private Set bundleURLs; private Set localConnectorTypes = null; @Autowired(required = true) @@ -213,7 +214,7 @@ public void initialize() { bundleURLs.addAll(scanDirectory(dir)); } - for (URL u : bundleURLs) { + for (URI u : bundleURLs) { LOGGER.debug("ICF bundle URL : {}", u); } @@ -543,8 +544,8 @@ private ConnectorInfoManager getRemoteConnectorInfoManager(ConnectorHostType hos * * @return Set of all bundle URL */ - private Set scanClassPathForBundles() { - Set bundle = new HashSet<>(); + private Set scanClassPathForBundles() { + Set bundle = new HashSet<>(); // scan class path for bundles Enumeration en = null; @@ -595,7 +596,11 @@ private Set scanClassPathForBundles() { URL tmp = new URL(toUrl(upath.substring(0, upath.lastIndexOf("!")))); if (isThisBundleCompatible(tmp)) { - bundle.add(tmp); + try { + bundle.add(tmp.toURI()); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } } else { LOGGER.warn("Skip loading ICF bundle {} due error occured", tmp); } @@ -623,23 +628,24 @@ private String toUrl(String string) { * @param path * @return */ - private Set scanDirectory(String path) { + private Set scanDirectory(String path) { // Prepare return object - Set bundle = new HashSet<>(); - // COnvert path to object File + Set bundle = new HashSet<>(); + // Convert path to object File File dir = new File(path); // Test if this path is single jar or need to do deep examination if (isThisJarFileBundle(dir)) { try { - if (isThisBundleCompatible(dir.toURI().toURL())) { - bundle.add(dir.toURI().toURL()); + final URI uri = dir.toURI(); + if (isThisBundleCompatible(uri.toURL())) { + bundle.add(uri); } else { - LOGGER.warn("Skip loading budle {} due error occured", dir.toURI().toURL()); + LOGGER.warn("Skip loading bundle {} due error occurred", uri.toURL()); } } catch (MalformedURLException e) { - LOGGER.error("This never happend we hope.", e); + LOGGER.error("This never happened we hope.", e); throw new SystemException(e); } return bundle; @@ -657,17 +663,18 @@ private Set scanDirectory(String path) { return bundle; } - // test all entires for bundle + // test all entries for bundle for (int i = 0; i < dirEntries.length; i++) { if (isThisJarFileBundle(dirEntries[i])) { try { - if (isThisBundleCompatible(dirEntries[i].toURI().toURL())) { - bundle.add(dirEntries[i].toURI().toURL()); + final URI uri = dirEntries[i].toURI(); + if (isThisBundleCompatible(uri.toURL())) { + bundle.add(uri); } else { - LOGGER.warn("Skip loading budle {} due error occured", dirEntries[i].toURI().toURL()); + LOGGER.warn("Skip loading bundle {} due error occurred", uri.toURL()); } } catch (MalformedURLException e) { - LOGGER.error("This never happend we hope.", e); + LOGGER.error("This never happened we hope.", e); throw new SystemException(e); } } diff --git a/repo/repo-sql-impl-test/src/main/java/com/evolveum/midpoint/repo/sql/testing/TestSqlRepositoryFactory.java b/repo/repo-sql-impl-test/src/main/java/com/evolveum/midpoint/repo/sql/testing/TestSqlRepositoryFactory.java index dd0c8c425b4..83b815bfb46 100644 --- a/repo/repo-sql-impl-test/src/main/java/com/evolveum/midpoint/repo/sql/testing/TestSqlRepositoryFactory.java +++ b/repo/repo-sql-impl-test/src/main/java/com/evolveum/midpoint/repo/sql/testing/TestSqlRepositoryFactory.java @@ -148,7 +148,7 @@ private void updateConfigurationBooleanProperty(Configuration configuration, Pro if (value == null) { return; } - boolean val = new Boolean(value).booleanValue(); + boolean val = Boolean.valueOf(value); LOGGER.info("Overriding loaded configuration with value read from system properties: {}={}", propertyName, val); configuration.setProperty(propertyName, val); } From 625559fbdf4c93f63ede16ce7d0ea6953a87f95c Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Mon, 9 Apr 2018 14:03:38 +0430 Subject: [PATCH 22/43] use static inner classes to keep instance size small, and avoid keeping references to creator objects if appropriate. --- .../midpoint/gui/api/component/password/PasswordPanel.java | 2 +- .../resource/component/DuplicateObjectTypeDetector.java | 2 +- .../web/component/wizard/resource/dto/WizardIssuesDto.java | 2 +- .../web/page/admin/certification/DefinitionStagePanel.java | 2 +- .../admin/configuration/dto/SystemConfigurationDto.java | 2 +- .../page/admin/reports/component/RunReportPopupPanel.java | 2 +- .../resources/component/TestConnectionMessagesPanel.java | 2 +- .../web/page/admin/roles/RoleGovernanceRelationsPanel.java | 2 +- .../prism/lex/json/AbstractJsonLexicalProcessor.java | 4 ++-- .../java/com/evolveum/midpoint/prism/path/ItemPath.java | 2 +- .../midpoint/prism/schema/XmlEntityResolverImpl.java | 2 +- .../java/com/evolveum/midpoint/prism/xnode/MapXNode.java | 2 +- .../impl/AccessCertificationClosingTaskHandler.java | 4 ++-- .../midpoint/model/common/util/ProfilingModelInspector.java | 6 +++--- .../midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java | 2 +- .../model/impl/lens/projector/DependencyProcessor.java | 2 +- .../impl/lens/projector/policy/PolicyStateRecorder.java | 2 +- .../model/impl/validator/ResourceValidatorImpl.java | 2 +- .../wf/impl/activiti/dao/ProcessInstanceManager.java | 2 +- .../midpoint/wf/impl/activiti/dao/WorkItemProvider.java | 2 +- .../wf/impl/processes/common/WfStageComputeHelper.java | 2 +- .../wf/impl/processors/primary/PolicyRuleApplication.java | 2 +- .../processors/primary/policy/ApprovalSchemaBuilder.java | 4 ++-- .../midpoint/provisioning/impl/ConnectorManager.java | 2 +- .../ucf/impl/builtin/ConnectorFactoryBuiltinImpl.java | 2 +- .../evolveum/midpoint/repo/sql/SqlPerformanceMonitor.java | 4 ++-- .../midpoint/repo/sql/query2/hqm/HibernateQuery.java | 4 ++-- .../midpoint/task/quartzimpl/execution/JobExecutor.java | 4 ++-- .../task/quartzimpl/handlers/JdbcPingTaskHandler.java | 2 +- .../work/segmentation/StringWorkSegmentationStrategy.java | 2 +- 30 files changed, 38 insertions(+), 38 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/password/PasswordPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/password/PasswordPanel.java index 2b96c1f0160..139ebd5a0d3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/password/PasswordPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/password/PasswordPanel.java @@ -256,7 +256,7 @@ protected void onUpdate(AjaxRequestTarget target) { } } - private class PasswordModel implements IModel { + private static class PasswordModel implements IModel { IModel psModel; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/DuplicateObjectTypeDetector.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/DuplicateObjectTypeDetector.java index 75d76fe12ff..6bc2e4606d8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/DuplicateObjectTypeDetector.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/DuplicateObjectTypeDetector.java @@ -35,7 +35,7 @@ public String getDuplicatesList() { return sb.toString(); } - private class ObjectTypeRecord { + private static class ObjectTypeRecord { @NotNull public final ShadowKindType kind; @NotNull public final String intent; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/WizardIssuesDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/WizardIssuesDto.java index 3748fd3969e..ea6b69f8ed8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/WizardIssuesDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/WizardIssuesDto.java @@ -131,7 +131,7 @@ static Severity fromModel(@NotNull com.evolveum.midpoint.model.api.validator.Iss } } - public class Issue implements Serializable { + public static class Issue implements Serializable { @NotNull private final Severity severity; @NotNull private final String text; @Nullable private final Class relatedStep; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/DefinitionStagePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/DefinitionStagePanel.java index 05404102c1a..9063b8e4823 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/DefinitionStagePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/DefinitionStagePanel.java @@ -201,7 +201,7 @@ public String getObject() { } - private class NoOffsetPrismReferencePanel extends PrismPropertyPanel { + private static class NoOffsetPrismReferencePanel extends PrismPropertyPanel { public NoOffsetPrismReferencePanel(String id, IModel propertyModel, Form form, PageBase pageBase) { super(id, propertyModel, form, null, pageBase); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/SystemConfigurationDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/SystemConfigurationDto.java index ba2ec9793e9..ff8677d67db 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/SystemConfigurationDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/SystemConfigurationDto.java @@ -64,7 +64,7 @@ public class SystemConfigurationDto implements Serializable { public static final String F_ADMIN_GUI_CONFIGURATION = "adminGuiConfiguration"; private AEPlevel aepLevel; - private class CleanupInfo implements Serializable { + private static class CleanupInfo implements Serializable { String ageValue; Integer records; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java index ba4fe74c868..faf7062f4a0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java @@ -587,7 +587,7 @@ public Component getComponent() { return this; } - class LookupReportPropertyModel extends LookupPropertyModel { + static class LookupReportPropertyModel extends LookupPropertyModel { private static final long serialVersionUID = 1L; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java index 8aa1f506988..4bedc907706 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java @@ -160,7 +160,7 @@ public void initResultsPanel(RepeatingView resultView, List opresults, } } - private class ConnectorStruct implements Serializable { + private static class ConnectorStruct implements Serializable { private String connectorName; private List connectorResultsDto; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleGovernanceRelationsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleGovernanceRelationsPanel.java index 4d56ebdb8de..c5c728354f9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleGovernanceRelationsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleGovernanceRelationsPanel.java @@ -232,7 +232,7 @@ protected boolean isGovernance(){ return true; } - class RoleRelationSelectionDto implements Serializable { + static class RoleRelationSelectionDto implements Serializable { private static final long serialVersionUID = 1L; private boolean approver; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java index 7e49cb42be6..7b2ef316078 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java @@ -105,7 +105,7 @@ private List readInternal(@NotNull ParserSource source, @NotNull Pars } } - private class IterativeParsingContext { + private static class IterativeParsingContext { final RootXNodeHandler handler; boolean dataSent; // true if we really found the list of objects and sent it out String defaultNamespace; // default namespace, if present @@ -621,7 +621,7 @@ private JsonParser configureParser(JsonParser parser) { //region Serialization implementation - class JsonSerializationContext { + static class JsonSerializationContext { @NotNull final JsonGenerator generator; @NotNull private final SerializationContext prismSerializationContext; private String currentNamespace; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java index 5e13132401c..8eec4ebac67 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java @@ -401,7 +401,7 @@ public CompareResult compareComplexOld(ItemPath otherPath) { /** * Alternative to normalization: reads the same sequence of segments of 'path' as segments of 'path.normalize()' */ - private class ItemPathNormalizingIterator implements Iterator { + private static class ItemPathNormalizingIterator implements Iterator { final ItemPath path; private int i = 0; private boolean nextIsArtificialId = false; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java index 8de4688e81d..1b88f0e1900 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java @@ -166,7 +166,7 @@ public InputSource resolveResourceUsingBuiltinResolver(String type, String names return inputSource; } - class Input implements LSInput { + static class Input implements LSInput { private String publicId; private String systemId; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java index 111f89fa9b9..a39afbba232 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java @@ -395,7 +395,7 @@ public RootXNode getSingleEntryMapAsRoot() { return new RootXNode(key, get(key)); } - private class Entry implements Map.Entry, Serializable { + private static class Entry implements Map.Entry, Serializable { private QName key; private XNode value; diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java index 69bbf0cb0c5..e7015e71998 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java @@ -277,7 +277,7 @@ public void launch(AccessCertificationCampaignType campaign, OperationResult par LOGGER.trace("Closing task for {} switched to background, control thread returning with task {}", toShortString(campaign), task); } - private class ObjectContext { + private static class ObjectContext { @NotNull final ObjectType object; @NotNull final List> modifications = new ArrayList<>(); @@ -286,7 +286,7 @@ private class ObjectContext { } } - private class RunContext { + private static class RunContext { final Task task; final Map objectContextMap = new HashMap<>(); final PerformerCommentsFormatter commentsFormatter; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/ProfilingModelInspector.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/ProfilingModelInspector.java index 6bbf330f617..8f05b62fb0a 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/ProfilingModelInspector.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/ProfilingModelInspector.java @@ -56,8 +56,8 @@ public class ProfilingModelInspector implements DiagnosticContext, ClockworkInsp private ModelContext lastLensContext; private ModelState currentState = null; private long totalRepoTime = 0; - - class Runtimes { + + static class Runtimes { long startTime = 0; long finishTime = 0; @@ -70,7 +70,7 @@ String etimeStr() { } } - class PartRuntime { + static class PartRuntime { public PartRuntime(String part) { super(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java index 52d6ed572b2..8bb62029cc7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java @@ -68,7 +68,7 @@ public void init() { } // TODO clean this up - private class EvaluationContext { + private static class EvaluationContext { private final List messages = new ArrayList<>(); private final List rules = new ArrayList<>(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/DependencyProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/DependencyProcessor.java index 3717605e39f..78e9f93d05c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/DependencyProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/DependencyProcessor.java @@ -616,7 +616,7 @@ private boolean wasExecuted(LensProjectionContext accountContext){ return true; } - class DependencyAndSource { + static class DependencyAndSource { ResourceObjectTypeDependencyType dependency; LensProjectionContext sourceProjectionContext; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java index d18248edba8..4b6cb69973b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java @@ -129,7 +129,7 @@ private ComputationResult compute(@NotNull List rulesToReco return cr; } - private class ComputationResult { + private static class ComputationResult { final Set oldPolicySituations = new HashSet<>(); final Set newPolicySituations = new HashSet<>(); final Set oldTriggeredRules = new HashSet<>(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java index aabf5e2026c..845024b2495 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java @@ -85,7 +85,7 @@ public class ResourceValidatorImpl implements ResourceValidator { @Autowired private PrismContext prismContext; - private class ResourceValidationContext { + private static class ResourceValidationContext { @NotNull final PrismObject resourceObject; @NotNull final ObjectReferenceType resourceRef; @NotNull final Scope scope; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceManager.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceManager.java index 4c1034d3640..d089b2d2a94 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceManager.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceManager.java @@ -119,7 +119,7 @@ public void onTaskDelete(Task task, OperationResult result) { } } - class Statistics { + static class Statistics { int processes = 0; int processesWithNonExistingTaskOid = 0; int processesWithNonWorkflowTaskOid = 0; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java index 2cd1cc22f74..c896629b175 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java @@ -249,7 +249,7 @@ public List getMidpointAssignees(TaskExtract taskExtract) { /** * Helper class to carry relevant data from both Task and DelegateTask (to avoid code duplication) */ - private class TaskExtract { + private static class TaskExtract { private String id; private String assignee; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfStageComputeHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfStageComputeHelper.java index dc69413aca8..befb31f7dc8 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfStageComputeHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfStageComputeHelper.java @@ -108,7 +108,7 @@ public ExpressionVariables getDefaultVariables(WfContextType wfContext, String r } // TODO name - public class ComputationResult { + public static class ComputationResult { private ApprovalLevelOutcomeType predeterminedOutcome; private AutomatedCompletionReasonType automatedCompletionReason; private Set approverRefs; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PolicyRuleApplication.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PolicyRuleApplication.java index eab1706e917..4ec696b5dc7 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PolicyRuleApplication.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PolicyRuleApplication.java @@ -31,7 +31,7 @@ */ public class PolicyRuleApplication { - class Cause { + static class Cause { private final ResourceShadowDiscriminator shadowDiscriminator; // non-null for projection context @NotNull private final ItemPath itemPath; // should be non-empty @NotNull private final PrismValue itemValue; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java index 7fe8701c60a..67c634fbcd4 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java @@ -51,7 +51,7 @@ void setProcessSpecification(ProcessSpecification processSpecification) { this.processSpecification = processSpecification; } - class Result { + static class Result { @NotNull final ApprovalSchemaType schemaType; @NotNull final SchemaAttachedPolicyRulesType attachedRules; @Nullable final ProcessSpecification processSpecification; @@ -68,7 +68,7 @@ public Result(@NotNull ApprovalSchemaType schemaType, } } - private class Fragment { + private static class Fragment { // object to which relations (approved, owner) are resolved // TODO test this thoroughly in presence of non-direct rules and merged schemas final PrismObject target; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java index 05a94ced7b6..e13f93564a2 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java @@ -533,7 +533,7 @@ public String getFrameworkVersion() { return connectorFactory.getFrameworkVersion(); } - private class ConfiguredConnectorInstanceEntry { + private static class ConfiguredConnectorInstanceEntry { public String connectorOid; public PrismContainer configuration; public ConnectorInstance connectorInstance; diff --git a/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ConnectorFactoryBuiltinImpl.java b/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ConnectorFactoryBuiltinImpl.java index 6dea32f25fa..6677f4a3fd7 100644 --- a/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ConnectorFactoryBuiltinImpl.java +++ b/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ConnectorFactoryBuiltinImpl.java @@ -277,7 +277,7 @@ public void shutdown() { // Nothing to do } - private class ConnectorStruct { + private static class ConnectorStruct { Class connectorClass; ConnectorType connectorObject; PrismSchema connectorConfigurationSchema; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlPerformanceMonitor.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlPerformanceMonitor.java index 1e6e63c48b9..a98a3c3325d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlPerformanceMonitor.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlPerformanceMonitor.java @@ -51,7 +51,7 @@ public class SqlPerformanceMonitor { private SqlRepositoryFactory sqlRepositoryFactory; - class OperationRecord { + static class OperationRecord { String kind; long handle; int attempts; @@ -121,7 +121,7 @@ private void writeStatisticsToFile(String file) { } - class StatEntry { + static class StatEntry { long totalTime, wastedTime; int attempts; int records; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java index 242671d38a1..9496e325322 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java @@ -58,7 +58,7 @@ public abstract class HibernateQuery { */ private List conditions = new ArrayList<>(); - public class Ordering { + public static class Ordering { @NotNull private final String byProperty; private final OrderDirection direction; @@ -80,7 +80,7 @@ public OrderDirection getDirection() { private List orderingList = new ArrayList<>(); - public class Grouping { + public static class Grouping { @NotNull private final String byProperty; Grouping(@NotNull String byProperty) { diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java index b4d3c206ee9..a4b56426a1b 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java @@ -216,7 +216,7 @@ public void execute(JobExecutionContext context) throws JobExecutionException { } - class GroupExecInfo { + static class GroupExecInfo { int limit; Set tasks = new HashSet<>(); @@ -314,7 +314,7 @@ private void addToGroupMap(Map groupMap, Task otherTask) } } - private class RescheduleTime { + private static class RescheduleTime { private final long timestamp; private final boolean regular; private RescheduleTime(long timestamp, boolean regular) { diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/JdbcPingTaskHandler.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/JdbcPingTaskHandler.java index 88e99e72eca..88ef16de576 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/JdbcPingTaskHandler.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/JdbcPingTaskHandler.java @@ -55,7 +55,7 @@ public void initialize() { taskManager.registerHandler(HANDLER_URI, this); } - private class Statistics { + private static class Statistics { Integer min = null; Integer max = null; int total = 0; diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/StringWorkSegmentationStrategy.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/StringWorkSegmentationStrategy.java index f7adb502098..901e0c422a2 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/StringWorkSegmentationStrategy.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/work/segmentation/StringWorkSegmentationStrategy.java @@ -209,7 +209,7 @@ private List processBoundaries() { return rv; } - private class Scanner { + private static class Scanner { final String string; int index; From f3c2d1f569f832ac644723344f589811812b6471 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 9 Apr 2018 15:20:03 +0200 Subject: [PATCH 23/43] Fix channel for live sync notifications (MID-4081) --- .../com/evolveum/midpoint/prism/SerializationOptions.java | 2 +- .../midpoint/model/impl/sync/LiveSyncTaskHandler.java | 7 ++++++- .../intest/sync/AbstractSynchronizationStoryTest.java | 4 ++++ .../midpoint/model/intest/sync/TestLiveSyncTask.java | 5 +++++ .../evolveum/midpoint/model/intest/sync/TestReconTask.java | 6 ++++++ .../evolveum/midpoint/wf/impl/tasks/WfTaskController.java | 4 +--- 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java index 45bf7b5f146..7e84b0e902e 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java @@ -36,7 +36,7 @@ public void setSerializeReferenceNames(boolean serializeReferenceNames) { this.serializeReferenceNames = serializeReferenceNames; } - public static SerializationOptions createSerializeReferenceNames(){ + public static SerializationOptions createSerializeReferenceNames() { SerializationOptions serializationOptions = new SerializationOptions(); serializationOptions.setSerializeReferenceNames(true); return serializationOptions; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java index 358a11b89f1..60af7f17a32 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.result.OperationConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -88,7 +89,11 @@ public TaskRunResult run(Task task) { TaskRunResult runResult = new TaskRunResult(); runResult.setOperationResult(opResult); - String resourceOid = task.getObjectOid(); + if (task.getChannel() == null) { + task.setChannel(SchemaConstants.CHANGE_CHANNEL_LIVE_SYNC_URI); + } + + String resourceOid = task.getObjectOid(); if (resourceOid == null) { LOGGER.error("Live Sync: No resource OID specified in the task"); opResult.recordFatalError("No resource OID specified in the task"); 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 5f17a7917fb..cac84473446 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 @@ -184,6 +184,8 @@ public void test110AddDummyGreenAccountMancomb() throws Exception { assertUsers(6); // notifications + displayAllNotifications(); + assertSingleDummyTransportMessageContaining("simpleAccountNotifier-SUCCESS", "Channel: " + getExpectedChannel()); notificationManager.setDisabled(true); // checkDummyTransportMessages("userPasswordNotifier", 1); // password is generated by mapping (if there's none) // checkDummyTransportMessages("accountPasswordNotifier", 1); // account password is then set @@ -194,6 +196,8 @@ public void test110AddDummyGreenAccountMancomb() throws Exception { // checkDummyTransportMessages("simpleUserNotifier-ADD", 1); } + protected abstract String getExpectedChannel(); + @Test public void test200ImportLiveSyncTaskDummyBlue() throws Exception { final String TEST_NAME = "test200ImportLiveSyncTaskDummyBlue"; diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestLiveSyncTask.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestLiveSyncTask.java index d889bf9f428..ea2b5dcd990 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestLiveSyncTask.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestLiveSyncTask.java @@ -17,6 +17,7 @@ import java.io.FileNotFoundException; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -42,7 +43,11 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti dummyResourceGreen.setSyncStyle(DummySyncStyle.SMART); getDummyResource().setSyncStyle(DummySyncStyle.DUMB); getDummyResource(RESOURCE_DUMMY_BLUE_NAME).setSyncStyle(DummySyncStyle.SMART); + } + @Override + protected String getExpectedChannel() { + return SchemaConstants.CHANGE_CHANNEL_LIVE_SYNC_URI; } @Override diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestReconTask.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestReconTask.java index c6f6261aaa6..7ccd725ed8f 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestReconTask.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestReconTask.java @@ -17,6 +17,7 @@ import java.io.FileNotFoundException; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -52,6 +53,11 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti allwaysCheckTimestamp = true; } + @Override + protected String getExpectedChannel() { + return SchemaConstants.CHANGE_CHANNEL_RECON_URI; + } + @Override protected void importSyncTask(PrismObject resource) throws FileNotFoundException { if (resource == resourceDummyGreen) { diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java index 94847998d34..4ae0412a90d 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java @@ -117,9 +117,7 @@ public WfTask submitWfTask(WfTaskCreationInstruction instruction, WfTask parentW */ public WfTask submitWfTask(WfTaskCreationInstruction instruction, Task parentTask, WfConfigurationType wfConfigurationType, String channelOverride, OperationResult result) throws SchemaException, ObjectNotFoundException { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Processing start instruction:\n{}", instruction.debugDump()); - } + LOGGER.trace("Processing start instruction:\n{}", instruction.debugDumpLazily()); Task task = submitTask(instruction, parentTask, wfConfigurationType, channelOverride, result); WfTask wfTask = recreateWfTask(task, instruction.getChangeProcessor()); if (!instruction.isNoProcess()) { From 8ee586fb0f80b27c615b3880a76117a7b560af4d Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 9 Apr 2018 18:46:10 +0200 Subject: [PATCH 24/43] small improvement for sorting in GUI --- .../assignment/PolicyRulesPanel.java | 1 + .../prism/ContainerValueWrapper.java | 52 +++++++++++++++++++ .../web/component/prism/ContainerWrapper.java | 4 +- .../prism/ItemWrapperComparator.java | 4 +- .../prism/PrismContainerValueHeaderPanel.java | 8 +-- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java index 0da6c489ad4..aa103d0704f 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java @@ -141,6 +141,7 @@ protected void newAssignmentClickPerformed(AjaxRequestTarget target) { newAssignment.asContainerable().setPolicyRule(new PolicyRuleType()); ContainerValueWrapper newAssignmentWrapper = createNewAssignmentContainerValueWrapper(newAssignment); newAssignmentWrapper.setShowEmpty(true, false); + newAssignmentWrapper.computeStripes(); assignmentDetailsPerformed(target, Arrays.asList(newAssignmentWrapper)); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index 067a1c22aa1..baec9ebf1d2 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -159,11 +159,13 @@ public void computeStripes() { if (item.isVisible()) { visibleProperties++; } + if (visibleProperties % 2 == 0) { item.setStripe(true); } else { item.setStripe(false); } + } } @@ -284,9 +286,40 @@ public void sort() { if (isSorted()) { collator.setStrength(Collator.SECONDARY); // e.g. "a" should be different from "á" collator.setDecomposition(Collator.FULL_DECOMPOSITION); // slower but more precise + +// List containerWrappers = new ArrayList<>(); +// List propertyOrReferenceWrapper = new ArrayList<>(); +// for(ItemWrapper w : properties) { +// if (w instanceof ContainerWrapper) { +// containerWrappers.add(w); +// continue; +// } +// +// if (PropertyOrReferenceWrapper.class.isAssignableFrom(w.getClass())) { +// propertyOrReferenceWrapper.add(w); +// } +// } + Collections.sort(properties, new Comparator() { @Override public int compare(ItemWrapper pw1, ItemWrapper pw2) { + + if (pw1 instanceof ContainerWrapper) { + ((ContainerWrapper) pw1).sort(); + } + + if (pw2 instanceof ContainerWrapper) { + ((ContainerWrapper) pw2).sort(); + } + + if (PropertyOrReferenceWrapper.class.isAssignableFrom(pw1.getClass()) && pw2 instanceof ContainerWrapper) { + return -1; + } + + if (PropertyOrReferenceWrapper.class.isAssignableFrom(pw2.getClass()) && pw1 instanceof ContainerWrapper) { + return 1; + } +// return compareByDisplayNames(pw1, pw2, collator); } }); @@ -294,6 +327,23 @@ public int compare(ItemWrapper pw1, ItemWrapper pw2) { Collections.sort(properties, new Comparator() { @Override public int compare(ItemWrapper pw1, ItemWrapper pw2) { + + if (pw1 instanceof ContainerWrapper) { + ((ContainerWrapper) pw1).sort(); + } + + if (pw2 instanceof ContainerWrapper) { + ((ContainerWrapper) pw2).sort(); + } + + if (PropertyOrReferenceWrapper.class.isAssignableFrom(pw1.getClass()) && pw2 instanceof ContainerWrapper) { + return -1; + } + + if (PropertyOrReferenceWrapper.class.isAssignableFrom(pw2.getClass()) && pw1 instanceof ContainerWrapper) { + return 1; + } + ItemDefinition id1 = pw1.getItemDefinition(); ItemDefinition id2 = pw2.getItemDefinition(); @@ -307,6 +357,7 @@ public int compare(ItemWrapper pw1, ItemWrapper pw2) { } }); } + } private int compareByDisplayNames(ItemWrapper pw1, ItemWrapper pw2, Collator collator) { @@ -563,6 +614,7 @@ public void addNewChildContainerValue(QName path, PageBase pageBase){ newContainerValue, objectStatus, ValueStatus.ADDED, new ItemPath(path)); newValueWrapper.setShowEmpty(true, false); + newValueWrapper.computeStripes(); childContainerWrapper.getValues().add(newValueWrapper); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index e281bcc6cc2..f1dd4a30a2b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -376,7 +376,9 @@ public boolean isStripe() { @Override public void setStripe(boolean isStripe) { - // Does not make much sense, but it is given by the interface + for (ContainerValueWrapper value : values) { + value.computeStripes(); + } } public PrismContainer createContainerAddDelta() throws SchemaException { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java index 5e2b9305278..14ce8944465 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java @@ -42,10 +42,12 @@ public int compare(ItemWrapper p1, ItemWrapper p2) { } if (def1 instanceof PrismContainerDefinition) { + ((ContainerWrapper) p1).sort(); return 1; } - if (def1 instanceof PrismContainerDefinition) { + if (def2 instanceof PrismContainerDefinition) { + ((ContainerWrapper) p2).sort(); return 1; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java index 2233478e662..4c955e2ddfb 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -120,9 +120,10 @@ public boolean isOn() { @Override public void onClick(AjaxRequestTarget target) { - ContainerValueWrapper containerValueWrapper = PrismContainerValueHeaderPanel.this.getModelObject(); - containerValueWrapper.setSorted(!containerValueWrapper.isSorted()); - containerValueWrapper.sort(); + ContainerValueWrapper containerValueWrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + containerValueWrapper.setSorted(!containerValueWrapper.isSorted()); + containerValueWrapper.sort(); + containerValueWrapper.computeStripes(); onButtonClick(target); } @@ -283,6 +284,7 @@ private void onShowEmptyClick(AjaxRequestTarget target) { ContainerValueWrapper wrapper = PrismContainerValueHeaderPanel.this.getModelObject(); wrapper.setShowEmpty(!wrapper.isShowEmpty(), false); + wrapper.computeStripes(); onButtonClick(target); } From e4c7ec2383d5a6401563222043cd8c197c0d83c6 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 9 Apr 2018 19:41:03 +0200 Subject: [PATCH 25/43] Partially reverting commit 2b4660cb5aeb8d6385762525faf75f2301cd790b, as the obvioysly the entrySet() optimization does not work everywhere. --- .../schema/xjc/schema/SchemaProcessor.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java b/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java index a6267738a30..cfe2b1c1e50 100644 --- a/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java +++ b/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java @@ -1117,9 +1117,9 @@ private void updateFields(Outline outline) { print("Updating fields and get/set methods: " + classOutline.implClass.fullName()); - for (Map.Entry field : fields.entrySet()) { - JFieldVar fieldVar = field.getValue(); - // marks a:rawType fields with @Raw - this has to be executed for any bean, not only for prism containers + for (Map.Entry field : fields.entrySet()) { + JFieldVar fieldVar = field.getValue(); + // marks a:rawType fields with @Raw - this has to be executed for any bean, not only for prism containers if (hasAnnotation(classOutline, fieldVar, A_RAW_TYPE) != null) { annotateFieldAsRaw(fieldVar); } @@ -1148,8 +1148,9 @@ private void processContainerFields(ClassOutline classOutline, Map fieldsToBeRemoved = new ArrayList<>(); - for (Map.Entry field : fields.entrySet()) { - JFieldVar fieldVar = field.getValue(); + // WARNING: cannot change to entrySet. For some reason entrySet does not work here. + for (String field : fields.keySet()) { + JFieldVar fieldVar = fields.get(field); if (isAuxiliaryField(fieldVar)) { continue; } @@ -1183,8 +1184,8 @@ private void processContainerFields(ClassOutline classOutline, Map fields = sourceClass.implClass.fields(); - for (Map.Entry field : fields.entrySet()) { - JFieldVar fieldVar = field.getValue(); + for (Map.Entry field : fields.entrySet()) { + JFieldVar fieldVar = field.getValue(); if (!isAuxiliaryField(fieldVar) && !hasAnnotationClass(fieldVar, XmlAnyElement.class)) { createFluentFieldMethods(fieldVar, targetClass, sourceClass); } From 11114f3de20b7f8c6cf19e6712ff27c562c7300e Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 9 Apr 2018 19:42:14 +0200 Subject: [PATCH 26/43] Fixing policy sample --- samples/policy/meta/policies-meta-approval.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/policy/meta/policies-meta-approval.xml b/samples/policy/meta/policies-meta-approval.xml index f6f3b4a66b0..9a445a31ab5 100644 --- a/samples/policy/meta/policies-meta-approval.xml +++ b/samples/policy/meta/policies-meta-approval.xml @@ -87,7 +87,7 @@ Role approver - owner + approver firstDecides reject From a7cd9d2aa2305f2de7a7002d6264abdd2bbc58f0 Mon Sep 17 00:00:00 2001 From: kate Date: Tue, 10 Apr 2018 12:10:32 +0200 Subject: [PATCH 27/43] MID-3253 "Delete all identities" -> OpResult box should be blue (background), not green (immediate success) --- .../midpoint/web/page/admin/configuration/PageDebugList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java index 6243c143de1..f4d63aa116d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java @@ -635,7 +635,6 @@ private void deleteAllIdentitiesConfirmed(AjaxRequestTarget target, DeleteAllDto } target.add(getFeedbackPanel()); - result.recomputeStatus(); showResult(result); } From 7b037ceb01a338326217ffc4fae46bc26059263d Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 14:42:57 +0200 Subject: [PATCH 28/43] Support more notification recipients (MID-4534) When recipient expression was used, the number of recipients was limited to 1. Thanking Michael for the fix. (cherry picked from commit c5757c3) --- .../midpoint/notifications/impl/handlers/BaseHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java index 12a23aac960..30ecac73e3e 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java @@ -181,6 +181,7 @@ private List evaluateExpression(ExpressionType expressionType, Expressio QName resultName = new QName(SchemaConstants.NS_C, "result"); PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl<>(resultName, DOMUtil.XSD_STRING, prismContext); + resultDef.setMaxOccurs(-1); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); From 746dea63c0564b462c55a255ad77c0ce6f6661ec Mon Sep 17 00:00:00 2001 From: kate Date: Tue, 10 Apr 2018 15:17:09 +0200 Subject: [PATCH 29/43] MID-4144 GUI fields: Cant copy text from readonly fields --- .../midpoint/web/component/prism/PrismValuePanel.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index 304d15bb312..30dfed9bb3f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -40,6 +40,7 @@ import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField; import org.apache.wicket.extensions.yui.calendar.DateTimeField; import org.apache.wicket.feedback.ComponentFeedbackMessageFilter; +import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; @@ -248,6 +249,14 @@ public boolean isEnabled() { return object == null || isAccessible(def, object.getStatus()); } + + @Override + public void onComponentTag(Component component, ComponentTag tag) { + if (!isEnabled()) { + tag.remove("disabled"); + tag.append("readonly", "readonly", " "); + } + } }); } } From ff9aabf98aada8179f3c696cd475798fe8c0f8a9 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Tue, 10 Apr 2018 15:39:03 +0200 Subject: [PATCH 30/43] fixing registration related issues - custom form used --- .../gui/api/util/WebModelServiceUtils.java | 9 +++- .../AbstractRoleAssignmentPanel.java | 1 + .../ApplicablePolicyGroupPanel.java | 5 ++- .../component/assignment/AssignmentPanel.java | 4 +- .../ConstructionAssociationPanel.java | 3 +- .../prism/ContainerValueWrapper.java | 23 +--------- .../prism/ContainerWrapperFactory.java | 42 +++++++++++-------- .../component/prism/ObjectWrapperFactory.java | 33 ++++++++------- .../prism/PrismContainerHeaderPanel.java | 6 ++- .../prism/PrismContainerValueHeaderPanel.java | 30 ++++++++++++- .../wizard/resource/ConfigurationStep.java | 5 ++- .../page/admin/PageAdminObjectDetails.java | 2 +- .../web/page/admin/cases/PageCase.java | 2 +- .../admin/home/PageMyPasswordQuestions.java | 2 +- .../web/page/admin/server/PageTaskEdit.java | 2 +- .../handlers/dto/GenericHandlerDto.java | 4 +- .../web/page/login/PageSelfRegistration.java | 2 +- .../stringpolicy/ValuePolicyProcessor.java | 8 +++- 18 files changed, 113 insertions(+), 70 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java index 9dd2b074312..b25e4e1106c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java @@ -713,8 +713,7 @@ public static void addIncludeOptionsForExportOrView(Collection assignmentTarg assignmentsModel.getObject().getValues().remove(assignmentToRemove); } else { if (added){ + //TODO: not sure if this is correct way of creating new value.. this value is added directly to the origin object... what about deltas?? PrismContainerValue newAssignment = assignmentsModel.getObject().getItem().createNewValue(); ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(assignmentTargetObject); AssignmentType assignmentType = newAssignment.asContainerable(); assignmentType.setTargetRef(ref); + Task task = getPageBase().createSimpleTask("Creating new applicable policy"); ContainerWrapperFactory factory = new ContainerWrapperFactory(getPageBase()); ContainerValueWrapper valueWrapper = factory.createContainerValueWrapper(assignmentsModel.getObject(), newAssignment, - assignmentsModel.getObject().getObjectStatus(), ValueStatus.ADDED, assignmentsModel.getObject().getPath()); + assignmentsModel.getObject().getObjectStatus(), ValueStatus.ADDED, assignmentsModel.getObject().getPath(), task); valueWrapper.setShowEmpty(true, false); assignmentsModel.getObject().getValues().add(valueWrapper); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java index 5d020439caa..991f80fc8cc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java @@ -50,6 +50,7 @@ import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.security.api.AuthorizationConstants; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.AjaxIconButton; import com.evolveum.midpoint.web.component.data.BoxedTablePanel; @@ -459,8 +460,9 @@ protected void deleteAssignmentPerformed(AjaxRequestTarget target, List createNewAssignmentContainerValueWrapper(PrismContainerValue newAssignment) { ContainerWrapperFactory factory = new ContainerWrapperFactory(getPageBase()); + Task task = getPageBase().createSimpleTask("Creating new assignment"); ContainerValueWrapper valueWrapper = factory.createContainerValueWrapper(getModelObject(), newAssignment, - getModelObject().getObjectStatus(), ValueStatus.ADDED, getModelObject().getPath()); + getModelObject().getObjectStatus(), ValueStatus.ADDED, getModelObject().getPath(), task); valueWrapper.setShowEmpty(true, false); getModelObject().getValues().add(valueWrapper); return valueWrapper; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java index 10be52569db..e2c10c755ab 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ConstructionAssociationPanel.java @@ -281,6 +281,7 @@ private List getAssociationsShadowRefs(boolean compareName, private void addNewShadowRefValuePerformed(AjaxRequestTarget target, RefinedAssociationDefinition def){ ObjectFilter filter = WebComponentUtil.createAssociationShadowRefFilter(def, getPageBase().getPrismContext(), resourceModel.getObject().getOid()); + Task task = getPageBase().createAnonymousTask("Adding new shadow"); ObjectBrowserPanel objectBrowserPanel = new ObjectBrowserPanel( getPageBase().getMainPopupBodyId(), ShadowType.class, Arrays.asList(ShadowType.COMPLEX_TYPE), false, getPageBase(), @@ -304,7 +305,7 @@ protected void onSelectPerformed(AjaxRequestTarget target, ShadowType object) { ContainerWrapperFactory factory = new ContainerWrapperFactory(getPageBase()); ContainerValueWrapper valueWrapper = factory.createContainerValueWrapper(associationWrapper, newAssociation, - associationWrapper.getObjectStatus(), ValueStatus.ADDED, associationWrapper.getPath()); + associationWrapper.getObjectStatus(), ValueStatus.ADDED, associationWrapper.getPath(), task); // valueWrapper.setShowEmpty(true, false); associationWrapper.getValues().add(valueWrapper); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index baec9ebf1d2..7bb8e395336 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -155,7 +155,7 @@ public void computeStripes() { } int visibleProperties = 0; - for (ItemWrapper item : properties) { + for (ItemWrapper item : properties) { if (item.isVisible()) { visibleProperties++; } @@ -599,26 +599,7 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel } } - public void addNewChildContainerValue(QName path, PageBase pageBase){ - ContainerWrapper childContainerWrapper = getContainer().findContainerWrapper(new ItemPath(getPath(), path)); - if (childContainerWrapper == null){ - return; - } - boolean isSingleValue = childContainerWrapper.getItemDefinition().isSingleValue(); - if (isSingleValue){ - return; - } - PrismContainerValue newContainerValue = childContainerWrapper.getItem().createNewValue(); - ContainerWrapperFactory factory = new ContainerWrapperFactory(pageBase); - ContainerValueWrapper newValueWrapper = factory.createContainerValueWrapper(childContainerWrapper, - newContainerValue, objectStatus, - ValueStatus.ADDED, new ItemPath(path)); - newValueWrapper.setShowEmpty(true, false); - newValueWrapper.computeStripes(); - childContainerWrapper.getValues().add(newValueWrapper); - - } - + private Item createItem(PropertyOrReferenceWrapper itemWrapper, ItemDefinition propertyDef) { List prismValues = new ArrayList<>(); for (Object vWrapper : itemWrapper.getValues()) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index 7aba8036740..50b3fb884d2 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -32,6 +32,7 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.TunnelException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -85,13 +86,14 @@ public ContainerWrapper createContainerWrapper( PrismContainer container, ContainerStatus objectStatus, ContainerStatus status, - ItemPath path) { + ItemPath path, + Task task) { result = new OperationResult(CREATE_PROPERTIES); ContainerWrapper cWrapper = new ContainerWrapper(container, objectStatus, status, path); - List> containerValues = createContainerValues(cWrapper, path); + List> containerValues = createContainerValues(cWrapper, path, task); cWrapper.setProperties(containerValues); cWrapper.computeStripes(); @@ -217,13 +219,13 @@ private boolean isEmpty(ValueWrapper shadowAssociationRef) { } - public ContainerWrapper createContainerWrapper(PrismContainer container, ContainerStatus objectStatus, ContainerStatus status, ItemPath path, boolean readonly) { + public ContainerWrapper createContainerWrapper(PrismContainer container, ContainerStatus objectStatus, ContainerStatus status, ItemPath path, boolean readonly, Task task) { result = new OperationResult(CREATE_PROPERTIES); ContainerWrapper cWrapper = new ContainerWrapper<>(container, objectStatus, status, path, readonly); - List> containerValues = createContainerValues(cWrapper, path); + List> containerValues = createContainerValues(cWrapper, path, task); cWrapper.setProperties(containerValues); cWrapper.computeStripes(); @@ -231,20 +233,20 @@ public ContainerWrapper createContainerWrapper(Pris return cWrapper; } - private List> createContainerValues(ContainerWrapper cWrapper, ItemPath path) { + private List> createContainerValues(ContainerWrapper cWrapper, ItemPath path, Task task) { List> containerValueWrappers = new ArrayList<>(); PrismContainer container = cWrapper.getItem(); if (container.getValues().isEmpty() && container.isSingleValue()) { PrismContainerValue pcv = container.createNewValue(); - ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, cWrapper.getObjectStatus(), ValueStatus.ADDED, cWrapper.getPath()); + ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, cWrapper.getObjectStatus(), ValueStatus.ADDED, cWrapper.getPath(), task); containerValueWrappers.add(containerValueWrapper); return containerValueWrappers; } container.getValues().forEach(pcv -> { - ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, cWrapper.getObjectStatus(), cWrapper.getStatus() == ContainerStatus.ADDING ? ValueStatus.ADDED : ValueStatus.NOT_CHANGED, pcv.getPath()); + ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, cWrapper.getObjectStatus(), cWrapper.getStatus() == ContainerStatus.ADDING ? ValueStatus.ADDED : ValueStatus.NOT_CHANGED, pcv.getPath(), task); containerValueWrappers.add(containerValueWrapper); }); @@ -252,10 +254,10 @@ private List> createContainer return containerValueWrappers; } - public ContainerValueWrapper createContainerValueWrapper(ContainerWrapper cWrapper, PrismContainerValue value, ContainerStatus objectStatus, ValueStatus status, ItemPath path){ + public ContainerValueWrapper createContainerValueWrapper(ContainerWrapper cWrapper, PrismContainerValue value, ContainerStatus objectStatus, ValueStatus status, ItemPath path, Task task){ ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper(cWrapper, value, objectStatus, status, path); - List properties = createProperties(containerValueWrapper, false); + List properties = createProperties(containerValueWrapper, false, task); containerValueWrapper.setProperties(properties); ReferenceWrapper shadowRefWrapper = (ReferenceWrapper) containerValueWrapper.findPropertyWrapper(ShadowAssociationType.F_SHADOW_REF); @@ -266,7 +268,7 @@ public ContainerValueWrapper createContainerValueWr return containerValueWrapper; } - public List createProperties(ContainerValueWrapper cWrapper, boolean onlyEmpty) { + public List createProperties(ContainerValueWrapper cWrapper, boolean onlyEmpty, Task task) { result = new OperationResult(CREATE_PROPERTIES); @@ -291,14 +293,20 @@ public List createP return; } - if (itemDef.isExperimental() && !WebModelServiceUtils.isEnableExperimentalFeature(modelServiceLocator)) { + if (itemDef.isExperimental() && !WebModelServiceUtils.isEnableExperimentalFeature(task, modelServiceLocator)) { LOGGER.trace("Skipping creating wrapper for {} because it is experimental a experimental features are not enabled.", itemDef.getName()); return; } LOGGER.trace("Creating wrapper for {}", itemDef); + try { createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers, onlyEmpty, cWrapper.getPath()); - createContainerWrapper(itemDef, cWrapper, containerWrappers, onlyEmpty); + createContainerWrapper(itemDef, cWrapper, containerWrappers, onlyEmpty, task); + } catch (Exception e) { + LoggingUtils.logUnexpectedException(LOGGER, "something strange happenned: " + e.getMessage(), e); + System.out.println(e.getMessage()); + throw new TunnelException(e); + } }); @@ -330,7 +338,7 @@ private void createPropertyOrReferenceWrapper(ItemDefi private void createContainerWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, - List> properties, boolean onlyEmpty){ + List> properties, boolean onlyEmpty, Task task){ if (itemDef instanceof PrismContainerDefinition) { @@ -367,7 +375,7 @@ private void createContainerWrapper(ItemDefinition ite // } // // } else { - subContainerWrapper = createContainerWrapper((PrismContainerDefinition) itemDef, cWrapper, onlyEmpty); + subContainerWrapper = createContainerWrapper((PrismContainerDefinition) itemDef, cWrapper, onlyEmpty, task); // } if (subContainerWrapper == null) { @@ -456,7 +464,7 @@ private ReferenceWrapper createReferenceWrapper(PrismR } private ContainerWrapper createContainerWrapper(PrismContainerDefinition def, - ContainerValueWrapper cWrapper, boolean onlyEmpty) { + ContainerValueWrapper cWrapper, boolean onlyEmpty, Task task) { PrismContainerValue containerValue = cWrapper.getContainerValue(); @@ -487,9 +495,9 @@ private ContainerWrapper createContainerWrapper(Pri return null; } return createContainerWrapper(newContainer, cWrapper.getObjectStatus(), ContainerStatus.ADDING, - cWrapper.getPath().append(new ItemPath(newContainer.getElementName()))); + cWrapper.getPath().append(new ItemPath(newContainer.getElementName())), task); } - return createContainerWrapper(container, cWrapper.getObjectStatus(), cWrapper.getStatus() == ValueStatus.ADDED ? ContainerStatus.ADDING: ContainerStatus.MODIFYING, container.getPath()); + return createContainerWrapper(container, cWrapper.getObjectStatus(), cWrapper.getStatus() == ValueStatus.ADDED ? ContainerStatus.ADDING: ContainerStatus.MODIFYING, container.getPath(), task); } private boolean isItemReadOnly(ItemDefinition def, ContainerValueWrapper cWrapper) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index 3f7cd0c768a..9b737d08b6f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -133,7 +133,7 @@ public ObjectWrapper createObjectWrapper(String displa } return createObjectWrapper(displayName, description, object, objectDefinitionForEditing, - objectClassDefinitionForEditing, status, result); + objectClassDefinitionForEditing, status, task, result); } catch (SchemaException | ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException | CommunicationException | SecurityViolationException ex) { throw new SystemException(ex); } @@ -141,15 +141,15 @@ public ObjectWrapper createObjectWrapper(String displa public ObjectWrapper createObjectWrapper(String displayName, String description, PrismObject object, PrismObjectDefinition objectDefinitionForEditing, - RefinedObjectClassDefinition objectClassDefinitionForEditing, ContainerStatus status) throws SchemaException { + RefinedObjectClassDefinition objectClassDefinitionForEditing, ContainerStatus status, Task task) throws SchemaException { return createObjectWrapper(displayName, description, object, objectDefinitionForEditing, - objectClassDefinitionForEditing, status, null); + objectClassDefinitionForEditing, status, task, null); } private ObjectWrapper createObjectWrapper(String displayName, String description, PrismObject object, PrismObjectDefinition objectDefinitionForEditing, RefinedObjectClassDefinition objectClassDefinitionForEditing, ContainerStatus status, - OperationResult result) throws SchemaException { + Task task, OperationResult result) throws SchemaException { if (result == null) { this.result = new OperationResult(CREATE_OBJECT_WRAPPER); @@ -161,7 +161,7 @@ private ObjectWrapper createObjectWrapper(String displ status); List> containerWrappers = createContainerWrappers(objectWrapper, object, - objectDefinitionForEditing, status, this.result); + objectDefinitionForEditing, status, task, this.result); objectWrapper.setContainers(containerWrappers); this.result.computeStatusIfUnknown(); @@ -176,21 +176,21 @@ private ObjectWrapper createObjectWrapper(String displ } private List> createContainerWrappers(ObjectWrapper oWrapper, - PrismObject object, PrismObjectDefinition objectDefinitionForEditing, ContainerStatus cStatus, OperationResult pResult) throws SchemaException { + PrismObject object, PrismObjectDefinition objectDefinitionForEditing, ContainerStatus cStatus, Task task, OperationResult pResult) throws SchemaException { OperationResult result = pResult.createSubresult(CREATE_CONTAINERS); List> containerWrappers = new ArrayList<>(); ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); try { - ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, oWrapper.getStatus(), cStatus, ItemPath.EMPTY_PATH); + ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, oWrapper.getStatus(), cStatus, ItemPath.EMPTY_PATH, task); mainContainerWrapper.setDisplayName("prismContainer.mainPanelDisplayName"); result.addSubresult(cwf.getResult()); containerWrappers.add(mainContainerWrapper); - addContainerWrappers(containerWrappers, oWrapper, object, null, result); + addContainerWrappers(containerWrappers, oWrapper, object, null, task, result); } catch (SchemaException | RuntimeException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Error occurred during container wrapping", e); + LoggingUtils.logUnexpectedException(LOGGER, "Error occurred during container wrapping" + e.getMessage(), e); result.recordFatalError("Error occurred during container wrapping, reason: " + e.getMessage(), e); throw e; } @@ -205,7 +205,7 @@ private List> c private void addContainerWrappers( List> containerWrappers, ObjectWrapper oWrapper, - PrismContainer parentContainer, ItemPath path, OperationResult result) throws SchemaException { + PrismContainer parentContainer, ItemPath path, Task task, OperationResult result) throws SchemaException { PrismContainerDefinition parentContainerDefinition = parentContainer.getDefinition(); @@ -222,7 +222,7 @@ private void addContainerWrapper continue; } - if (def.isExperimental() && !WebModelServiceUtils.isEnableExperimentalFeature(modelServiceLocator)) { + if (def.isExperimental() && !WebModelServiceUtils.isEnableExperimentalFeature(task, modelServiceLocator)) { LOGGER.trace("Skipping creating wrapper for container {} because it is experimental a experimental features are not enabled.", def.getName()); continue; } @@ -237,7 +237,7 @@ private void addContainerWrapper PrismContainer prismContainer = parentContainer.findContainer(def.getName()); - ContainerWrapper container = createContainerWrapper(oWrapper.getObject(), oWrapper.getStatus(), prismContainer, containerDef, cwf, newPath); + ContainerWrapper container = createContainerWrapper(oWrapper.getObject(), oWrapper.getStatus(), prismContainer, containerDef, cwf, newPath, task); result.addSubresult(cwf.getResult()); if (container != null) { containerWrappers.add(container); @@ -246,7 +246,8 @@ private void addContainerWrapper } } - private ContainerWrapper createContainerWrapper(PrismObject object, ContainerStatus objectStatus, PrismContainer prismContainer, PrismContainerDefinition containerDef, ContainerWrapperFactory cwf, ItemPath newPath) throws SchemaException{ + private ContainerWrapper createContainerWrapper(PrismObject object, ContainerStatus objectStatus, PrismContainer prismContainer, + PrismContainerDefinition containerDef, ContainerWrapperFactory cwf, ItemPath newPath, Task task) throws SchemaException{ if (ShadowAssociationType.COMPLEX_TYPE.equals(containerDef.getTypeName())) { ObjectType objectType = object.asObjectable(); ShadowType shadow; @@ -255,7 +256,7 @@ private ContainerWrapper crea } else { throw new SchemaException("Something very strange happenned. Association contianer in the " + objectType.getClass().getSimpleName() + "?"); } - Task task = modelServiceLocator.createSimpleTask("Load resource ref"); +// Task task = modelServiceLocator.createSimpleTask("Load resource ref"); //TODO: is it safe to case modelServiceLocator to pageBase? PrismObject resource = WebModelServiceUtils.loadObject(shadow.getResourceRef(), modelServiceLocator, task, result); @@ -275,11 +276,11 @@ private ContainerWrapper crea } if (prismContainer != null) { - return cwf.createContainerWrapper(prismContainer, objectStatus, ContainerStatus.MODIFYING, newPath); + return cwf.createContainerWrapper(prismContainer, objectStatus, ContainerStatus.MODIFYING, newPath, task); } prismContainer = containerDef.instantiate(); - return cwf.createContainerWrapper(prismContainer, objectStatus, ContainerStatus.ADDING, newPath); + return cwf.createContainerWrapper(prismContainer, objectStatus, ContainerStatus.ADDING, newPath, task); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java index 4d02ccbba70..35e81a87243 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java @@ -5,6 +5,7 @@ import org.apache.wicket.model.IModel; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; public class PrismContainerHeaderPanel extends PrismHeaderPanel>{ @@ -47,7 +48,10 @@ public void onClick(AjaxRequestTarget target) { private void addValue(AjaxRequestTarget target) { ContainerWrapperFactory cwf = new ContainerWrapperFactory(getPageBase()); ContainerWrapper containerWrapper = getModelObject(); - ContainerValueWrapper newContainerValue = cwf.createContainerValueWrapper(containerWrapper, containerWrapper.getItem().createNewValue(), containerWrapper.getObjectStatus(), ValueStatus.ADDED, containerWrapper.getPath()); + Task task = getPageBase().createSimpleTask("Creating new container"); + ContainerValueWrapper newContainerValue = cwf.createContainerValueWrapper(containerWrapper, + containerWrapper.getItem().createNewValue(), containerWrapper.getObjectStatus(), ValueStatus.ADDED, + containerWrapper.getPath(), task); newContainerValue.setShowEmpty(true, false); getModelObject().addValue(newContainerValue); onButtonClick(target); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java index 4c955e2ddfb..0213808629c 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -16,7 +16,11 @@ import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.gui.api.component.togglebutton.ToggleIconButton; +import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import org.apache.wicket.model.Model; @@ -261,7 +265,7 @@ protected void reloadParentContainerPanel(AjaxRequestTarget target){ protected void addNewContainerValuePerformed(AjaxRequestTarget ajaxRequestTarget){ isChildContainersSelectorPanelVisible = false; getModelObject().setShowEmpty(true, false); - getModelObject().addNewChildContainerValue(getSelectedContainerQName(), getPageBase()); + createNewContainerValue(getModelObject(), getSelectedContainerQName()); ajaxRequestTarget.add(getChildContainersSelectorPanel().getParent()); } @@ -288,6 +292,30 @@ private void onShowEmptyClick(AjaxRequestTarget target) { onButtonClick(target); } + + public void createNewContainerValue(ContainerValueWrapper containerValueWrapper, QName path){ + ContainerWrapper childContainerWrapper = containerValueWrapper.getContainer().findContainerWrapper(new ItemPath(getPath(), path)); + if (childContainerWrapper == null){ + return; + } + boolean isSingleValue = childContainerWrapper.getItemDefinition().isSingleValue(); + if (isSingleValue){ + return; + } + PrismContainerValue newContainerValue = childContainerWrapper.getItem().createNewValue(); + + Task task = getPageBase().createSimpleTask("Creating new container value wrapper"); + + ContainerWrapperFactory factory = new ContainerWrapperFactory(getPageBase()); + ContainerValueWrapper newValueWrapper = factory.createContainerValueWrapper(childContainerWrapper, + newContainerValue, containerValueWrapper.getObjectStatus(), + ValueStatus.ADDED, new ItemPath(path), task); + newValueWrapper.setShowEmpty(true, false); + newValueWrapper.computeStripes(); + childContainerWrapper.getValues().add(newValueWrapper); + + } + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java index 7ae7f769993..d376d487195 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java @@ -133,11 +133,12 @@ private List createConfigContainerWrappers() throws SchemaExce ContainerWrapperFactory cwf = new ContainerWrapperFactory(parentPage); ContainerWrapper containerWrapper; + Task task = getPageBase().createSimpleTask("Creting configuration container"); if (container != null) { - containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.MODIFYING, ContainerStatus.MODIFYING, containerPath, parentPage.isReadOnly()); + containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.MODIFYING, ContainerStatus.MODIFYING, containerPath, parentPage.isReadOnly(), task); } else { container = containerDef.instantiate(); - containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.ADDING, ContainerStatus.ADDING, containerPath, parentPage.isReadOnly()); + containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.ADDING, ContainerStatus.ADDING, containerPath, parentPage.isReadOnly(), task); containerWrapper.setShowEmpty(true, true); } containerWrappers.add(containerWrapper); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java index 3c6463b2cd9..19acf39b19e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java @@ -352,7 +352,7 @@ protected ObjectWrapper loadObjectWrapper(PrismObject objectToEdit, boolea result.recordFatalError("Couldn't get user.", ex); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load user", ex); try { - wrapper = owf.createObjectWrapper("pageAdminFocus.focusDetails", null, object, null, null, status); + wrapper = owf.createObjectWrapper("pageAdminFocus.focusDetails", null, object, null, null, status, task); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java index 8ec1a4ba89c..c08fdc1c51e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java @@ -135,7 +135,7 @@ private ObjectWrapper loadCase() { result.recordFatalError("Couldn't get case.", ex); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load case", ex); try { - wrapper = owf.createObjectWrapper("PageCase.details", null, caseInstance, null, null, status); + wrapper = owf.createObjectWrapper("PageCase.details", null, caseInstance, null, null, status, task); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageMyPasswordQuestions.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageMyPasswordQuestions.java index a7a2db94929..f1cadba3d0a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageMyPasswordQuestions.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageMyPasswordQuestions.java @@ -506,7 +506,7 @@ private ObjectWrapper loadUserWrapper(PrismObject userToEdit) { result.recordFatalError("Couldn't get user.", ex); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load user", ex); try { - wrapper = owf.createObjectWrapper("pageMyPasswordQuestions.userDetails", null, user, null, null, status); + wrapper = owf.createObjectWrapper("pageMyPasswordQuestions.userDetails", null, user, null, null, status, task); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java index ab5100f9402..83669396b05 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java @@ -335,7 +335,7 @@ protected ObjectWrapper loadObjectWrapper(PrismObject object result.recordFatalError("Couldn't get user.", ex); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load user", ex); try { - wrapper = owf.createObjectWrapper("pageAdminFocus.focusDetails", null, object, null, null, ContainerStatus.MODIFYING); + wrapper = owf.createObjectWrapper("pageAdminFocus.focusDetails", null, object, null, null, ContainerStatus.MODIFYING, task); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java index 882331fe9d5..3a663bf244b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.CloneUtil; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.web.component.prism.*; @@ -104,7 +105,8 @@ public GenericHandlerDto(TaskDto taskDto, @NotNull List items, PageBase pa } PrismContainerDefinition containerDefinition = new PrismContainerDefinitionImpl<>(new QName("Handler data"), ctd, prismContext); container.setDefinition(containerDefinition); - containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.MODIFYING, ContainerStatus.MODIFYING, ItemPath.EMPTY_PATH, true); + Task task = pageBase.createSimpleTask("Adding new container wrapper"); + containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.MODIFYING, ContainerStatus.MODIFYING, ItemPath.EMPTY_PATH, true, task); } public ContainerWrapper getContainer() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java index f4cc279e0cd..32d10688df0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java @@ -691,7 +691,7 @@ private String generateNonce(NonceCredentialsPolicyType n } policy = valuePolicy.asObjectable(); } - + return getModelInteractionService().generateValue(policy, 24, false, user, "nonce generation (registration)", task, result); } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java index 7e3b9cb00bc..a1eb99a21ad 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java @@ -125,11 +125,17 @@ public void setExpressionFactory(ExpressionFactory expressionFactory) { this.expressionFactory = expressionFactory; } - public String generate(ItemPath path, @NotNull ValuePolicyType policy, int defaultLength, boolean generateMinimalSize, + public String generate(ItemPath path, ValuePolicyType policy, int defaultLength, boolean generateMinimalSize, AbstractValuePolicyOriginResolver originResolver, String shortDesc, Task task, OperationResult parentResult) throws ExpressionEvaluationException, SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { Context ctx = new Context(path); OperationResult result = parentResult.createSubresult(OP_GENERATE); + if (policy == null) { + //lets create some default policy + policy = new ValuePolicyType().stringPolicy(new StringPolicyType().limitations(new LimitationsType().maxLength(defaultLength).minLength(defaultLength))); + + } + StringPolicyType stringPolicy = policy.getStringPolicy(); int maxAttempts = DEFAULT_MAX_ATTEMPTS; if (stringPolicy.getLimitations() != null && stringPolicy.getLimitations().getMaxAttempts() != null) { From 9116c051530cc9b9890e1905eb69df7e733cc5a4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 15:09:55 +0200 Subject: [PATCH 31/43] Create all approval tasks as root ones (MID-4508) Up to now, approvals that were started from a background task (e.g. live sync, reconciliation or members add/delete) executed in tasks which were subtasks of that background task. This had a number of negative consequences e.g. that such approvals were not shown on user's Tasks tab. Now all approval tasks are started as standalone ones. (cherry picked from commit e981801) --- .../BaseModelInvocationProcessingHelper.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java index da62c6b3cd4..2cffa19278f 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java @@ -150,17 +150,27 @@ private LocalizableMessage determineRootTaskName(ModelContext context) { */ private Task determineParentTaskForRoot(Task taskFromModel) { - // this is important: if existing task which we have got from model is transient (this is usual case), we create our root task as a task without parent! - // however, if the existing task is persistent (perhaps because the model operation executes already in the context of a workflow), we create a subtask - // todo think heavily about this; there might be a problem if a transient task from model gets (in the future) persistent - // -- in that case, it would not wait for its workflow-related children (but that's its problem, because children could finish even before - // that task is switched to background) +// // this is important: if existing task which we have got from model is transient (this is usual case), we create our root task as a task without parent! +// // however, if the existing task is persistent (perhaps because the model operation executes already in the context of a workflow), we create a subtask +// // todo think heavily about this; there might be a problem if a transient task from model gets (in the future) persistent +// // -- in that case, it would not wait for its workflow-related children (but that's its problem, because children could finish even before +// // that task is switched to background) +// +// if (taskFromModel.isTransient()) { +// return null; +// } else { +// return taskFromModel; +// } - if (taskFromModel.isTransient()) { - return null; - } else { - return taskFromModel; - } + /* + * Let us create all approval tasks as independent ones. This might resolve more issues, for example: + * - workflow tasks will be displayed on user Tasks tab (MID-4508): currently some of them are not, as they are technically subtasks + * - background tasks that initiate approvals (e.g. live sync or reconciliation) could end up with lots of subtasks, + * which makes their displaying take extraordinarily long + * + * It is to be seen if this will have some negative consequences. + */ + return null; } /** From fa01aa0580c5be9c9cac4ce8a69e9516bb29153c Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 15:30:33 +0200 Subject: [PATCH 32/43] Stop storing ref.targetName into repository It seems that storing targetName on references is not a good idea e.g. because of GUI complications and of general principle of avoiding data redundancy. (cherry picked from commit 0e2f9d4) --- .../com/evolveum/midpoint/repo/sql/AddGetObjectTest.java | 2 +- .../evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java index 126efb4f3ef..9d11a0ca208 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java @@ -134,7 +134,7 @@ public void simpleAddGetTest() throws Exception { // adhoc check whether reference.targetName is preserved if ("atestuserX00003".equals(PolyString.getOrig(object.getName()))) { String personaName = PolyString.getOrig(((UserType) object.asObjectable()).getPersonaRef().get(0).getTargetName()); - assertEquals("Wrong personaRef.targetName on atestuserX00003", "u-000", personaName); + assertEquals("Wrong personaRef.targetName on atestuserX00003", null, personaName); foundAtestuserX00003 = true; break; } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index 0fd731c5639..5e56401e7ff 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -260,8 +260,7 @@ public void updateFullObject(RObject object, PrismObject< // Its' because we're removing some properties during save operation and if save fails, // overwrite attempt (for example using object importer) might try to delete existing object // and then try to save this object one more time. - SerializationOptions options = SerializationOptions.createSerializeReferenceNames(); - String xml = prismContext.xmlSerializer().options(options).serialize(savedObject); + String xml = prismContext.xmlSerializer().serialize(savedObject); savedObject = prismContext.parseObject(xml); if (FocusType.class.isAssignableFrom(savedObject.getCompileTimeClass())) { @@ -272,7 +271,7 @@ public void updateFullObject(RObject object, PrismObject< savedObject.removeContainer(AccessCertificationCampaignType.F_CASE); } - xml = prismContext.xmlSerializer().options(options).serialize(savedObject); + xml = prismContext.xmlSerializer().serialize(savedObject); byte[] fullObject = RUtil.getByteArrayFromXml(xml, getConfiguration().isUseZip()); LOGGER.trace("Storing full object\n{}", xml); From 5624dc987fdd31f18134156c270212f74215ab19 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 15:56:11 +0200 Subject: [PATCH 33/43] Re-fix showing names in 'add' approvals (MID-4512) Now the information goes from wfContext.objectRef that contains the whole object. (cherry picked from commit 640c8c7) --- .../midpoint/web/page/admin/server/dto/TaskDto.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java index 91e745089f1..312e6459f0e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java @@ -312,14 +312,20 @@ private void fillInObjectRefAttributes(TaskType taskType, TaskDtoProviderOptions public String getTaskObjectName(TaskType taskType, PageBase pageBase, Task opTask, OperationResult thisOpResult) { OperationResult currentResult; + ObjectReferenceType objectRef; if (taskType.getWorkflowContext() != null) { // For workflow-related tasks the task object might not be created yet (MID-4512). The simplest way // of avoiding displaying the error is to use a separate operation result. currentResult = new OperationResult(TaskDto.class.getName() + ".getTaskObjectName"); + objectRef = taskType.getWorkflowContext().getObjectRef(); // here should be the name present (important for objects that are to be created) } else { currentResult = thisOpResult; + objectRef = null; } - return WebModelServiceUtils.resolveReferenceName(taskType.getObjectRef(), pageBase, opTask, currentResult); + if (objectRef == null) { // either not a workflow task, or wfc.objectRef does not exist + objectRef = taskType.getObjectRef(); + } + return WebModelServiceUtils.resolveReferenceName(objectRef, pageBase, opTask, currentResult); } private void fillInParentTaskAttributes(TaskType taskType, From ad70ec548b67962c137bcd655d1bd9df1de0cf14 Mon Sep 17 00:00:00 2001 From: kate Date: Tue, 10 Apr 2018 16:06:16 +0200 Subject: [PATCH 34/43] some style fix --- .../evolveum/midpoint/web/component/prism/PrismValuePanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index 30dfed9bb3f..638545aa39e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -252,8 +252,9 @@ public boolean isEnabled() { @Override public void onComponentTag(Component component, ComponentTag tag) { - if (!isEnabled()) { + if (component instanceof TextField && !isEnabled()) { tag.remove("disabled"); + tag.append("class", "input-readonly", " "); tag.append("readonly", "readonly", " "); } } From 2c6254c23fc9cad4c0e17cb81f87fd35cc7dc1be Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 16:25:39 +0200 Subject: [PATCH 35/43] Fix keySet->entrySet transition in ItemPathHolder --- .../midpoint/prism/marshaller/ItemPathHolder.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java index 8fdd483080f..53e58a6b558 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/ItemPathHolder.java @@ -543,18 +543,19 @@ public ItemPathHolder transposedPath(List parentPath) { private void addExplicitNsDeclarations(StringBuilder sb) { if (explicitNamespaceDeclarations != null) { - for (Map.Entry prefix : explicitNamespaceDeclarations.entrySet()) { + for (Map.Entry declaration : explicitNamespaceDeclarations.entrySet()) { sb.append("declare "); - final String declaration = explicitNamespaceDeclarations.get(prefix); + String prefix = declaration.getKey(); + String value = declaration.getValue(); if (prefix.equals("")) { sb.append("default namespace '"); - sb.append(declaration); + sb.append(value); sb.append("'; "); } else { sb.append("namespace "); sb.append(prefix); sb.append("='"); - sb.append(declaration); + sb.append(value); sb.append("'; "); } } From 52550b1d2e9f858d90f1f9e34ab942c62efe7714 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 17:19:43 +0200 Subject: [PATCH 36/43] Fix URL->URI transition test failures (at least some of them) --- .../com/evolveum/midpoint/util/MiscUtil.java | 12 ++++++++ .../connid/ConnectorFactoryConnIdImpl.java | 30 +++++++++---------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java index 9d69759df04..82f2ff9b36b 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java @@ -27,6 +27,9 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import java.io.*; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; import java.nio.channels.FileChannel; import java.util.*; import java.util.Map.Entry; @@ -697,4 +700,13 @@ public static Set filter(Set input, Predicate predicate) { public static Collection nonNullValues(@NotNull Collection values) { return values.stream().filter(Objects::nonNull).collect(Collectors.toList()); } + + public static URL toUrlUnchecked(URI uri) { + try { + return uri.toURL(); + } catch (MalformedURLException e) { + throw new SystemException(e); + } + } + } diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java index 5792a0fb17a..47e5e5df703 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java @@ -41,6 +41,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import com.evolveum.midpoint.util.MiscUtil; import org.apache.commons.configuration.Configuration; import org.identityconnectors.common.Version; import org.identityconnectors.common.security.Encryptor; @@ -173,17 +174,12 @@ public class ConnectorFactoryConnIdImpl implements ConnectorFactory { private ConnectorInfoManagerFactory connectorInfoManagerFactory; private ConnectorInfoManager localConnectorInfoManager; - private Set bundleURLs; + private Set bundleURIs; private Set localConnectorTypes = null; - @Autowired(required = true) - private MidpointConfiguration midpointConfiguration; - - @Autowired(required = true) - private Protector protector; - - @Autowired(required = true) - private PrismContext prismContext; + @Autowired private MidpointConfiguration midpointConfiguration; + @Autowired private Protector protector; + @Autowired private PrismContext prismContext; public ConnectorFactoryConnIdImpl() { } @@ -196,26 +192,26 @@ public ConnectorFactoryConnIdImpl() { public void initialize() { // OLD - // bundleURLs = listBundleJars(); - bundleURLs = new HashSet<>(); + // bundleURIs = listBundleJars(); + bundleURIs = new HashSet<>(); Configuration config = midpointConfiguration.getConfiguration("midpoint.icf"); // Is classpath scan enabled if (config.getBoolean("scanClasspath")) { // Scan class path - bundleURLs.addAll(scanClassPathForBundles()); + bundleURIs.addAll(scanClassPathForBundles()); } // Scan all provided directories @SuppressWarnings("unchecked") List dirs = config.getList("scanDirectory"); for (String dir : dirs) { - bundleURLs.addAll(scanDirectory(dir)); + bundleURIs.addAll(scanDirectory(dir)); } - for (URI u : bundleURLs) { - LOGGER.debug("ICF bundle URL : {}", u); + for (URI u : bundleURIs) { + LOGGER.debug("ICF bundle URI : {}", u); } connectorInfoManagerFactory = ConnectorInfoManagerFactory.getInstance(); @@ -502,9 +498,11 @@ private PrismSchema generateConnectorConfigurationSchema(ConnectorInfo cinfo, Co * * @return ICF connector info manager that manages local connectors */ + private ConnectorInfoManager getLocalConnectorInfoManager() { if (null == localConnectorInfoManager) { - localConnectorInfoManager = connectorInfoManagerFactory.getLocalManager(bundleURLs.toArray(new URL[0])); + URL[] urls = bundleURIs.stream().map(MiscUtil::toUrlUnchecked).toArray(URL[]::new); + localConnectorInfoManager = connectorInfoManagerFactory.getLocalManager(urls); } return localConnectorInfoManager; } From 23d4d58867fe3564c9fdd414dbbf44e98f0927df Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 10 Apr 2018 17:38:11 +0200 Subject: [PATCH 37/43] Add test for multivalued recipientExpression Also added toList and encodedToList variables in SimpleSmsTransport. --- .../schema/constants/SchemaConstants.java | 2 + .../model/intest/TestNotifications.java | 33 ++++++++++++++ .../notifications/system-configuration.xml | 45 +++++++++++++++++++ .../api/transports/SimpleSmsTransport.java | 20 +++++---- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index e659f2e883d..717e66b852c 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -466,7 +466,9 @@ public abstract class SchemaConstants { public static final QName C_FROM = new QName(NS_C, "from"); public static final QName C_ENCODED_FROM = new QName(NS_C, "encodedFrom"); public static final QName C_TO = new QName(NS_C, "to"); + public static final QName C_TO_LIST = new QName(NS_C, "toList"); public static final QName C_ENCODED_TO = new QName(NS_C, "encodedTo"); + public static final QName C_ENCODED_TO_LIST = new QName(NS_C, "encodedToList"); public static final QName C_MESSAGE_TEXT = new QName(NS_C, "messageText"); public static final QName C_ENCODED_MESSAGE_TEXT = new QName(NS_C, "encodedMessageText"); public static final QName C_MESSAGE = new QName(NS_C, "message"); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java index bce0e9ee182..63dff112be8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java @@ -422,6 +422,39 @@ public void test210SendSmsUsingPost() { assertEquals("Wrong 1st line of body", "Body=\"hello+world\"&To=%2B421905123456&From=%2B421999000999", httpHandler.lastRequest.body.get(0)); } + @Test + public void test215SendSmsUsingGeneralPost() { + final String TEST_NAME = "test215SendSmsUsingGeneralPost"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestNotifications.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + Event event = new CustomEvent(lightweightIdentifierGenerator, "general-post", null, + "hello world", EventOperationType.ADD, EventStatusType.SUCCESS, null); + notificationManager.processEvent(event, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess("processEvent result", result); + + assertNotNull("No http request found", httpHandler.lastRequest); + assertEquals("Wrong HTTP method", "POST", httpHandler.lastRequest.method); + assertEquals("Wrong URI", "/send", httpHandler.lastRequest.uri.toString()); + assertEquals("Wrong Content-Type header", singletonList("application/x-www-form-urlencoded"), + httpHandler.lastRequest.headers.get("content-type")); + assertEquals("Wrong X-Custom header", singletonList("test"), httpHandler.lastRequest.headers.get("x-custom")); + String username = "a9038321"; + String password = "5ecr3t"; + String expectedAuthorization = "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.ISO_8859_1)); + assertEquals("Wrong Authorization header", singletonList(expectedAuthorization), httpHandler.lastRequest.headers.get("authorization")); + assertEquals("Wrong 1st line of body", "Body=\"body\"&To=[%2B123, %2B456, %2B789]&From=from", httpHandler.lastRequest.body.get(0)); + } + @SuppressWarnings("Duplicates") private void preTestCleanup(AssignmentPolicyEnforcementType enforcementPolicy) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { assumeAssignmentPolicy(enforcementPolicy); diff --git a/model/model-intest/src/test/resources/notifications/system-configuration.xml b/model/model-intest/src/test/resources/notifications/system-configuration.xml index d3f05445de9..917e1ad1d86 100644 --- a/model/model-intest/src/test/resources/notifications/system-configuration.xml +++ b/model/model-intest/src/test/resources/notifications/system-configuration.xml @@ -236,6 +236,30 @@ Channel: $!event.channel sms:with-post + + customEvent + + + + + + from + + + +123 + +456 + +789 + + + body + + sms:with-post-multi + + target/mail-notifications.log @@ -271,5 +295,26 @@ Channel: $!event.channel target/sms.log + + + post + + + http://127.0.0.1:$$port$$/send + + + Content-Type: application/x-www-form-urlencoded + X-Custom: test + + + + + a9038321 + 5ecr3t + target/sms.log + + diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java index fec669ba1e4..f9813847142 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java @@ -75,6 +75,7 @@ import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @@ -174,11 +175,8 @@ public void send(Message message, String transportName, Event event, Task task, return; } - String to = message.getTo().get(0); - if (message.getTo().size() > 1) { - String msg = "Currently it is possible to send the SMS to one recipient only. Among " + message.getTo() + " the chosen one is " + to + " (the first one)."; - LOGGER.warn(msg) ; - } + List to = message.getTo(); + assert to.size() > 0; for (SmsGatewayConfigurationType smsGatewayConfigurationType : smsConfigurationType.getGateway()) { OperationResult resultForGateway = result.createSubresult(DOT_CLASS + "send.forGateway"); @@ -342,12 +340,18 @@ private List evaluateExpression(ExpressionType expressionType, Expressio return exprResult.getZeroSet().stream().map(ppv -> ppv.getValue()).collect(Collectors.toList()); } - protected ExpressionVariables getDefaultVariables(String from, String to, Message message) throws UnsupportedEncodingException { + protected ExpressionVariables getDefaultVariables(String from, List to, Message message) throws UnsupportedEncodingException { ExpressionVariables variables = new ExpressionVariables(); variables.addVariableDefinition(SchemaConstants.C_FROM, from); variables.addVariableDefinition(SchemaConstants.C_ENCODED_FROM, URLEncoder.encode(from, "US-ASCII")); - variables.addVariableDefinition(SchemaConstants.C_TO, to); - variables.addVariableDefinition(SchemaConstants.C_ENCODED_TO, URLEncoder.encode(to, "US-ASCII")); + variables.addVariableDefinition(SchemaConstants.C_TO, to.get(0)); + variables.addVariableDefinition(SchemaConstants.C_TO_LIST, to); + List encodedTo = new ArrayList<>(); + for (String s : to) { + encodedTo.add(URLEncoder.encode(s, "US-ASCII")); + } + variables.addVariableDefinition(SchemaConstants.C_ENCODED_TO, encodedTo.get(0)); + variables.addVariableDefinition(SchemaConstants.C_ENCODED_TO_LIST, encodedTo); variables.addVariableDefinition(SchemaConstants.C_MESSAGE_TEXT, message.getBody()); variables.addVariableDefinition(SchemaConstants.C_ENCODED_MESSAGE_TEXT, URLEncoder.encode(message.getBody(), "US-ASCII")); variables.addVariableDefinition(SchemaConstants.C_MESSAGE, message); From 855914f990ad2815bd39a32c5b95ee3a852c872b Mon Sep 17 00:00:00 2001 From: Viliam Repan Date: Tue, 10 Apr 2018 17:39:32 +0200 Subject: [PATCH 38/43] fixed ucf module tests --- .../ucf/impl/connid/ConnectorFactoryConnIdImpl.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java index 5792a0fb17a..bfdcd9ff316 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorFactoryConnIdImpl.java @@ -504,7 +504,17 @@ private PrismSchema generateConnectorConfigurationSchema(ConnectorInfo cinfo, Co */ private ConnectorInfoManager getLocalConnectorInfoManager() { if (null == localConnectorInfoManager) { - localConnectorInfoManager = connectorInfoManagerFactory.getLocalManager(bundleURLs.toArray(new URL[0])); + URL[] urls = new URL[bundleURLs.size()]; + int i = 0; + for (URI uri : bundleURLs) { + try { + urls[i] = uri.toURL(); + } catch (MalformedURLException ex) { + throw new SystemException(ex); + } + i++; + } + localConnectorInfoManager = connectorInfoManagerFactory.getLocalManager(urls); } return localConnectorInfoManager; } From 6d0d9673498652ac51785e356307274926114f0a Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 10 Apr 2018 18:32:59 +0200 Subject: [PATCH 39/43] Distinct option in adminGuiConfig --- .../xml/ns/public/common/common-core-3.xsd | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index aa6a0239f55..3abed5e53be 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -18289,6 +18289,7 @@ + @@ -18352,6 +18353,41 @@ + + + + Specifies whether "distinct" option should be used in database searches. + + + + + + + Automatic use of distinct option. The code would use distinct option + in case that the query suggest that there is possibility of search + result duplication. + Note: use of "distinct" option will produce cleaner (not duplicated) + search results. But its use may have performance impact. + + + + + + + + + + Disable use of "distinct" option. The option would never be used, + even if there is a risk of search result duplication. + + + + + + + + + From 768b0666ab092020fc27aad3d579276e3bb6cdf9 Mon Sep 17 00:00:00 2001 From: Michael Gruber Date: Tue, 10 Apr 2018 16:36:17 +0200 Subject: [PATCH 40/43] MID-4567 --- .../testing/story/TestReconNullValue.java | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestReconNullValue.java diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestReconNullValue.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestReconNullValue.java new file mode 100644 index 00000000000..b6abbb964de --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestReconNullValue.java @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2016-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.testing.story; + +import static org.testng.Assert.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.opends.server.types.DirectoryException; +import org.opends.server.types.Entry; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.evolveum.midpoint.util.exception.PolicyViolationException; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.processor.ResourceAttribute; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.util.MidPointTestConstants; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.exception.CommunicationException; +import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; +import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; + +/** + * + * Recon should delete resourceAttribute + * + * Users and the roles being assigned in tests: + * User0: IT-Role-HR + + * + * + * + * @author michael gruber + * + */ +@ContextConfiguration(locations = { "classpath:ctx-story-test-main.xml" }) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestReconNullValue extends AbstractStoryTest { + + + public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "recon-null-value"); + + private static final String RESOURCE_OPENDJ_OID = "10000000-0000-0000-0000-000000000003"; + private static final String RESOURCE_OPENDJ_NAMESPACE = MidPointConstants.NS_RI; + /// private static final QName OPENDJ_ASSOCIATION_GROUP_NAME = new + /// QName(RESOURCE_OPENDJ_NAMESPACE, "group"); + + public static final String ORG_TOP_OID = "00000000-8888-6666-0000-100000000001"; + public static final String OBJECT_TEMPLATE_USER_OID = "10000000-0000-0000-0000-000000000222"; + + private static final String USER_0_NAME = "User0"; + + private static final String LDAP_INTENT_DEFAULT = "default"; + + private static final String ACCOUNT_ATTRIBUTE_TITLE = "title"; + + + private ResourceType resourceOpenDjType; + private PrismObject resourceOpenDj; + + @Override + protected String getTopOrgOid() { + return ORG_TOP_OID; + } + + private File getTestDir() { + return TEST_DIR; + } + + + @Override + protected void startResources() throws Exception { + openDJController.startCleanServerRI(); + } + + @AfterClass + public static void stopResources() throws Exception { + openDJController.stop(); + } + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + + //Resources + resourceOpenDj = importAndGetObjectFromFile(ResourceType.class, new File(getTestDir(), "resource-opendj.xml"), RESOURCE_OPENDJ_OID, initTask, initResult); + resourceOpenDjType = resourceOpenDj.asObjectable(); + openDJController.setResource(resourceOpenDj); + + //org + importObjectFromFile(new File(getTestDir(), "org-top.xml"), initResult); + + //role + importObjectFromFile(new File(getTestDir(), "role-ldap.xml"), initResult); + + //template + importObjectFromFile(new File(getTestDir(), "object-template-user.xml"), initResult); + setDefaultUserTemplate(OBJECT_TEMPLATE_USER_OID); + } + + @Test + public void test000Sanity() throws Exception { + final String TEST_NAME = "test000Sanity"; + TestUtil.displayTestTitle(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + OperationResult testResultOpenDj = modelService.testResource(RESOURCE_OPENDJ_OID, task); + TestUtil.assertSuccess(testResultOpenDj); + + dumpOrgTree(); + dumpLdap(); + display("FINISHED: test000Sanity"); + } + + + + @Test + public void test100CreateUsers() throws Exception { + final String TEST_NAME = "test200CreateUsers"; + TestUtil.displayTestTitle(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestReconNullValue.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject user0Before = createUser(USER_0_NAME, "givenName0", "familyName0", true); + + + // WHEN + TestUtil.displayWhen(TEST_NAME); + display("Adding user0", user0Before); + addObject(user0Before, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject user0After = getObjectByName(UserType.class, USER_0_NAME); + display("user0 after", user0After); + + dumpOrgTree(); + + } + + /** + * add honorificPrefix + * + * in resource account value for title should have been added + * + */ + @Test + public void test140AddHonorificPrefix() throws Exception { + final String TEST_NAME = "test140AddHonorificPrefix"; + displayTestTitle(TEST_NAME); + + // GIVEN + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + dummyAuditService.clear(); + + + //TODO: best way to set extension properties? + PrismObject userBefore = getObjectByName(UserType.class, USER_0_NAME); + display("User before", userBefore); + PrismObject userNewPrism = userBefore.clone(); + prismContext.adopt(userNewPrism); + UserType userNew = userNewPrism.asObjectable(); + userNew.setHonorificPrefix(null); + + ObjectDelta delta = userBefore.diff(userNewPrism); + display("Modifying user with delta", delta); + + Collection> deltas = MiscSchemaUtil.createCollection(delta); + + // WHEN + displayWhen(TEST_NAME); + modelService.executeChanges(deltas, null, task, result); + + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getObjectByName(UserType.class, USER_0_NAME); + display("User after deleting attribute honorificPrefix", userAfter); + + + String accountOid = getLinkRefOid(userAfter, RESOURCE_OPENDJ_OID); + + // Check shadow + PrismObject accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result); + display("accountShadow after attribute deletion", accountShadow); + + // Check account + PrismObject accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result); + display("accountModel after attribute deletion", accountModel); + + PrismAsserts.assertNoItem(accountModel, openDJController.getAttributePath(ACCOUNT_ATTRIBUTE_TITLE)); + + } + + + /** + * remove title in Resoure Attributer + * + * in resource account value for title should have been removed + * + */ + @Test //MID-4567 + public void test150RemoveTitleRA() throws Exception { + final String TEST_NAME = "test150RemoveTitleRA"; + displayTestTitle(TEST_NAME); + + // GIVEN + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + dummyAuditService.clear(); + + + //TODO: best way to set extension properties? + PrismObject userBefore = getObjectByName(UserType.class, USER_0_NAME); + display("User before", userBefore); + + + openDJController.executeLdifChange("dn: uid="+USER_0_NAME+",ou=people,dc=example,dc=com\n"+ + "changetype: modify\n"+ + "add: title\n"+ + "title: Earl"); + + // WHEN + displayWhen(TEST_NAME); + modelService.recompute(UserType.class, userBefore.getOid(), null, task, result); + + + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getObjectByName(UserType.class, USER_0_NAME); + display("User smack after adding attribute title", userAfter); + + + String accountOid = getLinkRefOid(userAfter, RESOURCE_OPENDJ_OID); + + // Check shadow + PrismObject accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result); + display("accountShadow after attribute addition", accountShadow); + + // Check account + PrismObject accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result); + display("accountModel after attribute addition", accountModel); + + PrismAsserts.assertNoItem(accountModel, openDJController.getAttributePath( ACCOUNT_ATTRIBUTE_TITLE)); + + } + + private void dumpLdap() throws DirectoryException { + display("LDAP server tree", openDJController.dumpTree()); + display("LDAP server content", openDJController.dumpEntries()); + } + + + protected PrismObject getObjectByName( + Class clazz, String name) throws SchemaException, ObjectNotFoundException, SecurityViolationException, + CommunicationException, ConfigurationException, ExpressionEvaluationException { + PrismObject object = (PrismObject) findObjectByName(clazz, name); + assertNotNull("The object " + name + " of type " + clazz + " is missing!", object); + display(clazz + " " + name, object); + PrismAsserts.assertPropertyValue(object, F.F_NAME, PrismTestUtil.createPolyString(name)); + return object; + } + +} \ No newline at end of file From 154ff05e7dc5fdca897df19e37b09b5646067077 Mon Sep 17 00:00:00 2001 From: Michael Gruber Date: Tue, 10 Apr 2018 16:35:27 +0200 Subject: [PATCH 41/43] test for MID-4567 --- .../recon-null-value/object-template-user.xml | 47 +++++ .../resources/recon-null-value/org-top.xml | 25 +++ .../recon-null-value/resource-opendj.xml | 190 ++++++++++++++++++ .../resources/recon-null-value/role-ldap.xml | 35 ++++ 4 files changed, 297 insertions(+) create mode 100644 testing/story/src/test/resources/recon-null-value/object-template-user.xml create mode 100644 testing/story/src/test/resources/recon-null-value/org-top.xml create mode 100644 testing/story/src/test/resources/recon-null-value/resource-opendj.xml create mode 100644 testing/story/src/test/resources/recon-null-value/role-ldap.xml diff --git a/testing/story/src/test/resources/recon-null-value/object-template-user.xml b/testing/story/src/test/resources/recon-null-value/object-template-user.xml new file mode 100644 index 00000000000..28b9d6578ad --- /dev/null +++ b/testing/story/src/test/resources/recon-null-value/object-template-user.xml @@ -0,0 +1,47 @@ + + + + User Template + + + + + + RoleType + + + name + + + + + + + + + assignment + + + + diff --git a/testing/story/src/test/resources/recon-null-value/org-top.xml b/testing/story/src/test/resources/recon-null-value/org-top.xml new file mode 100644 index 00000000000..18acdeaa51e --- /dev/null +++ b/testing/story/src/test/resources/recon-null-value/org-top.xml @@ -0,0 +1,25 @@ + + + + + TOP + Top + 0000 + functional + diff --git a/testing/story/src/test/resources/recon-null-value/resource-opendj.xml b/testing/story/src/test/resources/recon-null-value/resource-opendj.xml new file mode 100644 index 00000000000..52b34683da7 --- /dev/null +++ b/testing/story/src/test/resources/recon-null-value/resource-opendj.xml @@ -0,0 +1,190 @@ + + + + + + Embedded Test OpenDJ + + + Dummy description, just for the test + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + + 10389 + localhost + dc=example,dc=com + cn=directory manager + + secret + + auto + entryUUID + ds-pwp-account-disabled + isMemberOf + uniqueMember + + + + false + + false + + false + + + + + + + + ri:groupOfUniqueNames + ri:organizationalUnit + ri:groupOfURLs + ri:ds-virtual-static-group + ri:inetOrgPerson + ri:organizationalPerson + ri:person + ri:top + + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + + Name cannot be weak. Changes in name trigger object rename. + + $user/name + + + + + + + + + ri:cn + Common Name + + + fullName + + + + + + ri:sn + + + familyName + + + + + + ri:givenName + + + givenName + + + + + + ri:title + false + + + honorificPrefix + + + + + + ri:isMemberOf + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=Directory Manager + + + + + + + + + + + + + + + + + + + + + + + + + + ri:ds-pwp-account-disabled + + true + + + + + + diff --git a/testing/story/src/test/resources/recon-null-value/role-ldap.xml b/testing/story/src/test/resources/recon-null-value/role-ldap.xml new file mode 100644 index 00000000000..cab58a597ac --- /dev/null +++ b/testing/story/src/test/resources/recon-null-value/role-ldap.xml @@ -0,0 +1,35 @@ + + role-ldap + + + + + + + name + Embedded Test OpenDJ + + + + account + default + + + + + + + + \ No newline at end of file From 268abcbea290db5fc7cd213ec4709e19274ea707 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Wed, 11 Apr 2018 10:31:49 +0200 Subject: [PATCH 42/43] Adding TestReconNullValue to story test suite and fixing mapping strength --- .../src/test/resources/recon-null-value/resource-opendj.xml | 1 + testing/story/testng-integration.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/testing/story/src/test/resources/recon-null-value/resource-opendj.xml b/testing/story/src/test/resources/recon-null-value/resource-opendj.xml index 52b34683da7..89ac7cdc6fa 100644 --- a/testing/story/src/test/resources/recon-null-value/resource-opendj.xml +++ b/testing/story/src/test/resources/recon-null-value/resource-opendj.xml @@ -137,6 +137,7 @@ ri:title false + strong honorificPrefix diff --git a/testing/story/testng-integration.xml b/testing/story/testng-integration.xml index adfe9cdf9fd..3749fba3fdc 100644 --- a/testing/story/testng-integration.xml +++ b/testing/story/testng-integration.xml @@ -49,6 +49,7 @@ + From fa93d132ffec84eebfab3501ea653b270b8ea34f Mon Sep 17 00:00:00 2001 From: Viliam Repan Date: Wed, 11 Apr 2018 13:10:10 +0200 Subject: [PATCH 43/43] cleanup in repository cache, global cache moved after "local" cache, fixed cloning based on readonly flag --- .../midpoint/repo/cache/RepositoryCache.java | 101 ++++++++++-------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java index 72f9f55c3c3..e579820270f 100644 --- a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java +++ b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java @@ -152,66 +152,81 @@ public static String debugDump() { public PrismObject getObject(Class type, String oid, Collection> options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { - if (supportsGlobalCaching(type, options)) { - CacheKey key = new CacheKey(type, oid); - CacheObject cacheObject = globalCache.get(key); - if (cacheObject == null) { - return reloadObject(key, options, parentResult); - } - - if (!shouldCheckVersion(cacheObject)) { - log("Cache: Global HIT {}", key); - return cacheObject.getObject(); - } - - if (hasVersionChanged(key, cacheObject, parentResult)) { - return reloadObject(key, options, parentResult); - } - - // version matches, renew ttl - cacheObject.setTimeToLive(System.currentTimeMillis() + cacheMaxTTL); - - log("Cache: Global HIT, version check {}", key); - return cacheObject.getObject(); - } + boolean readOnly = GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options)); if (!isCacheable(type) || !nullOrHarmlessOptions(options)) { + // local cache not interested in caching this object log("Cache: PASS {} ({})", oid, type.getSimpleName()); - Long startTime = repoOpStart(); - try { - return repositoryService.getObject(type, oid, options, parentResult); - } finally { - repoOpEnd(startTime); - } - + + PrismObject object = getObjectTryGlobalCache(type, oid, options, parentResult); + return cloneIfNecessary(object, readOnly); } + Cache cache = getCache(); - boolean readOnly = GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options)); if (cache == null) { log("Cache: NULL {} ({})", oid, type.getSimpleName()); } else { PrismObject object = (PrismObject) cache.getObject(oid); if (object != null) { - // TODO: result? - if (readOnly) { - log("Cache: HIT {} ({})", oid, type.getSimpleName()); - return object; - } else { - log("Cache: HIT(clone) {} ({})", oid, type.getSimpleName()); - return object.clone(); - } + log("Cache: HIT{} {} ({})", readOnly ? "" : "(clone)", oid, type.getSimpleName()); + return cloneIfNecessary(object, readOnly); } log("Cache: MISS {} ({})", oid, type.getSimpleName()); } - PrismObject object; + + PrismObject object = getObjectTryGlobalCache(type, oid, options, parentResult); + cacheObject(cache, object, readOnly); + + return cloneIfNecessary(object, readOnly); + } + + private PrismObject cloneIfNecessary(PrismObject object, boolean readOnly) { + if (readOnly) { + return object; + } + + return object.clone(); + } + + private PrismObject getObjectTryGlobalCache(Class type, String oid, Collection> options, + OperationResult parentResult) throws SchemaException, ObjectNotFoundException { + + if (!supportsGlobalCaching(type, options)) { + // caller is not interested in cached value, or global cache doesn't want to cache value + return getObjectInternal(type, oid, options, parentResult); + } + + CacheKey key = new CacheKey(type, oid); + CacheObject cacheObject = globalCache.get(key); + + if (cacheObject == null) { + return reloadObject(key, options, parentResult); + } + + if (!shouldCheckVersion(cacheObject)) { + log("Cache: Global HIT {}", key); + return cacheObject.getObject(); + } + + if (hasVersionChanged(key, cacheObject, parentResult)) { + return reloadObject(key, options, parentResult); + } + + // version matches, renew ttl + cacheObject.setTimeToLive(System.currentTimeMillis() + cacheMaxTTL); + + log("Cache: Global HIT, version check {}", key); + return cacheObject.getObject(); + } + + private PrismObject getObjectInternal(Class type, String oid, Collection> options, + OperationResult parentResult) throws SchemaException, ObjectNotFoundException { Long startTime = repoOpStart(); try { - object = repositoryService.getObject(type, oid, null, parentResult); + return repositoryService.getObject(type, oid, options, parentResult); } finally { repoOpEnd(startTime); } - cacheObject(cache, object, readOnly); - return object; } private Long repoOpStart() { @@ -791,7 +806,7 @@ private PrismObject reloadObject( log("Cache: Global MISS {}", key); try { - PrismObject object = repositoryService.getObject(key.getType(), key.getOid(), options, result); + PrismObject object = getObjectInternal(key.getType(), key.getOid(), options, result); long ttl = System.currentTimeMillis() + cacheMaxTTL; CacheObject cacheObject = new CacheObject<>(object, ttl);