diff --git a/.editorconfig b/.editorconfig index 5092bd92234..e69d9ac9836 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ trim_trailing_whitespace = true ij_continuation_indent_size = 8 ij_formatter_off_tag = @formatter:off ij_formatter_on_tag = @formatter:on -ij_formatter_tags_enabled = false +ij_formatter_tags_enabled = true ij_smart_tabs = false ij_visual_guides = 100,130,150,180 ij_wrap_on_typing = false @@ -156,7 +156,7 @@ ij_java_keep_first_column_comment = true ij_java_keep_indents_on_empty_lines = false ij_java_keep_line_breaks = true ij_java_keep_multiple_expressions_in_one_line = false -ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = true ij_java_keep_simple_classes_in_one_line = false ij_java_keep_simple_lambdas_in_one_line = false ij_java_keep_simple_methods_in_one_line = false diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java index 140ff62ead3..89e93703589 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java @@ -217,5 +217,7 @@ public class GuiStyleConstants { public static final String CLASS_ICON_CLAIM = "fa fa-paper-plane-o"; public static final String CLASS_ICON_TEXT = "fa fa-text-width"; + public static final String CLASS_ICON_TRASH = "fa fa-trash-o"; + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/MultivalueContainerListPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/MultivalueContainerListPanel.java index 93fd29bbe81..0d8c27597df 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/MultivalueContainerListPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/MultivalueContainerListPanel.java @@ -455,7 +455,7 @@ public List> getPerformedSelectedItems(IModel createNewItemContainerValueWrapper( PrismContainerValue newItem, PrismContainerWrapper model, AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ConditionPanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ConditionPanelFactory.java index 82f8aac111e..4737c3a234f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ConditionPanelFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ConditionPanelFactory.java @@ -35,7 +35,12 @@ public void register() { @Override protected Panel getPanel(PrismPropertyPanelContext panelCtx) { - AceEditorPanel conditionPanel = new AceEditorPanel(panelCtx.getComponentId(), null, new ConditionExpressionModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 200); + AceEditorPanel conditionPanel = new AceEditorPanel(panelCtx.getComponentId(), null, new ConditionExpressionModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 200){ + @Override + protected boolean isResizeToMaxHeight() { + return false; + } + }; // conditionPanel.getEditor().add(new OnChangeAjaxBehavior() { // @Override // protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java index 98a0a5a1e4d..869fb2830ff 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java @@ -107,7 +107,8 @@ public boolean isVisible() { return false; } - if (!((PrismContainerWrapper) parent).isExpanded() && parent.isMultiValue()) { + + if (!isShowOnTopLevel() && !((PrismContainerWrapper) parent).isExpanded() && parent.isMultiValue()) { return false; } return true; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java index 3e711501e5d..28b328038da 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java @@ -15,6 +15,7 @@ import com.evolveum.midpoint.model.api.ModelPublicConstants; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.api.context.ModelContext; +import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.delta.DeltaFactory; @@ -465,6 +466,15 @@ public void executeChangesInBackground(Collection taskType = task.getUpdatedTaskObject(); + AssignmentType archetypeAssignment = new AssignmentType(); + archetypeAssignment.setTargetRef(WebComponentUtil.createObjectRef(SystemObjectsType.ARCHETYPE_UTILITY_TASK.value(), + null, ArchetypeType.COMPLEX_TYPE)); + taskType.asObjectable().getAssignment().add(archetypeAssignment); + taskType.asObjectable().getArchetypeRef().add(WebComponentUtil.createObjectRef(SystemObjectsType.ARCHETYPE_UTILITY_TASK.value(), + null, ArchetypeType.COMPLEX_TYPE)); + taskManager.switchToBackground(task, result); result.setBackgroundTaskOid(task.getOid()); } catch (Exception e) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java index c7a4e3859a9..5d8bd914567 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java @@ -54,10 +54,15 @@ public boolean isVisible() { if (minSize > 0) { editor.setMinHeight(minSize); } + editor.setResizeToMaxHeight(isResizeToMaxHeight()); add(editor); } public AceEditor getEditor(){ return (AceEditor)get(ID_EDITOR); } + + protected boolean isResizeToMaxHeight() { + return true; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java index e24d0566d1d..7b5789e06ec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java @@ -14,6 +14,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.gui.api.component.PendingOperationPanel; +import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.QueryFactory; @@ -22,6 +23,7 @@ import com.evolveum.midpoint.web.component.menu.cog.ButtonInlineMenuItem; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.page.admin.server.PageTask; +import com.evolveum.midpoint.web.page.admin.server.PageTasks; import com.evolveum.midpoint.web.security.util.SecurityUtils; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -322,72 +324,21 @@ public boolean isVisible() { } }); - OperationResult result = new OperationResult(OPERATION_SEARCH_TASKS_FOR_RESOURCE); - - List> importTasks = WebModelServiceUtils - .searchObjects(TaskType.class, - getPageBase().getPrismContext().queryFor(TaskType.class) - .block() - .item(TaskType.F_OBJECT_REF).ref(getResourceModel().getObject().getOid()) - .and() - .item(TaskType.F_CATEGORY).eq(TaskCategory.IMPORTING_ACCOUNTS) - .endBlock() -// .or() //todo uncomment when archetype oid is fixed -// .item(AssignmentHolderType.F_ARCHETYPE_REF).ref(SystemObjectsType.ARCHETYPE_RECONCILIATION_TASK.value()) //TODO fix archetype ref - .build(), - result, getPageBase()); - - List> reconTasks = WebModelServiceUtils - .searchObjects(TaskType.class, - getPageBase().getPrismContext().queryFor(TaskType.class) - .block() - .item(TaskType.F_OBJECT_REF).ref(getResourceModel().getObject().getOid()) - .and() - .item(TaskType.F_CATEGORY).eq(TaskCategory.RECONCILIATION) - .endBlock() - .or() - .item(AssignmentHolderType.F_ARCHETYPE_REF).ref(SystemObjectsType.ARCHETYPE_RECONCILIATION_TASK.value()) - .build(), - result, getPageBase()); - - List> syncTasks = WebModelServiceUtils - .searchObjects(TaskType.class, - getPageBase().getPrismContext().queryFor(TaskType.class) - .block() - .item(TaskType.F_OBJECT_REF).ref(getResourceModel().getObject().getOid()) - .and() - .item(TaskType.F_CATEGORY).eq(TaskCategory.LIVE_SYNCHRONIZATION) - .endBlock() -// .or() //todo uncomment when archetype oid is fixed -// .item(AssignmentHolderType.F_ARCHETYPE_REF).ref(SystemObjectsType.ARCHETYPE_RECONCILIATION_TASK.value()) //TODO fix archetype ref - .build(), - result, getPageBase()); - -// List tasksForKind = getTasksForKind(importTasks); - -// List importTasks = new ArrayList<>(); -// List syncTasks = new ArrayList<>(); -// List reconTasks = new ArrayList<>(); -// for (TaskType task : tasksForKind) { -// if (TaskCategory.RECONCILIATION.equals(task.getCategory())) { -// reconTasks.add(task); -// } else if (TaskCategory.LIVE_SYNCHRONIZATION.equals(task.getCategory())) { -// syncTasks.add(task); -// } else if (TaskCategory.IMPORTING_ACCOUNTS.equals(task.getCategory())) { -// importTasks.add(task); -// } -// } - initButton(ID_IMPORT, "Import", " fa-download", TaskCategory.IMPORTING_ACCOUNTS, "", getTasksForKind(importTasks)); - initButton(ID_RECONCILIATION, "Reconciliation", " fa-link", TaskCategory.RECONCILIATION, SystemObjectsType.ARCHETYPE_RECONCILIATION_TASK.value(), getTasksForKind(reconTasks)); - initButton(ID_LIVE_SYNC, "Live Sync", " fa-refresh", TaskCategory.LIVE_SYNCHRONIZATION, "", getTasksForKind(syncTasks)); + initButton(ID_IMPORT, "Import", " fa-download", TaskCategory.IMPORTING_ACCOUNTS, SystemObjectsType.ARCHETYPE_IMPORT_TASK.value()); + initButton(ID_RECONCILIATION, "Reconciliation", " fa-link", TaskCategory.RECONCILIATION, SystemObjectsType.ARCHETYPE_RECONCILIATION_TASK.value()); + initButton(ID_LIVE_SYNC, "Live Sync", " fa-refresh", TaskCategory.LIVE_SYNCHRONIZATION, SystemObjectsType.ARCHETYPE_LIVE_SYNCH_TASK.value()); initCustomLayout(); } protected abstract void initShadowStatistics(WebMarkupContainer totals); - private void initButton(String id, String label, String icon, final String category, final String archetypeOid, - final List tasks) { + private void initButton(String id, String label, String icon, String category, String archetypeOid) { + + ObjectQuery existingTasksQuery = getExistingTasksQuery(archetypeOid); + OperationResult result = new OperationResult(OPERATION_SEARCH_TASKS_FOR_RESOURCE); + List> tasksList = WebModelServiceUtils.searchObjects(TaskType.class, existingTasksQuery, + result, getPageBase()); List items = new ArrayList<>(); @@ -402,7 +353,8 @@ public InlineMenuItemAction initAction() { @Override public void onClick(AjaxRequestTarget target) { - runTask(tasks, target); + List filteredByKindIntentTasks = getTasksForKind(tasksList); + redirectToTasksListPage(createInTaskOidQuery(filteredByKindIntentTasks), archetypeOid, target); } }; } @@ -427,7 +379,7 @@ public void onClick(AjaxRequestTarget target) { items.add(item); DropdownButtonPanel button = new DropdownButtonPanel(id, - new DropdownButtonDto(String.valueOf(tasks.size()), icon, label, items)) { + new DropdownButtonDto(String.valueOf(tasksList != null ? tasksList.size() : 0), icon, label, items)) { @Override protected String getSpecialDropdownMenuClass() { return "pull-left"; @@ -472,12 +424,41 @@ private void newTaskPerformed(String category, String archetypeOid, AjaxRequestT setResponsePage(new PageTask(taskType.asPrismObject(), true)); } - private void runTask(List tasks, AjaxRequestTarget target) { + private ObjectQuery createInTaskOidQuery(List tasksList){ + if (tasksList == null){ + return null; + } + List taskOids = new ArrayList<>(); + tasksList.forEach(task -> taskOids.add(task.getOid())); + return getPageBase().getPrismContext().queryFor(TaskType.class) + .id(taskOids.toArray(new String[0])) + .build(); + } + private void redirectToTasksListPage(ObjectQuery tasksQuery, String archetypeOid, AjaxRequestTarget target) { + String taskCollectionViewName = getTaskCollectionViewNameByArchetypeOid(archetypeOid); + PageParameters pageParameters = new PageParameters(); + if (StringUtils.isNotEmpty(taskCollectionViewName)){ + pageParameters.add(PageBase.PARAMETER_OBJECT_COLLECTION_NAME, taskCollectionViewName); + PageTasks pageTasks = new PageTasks(tasksQuery, pageParameters); + getPageBase().setResponsePage(pageTasks); + } else { + getPageBase().setResponsePage(PageTasks.class); + } - ResourceTasksPanel tasksPanel = new ResourceTasksPanel(getPageBase().getMainPopupBodyId(), - new ListModel(tasks), getPageBase()); - getPageBase().showMainPopup(tasksPanel, target); + } + private String getTaskCollectionViewNameByArchetypeOid(String archetypeOid) { + if (StringUtils.isEmpty(archetypeOid)) { + return ""; + } + List taskCollectionViews = + getPageBase().getCompiledGuiProfile().findAllApplicableArchetypeViews(TaskType.COMPLEX_TYPE); + for (CompiledObjectCollectionView view : taskCollectionViews) { + if (archetypeOid.equals(view.getCollection().getCollectionRef().getOid())) { + return view.getViewIdentifier(); + } + } + return ""; } private List getTasksForKind(List> tasks) { @@ -1167,6 +1148,32 @@ private List getSelectedShadowsList(ShadowType shadow) { return selectedShadow; } + private ObjectQuery getExistingTasksQuery(String archetypeRefOid){ + return getPageBase().getPrismContext().queryFor(TaskType.class) + .item(AssignmentHolderType.F_ARCHETYPE_REF).ref(archetypeRefOid) + .build(); + } + + private QName getTaskObjectClass(){ + QName objectClass = getObjectClass(); + if (objectClass == null) { + LOGGER.trace("Trying to determine objectClass for kind: {}, intent: {}", getKind(), getIntent()); + RefinedObjectClassDefinition objectClassDef = null; + try { + objectClassDef = getDefinitionByKind(); + } catch (SchemaException e) { + LOGGER.error("Failed to search for objectClass definition. Reason: {}", e.getMessage(), e); + } + if (objectClassDef == null) { + LOGGER.warn("Cannot find any definition for kind: {}, intent: {}", getKind(), getIntent()); + return null; + } + + objectClass = objectClassDef.getTypeName(); + } + return objectClass; + } + protected abstract GetOperationOptionsBuilder addAdditionalOptions(GetOperationOptionsBuilder builder); protected abstract boolean isUseObjectCounting(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageNodes.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageNodes.java index 8d90f10c33b..e826d50367f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageNodes.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageNodes.java @@ -11,6 +11,7 @@ import com.evolveum.midpoint.gui.api.component.MainObjectListPanel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.security.api.AuthorizationConstants; @@ -27,8 +28,10 @@ import com.evolveum.midpoint.web.component.menu.cog.ButtonInlineMenuItem; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction; +import com.evolveum.midpoint.web.component.util.EnableBehaviour; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.component.util.SelectableBeanImpl; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.web.page.admin.PageAdmin; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -38,12 +41,14 @@ import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; 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.xml.datatype.XMLGregorianCalendar; import java.util.ArrayList; @@ -122,6 +127,34 @@ protected String translate(Enum en) { } }); + columns.add(new CheckBoxColumn>(createStringResource("pageTasks.node.actualNode")) { + private static final long serialVersionUID = 1L; + + @Override + protected IModel getEnabled(IModel> rowModel) { + return Model.of(Boolean.FALSE); + } + + @Override + protected IModel getCheckBoxValueModel(IModel> rowModel) { + return new IModel() { + + private static final long serialVersionUID = 1L; + + @Override + public Boolean getObject() { + if (getTaskManager().getNodeId() != null && rowModel != null + && rowModel.getObject() != null && rowModel.getObject().getValue() != null + && getTaskManager().getNodeId().equals(rowModel.getObject().getValue().getNodeIdentifier())) { + return Boolean.TRUE; + } + + return Boolean.FALSE; + } + }; + } + }); + columns.add(new AbstractColumn, String>(createStringResource("pageTasks.node.contact")) { @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java index c8233f16f99..6bcfacc066e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java @@ -1,21 +1,25 @@ package com.evolveum.midpoint.web.page.admin.server; +import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.prism.ItemWrapper; import com.evolveum.midpoint.gui.api.prism.PrismContainerWrapper; import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.impl.prism.ItemEditabilityHandler; import com.evolveum.midpoint.gui.impl.prism.ItemPanelSettingsBuilder; import com.evolveum.midpoint.gui.impl.prism.ItemVisibilityHandler; import com.evolveum.midpoint.model.api.ModelAuthorizationAction; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.AuthorizationConstants; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskCategory; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; @@ -33,6 +37,7 @@ import com.evolveum.midpoint.web.page.admin.server.dto.TaskDtoExecutionStatus; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.web.util.TaskOperationUtils; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationStatsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskRecurrenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; @@ -74,6 +79,8 @@ public class PageTask extends PageAdminObjectDetails implements Refres private static final long serialVersionUID = 1L; private static final transient Trace LOGGER = TraceManager.getTrace(PageTask.class); + private static final String DOT_CLASS = PageTask.class.getName() + "."; + protected static final String OPERATION_EXECUTE_TASK_CHANGES = DOT_CLASS + "executeTaskChanges"; private static final int REFRESH_INTERVAL_IF_RUNNING = 2000; private static final int REFRESH_INTERVAL_IF_RUNNABLE = 2000; @@ -139,7 +146,6 @@ private void afterOperation(AjaxRequestTarget target, OperationResult result) { showResult(result); getObjectModel().reset(); refresh(target); - target.add(PageTask.this); } @@ -205,8 +211,57 @@ public void onClick(AjaxRequestTarget target) { resumePauseRefreshing.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); repeatingView.add(resumePauseRefreshing); - setOutputMarkupId(true); + AjaxIconButton cleanupPerformance = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), + createStringResource("operationalButtonsPanel.cleanupEnvironmentalPerformance")) { + + @Override + public void onClick(AjaxRequestTarget target) { + try { + getObjectWrapper().findProperty(ItemPath.create(TaskType.F_OPERATION_STATS, + OperationStatsType.F_ENVIRONMENTAL_PERFORMANCE_INFORMATION)).getValue().setRealValue(null); + } catch (SchemaException e){ + LOGGER.error("Cannot clear task results: {}", e.getMessage()); + } + saveTaskChanges(); + refresh(target); + } + }; + cleanupPerformance.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); + cleanupPerformance.add(new VisibleBehaviour(this::isNotRunning)); + repeatingView.add(cleanupPerformance); + + AjaxIconButton cleanupResults = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), + createStringResource("operationalButtonsPanel.cleanupResults")) { + + @Override + public void onClick(AjaxRequestTarget target) { + try { + getObjectWrapper().findProperty(TaskType.F_RESULT).getValue().setRealValue(null); + getObjectWrapper().findProperty(TaskType.F_RESULT_STATUS).getValue().setRealValue(null); + } catch (SchemaException e){ + LOGGER.error("Cannot clear task results: {}", e.getMessage()); + } + saveTaskChanges(); + refresh(target); + } + }; + cleanupResults.add(new VisibleBehaviour(this::isNotRunning)); + cleanupResults.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); + repeatingView.add(cleanupResults); + +// AjaxIconButton cleanupErrors = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), +// createStringResource("operationalButtonsPanel.cleanupErrors")) { +// +// @Override +// public void onClick(AjaxRequestTarget target) { +// refresh(target); +// } +// }; +// cleanupErrors.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); +// cleanupErrors.add(new VisibleBehaviour(this::isNotRunning)); +// repeatingView.add(cleanupErrors); + setOutputMarkupId(true); final Label status = new Label(repeatingView.newChildId(), () -> createRefreshingLabel()); status.setOutputMarkupId(true); @@ -214,6 +269,22 @@ public void onClick(AjaxRequestTarget target) { } + private void saveTaskChanges(){ + OperationResult result = new OperationResult(OPERATION_EXECUTE_TASK_CHANGES); + Task task = createSimpleTask(OPERATION_EXECUTE_TASK_CHANGES); + try { + ObjectDelta taskDelta = getObjectWrapper().getObjectDelta(); + if (!taskDelta.isEmpty()) { + taskDelta.revive(getPrismContext()); + getModelService().executeChanges(WebComponentUtil.createDeltaCollection(taskDelta), null, task, result); + result.computeStatus(); + getObjectModel().reset(); + } + } catch (Exception e) { + LOGGER.error("Cannot save tasks changes: {}", e.getMessage()); + } + showResult(result); + } private String createRefreshingLabel() { if (isRefreshEnabled()) { @@ -234,7 +305,7 @@ private boolean canSuspend() { PrismObject task = getObjectWrapper().getObject(); TaskType taskType = task.asObjectable(); return isAuthorized(ModelAuthorizationAction.SUSPEND_TASK, task) - && isRunnable(taskType) || isRunning(taskType) + && isRunnable(taskType) || isRunning() && !isWorkflow(task.asObjectable()); } @@ -259,8 +330,14 @@ private boolean isRunnable(TaskType task) { return TaskExecutionStatusType.RUNNABLE == task.getExecutionStatus(); } - private boolean isRunning(TaskType task) { - return task.getNodeAsObserved() != null; + private boolean isRunning() { + PrismObject task = getObjectWrapper().getObject(); + TaskType taskType = task.asObjectable(); + return taskType.getNodeAsObserved() != null; + } + + private boolean isNotRunning(){ + return !isRunning(); } private boolean isSuspended(TaskType task) { @@ -279,6 +356,9 @@ private boolean isWorkflow(TaskType task) { return TaskCategory.WORKFLOW.equals(task.getCategory()); } + private TaskType getTask(){ + return getObjectWrapper().getObject().asObjectable(); + } private IModel createSummaryPanelModel() { return isEditingFocus() ? @@ -453,9 +533,7 @@ private ItemVisibility getBasicTabVisibility(ItemPath path) { } private ItemEditabilityHandler getTaskEditabilityHandler(){ - PrismObject task = getObjectWrapper().getObject(); - TaskType taskType = task.asObjectable(); - ItemEditabilityHandler editableHandler = wrapper -> !isRunning(taskType); + ItemEditabilityHandler editableHandler = wrapper -> !isRunning(); return editableHandler; } @@ -486,6 +564,7 @@ protected void onPostProcessTarget(AjaxRequestTarget target) { @Override protected boolean shouldTrigger() { + PageTask.this.getObjectModel().reset(); return isRefreshEnabled(); } }; @@ -520,6 +599,8 @@ public void refresh(AjaxRequestTarget target) { // getObjectModel().reset(); target.add(getSummaryPanel()); target.add(getOperationalButtonsPanel()); + target.add(getFeedbackPanel()); + target.add(getMainPanel()); for (Component component : getMainPanel().getTabbedPanel()) { if (component instanceof TaskTabPanel) { @@ -534,7 +615,7 @@ public void refresh(AjaxRequestTarget target) { public boolean isRefreshEnabled() { if (refreshEnabled == null) { - return isRunning(getObjectWrapper().getObject().asObjectable()); + return isRunning(); } return refreshEnabled; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java index 72514637255..1ff15955a20 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java @@ -9,6 +9,7 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -37,6 +38,7 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.string.StringValue; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; @@ -57,6 +59,7 @@ label = "PageTasks.auth.tasks.label", description = "PageTasks.auth.tasks.description")}) public class PageTasks extends PageAdmin { + private static final long serialVersionUID = 1L; private static final String ID_TABLE = "table"; @@ -73,15 +76,23 @@ public PageTasks() { } public PageTasks(PageParameters params) { + this(null, params); + } + + public PageTasks(ObjectQuery predefinedQuery, PageParameters params) { super(params); TaskTablePanel tablePanel = new TaskTablePanel(ID_TABLE, UserProfileStorage.TableId.TABLE_TASKS, createOperationOptions()) { + private static final long serialVersionUID = 1L; @Override protected ObjectQuery addFilterToContentQuery(ObjectQuery query) { if (query == null) { query = getPrismContext().queryFactory().createQuery(); } + if (predefinedQuery != null){ + query.addFilter(predefinedQuery.getFilter()); + } query.addFilter(getPrismContext().queryFor(TaskType.class) .item(TaskType.F_PARENT) .isNull() @@ -101,6 +112,7 @@ protected List, String>> createColumns() { private Collection, String>> addCustomColumns(List, String>> columns) { columns.add(2, new ObjectReferenceColumn>(createStringResource("pageTasks.task.objectRef"), SelectableBeanImpl.F_VALUE+"."+TaskType.F_OBJECT_REF.getLocalPart()){ + private static final long serialVersionUID = 1L; @Override public IModel extractDataModel(IModel> rowModel) { SelectableBean bean = rowModel.getObject(); @@ -110,12 +122,14 @@ public IModel extractDataModel(IModel(createStringResource("pageTasks.task.executingAt"), SelectableBeanImpl.F_VALUE + "." + TaskType.F_NODE_AS_OBSERVED.getLocalPart())); columns.add(4, new AbstractExportableColumn, String>(createStringResource("pageTasks.task.currentRunTime"), TaskType.F_COMPLETION_TIMESTAMP.getLocalPart()) { + private static final long serialVersionUID = 1L; @Override public void populateItem(final Item>> item, final String componentId, final IModel> rowModel) { DateLabelComponent dateLabel = new DateLabelComponent(componentId, new IModel() { + private static final long serialVersionUID = 1L; @Override public Date getObject() { @@ -151,6 +165,7 @@ public IModel getDataModel(IModel> rowModel) { } }); columns.add(5, new AbstractExportableColumn, String>(createStringResource("pageTasks.task.scheduledToRunAgain")) { + private static final long serialVersionUID = 1L; @Override public void populateItem(Item>> item, String componentId, @@ -166,7 +181,6 @@ public IModel getDataModel(IModel> rowModel) { return columns; } - private Collection> createOperationOptions() { List propertiesToGet = new ArrayList<>(); propertiesToGet.add(TaskType.F_NODE_AS_OBSERVED); diff --git a/gui/admin-gui/src/main/resources/initial-objects/000-system-configuration.xml b/gui/admin-gui/src/main/resources/initial-objects/000-system-configuration.xml index 2a8c296e65d..16abb199a58 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/000-system-configuration.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/000-system-configuration.xml @@ -350,6 +350,38 @@ + + certification-tasks-view + 30 + TaskType + + + + + + approval-tasks-view + 30 + TaskType + + + + + + utility-tasks-view + 30 + TaskType + + + + + + system-tasks-view + 30 + TaskType + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/503-archetype-task-import.xml b/gui/admin-gui/src/main/resources/initial-objects/503-archetype-task-import.xml index 544b973ba8c..7d09626fd10 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/503-archetype-task-import.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/503-archetype-task-import.xml @@ -14,7 +14,7 @@ Import tasks - fa fa-cogs + fa fa-upload green diff --git a/gui/admin-gui/src/main/resources/initial-objects/504-archetype-task-live-sync.xml b/gui/admin-gui/src/main/resources/initial-objects/504-archetype-task-live-sync.xml index 05f030f00a0..3af293f332e 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/504-archetype-task-live-sync.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/504-archetype-task-live-sync.xml @@ -15,7 +15,7 @@ Live synchronization tasks - fa fa-cogs + fa fa-refresh green diff --git a/gui/admin-gui/src/main/resources/initial-objects/505-archetype-task-async-update.xml b/gui/admin-gui/src/main/resources/initial-objects/505-archetype-task-async-update.xml index a49e39a6f58..1e3d9854b1d 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/505-archetype-task-async-update.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/505-archetype-task-async-update.xml @@ -14,7 +14,7 @@ Asynchronous update tasks - fa fa-cogs + fa fa-bolt green diff --git a/gui/admin-gui/src/main/resources/initial-objects/507-archetype-task-report.xml b/gui/admin-gui/src/main/resources/initial-objects/507-archetype-task-report.xml index ab8e358d621..b9ea97d0e7b 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/507-archetype-task-report.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/507-archetype-task-report.xml @@ -45,20 +45,7 @@ weak - http://midpoint.evolveum.com/xml/ns/public/model/cleanup/handler-3 - - - handlerUri - - - - - - - - weak - - Cleanup + Report category diff --git a/gui/admin-gui/src/main/resources/initial-objects/521-archetype-task-approval.xml b/gui/admin-gui/src/main/resources/initial-objects/521-archetype-task-approval.xml index 8dfc8371249..20024c3a8de 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/521-archetype-task-approval.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/521-archetype-task-approval.xml @@ -4,7 +4,7 @@ ~ This work is dual-licensed under the Apache License 2.0 ~ and European Union Public License. See LICENSE file for details. --> - Approval-related task @@ -13,7 +13,7 @@ Approval-related tasks - fa fe-case-object + fe fe-case-object green @@ -24,6 +24,19 @@ TaskType + + + + weak + + http://midpoint.evolveum.com/xml/ns/public/workflow/operation-execution/handler-3 + + + handlerUri + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-util.xml b/gui/admin-gui/src/main/resources/initial-objects/528-archetype-task-util.xml similarity index 91% rename from gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-util.xml rename to gui/admin-gui/src/main/resources/initial-objects/528-archetype-task-util.xml index 9a86d40b1df..ce01c8df650 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-util.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/528-archetype-task-util.xml @@ -4,7 +4,7 @@ ~ This work is dual-licensed under the Apache License 2.0 ~ and European Union Public License. See LICENSE file for details. --> - Utility task @@ -13,7 +13,7 @@ Utility tasks - fa fa-people-carry + fa fa-wrench green diff --git a/gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-system.xml b/gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-system.xml new file mode 100644 index 00000000000..f423ba952c7 --- /dev/null +++ b/gui/admin-gui/src/main/resources/initial-objects/529-archetype-task-system.xml @@ -0,0 +1,40 @@ + + + System task + + + + System tasks + + fa fa-save + green + + + + + + + TaskType + + + + + + weak + + System + + + category + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/550-task-cleanup.xml b/gui/admin-gui/src/main/resources/initial-objects/550-task-cleanup.xml index 408b275e4f4..4a6c622c225 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/550-task-cleanup.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/550-task-cleanup.xml @@ -10,10 +10,13 @@ Cleanup A system task that repeatedly checks for outdated objects (e.g. closed tasks, old audit records) and removes them. + + + runnable - System + Cleanup http://midpoint.evolveum.com/xml/ns/public/model/cleanup/handler-3 recurring loose diff --git a/gui/admin-gui/src/main/resources/initial-objects/560-task-validity.xml b/gui/admin-gui/src/main/resources/initial-objects/560-task-validity.xml index 1228e97abef..cd387ed6176 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/560-task-validity.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/560-task-validity.xml @@ -13,6 +13,10 @@ runnable + + + + System http://midpoint.evolveum.com/xml/ns/public/model/focus-validity-scanner/handler-3 recurring diff --git a/gui/admin-gui/src/main/resources/initial-objects/570-task-trigger.xml b/gui/admin-gui/src/main/resources/initial-objects/570-task-trigger.xml index e84b633ba36..d874a27dbe6 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/570-task-trigger.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/570-task-trigger.xml @@ -13,6 +13,10 @@ runnable + + + + System http://midpoint.evolveum.com/xml/ns/public/model/trigger/scanner/handler-3 recurring diff --git a/gui/admin-gui/src/main/resources/static/less/admin-lte/less/dropdown.less b/gui/admin-gui/src/main/resources/static/less/admin-lte/less/dropdown.less index 7ac1db48b4d..6ce3c7ff657 100644 --- a/gui/admin-gui/src/main/resources/static/less/admin-lte/less/dropdown.less +++ b/gui/admin-gui/src/main/resources/static/less/admin-lte/less/dropdown.less @@ -26,9 +26,26 @@ .auto-width { white-space: nowrap; + max-width: 20vw; + width: max-content; > li { + padding-left: 10px; + padding-right: 10px; display: inline-block; + + .btn:first-child { + margin-left: -1px; + } + + .btn:last-child { + margin-right: -1px; + } + + .btn { + float: left; + margin-bottom: -1px; + } } } @@ -357,3 +374,21 @@ } } } + +@media (min-width: @screen-sm-max) and (max-width: @screen-md-max) { + .auto-width { + max-width: 30vw; + } +} + +@media (min-width: @screen-xs-max) and (max-width: @screen-sm-max) { + .auto-width { + max-width: 30vw; + } +} + +@media (max-width: @screen-xs-max) { + .auto-width { + max-width: 50vw; + } +} diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationSecurity.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationSecurity.java index 596395b8ee8..a9a65824752 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationSecurity.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationSecurity.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; +import com.evolveum.midpoint.test.TestResource; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import org.springframework.beans.factory.annotation.Autowired; @@ -52,16 +53,19 @@ @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class TestIntegrationSecurity extends AbstractInitializedGuiIntegrationTest { - public static final File TEST_DIR = new File("src/test/resources/security"); + private static final File TEST_DIR = new File("src/test/resources/security"); - protected static final File ROLE_UI_ALLOW_ALL_FILE = new File(TEST_DIR, "role-ui-allow-all.xml"); - protected static final String ROLE_UI_ALLOW_ALL_OID = "d8f78cfe-d05d-11e7-8ee6-038ce21862f3"; + private static final File ROLE_UI_ALLOW_ALL_FILE = new File(TEST_DIR, "role-ui-allow-all.xml"); + private static final String ROLE_UI_ALLOW_ALL_OID = "d8f78cfe-d05d-11e7-8ee6-038ce21862f3"; - protected static final File ROLE_UI_DENY_ALL_FILE = new File(TEST_DIR, "role-ui-deny-all.xml"); - protected static final String ROLE_UI_DENY_ALL_OID = "c4a5923c-d02b-11e7-9ac5-13b0d906fa81"; + private static final File ROLE_UI_DENY_ALL_FILE = new File(TEST_DIR, "role-ui-deny-all.xml"); + private static final String ROLE_UI_DENY_ALL_OID = "c4a5923c-d02b-11e7-9ac5-13b0d906fa81"; - protected static final File ROLE_UI_DENY_ALLOW_FILE = new File(TEST_DIR, "role-ui-deny-allow.xml"); - protected static final String ROLE_UI_DENY_ALLOW_OID = "da47fcf6-d02b-11e7-9e78-f31ae9aa0674"; + private static final File ROLE_UI_DENY_ALLOW_FILE = new File(TEST_DIR, "role-ui-deny-allow.xml"); + private static final String ROLE_UI_DENY_ALLOW_OID = "da47fcf6-d02b-11e7-9e78-f31ae9aa0674"; + + private static final TestResource ROLE_AUTHORIZATION_1 = new TestResource(TEST_DIR, "role-authorization-1.xml", "97984277-e809-4a86-ae9b-d5c40e09df0b"); + private static final TestResource ROLE_AUTHORIZATION_2 = new TestResource(TEST_DIR, "role-authorization-2.xml", "96b02d58-5147-4f5a-852c-0f415230ce2c"); private static final Trace LOGGER = TraceManager.getTrace(TestIntegrationSecurity.class); @@ -78,12 +82,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti repoAddObjectFromFile(ROLE_UI_ALLOW_ALL_FILE, initResult); repoAddObjectFromFile(ROLE_UI_DENY_ALL_FILE, initResult); repoAddObjectFromFile(ROLE_UI_DENY_ALLOW_FILE, initResult); - - // Temporary ... until initial object load is fixed -// ch.qos.logback.classic.Logger l = (ch.qos.logback.classic.Logger)org.slf4j.LoggerFactory.getLogger("com.evolveum.midpoint.web"); -// l.setLevel(ch.qos.logback.classic.Level.TRACE); -// l = (ch.qos.logback.classic.Logger)org.slf4j.LoggerFactory.getLogger("com.evolveum.midpoint.test"); -// l.setLevel(ch.qos.logback.classic.Level.TRACE); + repoAdd(ROLE_AUTHORIZATION_1, initResult); + repoAdd(ROLE_AUTHORIZATION_2, initResult); } @@ -205,6 +205,29 @@ public void test200DecideRoleUiDenyAllow() throws Exception { } + /** + * MID-5002 + */ + @Test + public void test300ConflictingAuthorizationIds() throws Exception { + final String TEST_NAME = "test300ConflictingAuthorizationIds"; + displayTestTitle(TEST_NAME); + // GIVEN + cleanupAutzTest(USER_JACK_OID); + assignRole(USER_JACK_OID, ROLE_AUTHORIZATION_1.oid); + assignRole(USER_JACK_OID, ROLE_AUTHORIZATION_2.oid); + PrismObject user = getUser(USER_JACK_OID); + display("user before", user); + + // WHEN + displayWhen(TEST_NAME); + login(USER_JACK_USERNAME); + + // THEN + displayThen(TEST_NAME); + assertLoggedInUsername(USER_JACK_USERNAME); + } + private void assertAllow(Authentication authentication, String path) { try { LOGGER.debug("*** Attempt to DECIDE {} (expected allow)", path); diff --git a/gui/admin-gui/src/test/resources/security/role-authorization-1.xml b/gui/admin-gui/src/test/resources/security/role-authorization-1.xml new file mode 100644 index 00000000000..de44ca0b8dc --- /dev/null +++ b/gui/admin-gui/src/test/resources/security/role-authorization-1.xml @@ -0,0 +1,14 @@ + + + + + UI Authorization 1 + + http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#read + + diff --git a/gui/admin-gui/src/test/resources/security/role-authorization-2.xml b/gui/admin-gui/src/test/resources/security/role-authorization-2.xml new file mode 100644 index 00000000000..2438e378967 --- /dev/null +++ b/gui/admin-gui/src/test/resources/security/role-authorization-2.xml @@ -0,0 +1,14 @@ + + + + + UI Authorization 2 + + http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modify + + diff --git a/infra/prism-impl/pom.xml b/infra/prism-impl/pom.xml index d9f2ca04839..2250f23165e 100644 --- a/infra/prism-impl/pom.xml +++ b/infra/prism-impl/pom.xml @@ -46,7 +46,6 @@ com.sun.xml.bind jaxb-xjc - org.apache.cxf @@ -148,5 +147,10 @@ test-ng test + + org.assertj + assertj-core + test + diff --git a/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/PerfRecorder.java b/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/PerfRecorder.java index 07bac06e321..995d95e4e11 100644 --- a/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/PerfRecorder.java +++ b/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/PerfRecorder.java @@ -6,11 +6,10 @@ */ package com.evolveum.midpoint.prism; -import org.testng.AssertJUnit; +import static org.assertj.core.api.Assertions.assertThat; /** * @author semancik - * */ public class PerfRecorder { @@ -18,16 +17,16 @@ public class PerfRecorder { private int count = 0; private Double min = null; private Double max = null; - private Double sum = 0D; + private double sum = 0d; public PerfRecorder(String name) { super(); this.name = name; } - public void record(int index, Double value) { + public void record(int index, double value) { sum += value; - count ++; + count++; if (min == null || value < min) { min = value; } @@ -53,20 +52,25 @@ public Double getSum() { } public double getAverage() { - return sum/count; + return sum / count; } public void assertAverageBelow(double expected) { - AssertJUnit.assertTrue(name+ ": Expected average below "+expected+" but was "+getAverage(), getAverage() < expected); + assertThat(getAverage()) + .as("average for %s", name) + .isLessThan(expected); + // remove in 2022 if everybody's happy: original without AssertJ +// AssertJUnit.assertTrue(name + ": Expected average below " + expected + " but was " + getAverage(), getAverage() < expected); } public void assertMaxBelow(double expected) { - AssertJUnit.assertTrue(name+ ": Expected maximum below "+expected+" but was "+max, max < expected); + assertThat(max) + .as("maximum for %s", name) + .isLessThan(expected); } - public String dump() { - return name + ": min / avg / max = "+min+" / "+getAverage()+" / "+max + " (sum="+sum+", count="+count+")"; + return name + ": min / avg / max = " + min + " / " + getAverage() + " / " + max + + " (sum=" + sum + ", count=" + count + ")"; } - } diff --git a/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/TestPerformance.java b/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/TestPerformance.java index 6306791170e..4c649b8941d 100644 --- a/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/TestPerformance.java +++ b/infra/prism-impl/src/test/java/com/evolveum/midpoint/prism/TestPerformance.java @@ -6,6 +6,8 @@ */ package com.evolveum.midpoint.prism; +import static org.assertj.core.api.Assertions.assertThat; + import static com.evolveum.midpoint.prism.PrismInternalTestUtil.*; import javax.xml.namespace.QName; @@ -19,12 +21,12 @@ /** * @author semancik - * */ public class TestPerformance { - private static final int ITERATIONS = 10000; + private static final int ITERATIONS = 10_000; + private static final double NANOS_TO_MILLIS_DOUBLE = 1_000_000d; @BeforeSuite public void setupDebug() { @@ -42,7 +44,7 @@ public void testPerfContainerNewValue() throws Exception { // GIVEN PrismContext ctx = constructInitializedPrismContext(); - PrismObjectDefinition userDefinition = getFooSchema(ctx).findObjectDefinitionByElementName(new QName(NS_FOO,"user")); + PrismObjectDefinition userDefinition = getFooSchema(ctx).findObjectDefinitionByElementName(new QName(NS_FOO, "user")); PrismObject user = userDefinition.instantiate(); PrismContainer assignmentContainer = user.findOrCreateContainer(UserType.F_ASSIGNMENT); PerfRecorder recorderCreateNewValue = new PerfRecorder("createNewValue"); @@ -50,7 +52,7 @@ public void testPerfContainerNewValue() throws Exception { PerfRecorder recorderSetRealValue = new PerfRecorder("setRealValue"); // WHEN - for (int i=0; i < ITERATIONS; i++) { + for (int i = 0; i < ITERATIONS; i++) { long tsStart = System.nanoTime(); PrismContainerValue newValue = assignmentContainer.createNewValue(); @@ -61,15 +63,15 @@ public void testPerfContainerNewValue() throws Exception { long ts2 = System.nanoTime(); - descriptionProperty.setRealValue("ass "+i); + descriptionProperty.setRealValue("ass " + i); long tsEnd = System.nanoTime(); - recorderCreateNewValue.record(i, ((double)(ts1 - tsStart))/1000000); - recorderFindOrCreateProperty.record(i, ((double)(ts2 - ts1))/1000000); - recorderSetRealValue.record(i, ((double)(tsEnd - ts2))/1000000); + recorderCreateNewValue.record(i, (ts1 - tsStart) / NANOS_TO_MILLIS_DOUBLE); + recorderFindOrCreateProperty.record(i, (ts2 - ts1) / NANOS_TO_MILLIS_DOUBLE); + recorderSetRealValue.record(i, (tsEnd - ts2) / NANOS_TO_MILLIS_DOUBLE); - System.out.println("Run "+i+": total "+(((double)(tsEnd - tsStart))/1000000)+"ms"); + System.out.println("Run " + i + ": total " + ((tsEnd - tsStart) / NANOS_TO_MILLIS_DOUBLE) + "ms"); } // THEN @@ -79,14 +81,11 @@ public void testPerfContainerNewValue() throws Exception { // Do not assert maximum here. The maximum values may jump around // quite wildly (e.g. because of garbage collector runs?) - recorderCreateNewValue.assertAverageBelow(0.05D); - - recorderFindOrCreateProperty.assertAverageBelow(0.1D); + recorderCreateNewValue.assertAverageBelow(0.05d); + recorderFindOrCreateProperty.assertAverageBelow(0.1d); + recorderCreateNewValue.assertAverageBelow(0.05d); - recorderCreateNewValue.assertAverageBelow(0.05D); - - System.out.println("User:"); - System.out.println(user.debugDump()); + assertThat(assignmentContainer.size()).isEqualTo(ITERATIONS); + // we skip the 20k-line dump, it's heavy on some (*cough*Windows) consoles and crashes JVM } - } 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 4562d755453..555cf1d4fae 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 @@ -21396,6 +21396,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -24172,32 +24193,33 @@ 3.7 - - - - - AbstractObjectTypeConfigurationType.type - - - - - - -

- Definition of object with respect to subject relation to a role. - Used to specify role approvers, owners and so on. -

-

- EXPERIMENTAL. Use at your own risk. -

-
- - 3.9 - -
-
- -
+ + + + + AbstractObjectTypeConfigurationType.type + + + + + + +

+ Definition of object with respect to subject relation to a role. + Used to specify role approvers, owners and so on. +

+

+ EXPERIMENTAL. Use at your own risk. +

+
+ + 3.9 + +
+
+ +
+ 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 96d9e75d10d..51bdb410b38 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 @@ -82,6 +82,7 @@ + diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/MidpointFunctions.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/MidpointFunctions.java index a8e151a79c1..129d344a10f 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/MidpointFunctions.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/MidpointFunctions.java @@ -54,7 +54,7 @@ import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; /** - * @author mederly + * */ @SuppressWarnings("unused") public interface MidpointFunctions { @@ -888,6 +888,8 @@ int countObjects(Class type, ObjectQuery query) List toList(String... s); + long getSequenceCounter(String sequenceOid) throws ObjectNotFoundException, SchemaException; + Collection getManagersOids(UserType user) throws SchemaException, ObjectNotFoundException, SecurityViolationException; Collection getManagersOidsExceptUser(UserType user) throws SchemaException, ObjectNotFoundException, SecurityViolationException, ExpressionEvaluationException; @@ -937,15 +939,25 @@ Collection getManagersOidsExceptUser(@NotNull Collection getParentOrgs(ObjectType object, QName relation, String orgType) throws SchemaException, SecurityViolationException; /** - * Returns parent orgs of the specified object that have a specific orgType. + * Returns parent org of the specified object that have a specific orgType. * @param object base object * @param orgType orgType to select - * @return parent orgs of the specified object that have a specific orgType + * @return parent org of the specified object that have a specific orgType * @throws SchemaException Internal schema error * @throws SecurityViolationException Security violation */ OrgType getParentOrgByOrgType(ObjectType object, String orgType) throws SchemaException, SecurityViolationException; + /** + * Returns parent org of the specified object that have a specific archetype. + * @param object base object + * @param archetypeOid archetype OID to select (null means "any archetype") + * @return parent org of the specified object that have a specific archetype + * @throws SchemaException Internal schema error + * @throws SecurityViolationException Security violation + */ + OrgType getParentOrgByArchetype(ObjectType object, String archetypeOid) throws SchemaException, SecurityViolationException; + /** * Returns parent orgs of the specified object that have a specific relation. * @param object base object @@ -1009,6 +1021,10 @@ Collection getManagersOidsExceptUser(@NotNull Collection lensContext) throws SchemaException; + + boolean hasLinkedAccount(String resourceOid); + boolean isDirectlyAssigned(F focusType, String targetOid); boolean isDirectlyAssigned(String targetOid); @@ -1118,6 +1134,31 @@ TaskType executeChangesAsynchronously(Collection> deltas, ModelEx String translate(LocalizableMessageType message); + Integer countAccounts(String resourceOid, QName attributeName, T attributeValue) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + + Integer countAccounts(ResourceType resourceType, QName attributeName, T attributeValue) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + + Integer countAccounts(ResourceType resourceType, String attributeName, T attributeValue) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + + boolean isUniquePropertyValue(ObjectType objectType, String propertyPathString, T propertyValue) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + + List getObjectsInConflictOnPropertyValue(O objectType, String propertyPathString, + T propertyValue, boolean getAllConflicting) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + + boolean isUniqueAccountValue(ResourceType resourceType, ShadowType shadowType, String attributeName, + T attributeValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException; + ModelContext getModelContext(); ModelElementContext getFocusContext(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/OrgStructFunctions.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/OrgStructFunctions.java index c470acd25f1..97400b22e55 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/OrgStructFunctions.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/expr/OrgStructFunctions.java @@ -16,9 +16,10 @@ import javax.xml.namespace.QName; import java.util.Collection; +import java.util.function.Predicate; /** - * @author mederly + * */ public interface OrgStructFunctions { @@ -48,6 +49,8 @@ Collection getManagersOidsExceptUser(@NotNull Collection getParentOrgsByRelation(ObjectType object, QName relation, boolean preAuthorized) throws SchemaException, SecurityViolationException; Collection getParentOrgsByRelation(ObjectType object, String relation, boolean preAuthorized) throws SchemaException, SecurityViolationException; @@ -58,6 +61,9 @@ Collection getManagersOidsExceptUser(@NotNull Collection getParentOrgs(ObjectType object, QName relation, String orgType, boolean preAuthorized) throws SchemaException, SecurityViolationException; + Collection getParentOrgs(ObjectType object, QName relation, @NotNull Predicate predicate, boolean preAuthorized) + throws SchemaException, SecurityViolationException; + Collection getManagersOfOrg(String orgOid, boolean preAuthorized) throws SchemaException, SecurityViolationException; boolean isManagerOf(UserType user, String orgOid, boolean preAuthorized); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ClusterRestService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ClusterRestService.java index 82c13b51dbc..73589331a91 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ClusterRestService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ClusterRestService.java @@ -9,7 +9,6 @@ import com.evolveum.midpoint.CacheInvalidationContext; import com.evolveum.midpoint.TerminateSessionEvent; import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; -import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipalManager; import com.evolveum.midpoint.model.impl.security.NodeAuthenticationToken; import com.evolveum.midpoint.model.impl.security.SecurityHelper; @@ -43,6 +42,7 @@ import javax.ws.rs.core.StreamingOutput; import java.io.File; import java.io.FileInputStream; +import java.nio.file.Paths; import java.util.List; /** @@ -83,8 +83,6 @@ public class ClusterRestService { @Autowired private CacheDispatcher cacheDispatcher; - @Autowired private ModelInteractionService modelInteractionService; - private static final Trace LOGGER = TraceManager.getTrace(ClusterRestService.class); public ClusterRestService() { @@ -236,7 +234,6 @@ public Response startLocalScheduler(@Context MessageContext mc) { return response; } - @SuppressWarnings("RSReferenceInspection") @POST @Path(TaskConstants.STOP_LOCAL_TASK_REST_PATH_PREFIX + "{oid}" + TaskConstants.STOP_LOCAL_TASK_REST_PATH_SUFFIX) @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, RestServiceUtil.APPLICATION_YAML}) @@ -323,7 +320,7 @@ static class FileResolution { private FileResolution resolveFile(String fileName) { FileResolution rv = new FileResolution(); - rv.file = new File(midpointConfiguration.getMidpointHome() + EXPORT_DIR + fileName); + rv.file = Paths.get(midpointConfiguration.getMidpointHome(), EXPORT_DIR, fileName).toFile(); if (forbiddenFileName(fileName)) { LOGGER.warn("File name '{}' is forbidden", fileName); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ExtensionSchemaRestService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ExtensionSchemaRestService.java index fdbb6d2b27b..307e70178be 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ExtensionSchemaRestService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ExtensionSchemaRestService.java @@ -21,6 +21,7 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; + import org.apache.commons.lang3.StringUtils; import org.apache.cxf.jaxrs.ext.MessageContext; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +32,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -100,10 +102,8 @@ private String computeName(SchemaDescription description) { } String midpointHome = System.getProperty(MidpointConfiguration.MIDPOINT_HOME_PROPERTY); - File home = new File(midpointHome, "/schema"); - java.nio.file.Path homePath = home.toPath(); - java.nio.file.Path filePath = file.toPath(); - java.nio.file.Path relative = homePath.relativize(filePath); + java.nio.file.Path homePath = Paths.get(midpointHome, "schema"); + java.nio.file.Path relative = homePath.relativize(file.toPath()); return relative.toString(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/cleanup/ShadowRefreshTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/cleanup/ShadowRefreshTaskHandler.java index 74af4458ae8..6d165f2220f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/cleanup/ShadowRefreshTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/cleanup/ShadowRefreshTaskHandler.java @@ -65,17 +65,16 @@ protected Class getType(Task task) { } @Override - protected boolean requiresDirectRepositoryAccess(AbstractScannerResultHandler resultHandler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { + protected boolean requiresDirectRepositoryAccess(AbstractScannerResultHandler resultHandler, + TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { return true; } @Override - protected ObjectQuery createQuery(AbstractScannerResultHandler handler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) throws SchemaException { - ObjectQuery query = super.createQuery(handler, runResult, coordinatorTask, opResult); + protected ObjectQuery createQuery(AbstractScannerResultHandler handler, TaskRunResult runResult, + Task coordinatorTask, OperationResult opResult) throws SchemaException { + ObjectQuery query = createQueryFromTask(handler, runResult, coordinatorTask, opResult); - if (query == null) { - query = getPrismContext().queryFactory().createQuery(); - } if (query.getFilter() == null) { ObjectFilter filter = prismContext.queryFor(ShadowType.class) .exists(ShadowType.F_PENDING_OPERATION) @@ -86,12 +85,6 @@ protected ObjectQuery createQuery(AbstractScannerResultHandler handl return query; } - @Override - protected void finish(AbstractScannerResultHandler handler, TaskRunResult runResult, RunningTask task, OperationResult opResult) - throws SchemaException { - super.finish(handler, runResult, task, opResult); - } - @Override protected AbstractScannerResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, final RunningTask coordinatorTask, OperationResult opResult) { @@ -111,5 +104,4 @@ protected boolean handleObject(PrismObject object, RunningTask worke handler.setStopOnError(false); return handler; } - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java index c7cfc637ca0..a6b522be59b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java @@ -83,8 +83,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Context; @@ -236,6 +234,7 @@ private void takePasswordsFromItemDelta(List passwords, Ite if (itemDelta.getPath().equivalent(PATH_CREDENTIALS_PASSWORD_VALUE)) { LOGGER.trace("Found password value add/modify delta"); + //noinspection unchecked Collection> values = itemDelta.isAdd() ? itemDelta.getValuesToAdd() : itemDelta.getValuesToReplace(); @@ -244,6 +243,7 @@ private void takePasswordsFromItemDelta(List passwords, Ite } } else if (itemDelta.getPath().equivalent(PATH_CREDENTIALS_PASSWORD)) { LOGGER.trace("Found password add/modify delta"); + //noinspection unchecked Collection> values = itemDelta.isAdd() ? itemDelta.getValuesToAdd() : itemDelta.getValuesToReplace(); @@ -254,6 +254,7 @@ private void takePasswordsFromItemDelta(List passwords, Ite } } else if (itemDelta.getPath().equivalent(ShadowType.F_CREDENTIALS)) { LOGGER.trace("Found credentials add/modify delta"); + //noinspection unchecked Collection> values = itemDelta.isAdd() ? itemDelta.getValuesToAdd() : itemDelta.getValuesToReplace(); @@ -293,6 +294,7 @@ public String getPlaintextUserPasswordFromDeltas(List> obj } } + @Override public boolean hasLinkedAccount(String resourceOid) { LensContext ctx = ModelExpressionThreadLocalHolder.getLensContext(); if (ctx == null) { @@ -415,6 +417,7 @@ public boolean isDirectlyAssigned(ObjectType target) { } // EXPERIMENTAL!! + @SuppressWarnings("unused") @Experimental public boolean hasActiveAssignmentTargetSubtype(String roleSubtype) { LensContext lensContext = ModelExpressionThreadLocalHolder.getLensContext(); @@ -426,14 +429,12 @@ public boolean hasActiveAssignmentTargetSubtype(String roleSubtype) { throw new UnsupportedOperationException("hasActiveAssignmentRoleSubtype works only with evaluatedAssignmentTriple"); } Collection> nonNegativeEvaluatedAssignments = evaluatedAssignmentTriple.getNonNegativeValues(); - if (nonNegativeEvaluatedAssignments == null) { - return false; - } for (EvaluatedAssignmentImpl nonNegativeEvaluatedAssignment : nonNegativeEvaluatedAssignments) { PrismObject target = nonNegativeEvaluatedAssignment.getTarget(); if (target == null) { continue; } + //noinspection unchecked Collection targetSubtypes = FocusTypeUtil.determineSubTypes((PrismObject) target); if (targetSubtypes.contains(roleSubtype)) { return true; @@ -564,6 +565,7 @@ public boolean isProjectionExists() { return projectionContext.isExists(); } + @Override public Integer countAccounts(String resourceOid, QName attributeName, T attributeValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -572,6 +574,7 @@ public Integer countAccounts(String resourceOid, QName attributeName, T attr return countAccounts(resourceType, attributeName, attributeValue, getCurrentTask(), result); } + @Override public Integer countAccounts(ResourceType resourceType, QName attributeName, T attributeValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -579,6 +582,7 @@ public Integer countAccounts(ResourceType resourceType, QName attributeName, return countAccounts(resourceType, attributeName, attributeValue, getCurrentTask(), result); } + @Override public Integer countAccounts(ResourceType resourceType, String attributeName, T attributeValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -591,17 +595,11 @@ private Integer countAccounts(ResourceType resourceType, QName attributeName OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { - RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); - RefinedObjectClassDefinition rAccountDef = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); - RefinedAttributeDefinition attrDef = rAccountDef.findAttributeDefinition(attributeName); - ObjectQuery query = prismContext.queryFor(ShadowType.class) - .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getItemName()).eq(attributeValue) - .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccountDef.getObjectClassDefinition().getTypeName()) - .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) - .build(); + ObjectQuery query = createAttributeQuery(resourceType, attributeName, attributeValue); return modelObjectResolver.countObjects(ShadowType.class, query, null, task, result); } + @Override public boolean isUniquePropertyValue(ObjectType objectType, String propertyPathString, T propertyValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -620,6 +618,7 @@ private boolean isUniquePropertyValue(final ObjectType objectType, ItemPath return conflictingObjects.isEmpty(); } + @Override public List getObjectsInConflictOnPropertyValue(O objectType, String propertyPathString, T propertyValue, boolean getAllConflicting) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, @@ -664,31 +663,30 @@ private List getObjectsInConflictOnPropertyValue(fi } final List conflictingObjects = new ArrayList<>(); - ResultHandler handler = new ResultHandler() { - @Override - public boolean handle(PrismObject object, OperationResult parentResult) { - if (objectType.getOid() == null) { - // We have found a conflicting object + ResultHandler handler = (object, parentResult) -> { + if (objectType.getOid() == null) { + // We have found a conflicting object + conflictingObjects.add(object.asObjectable()); + return getAllConflicting; + } else { + if (objectType.getOid().equals(object.getOid())) { + // We have found ourselves. No conflict (yet). Just go on. + return true; + } else { + // We have found someone else. Conflict. conflictingObjects.add(object.asObjectable()); return getAllConflicting; - } else { - if (objectType.getOid().equals(object.getOid())) { - // We have found ourselves. No conflict (yet). Just go on. - return true; - } else { - // We have found someone else. Conflict. - conflictingObjects.add(object.asObjectable()); - return getAllConflicting; - } } } }; + //noinspection unchecked modelObjectResolver.searchIterative((Class) objectType.getClass(), query, null, handler, task, result); return conflictingObjects; } + @Override public boolean isUniqueAccountValue(ResourceType resourceType, ShadowType shadowType, String attributeName, T attributeValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -706,35 +704,24 @@ private boolean isUniqueAccountValue(ResourceType resourceType, final Shadow Validate.notNull(shadowType, "Null shadow"); Validate.notNull(attributeName, "Null attribute name"); Validate.notNull(attributeValue, "Null attribute value"); - RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); - RefinedObjectClassDefinition rAccountDef = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); - RefinedAttributeDefinition attrDef = rAccountDef.findAttributeDefinition(attributeName); - ObjectQuery query = prismContext.queryFor(ShadowType.class) - .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getItemName()).eq(attributeValue) - .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccountDef.getObjectClassDefinition().getTypeName()) - .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) - .build(); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Determining uniqueness of attribute {} using query:\n{}", attributeName, query.debugDump()); - } + + ObjectQuery query = createAttributeQuery(resourceType, attributeName, attributeValue); + LOGGER.trace("Determining uniqueness of attribute {} using query:\n{}", attributeName, query.debugDumpLazily()); final Holder isUniqueHolder = new Holder<>(true); - ResultHandler handler = new ResultHandler() { - @Override - public boolean handle(PrismObject object, OperationResult parentResult) { - if (shadowType == null || shadowType.getOid() == null) { - // We have found a conflicting object + ResultHandler handler = (object, parentResult) -> { + if (shadowType.getOid() == null) { + // We have found a conflicting object + isUniqueHolder.setValue(false); + return false; + } else { + if (shadowType.getOid().equals(object.getOid())) { + // We have found ourselves. No conflict (yet). Just go on. + return true; + } else { + // We have found someone else. Conflict. isUniqueHolder.setValue(false); return false; - } else { - if (shadowType.getOid().equals(object.getOid())) { - // We have found ourselves. No conflict (yet). Just go on. - return true; - } else { - // We have found someone else. Conflict. - isUniqueHolder.setValue(false); - return false; - } } } }; @@ -744,6 +731,20 @@ public boolean handle(PrismObject object, OperationResult parentResu return isUniqueHolder.getValue(); } + private ObjectQuery createAttributeQuery(ResourceType resourceType, QName attributeName, T attributeValue) throws SchemaException { + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); + RefinedObjectClassDefinition rAccountDef = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); + RefinedAttributeDefinition attrDef = rAccountDef.findAttributeDefinition(attributeName); + if (attrDef == null) { + throw new SchemaException("No attribute '" + attributeName + "' in " + rAccountDef); + } + return prismContext.queryFor(ShadowType.class) + .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getItemName()).eq(attributeValue) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccountDef.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .build(); + } + @Override public ModelContext getModelContext() { return ModelExpressionThreadLocalHolder.getLensContext(); @@ -755,6 +756,7 @@ public ModelElementContext getFocusContext() { if (lensContext == null) { return null; } + //noinspection unchecked return (ModelElementContext) lensContext.getFocusContext(); } @@ -814,8 +816,9 @@ public ModelContext unwrapModelContext(LensContextType lensContextType) getCurrentResult(MidpointFunctions.class.getName() + "getObject")); } - public LensContextType wrapModelContext(LensContext lensContext) throws SchemaException { - return lensContext.toLensContextType(); + @Override + public LensContextType wrapModelContext(ModelContext lensContext) throws SchemaException { + return ((LensContext) lensContext).toLensContextType(); } // Convenience functions @@ -921,8 +924,9 @@ public void executeChanges( modelService.executeChanges(deltas, null, getCurrentTask(), getCurrentResult()); } + @SafeVarargs @Override - public void executeChanges(ObjectDelta... deltas) + public final void executeChanges(ObjectDelta... deltas) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, @@ -1037,6 +1041,7 @@ public PrismObject findShadowOwner(String accountOid) public PrismObject searchShadowOwner(String accountOid) throws ObjectNotFoundException, SecurityViolationException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException { + //noinspection unchecked return (PrismObject) modelService.searchShadowOwner(accountOid, null, getCurrentTask(), getCurrentResult()); } @@ -1171,6 +1176,7 @@ public ObjectDeltaType getResourceDelta(ModelContext context, String resourceOid return DeltaConvertor.toObjectDeltaType(sum); } + @Override public long getSequenceCounter(String sequenceOid) throws ObjectNotFoundException, SchemaException { return SequentialValueExpressionEvaluator.getSequenceCounter(sequenceOid, repositoryService, getCurrentResult()); } @@ -1179,7 +1185,7 @@ public long getSequenceCounter(String sequenceOid) throws ObjectNotFoundExceptio @Override public Collection getManagersOids(UserType user) - throws SchemaException, ObjectNotFoundException, SecurityViolationException { + throws SchemaException, SecurityViolationException { return orgStructFunctions.getManagersOids(user, false); } @@ -1193,6 +1199,11 @@ public OrgType getParentOrgByOrgType(ObjectType object, String orgType) throws S return orgStructFunctions.getParentOrgByOrgType(object, orgType, false); } + @Override + public OrgType getParentOrgByArchetype(ObjectType object, String archetypeOid) throws SchemaException, SecurityViolationException { + return orgStructFunctions.getParentOrgByArchetype(object, archetypeOid, false); + } + @Override public OrgType getOrgByOid(String oid) throws SchemaException { return orgStructFunctions.getOrgByOid(oid, false); @@ -1219,14 +1230,13 @@ public boolean isManagerOfOrgType(UserType user, String orgType) throws SchemaEx } @Override - public Collection getManagers(UserType user) - throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagers(UserType user) throws SchemaException, SecurityViolationException { return orgStructFunctions.getManagers(user, false); } @Override public Collection getManagersByOrgType(UserType user, String orgType) - throws SchemaException, ObjectNotFoundException, SecurityViolationException { + throws SchemaException, SecurityViolationException { return orgStructFunctions.getManagersByOrgType(user, orgType, false); } @@ -1243,7 +1253,7 @@ public Collection getParentOrgsByRelation(ObjectType object, String rel @Override public Collection getManagers(UserType user, String orgType, boolean allowSelf) - throws SchemaException, ObjectNotFoundException, SecurityViolationException { + throws SchemaException, SecurityViolationException { return orgStructFunctions.getManagers(user, orgType, allowSelf, false); } @@ -1255,7 +1265,7 @@ public Collection getParentOrgs(ObjectType object, String relation, Str @Override public Collection getManagersOidsExceptUser(UserType user) - throws SchemaException, ObjectNotFoundException, SecurityViolationException { + throws SchemaException, SecurityViolationException { return orgStructFunctions.getManagersOidsExceptUser(user, false); } @@ -1316,7 +1326,7 @@ public Map parseXmlToMap(String xml) { while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); - Integer code = event.getEventType(); + int code = event.getEventType(); if (code == XMLStreamConstants.START_ELEMENT) { StartElement startElement = event.asStartElement(); @@ -1332,9 +1342,9 @@ public Map parseXmlToMap(String xml) { StringBuilder valueBuilder; if (value != null) { - valueBuilder = new StringBuilder(value).append(" ").append(characters.getData().toString()); + valueBuilder = new StringBuilder(value).append(" ").append(characters.getData()); } else { - valueBuilder = new StringBuilder(characters.getData().toString()); + valueBuilder = new StringBuilder(characters.getData()); } value = valueBuilder.toString(); } @@ -1439,10 +1449,12 @@ public WorkflowService getWorkflowService() { public List getShadowsToActivate(Collection projectionContexts) { List shadows = new ArrayList<>(); + //noinspection unchecked for (ModelElementContext projectionCtx : projectionContexts) { - List executedShadowDelas = projectionCtx.getExecutedDeltas(); - for (ObjectDeltaOperation shadowDelta : executedShadowDelas) { + List executedShadowDeltas = projectionCtx.getExecutedDeltas(); + //noinspection unchecked + for (ObjectDeltaOperation shadowDelta : executedShadowDeltas) { if (shadowDelta.getExecutionResult().getStatus() == OperationResultStatus.SUCCESS && shadowDelta.getObjectDelta().getChangeType() == ChangeType.ADD) { PrismObject shadow = shadowDelta.getObjectDelta().getObjectToAdd(); @@ -1530,7 +1542,7 @@ private String createPrefixLinkByAuthSequence(String channel, String nameOfSeque } private SecurityPolicyType resolveSecurityPolicy(PrismObject user) { - SecurityPolicyType securityPolicy = securityContextManager.runPrivileged(new Producer() { + return securityContextManager.runPrivileged(new Producer() { private static final long serialVersionUID = 1L; @Override @@ -1553,7 +1565,6 @@ public SecurityPolicyType run() { } }); - return securityPolicy; } private String getPublicHttpUrlPattern() { @@ -1943,11 +1954,13 @@ public MessageWrapper wrap(AsyncUpdateMessageType message) { } // temporary + @SuppressWarnings("unused") public Map getMessageBodyAsMap(AsyncUpdateMessageType message) throws IOException { return wrap(message).getBodyAsMap(); } // temporary + @SuppressWarnings("unused") public Item getMessageBodyAsPrismItem(AsyncUpdateMessageType message) throws SchemaException { return wrap(message).getBodyAsPrismItem(PrismContext.LANG_XML); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java index 027a915b140..ee324dd66c3 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java @@ -35,6 +35,7 @@ import javax.xml.namespace.QName; import java.util.*; +import java.util.function.Predicate; import static com.evolveum.midpoint.schema.util.FocusTypeUtil.determineSubTypes; @@ -214,11 +215,11 @@ public OrgType getOrgByName(String name, boolean preAuthorized) throws SchemaExc List> result = searchObjects(OrgType.class, q, midpointFunctions.getCurrentResult(), preAuthorized); if (result.isEmpty()) { return null; - } - if (result.size() > 1) { + } else if (result.size() > 1) { throw new IllegalStateException("More than one organizational unit with the name '" + name + "' (there are " + result.size() + " of them)"); + } else { + return result.get(0).asObjectable(); } - return result.get(0).asObjectable(); } @Override @@ -226,16 +227,29 @@ public OrgType getParentOrgByOrgType(ObjectType object, String orgType, boolean Collection parentOrgs = getParentOrgs(object, PrismConstants.Q_ANY, orgType, preAuthorized); if (parentOrgs.isEmpty()) { return null; - } - if (parentOrgs.size() > 1) { + } else if (parentOrgs.size() > 1) { throw new IllegalArgumentException("Expected that there will be just one parent org of type "+orgType+" for "+object+", but there were "+parentOrgs.size()); + } else { + return parentOrgs.iterator().next(); + } + } + + @Override + public OrgType getParentOrgByArchetype(ObjectType object, String archetypeOid, boolean preAuthorized) throws SchemaException, SecurityViolationException { + Collection parentOrgs = getParentOrgs(object, PrismConstants.Q_ANY, org -> archetypeOid == null + || ObjectTypeUtil.hasArchetype(org, archetypeOid), preAuthorized); + if (parentOrgs.isEmpty()) { + return null; + } else if (parentOrgs.size() > 1) { + throw new IllegalArgumentException("Expected that there will be just one parent org of archetype "+archetypeOid+" for "+object+", but there were "+parentOrgs.size()); + } else { + return parentOrgs.iterator().next(); } - return parentOrgs.iterator().next(); } @Override public Collection getParentOrgsByRelation(ObjectType object, QName relation, boolean preAuthorized) throws SchemaException, SecurityViolationException { - return getParentOrgs(object, relation, null, preAuthorized); + return getParentOrgs(object, relation, org -> true, preAuthorized); } @Override @@ -245,7 +259,7 @@ public Collection getParentOrgsByRelation(ObjectType object, String rel @Override public Collection getParentOrgs(ObjectType object, boolean preAuthorized) throws SchemaException, SecurityViolationException { - return getParentOrgs(object, PrismConstants.Q_ANY, null, preAuthorized); + return getParentOrgs(object, PrismConstants.Q_ANY, org -> true, preAuthorized); } @Override @@ -254,7 +268,14 @@ public Collection getParentOrgs(ObjectType object, String relation, Str } @Override - public Collection getParentOrgs(ObjectType object, QName relation, String orgType, boolean preAuthorized) throws SchemaException, SecurityViolationException { + public Collection getParentOrgs(ObjectType object, QName relation, String orgType, boolean preAuthorized) + throws SchemaException, SecurityViolationException { + return getParentOrgs(object, relation, org -> orgType == null || determineSubTypes(org).contains(orgType), preAuthorized); + } + + @Override + public Collection getParentOrgs(ObjectType object, QName relation, @NotNull Predicatepredicate, boolean preAuthorized) + throws SchemaException, SecurityViolationException { List parentOrgRefs = object.getParentOrgRef(); List parentOrgs = new ArrayList<>(parentOrgRefs.size()); for (ObjectReferenceType parentOrgRef: parentOrgRefs) { @@ -272,7 +293,7 @@ public Collection getParentOrgs(ObjectType object, QName relation, Stri // This should not happen. throw new SystemException(e.getMessage(), e); } - if (orgType == null || determineSubTypes(parentOrg).contains(orgType)) { + if (predicate.test(parentOrg)) { parentOrgs.add(parentOrg); } } 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 02120f5753a..4feb4599294 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 @@ -37,8 +37,6 @@ * The purpose of this task is to detect and optionally fix anomalies in repository objects. * * However, currently its only function is to display information about objects size. - * - * @author Pavol Mederly */ @Component public class ObjectIntegrityCheckTaskHandler extends AbstractSearchIterativeModelTaskHandler { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java index 0ee04d371f4..469cf5a4ed9 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java @@ -41,10 +41,11 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import javax.xml.namespace.QName; +import java.lang.reflect.InvocationTargetException; import java.util.*; /** - * @author mederly + * */ public class ShadowIntegrityCheckResultHandler extends AbstractSearchIterativeResultHandler { @@ -52,8 +53,8 @@ public class ShadowIntegrityCheckResultHandler extends AbstractSearchIterativeRe private static final String CLASS_DOT = ShadowIntegrityCheckResultHandler.class.getName() + "."; private static final String DEFAULT_DUPLICATE_SHADOWS_RESOLVER_CLASS_NAME = DefaultDuplicateShadowsResolver.class.getName(); - public static final String KEY_EXISTS_ON_RESOURCE = CLASS_DOT + "existsOnResource"; - public static final String KEY_OWNERS = CLASS_DOT + "owners"; + static final String KEY_EXISTS_ON_RESOURCE = CLASS_DOT + "existsOnResource"; + static final String KEY_OWNERS = CLASS_DOT + "owners"; private PrismContext prismContext; private ProvisioningService provisioningService; @@ -79,34 +80,31 @@ public class ShadowIntegrityCheckResultHandler extends AbstractSearchIterativeRe private boolean dryRun; - public static final String INTENTS = "intents"; - public static final String UNIQUENESS = "uniqueness"; - public static final String NORMALIZATION = "normalization"; - public static final String OWNERS = "owners"; - public static final String FETCH = "fetch"; - public static final String EXTRA_DATA = "extraData"; - public static final String RESOURCE_REF = "resourceRef"; - public static final List KNOWN_KEYS = + private static final String INTENTS = "intents"; + private static final String UNIQUENESS = "uniqueness"; + private static final String NORMALIZATION = "normalization"; + private static final String OWNERS = "owners"; + private static final String FETCH = "fetch"; + private static final String EXTRA_DATA = "extraData"; + private static final String RESOURCE_REF = "resourceRef"; + private static final List KNOWN_KEYS = Arrays.asList(INTENTS, UNIQUENESS, NORMALIZATION, OWNERS, FETCH, EXTRA_DATA, RESOURCE_REF); private Map contextMap = new HashMap<>(); private Map> resources = new HashMap<>(); - private PrismObject configuration; - private ShadowStatistics statistics = new ShadowStatistics(); private DuplicateShadowsResolver duplicateShadowsResolver; private Set duplicateShadowsDetected = new HashSet<>(); private Set duplicateShadowsDeleted = new HashSet<>(); - public ShadowIntegrityCheckResultHandler(RunningTask coordinatorTask, String taskOperationPrefix, String processShortName, + ShadowIntegrityCheckResultHandler(RunningTask coordinatorTask, String taskOperationPrefix, String processShortName, String contextDesc, TaskManager taskManager, PrismContext prismContext, ProvisioningService provisioningService, MatchingRuleRegistry matchingRuleRegistry, RepositoryService repositoryService, SynchronizationService synchronizationService, - SystemObjectCache systemObjectCache, - OperationResult result) { + SystemObjectCache systemObjectCache) { super(coordinatorTask, taskOperationPrefix, processShortName, contextDesc, taskManager); this.prismContext = prismContext; this.provisioningService = provisioningService; @@ -177,8 +175,10 @@ public ShadowIntegrityCheckResultHandler(RunningTask coordinatorTask, String tas duplicateShadowsResolverClassName = DEFAULT_DUPLICATE_SHADOWS_RESOLVER_CLASS_NAME; } try { - duplicateShadowsResolver = (DuplicateShadowsResolver) Class.forName(duplicateShadowsResolverClassName).newInstance(); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { + duplicateShadowsResolver = (DuplicateShadowsResolver) Class.forName(duplicateShadowsResolverClassName) + .getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException + | NoSuchMethodException | InvocationTargetException e) { throw new SystemException("Couldn't instantiate duplicate shadows resolver " + duplicateShadowsResolverClassName); } } @@ -188,12 +188,6 @@ public ShadowIntegrityCheckResultHandler(RunningTask coordinatorTask, String tas checkDuplicatesOnPrimaryIdentifiersOnly = checkDuplicatesOnPrimaryIdentifiersOnlyProperty.getRealValue(); } - try { - configuration = systemObjectCache.getSystemConfiguration(result); - } catch (SchemaException e) { - throw new SystemException("Couldn't get system configuration", e); - } - try { dryRun = TaskUtil.isDryRun(coordinatorTask); } catch (SchemaException e) { @@ -329,7 +323,7 @@ private void checkShadow(ShadowCheckResult checkResult, PrismObject } if (checkExtraData) { - checkOrFixShadowActivationConsistency(checkResult, shadow, fixExtraData); + checkOrFixShadowActivationConsistency(checkResult, shadow); } PrismObject fetchedShadow = null; @@ -438,11 +432,11 @@ private void checkShadow(ShadowCheckResult checkResult, PrismObject } if (checkUniqueness) { if (!checkDuplicatesOnPrimaryIdentifiersOnly || primaryIdentifiers.contains(identifier)) { - addIdentifierValue(checkResult, context, identifier.getItemName(), value, shadow); + addIdentifierValue(context, identifier.getItemName(), value, shadow); } } if (checkNormalization) { - doCheckNormalization(checkResult, identifier, value, context); + doCheckNormalization(checkResult, identifier, value); } } @@ -559,7 +553,7 @@ private String skippedForDryRun() { } } - private void doCheckNormalization(ShadowCheckResult checkResult, RefinedAttributeDefinition identifier, String value, ObjectTypeContext context) throws SchemaException { + private void doCheckNormalization(ShadowCheckResult checkResult, RefinedAttributeDefinition identifier, String value) throws SchemaException { QName matchingRuleQName = identifier.getMatchingRuleQName(); if (matchingRuleQName == null) { return; @@ -593,12 +587,13 @@ ShadowStatistics.OTHER_FAILURE, new SchemaException("Normalized value is not a s if (fixNormalization) { PropertyDelta delta = identifier.createEmptyDelta(ItemPath.create(ShadowType.F_ATTRIBUTES, identifier.getItemName())); + //noinspection unchecked delta.setRealValuesToReplace(normalizedStringValue); checkResult.addFixDelta(delta, ShadowStatistics.NON_NORMALIZED_IDENTIFIER_VALUE); } } - private void addIdentifierValue(ShadowCheckResult checkResult, ObjectTypeContext context, QName identifierName, String identifierValue, PrismObject shadow) { + private void addIdentifierValue(ObjectTypeContext context, QName identifierName, String identifierValue, PrismObject shadow) { Map> valueMap = context.getIdentifierValueMap() .computeIfAbsent(identifierName, k -> new HashMap<>()); @@ -617,21 +612,6 @@ private void addIdentifierValue(ShadowCheckResult checkResult, ObjectTypeContext } } -// private String shortDumpList(List> list) { -// StringBuilder sb = new StringBuilder(); -// sb.append('['); -// boolean first = true; -// for (PrismObject object : list) { -// if (first) { -// first = false; -// } else { -// sb.append(", "); -// } -// sb.append(ObjectTypeUtil.toShortString(object.asObjectable())); -// } -// return sb.toString(); -// } - public ShadowStatistics getStatistics() { return statistics; } @@ -681,7 +661,7 @@ private String reportOrFixUniqueness(Task task, OperationResult result) { details.append("; sync situation = ").append(shadow.asObjectable().getSynchronizationSituation()).append("\n"); PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); if (attributesContainer != null && !attributesContainer.isEmpty()) { - for (Item item : attributesContainer.getValue().getItems()) { + for (Item item : attributesContainer.getValue().getItems()) { details.append(" - ").append(item.getElementName().getLocalPart()).append(" = "); details.append(item.getRealValues()); details.append("\n"); @@ -732,7 +712,7 @@ private void deleteShadows(DuplicateShadowsTreatmentInstruction instruction, Str List> owners; if (checkOwners) { - owners = (List) shadowToDelete.getUserData(KEY_OWNERS); + owners = shadowToDelete.getUserData(KEY_OWNERS); } else { owners = searchOwners(shadowToDelete, result); } @@ -758,8 +738,8 @@ private void deleteShadows(DuplicateShadowsTreatmentInstruction instruction, Str continue; } - for (PrismObject owner : owners) { - List modifications = new ArrayList<>(2); + for (PrismObject owner : owners) { + List> modifications = new ArrayList<>(2); ReferenceDelta deleteDelta = prismContext.deltaFactory().reference().createModificationDelete(FocusType.F_LINK_REF, owner.getDefinition(), prismContext.itemFactory().createReferenceValue(oid, ShadowType.COMPLEX_TYPE)); modifications.add(deleteDelta); @@ -771,7 +751,7 @@ private void deleteShadows(DuplicateShadowsTreatmentInstruction instruction, Str LOGGER.info("Executing modify delta{} for owner {}:\n{}", skippedForDryRun(), ObjectTypeUtil.toShortString(owner), DebugUtil.debugDump(modifications)); if (!dryRun) { try { - repositoryService.modifyObject((Class) owner.getClass(), owner.getOid(), modifications, result); + repositoryService.modifyObject(owner.getCompileTimeClass(), owner.getOid(), modifications, result); task.recordObjectActionExecuted(owner, ChangeType.MODIFY, null); } catch (ObjectNotFoundException | SchemaException | ObjectAlreadyExistsException | RuntimeException e) { task.recordObjectActionExecuted(owner, ChangeType.MODIFY, e); @@ -788,9 +768,11 @@ private void deleteShadows(DuplicateShadowsTreatmentInstruction instruction, Str public void completeProcessing(Task task, OperationResult result) { super.completeProcessing(task, result); - String uniquenessReport = null; + String uniquenessReport; if (checkUniqueness) { uniquenessReport = reportOrFixUniqueness(task, result); + } else { + uniquenessReport = null; } logConfiguration("Shadow integrity check finished. It was run with the configuration:"); @@ -811,7 +793,7 @@ public void completeProcessing(Task task, OperationResult result) { } // adapted from ProvisioningUtil - public void checkOrFixShadowActivationConsistency(ShadowCheckResult checkResult, PrismObject shadow, boolean fix) { + private void checkOrFixShadowActivationConsistency(ShadowCheckResult checkResult, PrismObject shadow) { if (shadow == null) { // just for sure return; } @@ -830,14 +812,14 @@ public void checkOrFixShadowActivationConsistency(ShadowCheckResult checkResult, checkOrFixActivationItem(checkResult, shadow, activation.asPrismContainerValue(), ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP); } - private void checkOrFixActivationItem(ShadowCheckResult checkResult, PrismObject shadow, PrismContainerValue activation, ItemName itemName) { - PrismProperty property = activation.findProperty(itemName); + private void checkOrFixActivationItem(ShadowCheckResult checkResult, PrismObject shadow, PrismContainerValue activation, ItemName itemName) { + PrismProperty property = activation.findProperty(itemName); if (property == null || property.isEmpty()) { return; } checkResult.recordWarning(ShadowStatistics.EXTRA_ACTIVATION_DATA, "Unexpected activation item: " + property); if (fixExtraData) { - PropertyDelta delta = prismContext.deltaFactory().property().createReplaceEmptyDelta(shadow.getDefinition(), ItemPath.create(ShadowType.F_ACTIVATION, itemName)); + PropertyDelta delta = prismContext.deltaFactory().property().createReplaceEmptyDelta(shadow.getDefinition(), ItemPath.create(ShadowType.F_ACTIVATION, itemName)); checkResult.addFixDelta(delta, ShadowStatistics.EXTRA_ACTIVATION_DATA); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckTaskHandler.java index dadc5cc3c60..7b84b926737 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckTaskHandler.java @@ -19,8 +19,6 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskCategory; import com.evolveum.midpoint.task.api.TaskRunResult; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskPartitionDefinitionType; @@ -52,24 +50,10 @@ public class ShadowIntegrityCheckTaskHandler extends AbstractSearchIterativeMode public static final String HANDLER_URI = ModelPublicConstants.SHADOW_INTEGRITY_CHECK_TASK_HANDLER_URI; - // WARNING! This task handler is efficiently singleton! - // It is a spring bean and it is supposed to handle all search task instances - // Therefore it must not have task-specific fields. It can only contain fields specific to - // all tasks of a specified type - - @Autowired - private ProvisioningService provisioningService; - - @Autowired - private MatchingRuleRegistry matchingRuleRegistry; - - @Autowired - private SynchronizationService synchronizationService; - - @Autowired - private SystemObjectCache systemObjectCache; - - private static final Trace LOGGER = TraceManager.getTrace(ShadowIntegrityCheckTaskHandler.class); + @Autowired private ProvisioningService provisioningService; + @Autowired private MatchingRuleRegistry matchingRuleRegistry; + @Autowired private SynchronizationService synchronizationService; + @Autowired private SystemObjectCache systemObjectCache; public ShadowIntegrityCheckTaskHandler() { super("Shadow integrity check", OperationConstants.CHECK_SHADOW_INTEGRITY); @@ -83,10 +67,11 @@ private void initialize() { } @Override - protected ShadowIntegrityCheckResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, RunningTask coordinatorTask, OperationResult opResult) { + protected ShadowIntegrityCheckResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, + RunningTask coordinatorTask, OperationResult opResult) { return new ShadowIntegrityCheckResultHandler(coordinatorTask, ShadowIntegrityCheckTaskHandler.class.getName(), "check shadow integrity", "check shadow integrity", taskManager, prismContext, provisioningService, - matchingRuleRegistry, repositoryService, synchronizationService, systemObjectCache, opResult); + matchingRuleRegistry, repositoryService, synchronizationService, systemObjectCache); } @Override @@ -95,7 +80,8 @@ protected Class getType(Task task) { } @Override - protected boolean requiresDirectRepositoryAccess(ShadowIntegrityCheckResultHandler resultHandler, TaskRunResult runResult, Task coordinatorTask, OperationResult opResult) { + protected boolean requiresDirectRepositoryAccess(ShadowIntegrityCheckResultHandler resultHandler, TaskRunResult runResult, + Task coordinatorTask, OperationResult opResult) { return true; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java index 460900c36e7..a044c27c272 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java @@ -9,6 +9,7 @@ import com.evolveum.midpoint.model.api.ScriptExecutionException; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.RelationTypes; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; @@ -16,6 +17,7 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; @@ -34,6 +36,9 @@ public class AssignExecutor extends AssignmentOperationsExecutor { private static final Trace LOGGER = TraceManager.getTrace(AssignExecutor.class); + @Autowired + protected RelationRegistry relationRegistry; + // private static final String NAME = "assign"; // private static final String PARAM_RESOURCE = "resource"; // private static final String PARAM_ROLE = "role"; @@ -139,20 +144,21 @@ protected ObjectDelta createDelta(AssignmentHolderType obj List assignments = new ArrayList<>(); if (roles != null) { + List relationDefinitions = relationRegistry.getRelationDefinitions(); for (ObjectReferenceType roleRef : roles) { AssignmentType assignmentType = new AssignmentType(); - RelationTypes foundRelation = null; - for (RelationTypes relationType : RelationTypes.values()) { + RelationDefinitionType foundRelation = null; + for (RelationDefinitionType relationDefinitionType : relationDefinitions) { if (prismContext.relationMatches(QNameUtil.uriToQName(relation, true), - relationType.getRelation())) { - foundRelation = relationType; + relationDefinitionType.getRef())) { + foundRelation = relationDefinitionType; break; } } if(foundRelation == null) { throw new IllegalArgumentException("Relation " + relation + " not found"); } - roleRef.setRelation(foundRelation.getRelation()); + roleRef.setRelation(foundRelation.getRef()); assignmentType.setTargetRef(roleRef); assignments.add(assignmentType); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/GuiProfileCompiler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/GuiProfileCompiler.java index 00ffa05c566..227106b5e92 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/GuiProfileCompiler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/GuiProfileCompiler.java @@ -449,7 +449,7 @@ private void compileSearchBox(CompiledObjectCollectionView existingView, GuiObje private void joinForms(ObjectFormsType objectForms, ObjectFormType newForm) { objectForms.getObjectForm().removeIf(currentForm -> isTheSameObjectForm(currentForm, newForm)); - objectForms.getObjectForm().add(newForm.clone()); + objectForms.getObjectForm().add(newForm.clone().id(null)); } private void joinObjectDetails(GuiObjectDetailsSetType objectDetailsSet, GuiObjectDetailsPageType newObjectDetails) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthneticationEvaluatorImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthenticationEvaluatorImpl.java similarity index 81% rename from model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthneticationEvaluatorImpl.java rename to model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthenticationEvaluatorImpl.java index 25b66f24658..a15c161b1ea 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthneticationEvaluatorImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/SecurityQuestionAuthenticationEvaluatorImpl.java @@ -20,15 +20,11 @@ import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.SecurityUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionAnswerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionsCredentialsPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionsCredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @Component("securityQuestionsAuthenticationEvaluator") -public class SecurityQuestionAuthneticationEvaluatorImpl extends AuthenticationEvaluatorImpl{ +public class SecurityQuestionAuthenticationEvaluatorImpl + extends AuthenticationEvaluatorImpl { @Override protected void checkEnteredCredentials(ConnectionEnvironment connEnv, @@ -41,7 +37,7 @@ protected void checkEnteredCredentials(ConnectionEnvironment connEnv, Map enteredQuestionAnswer = authCtx.getQuestionAnswerMap(); boolean allBlank = false; for (String enteredAnswers : enteredQuestionAnswer.values()) { - if (StringUtils.isBlank(enteredAnswers)){ + if (StringUtils.isBlank(enteredAnswers)) { allBlank = true; } } @@ -80,19 +76,16 @@ protected boolean passwordMatches(ConnectionEnvironment connEnv, MidPointPrincip SecurityQuestionsCredentialsPolicyType policy = authCtx.getPolicy(); Integer iNumberOfQuestions = policy.getQuestionNumber(); - int numberOfQuestions = 0; - if (iNumberOfQuestions != null){ - numberOfQuestions = iNumberOfQuestions.intValue(); - } + int numberOfQuestions = iNumberOfQuestions != null ? iNumberOfQuestions : 0; Map enteredQuestionsAnswers = authCtx.getQuestionAnswerMap(); - if (numberOfQuestions > enteredQuestionsAnswers.size()){ + if (numberOfQuestions > enteredQuestionsAnswers.size()) { return false; } List quetionsAnswers = passwordType.getQuestionAnswer(); int matched = 0; - for (SecurityQuestionAnswerType questionAnswer : quetionsAnswers){ + for (SecurityQuestionAnswerType questionAnswer : quetionsAnswers) { String enteredAnswer = enteredQuestionsAnswers.get(questionAnswer.getQuestionIdentifier()); if (StringUtils.isNotBlank(enteredAnswer)) { if (decryptAndMatch(connEnv, principal, questionAnswer.getQuestionAnswer(), enteredAnswer)) { @@ -109,7 +102,7 @@ protected boolean passwordMatches(ConnectionEnvironment connEnv, MidPointPrincip protected CredentialPolicyType getEffectiveCredentialPolicy(SecurityPolicyType securityPolicy, SecurityQuestionsAuthenticationContext authnCtx) throws SchemaException { SecurityQuestionsCredentialsPolicyType policy = authnCtx.getPolicy(); - if (policy == null){ + if (policy == null) { policy = SecurityUtil.getEffectiveSecurityQuestionsCredentialsPolicy(securityPolicy); } authnCtx.setPolicy(policy); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/DeleteNotUpdatedShadowTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/DeleteNotUpdatedShadowTaskHandler.java index f6585f4e03d..030ae22b2cc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/DeleteNotUpdatedShadowTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/DeleteNotUpdatedShadowTaskHandler.java @@ -18,15 +18,15 @@ import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.task.api.*; +import com.evolveum.midpoint.util.exception.*; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; -import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.api.ModelPublicConstants; -import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.impl.ModelConstants; import com.evolveum.midpoint.model.impl.util.AbstractSearchIterativeModelTaskHandler; import com.evolveum.midpoint.model.impl.util.ModelImplUtils; @@ -39,20 +39,10 @@ import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription; -import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.common.task.AbstractSearchIterativeResultHandler; import com.evolveum.midpoint.schema.result.OperationConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.exception.CommonException; -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.PolicyViolationException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; @@ -76,7 +66,6 @@ public class DeleteNotUpdatedShadowTaskHandler extends AbstractSearchIterativeMo @Autowired private PrismContext prismContext; @Autowired private SynchronizationService synchronizationService; @Autowired private Clock clock; - @Autowired private ModelService model; @Autowired private ProvisioningService provisioningService; private static final Trace LOGGER = TraceManager.getTrace(DeleteNotUpdatedShadowTaskHandler.class); @@ -97,18 +86,20 @@ protected Class getType(Task task) { } @Override - protected AbstractSearchIterativeResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, final RunningTask coordinatorTask, - OperationResult opResult) { + protected AbstractSearchIterativeResultHandler createHandler(TaskPartitionDefinitionType partition, + TaskRunResult runResult, final RunningTask coordinatorTask, OperationResult opResult) { - AbstractSearchIterativeResultHandler handler = new AbstractSearchIterativeResultHandler( - coordinatorTask, DeleteNotUpdatedShadowTaskHandler.class.getName(), "delete not updated shadow", "delete not updated shadow task", partition, taskManager) { + PrismObject resource = getResource(coordinatorTask); + checkResource(resource); + AbstractSearchIterativeResultHandler handler = new AbstractSearchIterativeResultHandler( + coordinatorTask, DeleteNotUpdatedShadowTaskHandler.class.getName(), "delete not updated shadow", + "delete not updated shadow task", partition, taskManager) { @Override - protected boolean handleObject(PrismObject object, RunningTask workerTask, OperationResult result) throws CommonException, PreconditionViolationException { - deleteShadow(object, getOptions(coordinatorTask), workerTask, result); + protected boolean handleObject(PrismObject object, RunningTask workerTask, OperationResult result) { + deleteShadow(object, resource, workerTask, result); return true; } - }; handler.setStopOnError(false); return handler; @@ -123,9 +114,9 @@ protected Collection> createSearchOptions( @Override protected ObjectQuery createQuery(AbstractSearchIterativeResultHandler handler, TaskRunResult runResult, - Task task, OperationResult opResult) throws SchemaException { + Task task, OperationResult opResult) { Duration notUpdatedDuration = task.getExtensionPropertyRealValue(NOT_UPDATED_DURATION_PROPERTY_NAME); - if(notUpdatedDuration == null) { + if (notUpdatedDuration == null) { throw new IllegalArgumentException("Duration for deleting not updated shadow is missing in task extension"); } @@ -136,7 +127,7 @@ protected ObjectQuery createQuery(AbstractSearchIterativeResultHandler resource = getResource(task); - ObjectClassComplexTypeDefinition objectclassDef = null; + ObjectClassComplexTypeDefinition objectclassDef; RefinedResourceSchema refinedSchema; try { @@ -145,12 +136,12 @@ protected ObjectQuery createQuery(AbstractSearchIterativeResultHandler getResource(Task task) { - String resourceOid = task.getObjectOid(); if (resourceOid == null) { throw new IllegalArgumentException("Resource OID is missing in task extension"); } - PrismObject resource = null; - ObjectClassComplexTypeDefinition objectclassDef = null; try { - resource = provisioningService.getObject(ResourceType.class, resourceOid, null, task, task.getResult()); - - RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); - objectclassDef = ModelImplUtils.determineObjectClass(refinedSchema, task); + return provisioningService.getObject(ResourceType.class, resourceOid, null, task, task.getResult()); } catch (ObjectNotFoundException ex) { // This is bad. The resource does not exist. Permanent problem. - processErrorPartial("Resource does not exist, OID: " + resourceOid, ex, task.getResult()); + throw processErrorAndCreateException("Resource does not exist, OID: " + resourceOid, ex, task.getResult()); } catch (CommunicationException ex) { // Error, but not critical. Just try later. - processErrorPartial("Communication error", ex, task.getResult()); + throw processErrorAndCreateException("Communication error", ex, task.getResult()); } catch (SchemaException ex) { // Not sure about this. But most likely it is a misconfigured resource or connector // It may be worth to retry. Error is fatal, but may not be permanent. - processErrorPartial("Error dealing with schema", ex, task.getResult()); + throw processErrorAndCreateException("Error dealing with schema", ex, task.getResult()); } catch (RuntimeException ex) { // Can be anything ... but we can't recover from that. // It is most likely a programming error. Does not make much sense // to retry. - processErrorPartial("Internal Error", ex, task.getResult()); + throw processErrorAndCreateException("Internal Error", ex, task.getResult()); } catch (ConfigurationException ex) { // Not sure about this. But most likely it is a misconfigured resource or connector // It may be worth to retry. Error is fatal, but may not be permanent. - processErrorPartial("Configuration error", ex, task.getResult()); + throw processErrorAndCreateException("Configuration error", ex, task.getResult()); } catch (SecurityViolationException ex) { - processErrorPartial("Security violation", ex, task.getResult()); + throw processErrorAndCreateException("Security violation", ex, task.getResult()); } catch (ExpressionEvaluationException ex) { - processErrorPartial("Expression error", ex, task.getResult()); - } - - if(resource == null) { - throw new IllegalArgumentException("Resource is null"); + throw processErrorAndCreateException("Expression error", ex, task.getResult()); } + } - PrismProperty status = resource.findProperty(ItemPath.create(ResourceType.F_OPERATIONAL_STATE, OperationalStateType.F_LAST_AVAILABILITY_STATUS)); + private void checkResource(PrismObject resource) { + PrismProperty status = resource.findProperty(ItemPath.create(ResourceType.F_OPERATIONAL_STATE, + OperationalStateType.F_LAST_AVAILABILITY_STATUS)); - if(status == null || !AvailabilityStatusType.UP.equals(status.getRealValue())) { + if (status == null || !AvailabilityStatusType.UP.equals(status.getRealValue())) { throw new IllegalArgumentException("Resource have to have value of last availability status on UP"); } - - return resource; } - private void processErrorPartial(String errorDesc, Exception ex, OperationResult opResult) { + private RuntimeException processErrorAndCreateException(String errorDesc, Throwable ex, OperationResult opResult) { String message; if (ex == null) { message = errorDesc; } else { message = errorDesc+": "+ex.getMessage(); } - LOGGER.error("Reconciliation: {}-{}", new Object[]{message, ex}); + LOGGER.error("Delete not updated shadow task handler: {}-{}", message, ex, ex); opResult.recordFatalError(message, ex); + throw new SystemException(message, ex); } - private ModelExecuteOptions getOptions(Task coordinatorTask) throws SchemaException { - ModelExecuteOptions modelExecuteOptions; - ModelExecuteOptions modelExecuteOptionsFromTask = ModelImplUtils.getModelExecuteOptions(coordinatorTask); - if (modelExecuteOptionsFromTask != null) { - modelExecuteOptions = modelExecuteOptionsFromTask; - } else { - modelExecuteOptions = ModelExecuteOptions.createReconcile(); - } - LOGGER.trace("ModelExecuteOptions: {}", modelExecuteOptions); - return modelExecuteOptions; - } - - private void deleteShadow(PrismObject shadow, ModelExecuteOptions options, Task task, OperationResult result) throws SchemaException, - ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ObjectAlreadyExistsException, - ConfigurationException, PolicyViolationException, SecurityViolationException, PreconditionViolationException { + private void deleteShadow(PrismObject shadow, PrismObject resource, Task task, OperationResult result) { ResourceObjectShadowChangeDescription change = new ResourceObjectShadowChangeDescription(); change.setObjectDelta(shadow.createDeleteDelta()); - change.setResource(getResource(task)); + change.setResource(resource); change.setOldShadow(shadow); change.setCurrentShadow(shadow); synchronizationService.notifyChange(change, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ExecuteChangesTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ExecuteChangesTaskHandler.java index a3abd52c2ed..858a7501bc1 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ExecuteChangesTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ExecuteChangesTaskHandler.java @@ -49,14 +49,9 @@ public class ExecuteChangesTaskHandler extends AbstractSearchIterativeModelTaskH public static final String HANDLER_URI = ModelConstants.NS_SYNCHRONIZATION_TASK_PREFIX + "/execute/handler-3"; - @Autowired - private TaskManager taskManager; - - @Autowired - private PrismContext prismContext; - - @Autowired - private ModelService model; + @Autowired private TaskManager taskManager; + @Autowired private PrismContext prismContext; + @Autowired private ModelService model; private static final Trace LOGGER = TraceManager.getTrace(ExecuteChangesTaskHandler.class); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerResultHandler.java index e37e37db442..77f25fe9f6e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerResultHandler.java @@ -17,9 +17,9 @@ public abstract class AbstractScannerResultHandler extends AbstractSearchIterativeResultHandler { protected XMLGregorianCalendar lastScanTimestamp; - protected XMLGregorianCalendar thisScanTimestamp; + private XMLGregorianCalendar thisScanTimestamp; - public AbstractScannerResultHandler(RunningTask coordinatorTask, String taskOperationPrefix, + protected AbstractScannerResultHandler(RunningTask coordinatorTask, String taskOperationPrefix, String processShortName, String contextDesc, TaskManager taskManager) { super(coordinatorTask, taskOperationPrefix, processShortName, contextDesc, taskManager); } @@ -36,10 +36,7 @@ public XMLGregorianCalendar getThisScanTimestamp() { return thisScanTimestamp; } - public void setThisScanTimestamp(XMLGregorianCalendar thisScanTimestamp) { + void setThisScanTimestamp(XMLGregorianCalendar thisScanTimestamp) { this.thisScanTimestamp = thisScanTimestamp; } - - - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java index ff706ffba20..8abc62c1f0b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java @@ -23,8 +23,6 @@ import com.evolveum.midpoint.task.api.TaskRunResult; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; @@ -39,8 +37,6 @@ public abstract class AbstractScannerTaskHandler type, String taskName, String taskOperationPrefix) { super(taskName, taskOperationPrefix); } @@ -53,10 +49,12 @@ protected boolean initializeRun(H handler, TaskRunResult runResult, return false; } - XMLGregorianCalendar lastScanTimestamp = null; + XMLGregorianCalendar lastScanTimestamp; PrismProperty lastScanTimestampProperty = task.getExtensionPropertyOrClone(SchemaConstants.MODEL_EXTENSION_LAST_SCAN_TIMESTAMP_PROPERTY_NAME); if (lastScanTimestampProperty != null) { lastScanTimestamp = lastScanTimestampProperty.getValue().getValue(); + } else { + lastScanTimestamp = null; } handler.setLastScanTimestamp(lastScanTimestamp); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AuditReindexTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AuditReindexTaskHandler.java index b70cdd2ad70..417cf591594 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AuditReindexTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AuditReindexTaskHandler.java @@ -35,20 +35,16 @@ @Component public class AuditReindexTaskHandler implements TaskHandler { - static final Trace LOGGER = TraceManager.getTrace(AuditReindexTaskHandler.class); + private static final Trace LOGGER = TraceManager.getTrace(AuditReindexTaskHandler.class); public static final String HANDLER_URI = ModelPublicConstants.AUDIT_REINDEX_TASK_HANDLER_URI; private static final String TASK_NAME = "AuditReindex"; - private int maxResults = 20; - private int firstResult = 0; + private static final int BATCH_SIZE = 20; - @Autowired - protected AuditService auditService; - - @Autowired - protected TaskManager taskManager; + @Autowired protected AuditService auditService; + @Autowired protected TaskManager taskManager; @PostConstruct private void initialize() { @@ -95,6 +91,8 @@ public int getProgress() { e); } Map params = new HashMap<>(); + int firstResult = 0; + int maxResults = BATCH_SIZE; while (true) { params.put("setFirstResult", firstResult); params.put("setMaxResults", maxResults); @@ -151,7 +149,6 @@ public int getProgress() { LOGGER.trace("{} run finished (task {}, run result {})", TASK_NAME, coordinatorTask, runResult); return runResult; - } @Override diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexResultHandler.java index 10aae098165..0726aa5a5d5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexResultHandler.java @@ -22,7 +22,7 @@ import java.util.ArrayList; /** - * @author mederly + * */ public class ReindexResultHandler extends AbstractSearchIterativeResultHandler { @@ -30,12 +30,13 @@ public class ReindexResultHandler extends AbstractSearchIterativeResultHandler object, RunningTask workerTask, OperationResult parentResult) throws CommonException { - OperationResult result = parentResult.createMinorSubresult(CLASS_DOT + "handleObject"); + OperationResult result = parentResult.createMinorSubresult(OP_HANDLE_OBJECT); repositoryService.modifyObject(object.asObjectable().getClass(), object.getOid(), new ArrayList<>(), RepoModifyOptions.createExecuteIfNoChanges(), result); result.computeStatusIfUnknown(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java index 4c3887bdcc9..44ba9009b53 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/ReindexTaskHandler.java @@ -22,8 +22,6 @@ 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.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskPartitionDefinitionType; @@ -36,21 +34,12 @@ * It simply executes empty modification delta on each repository object. * * TODO implement also for sub-objects, namely certification cases. - * - * @author Pavol Mederly */ @Component public class ReindexTaskHandler extends AbstractSearchIterativeModelTaskHandler { public static final String HANDLER_URI = ModelPublicConstants.REINDEX_TASK_HANDLER_URI; - // WARNING! This task handler is efficiently singleton! - // It is a spring bean and it is supposed to handle all search task instances - // Therefore it must not have task-specific fields. It can only contain fields specific to - // all tasks of a specified type - - private static final Trace LOGGER = TraceManager.getTrace(ReindexTaskHandler.class); - public ReindexTaskHandler() { super("Reindex", OperationConstants.REINDEX); setLogFinishInfo(true); @@ -63,8 +52,9 @@ private void initialize() { } @Override - protected ReindexResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, RunningTask coordinatorTask, OperationResult opResult) - throws SchemaException, SecurityViolationException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException { + protected ReindexResultHandler createHandler(TaskPartitionDefinitionType partition, TaskRunResult runResult, + RunningTask coordinatorTask, OperationResult opResult) throws SchemaException, SecurityViolationException, + ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException { securityEnforcer.authorize(AuthorizationConstants.AUTZ_ALL_URL, null, AuthorizationParameters.EMPTY, null, coordinatorTask, opResult); return new ReindexResultHandler(coordinatorTask, ReindexTaskHandler.class.getName(), "reindex", "reindex", taskManager, repositoryService); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java index 7e785206523..d8a71676fe5 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.notifications.api.transports.Message; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.crypto.EncryptionException; +import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemName; @@ -95,6 +96,7 @@ public class TestScriptingBasic extends AbstractInitializedModelIntegrationTest private static final File UNASSIGN_FROM_WILL_2_FILE = new File(TEST_DIR, "unassign-from-will-2.xml"); private static final File UNASSIGN_FROM_WILL_3_FILE = new File(TEST_DIR, "unassign-from-will-3.xml"); private static final File ASSIGN_TO_WILL_FILE = new File(TEST_DIR, "assign-to-will.xml"); + private static final File ASSIGN_TO_WILL_2_FILE = new File(TEST_DIR, "assign-to-will-2.xml"); private static final File PURGE_DUMMY_BLACK_SCHEMA_FILE = new File(TEST_DIR, "purge-dummy-black-schema.xml"); private static final File TEST_DUMMY_RESOURCE_FILE = new File(TEST_DIR, "test-dummy-resource.xml"); private static final File NOTIFICATION_ABOUT_JACK_FILE = new File(TEST_DIR, "notification-about-jack.xml"); @@ -716,6 +718,43 @@ public void test393UnassignFromWill3() throws Exception { MidPointAsserts.assertNotAssignedResource(will, "10000000-0000-0000-0000-000000000004"); } + @Test + public void test394AssignToWill2() throws Exception { + final String TEST_NAME = "test394AssignToWill2"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + QName customRelation = new QName("http://midpoint.evolveum.com/xml/ns/samples/piracy", "piracy:captain"); + + Task task = createTask(DOT_CLASS + TEST_NAME); + OperationResult result = task.getResult(); + PrismProperty expression = parseAnyData(ASSIGN_TO_WILL_2_FILE); + + PrismObject systemConfig = repositoryService.getObject(SystemConfigurationType.class, + SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, result); + RoleManagementConfigurationType roleManagement = systemConfig.asObjectable().getRoleManagement(); + PrismContainerValue oldValue = systemConfig.asObjectable().getRoleManagement().asPrismContainerValue(); + roleManagement.beginRelations().beginRelation().setRef(customRelation); + Collection modifications = new ArrayList<>(); + ContainerDelta deleteDelta = prismContext.deltaFactory().container().createModificationReplace(SystemConfigurationType.F_ROLE_MANAGEMENT, + SystemConfigurationType.class, oldValue.clone()); + ((Collection)modifications).add(deleteDelta); + modifySystemObjectInRepo(SystemConfigurationType.class, + SystemObjectsType.SYSTEM_CONFIGURATION.value(), modifications, result); + + // WHEN + ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), task, result); + + // THEN + dumpOutput(output, result); + assertOutputData(output, 1, OperationResultStatus.SUCCESS); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject will = getUser(USER_WILL_OID); + display("will after assignments creation", will); + MidPointAsserts.assertAssigned(will, "12345678-d34d-b33f-f00d-555555556666", RoleType.COMPLEX_TYPE, customRelation); + } + @Test public void test400PurgeSchema() throws Exception { final String TEST_NAME = "test400PurgeSchema"; diff --git a/model/model-intest/src/test/resources/scripting/assign-to-will-2.xml b/model/model-intest/src/test/resources/scripting/assign-to-will-2.xml new file mode 100644 index 00000000000..dfe5ec7da92 --- /dev/null +++ b/model/model-intest/src/test/resources/scripting/assign-to-will-2.xml @@ -0,0 +1,31 @@ + + + + + c:UserType + + + c:name + willTurner + + + + assign + + role + 12345678-d34d-b33f-f00d-555555556666 + + + relation + piracy:captain + + + diff --git a/pom.xml b/pom.xml index 131d7b9bd86..c52c665f450 100644 --- a/pom.xml +++ b/pom.xml @@ -22,21 +22,25 @@ for other possibilities (mostly to make build faster by running only most important int-tests). - Test JARs of some modules are created, installed/deployed and used downstream (search for test-jar). - VARIOUS MVN COMMANDS + VARIOUS MVN COMMANDS (with rough times on average notebook) - Quick run without any tests: + Quick run without any tests (~6m): mvn clean install -P -dist -DskipTests -Dmaven.javadoc.skip -Dcheckstyle.skip - "Quick" build with unit tests only and checkstyle: + "Quick" build with unit tests only and checkstyle (~30m): mvn clean install -P -dist -DskipITs -Dmaven.javadoc.skip - "Quick" build with smaller integration test set and output to stdout: - mvn clean install -P -dist -DintegrationTestSuite=fast -Dmaven.javadoc.skip -DredirectTestOutputToFile=false + "Quick" build with smaller integration test (~1h20m): + mvn clean install -P -dist -DintegrationTestSuite=fast -Dmaven.javadoc.skip - Long test run (with 16g on CI server, but this should work too - isn't Xmx even unnecessary?), runs just under 900 tests: + Running tests of a selected module (-pl) with output to stdout (don't use stdout for complete build, it's too much): + mvn clean install -DredirectTestOutputToFile=false -pl model/model-intest + + Long test run (with 16g on CI server, but this should work too - isn't Xmx even unnecessary?), + runs just under 900 tests (~1h50m): mvn -P tomcat,extratest clean install -Dsurefire.args="-Xmx8g" -Dfailsafe.args="-Xmx8g -Duser.language=en" - Comprehensive quick build/dist with normally excluded modules including checkstyle, but no tests/javadoc: + Comprehensive quick build/dist with normally excluded modules including checkstyle, but no tests/javadoc (~13m): mvn clean install -P dist,extratest,conntest,schrodinger -DskipTests -Dmaven.javadoc.skip --> @@ -572,11 +576,6 @@ jsr250-api 1.0 - - javax.annotation - javax.annotation-api - 1.2 - javax.jws jsr181-api diff --git a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/MidPointPrincipal.java b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/MidPointPrincipal.java index a4af5dfb74c..f8bf19e454a 100644 --- a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/MidPointPrincipal.java +++ b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/MidPointPrincipal.java @@ -30,7 +30,6 @@ public class MidPointPrincipal implements UserDetails, DebugDumpable, ShortDumpable { private static final long serialVersionUID = 8299738301872077768L; - // TODO: user may be switched to FocusType later (MID-4205) @NotNull private final FocusType focus; private Collection authorizations = new ArrayList<>(); private ActivationStatusType effectiveActivationStatus; diff --git a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java index a840105db74..900eaa721aa 100644 --- a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java +++ b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java @@ -811,19 +811,6 @@ default List listSubtasksDeeply(OperationResult result) throws SchemaExcep */ void startWaitingForTasksImmediate(OperationResult result) throws SchemaException, ObjectNotFoundException; - /** - * There is a special "marker" task handler (@see WaitForTasksTaskHandler) that, when executed, causes - * current task to wait for its prerequisities. It is used on occasions where you want the task to execute - * something (handler1), then wait for subtasks, then e.g. execute something other (handler2). Therefore the - * stack will look like this: - * - * - handler1 - * - WaitForTasksTaskHandler - * - handler2 - */ - @SuppressWarnings("unused") - void pushWaitForTasksHandlerUri(); - // ====================================================================================== Supplementary information /** diff --git a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/test/NullTaskImpl.java b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/test/NullTaskImpl.java index 4627daf7963..f48406b7fd3 100644 --- a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/test/NullTaskImpl.java +++ b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/test/NullTaskImpl.java @@ -620,11 +620,6 @@ public void makeWaiting(TaskWaitingReason reason, TaskUnpauseActionType unpauseA throw new UnsupportedOperationException(); } - @Override - public void pushWaitForTasksHandlerUri() { - throw new UnsupportedOperationException(); - } - @Override public Long getCompletionTimestamp() { throw new UnsupportedOperationException(); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/Initializer.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/Initializer.java index 86b8886dc90..e599c9a2605 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/Initializer.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/Initializer.java @@ -14,8 +14,6 @@ import com.evolveum.midpoint.task.quartzimpl.execution.JobExecutor; import com.evolveum.midpoint.task.quartzimpl.execution.JobStarter; import com.evolveum.midpoint.task.quartzimpl.handlers.NoOpTaskHandler; -import com.evolveum.midpoint.task.quartzimpl.handlers.WaitForSubtasksByPollingTaskHandler; -import com.evolveum.midpoint.task.quartzimpl.handlers.WaitForTasksTaskHandler; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeErrorStatusType; @@ -79,8 +77,6 @@ public void init(OperationResult result) throws TaskManagerInitializationExcepti } NoOpTaskHandler.instantiateAndRegister(taskManager); - WaitForSubtasksByPollingTaskHandler.instantiateAndRegister(taskManager); - WaitForTasksTaskHandler.instantiateAndRegister(taskManager); JobExecutor.setTaskManagerQuartzImpl(taskManager); // unfortunately, there seems to be no clean way of letting jobs know the taskManager JobStarter.setTaskManagerQuartzImpl(taskManager); // the same here 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 f43cecff538..6a016967c96 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 @@ -26,8 +26,6 @@ import com.evolveum.midpoint.schema.statistics.SynchronizationInformation; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.*; -import com.evolveum.midpoint.task.quartzimpl.handlers.WaitForSubtasksByPollingTaskHandler; -import com.evolveum.midpoint.task.quartzimpl.handlers.WaitForTasksTaskHandler; import com.evolveum.midpoint.task.quartzimpl.statistics.Statistics; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; @@ -2249,36 +2247,6 @@ public TaskQuartzImpl createSubtask() { return sub; } - @Deprecated - public TaskRunResult waitForSubtasks(Integer interval, OperationResult parentResult) - throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { - return waitForSubtasks(interval, null, parentResult); - } - - @Deprecated - public TaskRunResult waitForSubtasks(Integer interval, Collection> extensionDeltas, - OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { - - OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + "waitForSubtasks"); - result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskQuartzImpl.class); - result.addContext(OperationResult.CONTEXT_OID, getOid()); - - TaskRunResult trr = new TaskRunResult(); - trr.setRunResultStatus(TaskRunResult.TaskRunResultStatus.RESTART_REQUESTED); - trr.setOperationResult(null); - - ScheduleType schedule = new ScheduleType(); - if (interval != null) { - schedule.setInterval(interval); - } else { - schedule.setInterval(30); - } - pushHandlerUri(WaitForSubtasksByPollingTaskHandler.HANDLER_URI, schedule, null, extensionDeltas); - setBinding(TaskBinding.LOOSE); - flushPendingModifications(result); - return trr; - } - @Override public List> listPersistentSubtasksRaw(OperationResult parentResult) throws SchemaException { OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + "listPersistentSubtasksRaw"); @@ -2359,12 +2327,6 @@ public List listPrerequisiteTasks(OperationResult parentResult) throws Sch return taskManager.resolveTasksFromTaskTypes(listPrerequisiteTasksRaw(result), result); } - @Override - public void pushWaitForTasksHandlerUri() { - pushHandlerUri(WaitForTasksTaskHandler.HANDLER_URI, new ScheduleType(), null); - } - - @Override public void close(OperationResult taskResult, boolean saveState, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/LightweightPartitioningTaskHandler.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/LightweightPartitioningTaskHandler.java index a3017de7fba..5c2b6fb26e2 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/LightweightPartitioningTaskHandler.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/LightweightPartitioningTaskHandler.java @@ -105,7 +105,7 @@ public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType taskParti partitions.sort(comparator); Iterator partitionsIterator = partitions.iterator(); - while(partitionsIterator.hasNext()) { + while (partitionsIterator.hasNext()) { TaskPartitionDefinitionType partition = partitionsIterator.next(); TaskHandler handler = taskManager.getHandler(partition.getHandlerUri()); LOGGER.trace("Starting to execute handler {} defined in partition {}", handler, partition); @@ -137,32 +137,6 @@ public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType taskParti } -// for (TaskPartitionDefinitionType partition : partitions) { -// TaskHandler handler = taskManager.getHandler(partition.getHandlerUri()); -// LOGGER.trace("Starting to execute handler {} defined in partition {}", handler, partition); -// TaskRunResult subHandlerResult = handlerExecutor.executeHandler((RunningTaskQuartzImpl) task, partition, handler, opResult); -// OperationResult subHandlerOpResult = subHandlerResult.getOperationResult(); -// opResult.addSubresult(subHandlerOpResult); -// runResult = subHandlerResult; -// runResult.setProgress(task.getProgress()); -// -// if (!canContinue(task, subHandlerResult)) { -// break; -// } -// -// if (subHandlerOpResult.isError()) { -// break; -// } -// -// try { -// LOGGER.trace("Cleaning up work state in task {}, workState: {}", task, task.getWorkState()); -// cleanupWorkState(task, runResult.getOperationResult()); -// } catch (ObjectNotFoundException | SchemaException | ObjectAlreadyExistsException e) { -// LOGGER.error("Unexpected error during cleaning work state: " + e.getMessage(), e); -// throw new IllegalStateException(e); -// } -// } - runResult.setProgress(runResult.getProgress() + 1); opResult.computeStatusIfUnknown(); counterManager.cleanupCounters(task.getOid()); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForSubtasksByPollingTaskHandler.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForSubtasksByPollingTaskHandler.java deleted file mode 100644 index 492aa7dcf8a..00000000000 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForSubtasksByPollingTaskHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.task.quartzimpl.handlers; - -import java.util.List; - -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.RunningTask; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.task.api.TaskHandler; -import com.evolveum.midpoint.task.api.TaskRunResult; -import com.evolveum.midpoint.task.api.TaskRunResult.TaskRunResultStatus; -import com.evolveum.midpoint.task.quartzimpl.InternalTaskInterface; -import com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskPartitionDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; - -/** - * @author Pavol Mederly - */ -@Deprecated -public class WaitForSubtasksByPollingTaskHandler implements TaskHandler { - - private static final Trace LOGGER = TraceManager.getTrace(WaitForSubtasksByPollingTaskHandler.class); - public static final String HANDLER_URI = "http://midpoint.evolveum.com/xml/ns/public/task/wait-for-subtasks-polling/handler-3"; - - private static WaitForSubtasksByPollingTaskHandler instance = null; - private TaskManagerQuartzImpl taskManagerImpl; - - private WaitForSubtasksByPollingTaskHandler() {} - - public static void instantiateAndRegister(TaskManagerQuartzImpl taskManager) { - if (instance == null) - instance = new WaitForSubtasksByPollingTaskHandler(); - taskManager.registerHandler(HANDLER_URI, instance); - instance.taskManagerImpl = taskManager; - } - - @Override - public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType partition) { - - OperationResult opResult = new OperationResult(WaitForSubtasksByPollingTaskHandler.class.getName()+".run"); - TaskRunResult runResult = new TaskRunResult(); - - LOGGER.info("WaitForSubtasksByPollingTaskHandler run starting; in task " + task.getName()); - - List> subtasks; - try { - subtasks = ((InternalTaskInterface) task).listPersistentSubtasksRaw(opResult); - } catch (SchemaException e) { - throw new SystemException("Couldn't list subtasks of " + task + " due to schema exception", e); - } - - LOGGER.info("Number of subtasks found: " + subtasks.size() + "; task = {}", task); - boolean allClosed = true; - for (PrismObject t : subtasks) { - if (t.asObjectable().getExecutionStatus() != TaskExecutionStatusType.CLOSED) { - LOGGER.info("Subtask " + t.getOid() + "/" + t.asObjectable().getName() + " is not closed, it is " + t.asObjectable().getExecutionStatus() + ", for task {}", task); - allClosed = false; - break; - } - } - - TaskRunResultStatus status; - if (allClosed) { - LOGGER.info("All subtasks are closed, finishing waiting for them; task = {}", task); - status = TaskRunResultStatus.FINISHED_HANDLER; - } else { - status = TaskRunResultStatus.FINISHED; - } - - runResult.setRunResultStatus(status); - LOGGER.info("WaitForSubtasksByPollingTaskHandler run finishing; in task " + task.getName()); - return runResult; - } - - @Override - public Long heartbeat(Task task) { - return null; // not to overwrite progress information! - } - - @Override - public void refreshStatus(Task task) { - } - - @Override - public String getCategoryName(Task task) { - return null; // hopefully we will never need to derive category from this handler! (category is filled-in when persisting tasks) - } -} diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForTasksTaskHandler.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForTasksTaskHandler.java deleted file mode 100644 index 83f41fbc1dc..00000000000 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/handlers/WaitForTasksTaskHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.task.quartzimpl.handlers; - -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.*; -import com.evolveum.midpoint.task.api.TaskRunResult.TaskRunResultStatus; -import com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskPartitionDefinitionType; - -/** - * This is very simple task handler that causes the process to enter WAITING for OTHER_TASKS state. - * - * @author Pavol Mederly - */ -public class WaitForTasksTaskHandler implements TaskHandler { - - private static final Trace LOGGER = TraceManager.getTrace(WaitForTasksTaskHandler.class); - public static final String HANDLER_URI = "http://midpoint.evolveum.com/xml/ns/public/task/wait-for-tasks/handler-3"; - - private static WaitForTasksTaskHandler instance = null; - private TaskManagerQuartzImpl taskManagerImpl; - - private WaitForTasksTaskHandler() {} - - public static void instantiateAndRegister(TaskManagerQuartzImpl taskManager) { - if (instance == null) { - instance = new WaitForTasksTaskHandler(); - } - taskManager.registerHandler(HANDLER_URI, instance); - instance.taskManagerImpl = taskManager; - } - - @Override - public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType partition) { - - OperationResult result = task.getResult().createSubresult(WaitForTasksTaskHandler.class.getName()+".run"); - result.recordInProgress(); - - LOGGER.debug("WaitForTasksTaskHandler run starting; in task " + task.getName()); - try { - // todo resolve this brutal hack - taskManagerImpl.pauseTask(task, TaskWaitingReason.OTHER, result); - task.startWaitingForTasksImmediate(result); - } catch (SchemaException | ObjectNotFoundException e) { - throw new SystemException("Couldn't mark task as waiting for prerequisite tasks", e); // should not occur; will be handled by task runner - } - LOGGER.debug("WaitForTasksTaskHandler run finishing; in task " + task.getName()); - - result.computeStatus(); - - TaskRunResult runResult = new TaskRunResult(); - runResult.setOperationResult(result); - runResult.setRunResultStatus(TaskRunResultStatus.FINISHED); - return runResult; - } - - @Override - public Long heartbeat(Task task) { - return null; // not to overwrite progress information! - } - - @Override - public void refreshStatus(Task task) { - } - - @Override - public String getCategoryName(Task task) { - return null; // hopefully we will never need to derive category from this handler! (category is filled-in when persisting tasks) - } -} diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/AbstractTaskManagerTest.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/AbstractTaskManagerTest.java index 6237da39a13..b6bc3b72346 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/AbstractTaskManagerTest.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/AbstractTaskManagerTest.java @@ -83,7 +83,6 @@ public class AbstractTaskManagerTest extends AbstractTestNGSpringContextTests { protected MockWorkBucketsTaskHandler workBucketsTaskHandler; protected MockWorkBucketsTaskHandler partitionedWorkBucketsTaskHandler; protected MockSingleTaskHandler l1Handler, l2Handler, l3Handler; - protected MockSingleTaskHandler waitForSubtasksTaskHandler; protected MockCycleTaskHandler cycleFinishingHandler; protected MockParallelTaskHandler parallelTaskHandler; protected MockLongTaskHandler longTaskHandler; @@ -124,8 +123,6 @@ protected void initHandlers() { taskManager.registerHandler(L2_TASK_HANDLER_URI, l2Handler); taskManager.registerHandler(L3_TASK_HANDLER_URI, l3Handler); - waitForSubtasksTaskHandler = new MockSingleTaskHandler("WFS", taskManager); - taskManager.registerHandler(WAIT_FOR_SUBTASKS_TASK_HANDLER_URI, waitForSubtasksTaskHandler); parallelTaskHandler = new MockParallelTaskHandler("1", taskManager); taskManager.registerHandler(PARALLEL_TASK_HANDLER_URI, parallelTaskHandler); longTaskHandler = new MockLongTaskHandler("1", taskManager); diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/MockSingleTaskHandler.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/MockSingleTaskHandler.java index c332bcf06cb..b0c556587cf 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/MockSingleTaskHandler.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/MockSingleTaskHandler.java @@ -8,7 +8,6 @@ import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.*; @@ -21,8 +20,6 @@ import org.apache.commons.lang.Validate; -import java.util.ArrayList; - import static com.evolveum.midpoint.task.quartzimpl.TaskTestUtil.createExtensionDelta; /** @@ -34,15 +31,12 @@ public class MockSingleTaskHandler implements TaskHandler { private static final Trace LOGGER = TraceManager.getTrace(MockSingleTaskHandler.class); private static final String NS_EXT = "http://myself.me/schemas/whatever"; private static final ItemName L1_FLAG_QNAME = new ItemName(NS_EXT, "l1Flag", "m"); - private static final ItemName WFS_FLAG_QNAME = new ItemName(NS_EXT, "wfsFlag", "m"); private TaskManagerQuartzImpl taskManager; private String id; private PrismPropertyDefinition l1FlagDefinition; - private PrismPropertyDefinition wfsFlagDefinition; - MockSingleTaskHandler(String id, TaskManagerQuartzImpl taskManager) { this.id = id; @@ -50,8 +44,6 @@ public class MockSingleTaskHandler implements TaskHandler { l1FlagDefinition = taskManager.getPrismContext().getSchemaRegistry().findPropertyDefinitionByElementName(L1_FLAG_QNAME); Validate.notNull(l1FlagDefinition, "l1Flag property is unknown"); - wfsFlagDefinition = taskManager.getPrismContext().getSchemaRegistry().findPropertyDefinitionByElementName(WFS_FLAG_QNAME); - Validate.notNull(wfsFlagDefinition, "wfsFlag property is unknown"); } private boolean hasRun = false; @@ -118,34 +110,6 @@ public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType partition } } else if ("L3".equals(id)) { LOGGER.info("L3 handler, simply exiting. Progress = " + task.getProgress()); - } else if ("WFS".equals(id)) { - - PrismProperty wfsFlag = task.getExtensionPropertyOrClone(WFS_FLAG_QNAME); - - if (wfsFlag == null || !wfsFlag.getRealValue()) { - - LOGGER.info("Wait-for-subtasks creating subtasks..."); - - Task t1 = task.createSubtask(); - t1.setHandlerUri(AbstractTaskManagerTest.L3_TASK_HANDLER_URI); - taskManager.switchToBackground(t1, opResult); - - Task t2 = task.createSubtask(); - t2.setHandlerUri(AbstractTaskManagerTest.SINGLE_TASK_HANDLER_URI); - taskManager.switchToBackground(t2, opResult); - - try { - ArrayList> deltas = new ArrayList<>(); - deltas.add(createExtensionDelta(wfsFlagDefinition, true, taskManager.getPrismContext())); - runResult = ((TaskQuartzImpl) task).waitForSubtasks(2, deltas, opResult); - runResult.setProgress(1L); - } catch (Exception e) { - throw new SystemException("WaitForSubtasks failed.", e); - } - } else { - LOGGER.info("Wait-for-subtasks seems to finish successfully; progress = " + task.getProgress() + ", wfsFlag = " + wfsFlag.getRealValue()); - } - } LOGGER.info("MockSingle.run stopping"); diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/PartitionedMockWorkBucketsTaskHandlerCreator.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/PartitionedMockWorkBucketsTaskHandlerCreator.java index a594fea6323..adf952e8c8e 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/PartitionedMockWorkBucketsTaskHandlerCreator.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/PartitionedMockWorkBucketsTaskHandlerCreator.java @@ -18,19 +18,19 @@ * @author mederly * */ -public class PartitionedMockWorkBucketsTaskHandlerCreator { +class PartitionedMockWorkBucketsTaskHandlerCreator { private TaskManager taskManager; private PrismContext prismContext; - public PartitionedMockWorkBucketsTaskHandlerCreator(TaskManager taskManager, + PartitionedMockWorkBucketsTaskHandlerCreator(TaskManager taskManager, PrismContext prismContext) { this.taskManager = taskManager; this.prismContext = prismContext; } @SuppressWarnings("Duplicates") - public void initializeAndRegister(String handlerUri) { + void initializeAndRegister(String handlerUri) { taskManager.createAndRegisterPartitioningTaskHandler(handlerUri, this::createPartitioningDefinition); } diff --git a/repo/task-quartz-impl/src/test/resources/schema/whatever-extension.xsd b/repo/task-quartz-impl/src/test/resources/schema/whatever-extension.xsd index b7d9905ec5d..350623661bd 100644 --- a/repo/task-quartz-impl/src/test/resources/schema/whatever-extension.xsd +++ b/repo/task-quartz-impl/src/test/resources/schema/whatever-extension.xsd @@ -41,15 +41,6 @@ - - - - false - 0 - 1 - - -