diff --git a/build-system/pom.xml b/build-system/pom.xml index 7b89445ce4b..48f36326290 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -74,7 +74,7 @@ 9.4.1212.jre7 1.5.5 6.0.5 - 7.6.0 + 7.9.0-SNAPSHOT 2.4.0 5.22.0 5.22.0 @@ -84,7 +84,7 @@ 6.4.1 10.11.1.1 1.8.0 - 2.8.6 + 2.8.9 1.15 2.20 @@ -272,6 +272,11 @@ stax-api 1.0-2 + + org.codehaus.staxmate + staxmate + 2.0.1 + stax stax-api diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java index 383520158a2..7a2dc21465c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java @@ -39,6 +39,7 @@ import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -100,11 +101,11 @@ public static OpResult getOpResult(PageBase page, OperationResult result){ } if (result.getParams() != null) { - for (Map.Entry entry : result.getParams().entrySet()) { + for (Map.Entry> entry : result.getParams().entrySet()) { String paramValue = null; - Object value = entry.getValue(); - if (value != null) { - paramValue = value.toString(); + Collection values = entry.getValue(); + if (values != null) { + paramValue = values.toString(); } opResult.getParams().add(new Param(entry.getKey(), paramValue)); @@ -112,11 +113,11 @@ public static OpResult getOpResult(PageBase page, OperationResult result){ } if(result.getContext() != null){ - for (Map.Entry entry : result.getContext().entrySet()) { + for (Map.Entry> entry : result.getContext().entrySet()) { String contextValue = null; - Object value = entry.getValue(); - if (value != null) { - contextValue = value.toString(); + Collection values = entry.getValue(); + if (values != null) { + contextValue = values.toString(); } opResult.getContexts().add(new Context(entry.getKey(), contextValue)); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java index c48278cc29c..71dfa8b8941 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java @@ -1079,25 +1079,29 @@ public RestartResponseException getRestartResponseException(Class void validateObject(String lexicalRepresentation, final Holder objectHolder, - String language, boolean validateSchema, Class clazz, OperationResult result) { + public void parseObject(String lexicalRepresentation, final Holder objectHolder, + String language, boolean validateSchema, boolean skipChecks, Class clazz, OperationResult result) { boolean isListOfObjects = List.class.isAssignableFrom(clazz); boolean isObjectable = Objectable.class.isAssignableFrom(clazz); - if (language == null || PrismContext.LANG_JSON.equals(language) || PrismContext.LANG_YAML.equals(language) + if (skipChecks || language == null || PrismContext.LANG_JSON.equals(language) || PrismContext.LANG_YAML.equals(language) || (!isObjectable && !isListOfObjects)) { T object; try { if (isListOfObjects) { List> prismObjects = getPrismContext().parserFor(lexicalRepresentation) .language(language).parseObjects(); - for (PrismObject prismObject : prismObjects) { - prismObject.checkConsistence(); + if (!skipChecks) { + for (PrismObject prismObject : prismObjects) { + prismObject.checkConsistence(); + } } object = (T) prismObjects; } else if (isObjectable) { PrismObject prismObject = getPrismContext().parserFor(lexicalRepresentation).language(language).parse(); - prismObject.checkConsistence(); + if (!skipChecks) { + prismObject.checkConsistence(); + } object = (T) prismObject.asObjectable(); } else { object = getPrismContext().parserFor(lexicalRepresentation).language(language).type(clazz).parseRealValue(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java index bb7ecc6fe41..f9206199481 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java @@ -1100,8 +1100,10 @@ public static boolean isSuccessOrHandledError(OperationResult result) { } public static boolean isSuccessOrHandledError(OperationResultType resultType) { - OperationResult result = OperationResult.createOperationResult(resultType); - return isSuccessOrHandledError(result); + if (resultType == null) { + return false; + } + return resultType.getStatus() == OperationResultStatusType.SUCCESS || resultType.getStatus() == OperationResultStatusType.HANDLED_ERROR; } public static boolean isSuccessOrHandledErrorOrWarning(OperationResult result) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/ObjectPolicyConfigurationEditor.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/ObjectPolicyConfigurationEditor.java index adcd434afaf..43d4f5998e2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/ObjectPolicyConfigurationEditor.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/ObjectPolicyConfigurationEditor.java @@ -256,11 +256,21 @@ public String load() { if(config != null){ ObjectReferenceType ref = config.getTemplateRef(); - if(ref != null){ - sb.append(WebComponentUtil.getOrigStringFromPoly(ref.getTargetName())).append(": "); + if (ref != null) { + sb.append(WebComponentUtil.getOrigStringFromPoly(ref.getTargetName())); } - if(config.getType() != null){ + if (config.getConflictResolution() != null) { + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(getString("ObjectPolicyConfigurationEditor.conflictResolution")); + } + + if(config.getType() != null) { + if (sb.length() > 0) { + sb.append(": "); + } sb.append(config.getType().getLocalPart()); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableBeanObjectDataProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableBeanObjectDataProvider.java index fe5d3d2b22e..db3f1dcef11 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableBeanObjectDataProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/SelectableBeanObjectDataProvider.java @@ -39,6 +39,8 @@ import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -209,11 +211,15 @@ protected Iterator> handleNotSuccessOrHandledErrorInIterator(O public SelectableBean createDataObjectWrapper(O obj) { SelectableBean selectable = new SelectableBean(obj); - if (!WebComponentUtil.isSuccessOrHandledError(obj.getFetchResult())){ - selectable.setResult(obj.getFetchResult()); + if (!WebComponentUtil.isSuccessOrHandledError(obj.getFetchResult())) { + try { + selectable.setResult(obj.getFetchResult()); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } } for (O s : selected){ - if (s.getOid().equals(obj.getOid())){ + if (s.getOid().equals(obj.getOid())) { selectable.setSelected(true); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DataLanguagePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DataLanguagePanel.java index 1cb2b7a8d38..af6646796f1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DataLanguagePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DataLanguagePanel.java @@ -20,7 +20,7 @@ import com.evolveum.midpoint.prism.Objectable; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.prism.PrismSerializer; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.Holder; import org.apache.commons.lang3.StringUtils; @@ -76,23 +76,27 @@ protected void onStateChanged(int updatedIndex, AjaxRequestTarget target) { return; } - OperationResult result = new OperationResult(DataLanguagePanel.class.getName() + ".validateObject"); + OperationResult result = new OperationResult(DataLanguagePanel.class.getName() + ".parseObject"); Holder objectHolder = new Holder<>(null); try { - pageBase.validateObject(currentObjectString, objectHolder, LANGUAGES.get(currentLanguageIndex), isValidateSchema(), dataType, result); + pageBase.parseObject(currentObjectString, objectHolder, LANGUAGES.get(currentLanguageIndex), false, true, dataType, result); if (result.isAcceptable()) { Object updatedObject = objectHolder.getValue(); String updatedObjectString; + PrismSerializer serializer = pageBase.getPrismContext().serializerFor(updatedLanguage); if (List.class.isAssignableFrom(dataType)) { - updatedObjectString = pageBase.getPrismContext().serializerFor(updatedLanguage) - .serializeObjects((List>) updatedObject, SchemaConstants.C_OBJECTS); + @SuppressWarnings({ "unchecked", "raw" }) + List> list = (List>) updatedObject; + if (list.size() != 1) { + updatedObjectString = serializer.serializeObjects(list, null); + } else { + updatedObjectString = serializer.serialize(list.get(0)); + } } else if (Objectable.class.isAssignableFrom(dataType)) { - updatedObjectString = pageBase.getPrismContext().serializerFor(updatedLanguage) - .serialize(((Objectable) updatedObject).asPrismObject()); + updatedObjectString = serializer.serialize(((Objectable) updatedObject).asPrismObject()); } else { - updatedObjectString = pageBase.getPrismContext().serializerFor(updatedLanguage) - .serializeRealValue(updatedObject); + updatedObjectString = serializer.serializeRealValue(updatedObject); } processLanguageSwitch(target, updatedIndex, updatedLanguage, updatedObjectString); } else { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/SelectableBean.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/SelectableBean.java index 05998647efb..6ca0fa4656c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/SelectableBean.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/SelectableBean.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +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.web.component.data.column.InlineMenuable; @@ -77,7 +78,7 @@ public void setResult(OperationResult result) { this.result = result; } - public void setResult(OperationResultType resultType) { + public void setResult(OperationResultType resultType) throws SchemaException { this.result = OperationResult.createOperationResult(resultType); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java index 96ee04a99d0..70c4388cd78 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java @@ -142,7 +142,7 @@ private void startPerformed(AjaxRequestTarget target) { getScriptingService().evaluateExpression((ScriptingExpressionType) parsed, task, result); result.recordStatus(OperationResultStatus.SUCCESS, "Action executed. Returned " + executionResult.getDataOutput().size() + " item(s). Console and data output available via 'Export to XML' function."); result.addReturn("console", executionResult.getConsoleOutput()); - result.addCollectionOfSerializablesAsReturn("data", executionResult.getDataOutput()); + result.addArbitraryObjectCollectionAsReturn("data", executionResult.getDataOutput()); } catch (ScriptExecutionException|SchemaException|SecurityViolationException e) { result.recordFatalError("Couldn't execute bulk action", e); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't execute bulk action", e); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java index 463482e289f..df2773f1323 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java @@ -410,6 +410,6 @@ public void savePerformed(AjaxRequestTarget target) { } private void validateObject(OperationResult result, Holder objectHolder) { - validateObject(objectViewDto.getXml(), objectHolder, dataLanguage, validateSchema.getObject(), Objectable.class, result); + parseObject(objectViewDto.getXml(), objectHolder, dataLanguage, validateSchema.getObject(), false, Objectable.class, result); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java index 73fda8c9ff7..b1390a72f33 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java @@ -92,13 +92,13 @@ public class PageImportObject extends PageAdminConfiguration { private static final Integer INPUT_FILE = 1; private static final Integer INPUT_XML = 2; - private LoadableModel model; + private LoadableModel optionsModel; private IModel xmlEditorModel; private String dataLanguage; public PageImportObject() { - model = new LoadableModel(false) { + optionsModel = new LoadableModel(false) { @Override protected ImportOptionsType load() { @@ -114,7 +114,7 @@ private void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); - ImportOptionsPanel importOptions = new ImportOptionsPanel(ID_IMPORT_OPTIONS, model); + ImportOptionsPanel importOptions = new ImportOptionsPanel(ID_IMPORT_OPTIONS, optionsModel); mainForm.add(importOptions); final WebMarkupContainer input = new WebMarkupContainer(ID_INPUT); @@ -336,7 +336,7 @@ private void savePerformed(boolean raw, String operationName, AjaxRequestTarget Task task = createSimpleTask(operationName); InputDescription inputDescription = getInputDescription(raw); stream = inputDescription.inputStream; - getModelService().importObjectsFromStream(stream, inputDescription.dataLanguage, model.getObject(), task, result); + getModelService().importObjectsFromStream(stream, inputDescription.dataLanguage, optionsModel.getObject(), task, result); result.recomputeStatus(); } catch (Exception ex) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java index bd343d11302..8c6dd7fa0c0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java @@ -341,6 +341,7 @@ private void saveObjectPolicies(SystemConfigurationType systemConfig) { } newObjectPolicyConfig.getPropertyConstraint().addAll(constraintList); + newObjectPolicyConfig.setConflictResolution(o.getConflictResolution()); confList.add(newObjectPolicyConfig); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ImportOptionsPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ImportOptionsPanel.html index a1d5e8cdd18..378f61c2617 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ImportOptionsPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ImportOptionsPanel.html @@ -54,28 +54,22 @@
- +
-
- - -
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectPolicyPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectPolicyPanel.html index f5f87eda1ed..48f3e2cf117 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectPolicyPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectPolicyPanel.html @@ -32,6 +32,15 @@
+
+ +
+ +
+
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java index 0871c2bf661..256960adbcb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java @@ -3,8 +3,6 @@ import static java.util.stream.Collectors.toList; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; -import java.io.IOException; -import java.io.OutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -17,39 +15,23 @@ import javax.xml.namespace.QName; import org.apache.wicket.AttributeModifier; -import org.apache.wicket.Component; -import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.behavior.Behavior; -import org.apache.wicket.event.Broadcast; -import org.apache.wicket.event.IEventSink; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.export.CSVDataExporter; -import org.apache.wicket.extensions.markup.html.repeater.data.table.export.ExportToolbar; -import org.apache.wicket.extensions.markup.html.repeater.data.table.export.IExportableColumn; import org.apache.wicket.extensions.yui.calendar.DateTimeField; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.EnumChoiceRenderer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; -import org.apache.wicket.markup.html.link.AbstractLink; -import org.apache.wicket.markup.html.link.ResourceLink; -import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.repeater.Item; -import org.apache.wicket.markup.repeater.data.IDataProvider; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; -import org.apache.wicket.request.component.IRequestablePage; -import org.apache.wicket.request.resource.ResourceStreamResource; -import org.apache.wicket.util.resource.IResourceStream; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.gui.api.component.BasePanel; @@ -123,6 +105,7 @@ public class AuditLogViewerPanel extends BasePanel { private static final String ID_MAIN_FORM = "mainForm"; private static final String ID_SEARCH_BUTTON = "searchButton"; + private static final String ID_RESET_SEARCH_BUTTON = "resetSearchButton"; private static final String ID_FEEDBACK = "feedback"; public static final String TARGET_NAME_LABEL_VISIBILITY = "targetNameLabel"; @@ -144,8 +127,7 @@ public class AuditLogViewerPanel extends BasePanel { + ".resolveReferenceName()"; private static final int DEFAULT_PAGE_SIZE = 10; - private IModel auditSearchDto; - private AuditSearchDto searchDto; + private IModel auditSearchModel; private PageBase pageBase; private Map visibilityMap; private AuditLogStorage auditLogStorage; @@ -161,13 +143,12 @@ public AuditLogViewerPanel(String id, PageBase pageBase, AuditSearchDto searchDt public AuditLogViewerPanel(String id, PageBase pageBase, AuditSearchDto searchDto, Map visibilityMap){ super(id); this.pageBase = pageBase; - this.searchDto = searchDto; this.visibilityMap = visibilityMap; - initAuditSearchModel(); + initAuditSearchModel(searchDto); initLayout(); } - private void initAuditSearchModel(){ + private void initAuditSearchModel(AuditSearchDto searchDto){ if (pageBase instanceof PageUser){ auditLogStorage = pageBase.getSessionStorage().getUserHistoryAuditLog(); } else { @@ -176,7 +157,7 @@ private void initAuditSearchModel(){ if (searchDto == null){ searchDto = auditLogStorage.getSearchDto(); } - auditSearchDto = new Model(searchDto); + auditSearchModel = new Model(searchDto); } @@ -200,7 +181,7 @@ private void initParametersPanel(Form mainForm) { mainForm.add(parametersPanel); PropertyModel fromModel = new PropertyModel( - auditSearchDto, AuditSearchDto.F_FROM); + auditSearchModel, AuditSearchDto.F_FROM); DatePanel from = new DatePanel(ID_FROM, fromModel); DateValidator dateFromValidator = WebComponentUtil.getRangeValidator(mainForm, @@ -214,7 +195,7 @@ private void initParametersPanel(Form mainForm) { from.setOutputMarkupId(true); parametersPanel.add(from); - PropertyModel toModel = new PropertyModel(auditSearchDto, + PropertyModel toModel = new PropertyModel(auditSearchModel, AuditSearchDto.F_TO); DatePanel to = new DatePanel(ID_TO, toModel); DateValidator dateToValidator = WebComponentUtil.getRangeValidator(mainForm, @@ -228,7 +209,7 @@ private void initParametersPanel(Form mainForm) { to.setOutputMarkupId(true); parametersPanel.add(to); - PropertyModel changedItemModel = new PropertyModel(auditSearchDto, + PropertyModel changedItemModel = new PropertyModel(auditSearchModel, AuditSearchDto.F_CHANGED_ITEM); ItemPathPanel changedItemPanel = new ItemPathPanel(ID_CHANGED_ITEM, changedItemModel, pageBase); @@ -237,7 +218,7 @@ private void initParametersPanel(Form mainForm) { changedItemPanel.setOutputMarkupId(true); parametersPanel.add(changedItemPanel); - PropertyModel hostIdentifierModel = new PropertyModel<>(auditSearchDto, + PropertyModel hostIdentifierModel = new PropertyModel<>(auditSearchModel, AuditSearchDto.F_HOST_IDENTIFIER); TextPanel hostIdentifier = new TextPanel<>(ID_HOST_IDENTIFIER, hostIdentifierModel); hostIdentifier.getBaseFormComponent().add(new EmptyOnChangeAjaxFormUpdatingBehavior()); @@ -248,7 +229,7 @@ private void initParametersPanel(Form mainForm) { ListModel eventTypeListModel = new ListModel( Arrays.asList(AuditEventTypeType.values())); PropertyModel eventTypeModel = new PropertyModel( - auditSearchDto, AuditSearchDto.F_EVENT_TYPE); + auditSearchModel, AuditSearchDto.F_EVENT_TYPE); DropDownChoicePanel eventType = new DropDownChoicePanel( ID_EVENT_TYPE, eventTypeModel, eventTypeListModel, new EnumChoiceRenderer(), true); @@ -265,7 +246,7 @@ private void initParametersPanel(Form mainForm) { ListModel eventStageListModel = new ListModel( Arrays.asList(AuditEventStageType.values())); PropertyModel eventStageModel = new PropertyModel( - auditSearchDto, AuditSearchDto.F_EVENT_STAGE); + auditSearchModel, AuditSearchDto.F_EVENT_STAGE); DropDownChoicePanel eventStageField = new DropDownChoicePanel( ID_EVENT_STAGE_FIELD, eventStageModel, eventStageListModel, new EnumChoiceRenderer(), true); @@ -278,7 +259,7 @@ private void initParametersPanel(Form mainForm) { ListModel outcomeListModel = new ListModel( Arrays.asList(OperationResultStatusType.values())); PropertyModel outcomeModel = new PropertyModel( - auditSearchDto, AuditSearchDto.F_OUTCOME); + auditSearchModel, AuditSearchDto.F_OUTCOME); DropDownChoicePanel outcome = new DropDownChoicePanel( ID_OUTCOME, outcomeModel, outcomeListModel, new EnumChoiceRenderer(), true); @@ -297,7 +278,7 @@ private void initParametersPanel(Form mainForm) { } } ListModel channelListModel = new ListModel(channelQnameList); - PropertyModel channelModel = new PropertyModel(auditSearchDto, + PropertyModel channelModel = new PropertyModel(auditSearchModel, AuditSearchDto.F_CHANNEL); DropDownChoicePanel channel = new DropDownChoicePanel(ID_CHANNEL, channelModel, channelListModel, new QNameChoiceRenderer(), true); @@ -310,7 +291,7 @@ private void initParametersPanel(Form mainForm) { allowedClasses.add(UserType.class); MultiValueChoosePanel chooseInitiatorPanel = new SingleValueChoosePanel( ID_INITIATOR_NAME, allowedClasses, objectReferenceTransformer, - new PropertyModel(auditSearchDto, AuditSearchDto.F_INITIATOR_NAME)); + new PropertyModel(auditSearchModel, AuditSearchDto.F_INITIATOR_NAME)); parametersPanel.add(chooseInitiatorPanel); WebMarkupContainer targetOwnerName = new WebMarkupContainer(ID_TARGET_OWNER_NAME); @@ -318,7 +299,7 @@ private void initParametersPanel(Form mainForm) { parametersPanel.add(targetOwnerName); MultiValueChoosePanel chooseTargerOwnerPanel = new SingleValueChoosePanel( - ID_TARGET_OWNER_NAME_FIELD, allowedClasses, objectReferenceTransformer, new PropertyModel(auditSearchDto, AuditSearchDto.F_TARGET_OWNER_NAME)); + ID_TARGET_OWNER_NAME_FIELD, allowedClasses, objectReferenceTransformer, new PropertyModel(auditSearchModel, AuditSearchDto.F_TARGET_OWNER_NAME)); chooseTargerOwnerPanel.add(visibilityByKey(visibilityMap, TARGET_OWNER_FIELD_VISIBILITY)); targetOwnerName.add(chooseTargerOwnerPanel); @@ -331,47 +312,59 @@ private void initParametersPanel(Form mainForm) { MultiValueChoosePanel chooseTargetPanel = new MultiValueChoosePanel( ID_TARGET_NAME_FIELD, - new PropertyModel>(auditSearchDto, AuditSearchDto.F_TARGET_NAMES_OBJECTS), + new PropertyModel>(auditSearchModel, AuditSearchDto.F_TARGET_NAMES_OBJECTS), allowedClassesAll); chooseTargetPanel.setOutputMarkupId(true); chooseTargetPanel.add(visibilityByKey(visibilityMap, TARGET_NAME_FIELD_VISIBILITY)); targetName.add(chooseTargetPanel); - AjaxSubmitButton ajaxButton = new AjaxSubmitButton(ID_SEARCH_BUTTON, + AjaxSubmitButton searchButton = new AjaxSubmitButton(ID_SEARCH_BUTTON, createStringResource("BasicSearchPanel.search")) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form form) { - auditLogStorage.setSearchDto(searchDto); - auditLogStorage.setPageNumber(0); - Form mainForm = (Form) getParent().getParent(); - addOrReplaceTable(mainForm); - pageBase.getFeedbackPanel().getFeedbackMessages().clear(); + searchUpdatePerformed(target, form, auditSearchModel.getObject()); + } + + @Override + protected void onError(AjaxRequestTarget target, Form form){ target.add(pageBase.getFeedbackPanel()); - target.add(mainForm); + } + }; + searchButton.setOutputMarkupId(true); + parametersPanel.add(searchButton); + + AjaxSubmitButton resetSearchButton = new AjaxSubmitButton(ID_RESET_SEARCH_BUTTON, + createStringResource("AuditLogViewerPanel.resetSearchButton")) { + private static final long serialVersionUID = 1L; + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + auditSearchModel.setObject(new AuditSearchDto()); + searchUpdatePerformed(target, form, new AuditSearchDto()); } @Override - protected void onError(AjaxRequestTarget target, Form form){ + protected void onError(AjaxRequestTarget target, Form form){ target.add(pageBase.getFeedbackPanel()); } }; - + resetSearchButton.setOutputMarkupId(true); + parametersPanel.add(resetSearchButton); + WebMarkupContainer valueRefTargetNameContainer = new WebMarkupContainer(ID_VALUE_REF_TARGET_NAMES); valueRefTargetNameContainer.add(visibilityByKey(visibilityMap, TARGET_NAME_LABEL_VISIBILITY)); parametersPanel.add(valueRefTargetNameContainer); MultiValueChoosePanel chooseValueRefTargetNamePanel = new MultiValueChoosePanel( ID_VALUE_REF_TARGET_NAMES_FIELD, - new PropertyModel>(auditSearchDto, AuditSearchDto.F_VALUE_REF_TARGET_NAME), + new PropertyModel>(auditSearchModel, AuditSearchDto.F_VALUE_REF_TARGET_NAME), allowedClassesAll); chooseValueRefTargetNamePanel.setOutputMarkupId(true); chooseValueRefTargetNamePanel.add(visibilityByKey(visibilityMap, VALUE_REF_TARGET_NAME_FIELD_VISIBILITY)); valueRefTargetNameContainer.add(chooseValueRefTargetNamePanel); - ajaxButton.setOutputMarkupId(true); - parametersPanel.add(ajaxButton); } // Serializable as it becomes part of panel which is serialized @@ -402,7 +395,7 @@ private void addOrReplaceTable(Form mainForm) { public Map getParameters() { Map parameters = new HashMap(); - AuditSearchDto search = auditSearchDto.getObject(); + AuditSearchDto search = auditSearchModel.getObject(); parameters.put("from", search.getFrom()); parameters.put("to", search.getTo()); @@ -624,6 +617,19 @@ private void createReferenceColumn(ObjectReferenceType ref, Item item, String co item.add(new AttributeModifier("style", new Model("width: 10%;"))); } + private void searchUpdatePerformed(AjaxRequestTarget target, Form form, AuditSearchDto searchDto){ + auditLogStorage.setSearchDto(searchDto); + auditLogStorage.setPageNumber(0); + Form mainForm = getMainFormComponent(); + addOrReplaceTable(mainForm); + pageBase.getFeedbackPanel().getFeedbackMessages().clear(); + target.add(pageBase.getFeedbackPanel()); + target.add(mainForm); + } + + private Form getMainFormComponent(){ + return (Form) get(ID_MAIN_FORM); + } // public WebMarkupContainer getFeedbackPanel() { // return (FeedbackPanel) get(pageBase.createComponentPath(ID_MAIN_FORM, ID_FEEDBACK)); // } 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 ae66b29a9b3..3949c22ed4d 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 @@ -84,6 +84,7 @@ 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.exception.SystemException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -634,7 +635,12 @@ public IModel getDataModel(IModel> rowModel) @Override public void onClick(AjaxRequestTarget target, IModel> rowModel) { OperationResultType resultType = getResult(rowModel); - OperationResult result = OperationResult.createOperationResult(resultType); + OperationResult result; + try { + result = OperationResult.createOperationResult(resultType); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } OperationResultPanel body = new OperationResultPanel( ResourceContentPanel.this.getPageBase().getMainPopupBodyId(), diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java index 7369d767eb5..5fae91d28bc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/component/TestConnectionMessagesPanel.java @@ -83,7 +83,7 @@ private void initResultsModel(String resourceOid) { for (OperationResult subresult: result.getSubresults()) { if (isConnectorResult(subresult)) { ConnectorStruct connectorStruct = new ConnectorStruct(); - connectorStruct.connectorName = (String) subresult.getParams().get(OperationResult.PARAM_NAME); + connectorStruct.connectorName = subresult.getParamSingle(OperationResult.PARAM_NAME); if (connectorStruct.connectorName == null) { connectorStruct.connectorName = ""; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java index 753c1b753a5..5a1d82feece 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java @@ -25,6 +25,8 @@ 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.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -109,7 +111,11 @@ private ObjectWrapper loadAccount(PageParameters parameters) { ObjectWrapper wrapper = ObjectWrapperUtil.createObjectWrapper(null, null, account, ContainerStatus.MODIFYING, task, this); OperationResultType fetchResult = account.getPropertyRealValue(ShadowType.F_FETCH_RESULT, OperationResultType.class); - wrapper.setFetchResult(OperationResult.createOperationResult(fetchResult)); + try { + wrapper.setFetchResult(OperationResult.createOperationResult(fetchResult)); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } wrapper.setShowEmpty(false); return wrapper; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java index a5744026aea..4b625155b9b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java @@ -288,7 +288,7 @@ private void fillInParentTaskAttributes(TaskType taskType, TaskService taskServi } } - private void fillInOperationResultAttributes(TaskType taskType) { + private void fillInOperationResultAttributes(TaskType taskType) throws SchemaException { opResult = new ArrayList(); if (taskType.getResult() != null) { taskOperationResult = OperationResult.createOperationResult(taskType.getResult()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/DefaultGuiProgressListener.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/DefaultGuiProgressListener.java index 168f321d9c7..80319d20436 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/DefaultGuiProgressListener.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/DefaultGuiProgressListener.java @@ -57,8 +57,7 @@ import java.util.List; import java.util.Map; -import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.FOCUS_OPERATION; -import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.RESOURCE_OBJECT_OPERATION; +import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.*; import static com.evolveum.midpoint.model.api.ProgressInformation.StateType; import static com.evolveum.midpoint.model.api.ProgressInformation.StateType.ENTERING; import static com.evolveum.midpoint.model.api.ProgressInformation.StateType.EXITING; @@ -85,7 +84,7 @@ public DefaultGuiProgressListener(ProgressReportingAwarePage parentPage, Progres public void onProgressAchieved(ModelContext modelContext, ProgressInformation progressInformation) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("onProgressAchieved: {}\n, modelContext = \n{}", new Object[]{progressInformation.debugDump(), modelContext.debugDump(2)}); + LOGGER.trace("onProgressAchieved: {}\n, modelContext = \n{}", progressInformation.debugDump(), modelContext.debugDump(2)); } if (progressDto == null) { @@ -97,20 +96,19 @@ public void onProgressAchieved(ModelContext modelContext, ProgressInformation pr progressDto.log(progressInformation.getMessage()); } - List progressReportActivities = progressDto.getProgressReportActivities(); - - if (progressInformation != null) { - + ProgressInformation.ActivityType activity = progressInformation.getActivityType(); + if (activity != CLOCKWORK && activity != WAITING) { + List progressReportActivities = progressDto.getProgressReportActivities(); ProgressReportActivityDto si = findRelevantStatusItem(progressReportActivities, progressInformation); - if (si == null) { progressDto.add(createStatusItem(progressInformation, modelContext)); } else { updateStatusItemState(si, progressInformation, modelContext); } + addExpectedStatusItems(progressReportActivities, modelContext); + } else { + // these two should not be visible in the list of activities } - - addExpectedStatusItems(progressReportActivities, modelContext); } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/dto/FocusSubwrapperDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/dto/FocusSubwrapperDto.java index 6c7a7ffade1..1d5cf542174 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/dto/FocusSubwrapperDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/dto/FocusSubwrapperDto.java @@ -29,8 +29,9 @@ * @author lazyman */ public class FocusSubwrapperDto implements Serializable { + private static final long serialVersionUID = 1L; - private ObjectWrapper object; + private ObjectWrapper object; private UserDtoStatus status; private boolean loadedOK = true; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java index 66b447b0802..315027d9056 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java @@ -18,7 +18,10 @@ import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; import java.io.InputStreamReader; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.io.Reader; import java.net.URI; import java.net.URL; @@ -51,6 +54,10 @@ import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; import org.apache.wicket.core.request.mapper.MountedMapper; +import org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream; +import org.apache.wicket.core.util.objects.checker.IObjectChecker; +import org.apache.wicket.core.util.objects.checker.NotDetachedModelChecker; +import org.apache.wicket.core.util.objects.checker.ObjectSerializationChecker; import org.apache.wicket.markup.head.PriorityFirstComparator; import org.apache.wicket.markup.html.SecurePackageResourceGuard; import org.apache.wicket.markup.html.WebPage; @@ -59,6 +66,7 @@ import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.request.resource.SharedResourceReference; import org.apache.wicket.resource.loader.IStringResourceLoader; +import org.apache.wicket.serialize.java.JavaSerializer; import org.apache.wicket.settings.ApplicationSettings; import org.apache.wicket.settings.ResourceSettings; import org.apache.wicket.spring.injection.annot.SpringComponentInjector; @@ -262,6 +270,7 @@ public void init() { if (RuntimeConfigurationType.DEVELOPMENT.equals(getConfigurationType())) { getDebugSettings().setAjaxDebugModeEnabled(true); getDebugSettings().setDevelopmentUtilitiesEnabled(true); + initializeDevelopmentSerializers(); } //pretty url for resources (e.g. images) @@ -285,7 +294,23 @@ public void init() { new DescriptorLoader().loadData(this); } - private void mountFiles(String path, Class clazz) { + private void initializeDevelopmentSerializers() { +// JavaSerializer javaSerializer = new JavaSerializer( getApplicationKey() ) { +// @Override +// protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException { +// LOGGER.info("XXXXXXX YX Y"); +//// IObjectChecker checker1 = new MidPointObjectChecker(); +////// IObjectChecker checker2 = new NotDetachedModelChecker(); +//// IObjectChecker checker3 = new ObjectSerializationChecker(); +//// return new CheckingObjectOutputStream(out, checker1, checker3); +// return new ObjectOutputStream(out); +// } +// }; +// getFrameworkSettings().setSerializer( javaSerializer ); + + } + + private void mountFiles(String path, Class clazz) { try { List list = new ArrayList<>(); String packagePath = clazz.getPackage().getName().replace('.', '/'); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointObjectChecker.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointObjectChecker.java new file mode 100644 index 00000000000..bd2cf76ab72 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointObjectChecker.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.web.security; + +import java.util.List; + +import javax.xml.bind.JAXBElement; + +import org.apache.wicket.core.util.objects.checker.IObjectChecker; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.util.DOMUtil; +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.ResourceType; + +/** + * @author semancik + * + */ +public class MidPointObjectChecker implements IObjectChecker { + + private static final Trace LOGGER = TraceManager.getTrace(MidPointObjectChecker.class); + + private String label; + + public MidPointObjectChecker() { + this(null); + } + + public MidPointObjectChecker(String label) { + super(); + this.label = label; + } + + /* (non-Javadoc) + * @see org.apache.wicket.core.util.objects.checker.IObjectChecker#check(java.lang.Object) + */ + @SuppressWarnings("unchecked") + @Override + public Result check(Object object) { + + if (label != null) { + LOGGER.info("CHECK: {}: {}", label, object); + } + + if (object instanceof PrismObject) { + return checkObject((PrismObject)object); + } else if (object instanceof ObjectType) { + return checkObject(((ObjectType)object).asPrismObject()); + } else if (object instanceof Document) { + return new Result( Result.Status.FAILURE, "Storage of DOM documents not allowed: "+object); +// LOGGER.warn("Attempt to serialize DOM element: {}", DOMUtil.getQName((Element)object)); +// } else if (object instanceof Element) { +// return new Result( Result.Status.FAILURE, "Storage of DOM elements not allowed: "+object); +//// LOGGER.warn("Attempt to serialize DOM element: {}", DOMUtil.getQName((Element)object)); + + // JAXBElement: expression evaluator in expressions, it is JAXBElement even in prism objects +// } else if (object instanceof JAXBElement) { +// return new Result( Result.Status.FAILURE, "Storage of JAXB elements not allowed: "+object); +// LOGGER.warn("Attempt to serialize DOM element: {}", DOMUtil.getQName((Element)object)); + } + + return Result.SUCCESS; + } + + + + private Result checkObject(PrismObject object) { + + LOGGER.info("Check for serialization of prism object: {}", object); +// if (object.canRepresent(ResourceType.class)) { +// return new Result( Result.Status.FAILURE, "Storage of ResourceType objects not allowed: "+object); +// } + + return Result.SUCCESS; + } + + + + /* (non-Javadoc) + * @see org.apache.wicket.core.util.objects.checker.IObjectChecker#getExclusions() + */ + @Override + public List> getExclusions() { + return null; + } + +} diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 50df1abf4d1..072cdec9ad5 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -387,8 +387,7 @@ importOptionsPanel.stopAfter=Stop after errors exceed importOptionsPanel.summarizeErrors=Summarize errors importOptionsPanel.summarizeSuccesses=Summarize successes importOptionsPanel.validateDynamicSchema=Validate dynamic schema -importOptionsPanel.validateStaticSchema=Validate static schema -importOptionsPanel.note=(*) These options are supported only when importing XML +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Approval schema ItemApprovalPanel.currentWorkItems=Current work items ItemApprovalPanel.nextStages=Following stages @@ -611,6 +610,8 @@ ObjectPolicyDialog.button.save=Save ObjectPolicyDialog.label=Edit Object Policy ObjectPolicyDialog.label.oidBound.help=Oid bound - The property value will be bound to OID. This property will be set to the value of OID and it cannot be changed. ObjectPolicyDialog.propertyConstraint=Property constraint +ObjectPolicyDialog.conflictResolution=Conflict resolution +ObjectPolicyDialog.present=(present) ObjectPolicyDialog.property.placeholder=Insert property path ObjectPolicyDialog.subtype=Object subtype ObjectPolicyDialog.template=Object template @@ -2560,7 +2561,7 @@ runReportPopupContent.param.name.initiatorName = Initiator Name runReportPopupContent.param.name.outcome = Outcome runReportPopupContent.param.name=Parameter name runReportPopupContent.param.name.targetName = Target Name -runReportPopupContent.param.name.filter=Filter resulting roles? true/false (default is false) +runReportPopupContent.param.name.filter=Filter resulting roles? true/false (default is false) runReportPopupContent.param.name.to = Date To runReportPopupContent.param.value=Parameter value runReportPopupContent.param.name.alsoClosedCampaigns=Also closed campaigns? (default is false) @@ -3592,6 +3593,7 @@ PageAuditLogViewer.outcomeLabel=Outcome PageAuditLogViewer.changedItem=Item changed PageAuditLogViewer.valueRefTargetNamesLabel=Reference Target AuditLogViewerPanel.dateValidatorMessage=From date must be before To date. +AuditLogViewerPanel.resetSearchButton=Reset search AuditEventRecordType.timestamp=Time AuditEventRecordType.initiatorRef=Initiator AuditEventRecordType.taskIdentifier=Task Identifier @@ -3699,7 +3701,7 @@ wf.causeName=Cause name wf.causeDisplayName=Cause display name PageAccountActivation.account.activation.successful=Activation of accounts was successful PageAccountActivation.account.activation.failed=Failed to activate accounts. Please, contact system administrator -PageAccountActivation.activated.shadows=Activated shadows: +PageAccountActivation.activated.shadows=Activated shadows: PageAccountActivation.button.activate=Activate PageAccountActivation.activate.accounts.label=Account activation for user '{0}'. PageAccountActivation.provide.password=Please, provide your password to activate accounts. @@ -3744,4 +3746,5 @@ ObjectReferenceType.relation=Relation FocusType.consents=Consents AbstractAssignmentDetailsPanel.properties=Properties AssignmentPanel.doneButton=Done -AssignmentPanel.cancelButton=Cancel \ No newline at end of file +AssignmentPanel.cancelButton=Cancel +ObjectPolicyConfigurationEditor.conflictResolution=(conflict resolution) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties index 024661e5a43..2767657089d 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties @@ -392,7 +392,7 @@ importOptionsPanel.stopAfter=Skončit při překročení limitu chyb importOptionsPanel.summarizeErrors=Sumarizovat chyby importOptionsPanel.summarizeSuccesses=Sumarizovat úspěchy importOptionsPanel.validateDynamicSchema=Validovat dynamické schéma -importOptionsPanel.validateStaticSchema=Validovat statické schéma +importOptionsPanel.validateStaticSchema=Validovat statické schéma (jen pro XML soubory) ItemApprovalPanel.approvalSchema=Schéma schvalování ItemApprovalPanel.currentWorkItems=Aktuální pracovní položky ItemApprovalPanel.nextStages=Následující fáze @@ -1592,7 +1592,7 @@ PageImportObject.embeddedEditor=Vložený editor PageImportObject.file=Soubor PageImportObject.getObjectsFrom=Získat objekt z pageImportObject.message.emptyXml=Nepodařilo se uložit prázdné XML. -PageImportObject.message.help=Vyberte XML sobor pro import. +PageImportObject.message.help=Vyberte XML, JSON nebo YAML soubor pro import. pageImportObject.message.nullFile=Nahraný soubor je null. PageImportObject.title=Importovat objekty PageInternals.button.changeTime=Změnit čas @@ -1726,7 +1726,7 @@ PageNewReport.embeddedEditor=Vložený editor PageNewReport.file=Soubor PageNewReport.getObjectsFrom=Vytvořit report z PageNewReport.message.emptyXml=Nepodařilo se uložit prázdné XML. -PageNewReport.message.help=Vyberte XML sobor pro import. +PageNewReport.message.help=Vyberte XML soubor pro import. PageNewReport.message.nullFile=Nahraný soubor je null. PageNewReport.title=Importovat Jasper report PageOrgTree.message.noOrgStructDefined=Org. struktura není definována. @@ -3723,3 +3723,4 @@ AbstractAssignmentDetailsPanel.doneButton=Hotovo ApprovalProcessesPreviewPanel.processRelatedTo=Schvalovací proces vztahující se k {0} ApprovalProcessesPreviewPanel.process=Schvalovací proces ApprovalProcessExecutionInformationPanel.stage=Fáze {0}/{1} +PageImportResource.title=Import definice aplikace diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties index 14465f4974d..58ef4274caa 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties @@ -388,7 +388,7 @@ importOptionsPanel.stopAfter=Anhalten, wenn die Fehleranzahl mehr als X ist importOptionsPanel.summarizeErrors=Fehler zusammenfassen importOptionsPanel.summarizeSuccesses=Erfolge zusammenfassen importOptionsPanel.validateDynamicSchema=Dynamisches Schema überprüfen -importOptionsPanel.validateStaticSchema=Statisches Schema überprüfen +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Schemabestätigung ItemApprovalPanel.currentWorkItems=aktuelle Arbeitselemente ItemApprovalPanel.nextStages=Following stages @@ -1587,7 +1587,7 @@ PageImportObject.embeddedEditor=Eingebetteter Editor PageImportObject.file=Datei PageImportObject.getObjectsFrom=Hole Objekt von pageImportObject.message.emptyXml=Ein leeres XML kann nicht gespeichert werden. -PageImportObject.message.help=XML Importdatei auswählen +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Hochgeladene Datei ist leer. PageImportObject.title=Objekte importieren PageInternals.button.changeTime=Änderungszeitpunkt @@ -3695,3 +3695,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties index 6eba480c58e..5373235340b 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Stop after errors exceed importOptionsPanel.summarizeErrors=Summarize errors importOptionsPanel.summarizeSuccesses=Summarize successes importOptionsPanel.validateDynamicSchema=Validate dynamic schema -importOptionsPanel.validateStaticSchema=Validate static schema +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Approval schema ItemApprovalPanel.currentWorkItems=Current work items ItemApprovalPanel.nextStages=Following stages @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties index c6a65ff4767..4560c878971 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Se detiene después de los errores exceden importOptionsPanel.summarizeErrors=Resumir errores importOptionsPanel.summarizeSuccesses=Resumir éxitos importOptionsPanel.validateDynamicSchema=Validar esquema dinámico -importOptionsPanel.validateStaticSchema=Validar esquema estático +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Esquema de Aprobación ItemApprovalPanel.currentWorkItems=Puntos del actual trabajo ItemApprovalPanel.nextStages=Following stages @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Editor embebido PageImportObject.file=Fichero PageImportObject.getObjectsFrom=Obtener objetos desde pageImportObject.message.emptyXml=No se puede guardar un xml vacío. -PageImportObject.message.help=Escoger XML archivo para importar. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Fichero subido es nulo. PageImportObject.title=Importar objetos PageInternals.button.changeTime=Cambiar tiempo @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties index 1dcbb7d1248..5e3b25ee88e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Peatub kui vigade arv ületab importOptionsPanel.summarizeErrors=Vigade kokkuvõte importOptionsPanel.summarizeSuccesses=Õnnestumiste kokkuvõte importOptionsPanel.validateDynamicSchema=Kontrolli dünaamilist skeemi -importOptionsPanel.validateStaticSchema=Kontrolli staatilist skeemi +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Kinnitamise skeem ItemApprovalPanel.currentWorkItems=Aktiivsed tööüksused ItemApprovalPanel.nextStages=Järgnevad etapid @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Tekstiredaktoriga PageImportObject.file=Failist PageImportObject.getObjectsFrom=Objektid võetakse pageImportObject.message.emptyXml=Ei saa salvestada tühja xml-i. -PageImportObject.message.help=Vali imporditav XML-fail. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Üleslaaditud fail on null. PageImportObject.title=Objektide importimine PageInternals.button.changeTime=Muuda aega @@ -3096,9 +3096,9 @@ MyRequestsPanel.started = Algas MyRequestsPanel.rejected = Tagasi lükatud MyRequestsPanel.approved = Kinnitatud MyRequestsPanel.inProgress = Pooleli -MyRequestsPanel.unknown = Unknown +MyRequestsPanel.unknown = Tundmatu MyRequestsPanel.future = Future -MyRequestsPanel.cancelled = Cancelled +MyRequestsPanel.cancelled = Loobutud MyRequestsPanel.name = Nimi PageSelfProfile.title=Redigeeri profiili PageSelfDashboard.title=Kodu @@ -3203,8 +3203,8 @@ PagePreviewChanges.primaryChangesOne=Esmased muudatused: {0} objekt PagePreviewChanges.primaryChangesMore=Esmased muudatused: {0} objekti PagePreviewChanges.secondaryChangesOne=Teisesed muudatused: {0} objekt PagePreviewChanges.secondaryChangesMore=Teisesed muudatused: {0} objekti -PagePreviewChanges.policyViolationMessages=Policy violation messages -PagePreviewChanges.approvalsRequired=Approvals required +PagePreviewChanges.policyViolationMessages=Poliitika rikkumise teated +PagePreviewChanges.approvalsRequired=Nõutavad kinnitused PagePreviewChanges.button.continueEditing=Jätka redigeerimist PagePreviewChanges.button.save=Salvesta ScenePanel.object={0} objekt @@ -3691,5 +3691,6 @@ PolicyRule.situationLabel=Situatsioon PolicyRule.actionLabel=Tegevus AbstractAssignmentDetailsPanel.doneButton=Valmis ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} -ApprovalProcessesPreviewPanel.process=Approval process -ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +ApprovalProcessesPreviewPanel.process=Kinnitusprotsess +ApprovalProcessExecutionInformationPanel.stage=Etapp {0}/{1} +PageImportResource.title=Impordi ressursi definitsioon diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties index 1a97da42200..ed21c460aed 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # -AbstractRoleType.delegable=Delegable -AbstractRoleType.requestable=Requestable +AbstractRoleType.delegable=Delegoitavissa +AbstractRoleType.requestable=Pyydettävissä ACAttributePanel.button.showExprEditor=Näytä Lauseke ACAttributePanel.hasOutbound=Sisältää ulosmenevää kartoistusta ACAttributePanel.required=Vaadittu @@ -42,9 +42,9 @@ AssignmentEditorPanel.description=Kuvaus AssignmentEditorPanel.enabledFrom={0}, from {1,date,medium} AssignmentEditorPanel.enabledFromTo={0}, from {1,date,medium} to {2,date,medium} AssignmentEditorPanel.enabledTo={0}, to {1,date,medium} -AssignmentEditorPanel.focusType=Focus type +AssignmentEditorPanel.focusType=Fokus tyyppi AssignmentEditorPanel.hideEmpty=Piilota tyhjät -AssignmentEditorPanel.loadError=Error loading object +AssignmentEditorPanel.loadError=Virhe objektia ladatessa AssignmentEditorPanel.manager=Manageri AssignmentEditorPanel.member=Jäsen AssignmentEditorPanel.name.focus=(kohdista kartoitus) @@ -57,22 +57,22 @@ AssignmentEditorPanel.showEmpty=Näytä tyhjä AssignmentEditorPanel.showMore=Näytä lisää AssignmentEditorPanel.targetError=Toimeksiannon kohdetta ei löytynyt. Joko kohde oid on epämuodostunut tai kohde objektia ei ole olemassa. AssignmentEditorPanel.target=Kohde -AssignmentEditorPanel.tenantRef=Tenant +AssignmentEditorPanel.tenantRef=Haltija AssignmentEditorPanel.undefined=Määrittelemätön AssignmentEditorPanel.metadataBlock={0} Metadata AssignmentActivationPopupPanel.title=Aktivointi AssignmentActivationPopupPanel.okButton=OK AssignmentActivationPopupPanel.cancelButton=Peruuta -MetadataPanel.requestTimestamp=Request timestamp +MetadataPanel.requestTimestamp=Pyydä aikaleimaa MetadataPanel.requestorRef=Pyytäjä -MetadataPanel.createTimestamp=Create timestamp +MetadataPanel.createTimestamp=Luo aikaleima MetadataPanel.creatorRef=Luoja MetadataPanel.createApproverRef=Luo hyväksyjä -MetadataPanel.createApprovalTimestamp=Create Approval Timestamp -MetadataPanel.modifyTimestamp=Modify timestamp +MetadataPanel.createApprovalTimestamp=Luo Hyväksymis Aikaleima +MetadataPanel.modifyTimestamp=Muuta aikaleima MetadataPanel.modifierRef=Muokkaaja -MetadataPanel.modifyApproverRef=Modify approver -MetadataPanel.modifyApprovalTimestamp=Modify approval timestamp +MetadataPanel.modifyApproverRef=muuta hyväksyjä +MetadataPanel.modifyApprovalTimestamp=Muuta hyväksymis aikaleima RelationTypes.MANAGER=Manageri RelationTypes.OWNER=Omistaja RelationTypes.APPROVER=Hyväksyjä @@ -80,40 +80,40 @@ RelationTypes.MEMBER=Jäsen DelegationEditorPanel.from=From DelegationEditorPanel.to=To DelegationEditorPanel.meLabel=Nykyinen käyttäjä -DelegationEditorPanel.limitPrivilegesButton=Limit privileges -DelegationEditorPanel.privileges=Assignment privileges -DelegationEditorPanel.workflowApprovals=Workflow approvals -DelegationEditorPanel.delegateApprovalWorkItems=Delegate completion of approval work items -DelegationEditorPanel.delegateCertificationWorkItems=Delegate review of certification work items -DelegationEditorPanel.allPrivilegesLabel=Delegate all/selected assignment privileges +DelegationEditorPanel.limitPrivilegesButton=Rajoita etuoikeuksia +DelegationEditorPanel.privileges=Toimeksianto etuoikeudet +DelegationEditorPanel.workflowApprovals=Työnkulku hyväksynnät +DelegationEditorPanel.delegateApprovalWorkItems=Delegoi hyväksyntä työalkioiden valmistuminen +DelegationEditorPanel.delegateCertificationWorkItems=Delegoi sertifikointi työalkioiden arviointi +DelegationEditorPanel.allPrivilegesLabel=Delegoi kaikki/valitut toimeeksianto etuoikeudet DelegationEditorPanel.noPrivilegesLabel=Ei etuoikeuksia -DelegationEditorPanel.delegateManagementWorkItems=Delegate completion of case management work items +DelegationEditorPanel.delegateManagementWorkItems=Delegoi tapaus hallinnan työalkioiden valmistuminen AssignmentPreviewDialog.button.cancel=Peruuta AssignmentPreviewDialog.column.description=Kuvaus AssignmentPreviewDialog.column.intent=Aikomus -AssignmentPreviewDialog.column.kind=Kind +AssignmentPreviewDialog.column.kind=Laji AssignmentPreviewDialog.column.name=Nimi AssignmentPreviewDialog.column.orgRef=Org -AssignmentPreviewDialog.column.tenant=Tenant +AssignmentPreviewDialog.column.tenant=Haltija AssignmentPreviewDialog.label=Tarkastele suoria ja epäsuoria toimeksiantoja -AssignmentPreviewDialog.delegationPreviewLabel=Limit privileges +AssignmentPreviewDialog.delegationPreviewLabel=Rajoita etuoikeuksia AssignmentPreviewDialog.type.direct=Suoraan AssignmentPreviewDialog.type.indirect=Epäsuora AssignmentTablePanel.menu.assign=Osoita AssignmentTablePanel.menu.assignOrg=Osoita Org. -AssignmentTablePanel.menu.assignOrg.noorgs=No organization structure defined. +AssignmentTablePanel.menu.assignOrg.noorgs=Organisaatio rakennetta ei tarkennettu. AssignmentTablePanel.menu.assignRole=Osoita rooli -AssignmentTablePanel.menu.addDelegation=Add delegation -AssignmentTablePanel.menu.deleteDelegation=Delete delegation +AssignmentTablePanel.menu.addDelegation=Lisää delegointi +AssignmentTablePanel.menu.deleteDelegation=Poista delegointi AssignmentTablePanel.menu.unassign=Poista osoitus AssignmentTablePanel.menu.showAllAssignments=Näytä kaikki Osoitukset -AssignmentTablePanel.message.couldntAssignObject=Ei voitu osoittaa '{0}', syy: {1}. +AssignmentTablePanel.message.couldntAssignObject=Ei voitu osoittaa objektia '{0}', syy: {1}. AssignmentTablePanel.message.illegalAssignmentState=Laiton toimeksiannon tila '{0}'. AssignmentTablePanel.message.noAssignmentSelected=Ei osoitusta valittuna -AssignmentTablePanel.message.noDelegationsSelected=No delegation selected. +AssignmentTablePanel.message.noDelegationsSelected=Delegointia ei valittu. AssignmentTablePanel.modal.message.delete=Oletko varma, että haluat poistaa {0} toimeksiantoa? -AssignmentTablePanel.modal.message.deleteDelegation=Do you really want to delete {0} delegation(s)? -AssignmentTablePanel.modal.message.noDelegationWarning=User doesn't have any delegable item +AssignmentTablePanel.modal.message.deleteDelegation=Haluatko varmasti poistaa delegaatio(t) {0}? +AssignmentTablePanel.modal.message.noDelegationWarning=Käyttäjällä ei ole delegoitavaa asiaa AssignmentTablePanel.modal.title.confirmDeletion=Vahvista poisto AssignmentTablePanel.modal.title.selectAssignment=valitse objekti(t) associationAttribute.nullValid=Valitse Yksi @@ -132,17 +132,17 @@ capabilityActivationPanel.label.disableList=Poista Lista käytöstä capabilityActivationPanel.label.enabledDisabled=Käytössä/poistettu käytöstä capabilityActivationPanel.label.enabled=Otettu käyttöön capabilityActivationPanel.label.enableList=Ota käyttöön Lista -capabilityActivationPanel.label.normalList=Normal list -capabilityActivationPanel.label.lockedList=Locked list +capabilityActivationPanel.label.normalList=Normaali lista +capabilityActivationPanel.label.lockedList=Lukittu lista capabilityActivationPanel.label.ignoreAttribute=Sivuuta atribuutti capabilityActivationPanel.label.returnedByDefault=Palautettu oletusarvoisesti capabilityActivationPanel.label.status.message=Sama kuin Käytössä/poistettu käytöstä capabilityActivationPanel.label.status=Tila -capabilityActivationPanel.label.lockout=Lockout -capabilityActivationPanel.label.validFrom=Valid from +capabilityActivationPanel.label.lockout=lukitus +capabilityActivationPanel.label.validFrom=voimassa alkaen capabilityActivationPanel.label.validTo=voimassa asti capabilityActivationPanel.list.placeholder=Syötä arvo -capabilityCredentialsPanel.label=Valtakirjan konfiguraatio +capabilityCredentialsPanel.label=Tunnusten konfiguraatio capabilityCredentialsPanel.label.enabled=Otettu käyttöön capabilityCredentialsPanel.label.password=Salasana capabilityCredentialsPanel.label.returned=Palautettu oletusarvoisesti @@ -151,72 +151,72 @@ capabilityScriptPanel.label.enabled=Otettu käyttöön capabilityScriptPanel.label.onConnector=Liittimessä capabilityScriptPanel.label.onResource=Resurssissa capabilityScriptPanel.label=Scripti Konfiguraatio -CapabilityStep.capabilities=Capabilities -CapabilityStep.addCapabilities=Add capabilities -CapabilityStep.disabled=(disabled) +CapabilityStep.capabilities=Kyvyt +CapabilityStep.addCapabilities=Lisää kyvyt +CapabilityStep.disabled=(poistettu käytöstä) CapabilityStep.activation.tooltip.attributeName=Name of the attribute that contains a value for simulated administrativeStatus. This is usually an attribute that contains some kind of enabled/disabled information. Typical examples are attributes such as "enabled", "ds-pwp-account-disabled", "accountStatus", etc. -CapabilityStep.activation.tooltip.disableList=List of attribute values that represent the "disabled" state. If any of these values are present in the attribute then the object will be considered to be disabled. Typical values are "false", "disabled", "0" or empty value. -CapabilityStep.activation.tooltip.enabled=True if this capability is active. False if it is disabled. Disabled capability acts in the same way as if it was not there. Capabilities can be disabled e.g. to work around connector bugs, to make resource read-only, etc. -CapabilityStep.activation.tooltip.enableList=List of attribute values that represent the "enabled" state. If any of these values are present in the attribute then the object will be considered to be enabled. Typical values are "true", "ENABLED", "1" and so on. +CapabilityStep.activation.tooltip.disableList=Lista atribuutti arvoista jotka edustaa "pois käytöstä" tilaa. Jos yksikään näistä arvoista sisältyy atribuuttiin niin objekti lasketaan poistetuksi käytöstä. Yleiset arvot ovat "epätosi", "pois käytöstä", "0" tai tyhjä arvo. +CapabilityStep.activation.tooltip.enabled=Tosi jos kyky on aktiivinen. Epätosi jos se on poistettu käytöstä. Käytöstä poistettu kyky toimii kuin ei olisi olemassa. Kykyjä voi poistaa käytöstä esimerkiksi ohittaakseen liitin virheitä, tehdäksesi resurssista vain luettavan, jne. +CapabilityStep.activation.tooltip.enableList=Lista atribuutti arvoista jotka edustaa "käytössä" tilaa. Jos yksikään näistä arvoista sisältyy atribuuttiin niin objekti lasketaan käytössä olevaksi. Yleiset arvot ovat "tosi", "käytöstä", "1", jne.. CapabilityStep.activation.tooltip.ignoreAttribute=If set to true then the attribute which is used for simulated activation will be marked as ignored in the schema. I.e. system will pretend that this attribute does not exist and only use the standard administrativeStatus. This is the default. If set to false then the attribute will also be visible in the schema and both the administrativeStatus and the original attribute will work. This may be needed if the attribute has a richer set of states than the administrativeStatus attribute. But in this case beware of value conflicts between administrativeStatus and the original attribute. CapabilityStep.activation.tooltip.lockoutAttributeName=Name of the attribute that contains a value for simulated lockoutStatus. This is usually an attribute that contains some kind of normal/locked information. CapabilityStep.activation.tooltip.lockoutNormalList=List of attribute values that represent the "normal" state. If any of these values are present in the attribute then the object will be considered to be in a normal state. CapabilityStep.activation.tooltip.lockoutLockedList=List of attribute values that represent the "locked" state. If any of these values are present in the attribute then the object will be considered to be in a locked state. CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=If set to true then the attribute which is used for simulated activation will be marked as ignored in the schema. I.e. system will pretend that this attribute does not exist and only use the standard lockoutStatus. This is the default. If set to false then the attribute will also be visible in the schema and both the lockoutStatus and the original attribute will work. This may be needed if the attribute has a richer set of states than the lockoutStatus attribute. But in this case beware of value conflicts between lockoutStatus and the original attribute. -CapabilityStep.activation.tooltip.returnedByDefault=If true then the activation attribute is returned with resource objects by default and it does not need to be requested. If false then the activation attribute has to be explicitly requested. +CapabilityStep.activation.tooltip.returnedByDefault=Jos tosi niin aktivaatio attribuutti palautetaan resurssi objektien kanssa oletusarvoisesti ja sitä ei tarvitse pyytää. Jos epätosi nni aktivaatio atribbuutia pitää suoraan pyytää. CapabilityStep.activation.tooltip.validFromEnabled=True if the resource supports validFrom activation property. CapabilityStep.activation.tooltip.validFromReturned=True if the validFrom property is returned by default. False if it needs to be explicitly requested. CapabilityStep.activation.tooltip.validToEnabled=True if the resource supports validTo activation property CapabilityStep.activation.tooltip.validToReturned=True if the validTo property is returned by default. False if it needs to be explicitly requested. -CapabilityStep.capability.activation.tooltip=Activation capability. Ability to enable/disable accounts, set validity dates, etc. +CapabilityStep.capability.activation.tooltip=Aktivointi kyky. Kyky ottaa käyttöön/poistaa käytöstä tilejä, asettaa voimassaolo päiväykset, jne. CapabilityStep.capability.create.tooltip=Kyky luoda (lisätä) uusia objekteja resurssiin. -CapabilityStep.capability.credentials.tooltip=Kyky asettaa valtakirjoja resurssi tileihin. +CapabilityStep.capability.credentials.tooltip=Kyky asettaa tunnuksia resurssi tileihin. CapabilityStep.capability.delete.tooltip=Kyky poistaa olemassa olevia objekteja resurssista. -CapabilityStep.capability.liveSync.tooltip=Live synchronization capability. Ability to efficiently fetch data changes in almost-real-time. +CapabilityStep.capability.liveSync.tooltip=Live synkronisaatio kyky. Kyky noutaa data muutoksia tehokkaasti melkein tosi ajassa. CapabilityStep.capability.read.tooltip=Kyky lukea dataa resurssista. CapabilityStep.capability.script.tooltip=Kyky suorittaa ohjelmakoodi liittimessä ja resurssissa. CapabilityStep.capability.testConnection.tooltip=Kyky testata yhteyttä resurssiin. CapabilityStep.capability.update.tooltip=Kyky päivittää (muokata) olemassa olevia objekteja resurssissa. CapabilityStep.configured=Konfiguroitu -CapabilityStep.credentials.tooltip.enabled=True if this capability is active. False if it is disabled. Disabled capability acts in the same way as if it was not there. Capabilities can be disabled e.g. to work around connector bugs, to make resource read-only, etc. -CapabilityStep.credentials.tooltip.passEnabled=True if the resource supports password credentials. +CapabilityStep.credentials.tooltip.enabled=Tosi jos kyky on aktiivinen. Epätosi jos se on poistettu käytöstä. Käytöstä poistettu kyky toimii kuin ei olisi olemassa. Kykyjä voi poistaa käytöstä esimerkiksi ohittaakseen liitin virheitä, tehdäksesi resurssista vain luettavan, jne. +CapabilityStep.credentials.tooltip.passEnabled=Tosi jos resurssi tukee salasana tunnuksia CapabilityStep.credentials.tooltip.passReturned=Tosi jos salasana palautetaan oletusarvoisesti. Väärä jos se pitää pyytää erikseen. CapabilityStep.message.cantLoadCaps=Ei pystynyt lataamaan kykyjä CapabilityStep.native=Natiivi -CapabilityStep.script.tooltip.enabled=True if this capability is active. False if it is disabled. Disabled capability acts in the same way as if it was not there. Capabilities can be disabled e.g. to work around connector bugs, to make resource read-only, etc. -CapabilityStep.script.tooltip.onConnector=Capability to execute scripts "on connector". This means that the scripts will be executed on the machine where the connector is installed. This is usually system node or a connector server. -CapabilityStep.script.tooltip.onResource=Capability to execute scripts "on resource". This means that the scripts will be executed on the machine where the connector connects. This is usually the server that hosts the resource (AD server, remote Unix machine, database server, etc.) +CapabilityStep.script.tooltip.enabled=Tosi jos kyky on aktiivinen. Epätosi jos se on poistettu käytöstä. Käytöstä poistettu kyky toimii kuin ei olisi olemassa. Kykyjä voi poistaa käytöstä esimerkiksi ohittaakseen liitin virheitä, tehdäksesi resurssista vain luettavan, jne. +CapabilityStep.script.tooltip.onConnector=Kyky suorittaa ohjelmakoodi "liittimessä". Tämä tarkoittaa, että ohjelmakoodi suoritetaan koneessa johon liitin on asennettu. Tämä on yleensä järjestelmä solmu tai liitin serveri. +CapabilityStep.script.tooltip.onResource=Kyky suorittaa ohjelmakoodi "liittimessä". Tämä tarkoittaa, että ohjelmakoodi suoritetaan koneessa johon liitin on kiinnitetty. Tämäon yleensä se serveri, joka isännöi resurssia (AD serveri, Unix etäkone, tietokanta serveri, jne.) CapabilityStep.title=Kyvyt capabilityValuePanel.label.capability.create=Luo kyky capabilityValuePanel.label.capability.delete=Poista kyky -capabilityValuePanel.label.capability.liveSync=Live synchronization capability +capabilityValuePanel.label.capability.liveSync=Live synkronisaatiio kyky capabilityValuePanel.label.capability.read=Lue kyky capabilityValuePanel.label.capability.testConnection=Testaa yhteys kyky capabilityValuePanel.label.capability.update=Päivitä kyky capabilityValuePanel.label.enabled=Otettu käyttöön -capabilityValuePanel.label.capability.addRemoveAttributeValues=Add/remove values capability -capabilityValuePanel.label.capability.auxiliaryObjectClasses=Auxiliary object classes capability +capabilityValuePanel.label.capability.addRemoveAttributeValues=Lisää/poista arvojen kyky +capabilityValuePanel.label.capability.auxiliaryObjectClasses=Apu objekti luokkien kyky CertDefinitionPage.message.cantSaveEmpty=Ei pysty tallentamaan tyhjää XML-tiedostoa CertDefinitionPage.message.cantSaveEmptyName=Ei voi tallentaa määritelmää ilman nimeä Channel.discovery=Löytö Channel.import=Tuo -Channel.liveSync=Live Synchronization +Channel.liveSync=Live synkronisaatio Channel.null=Valitse Yksi channel.nullValid=Valitse Yksi Channel.reconciliation=Täsmäyttäminen -Channel.recompute=Recompute +Channel.recompute=Uudelleenlaske Channel.user=Käyttäjä Channel.webService=Web Palvelu CheckTableHeader.label.error=Virhe CheckTableHeader.protected=Suojattu CheckTableHeader.showMore=Näytä lisää -CheckTableHeader.triggerPlanned=Trigger planned on {0}. +CheckTableHeader.triggerPlanned=Käynnistys suunniteltu {0}. CheckTableHeader.triggerUnknownTime=Käynnistys ilman ajastusta chooseTypeDialog.button.cancel=Peruuta chooseTypeDialog.column.name=Nimi -chooseTypeDialog.message.queryError=Virhe tapahti kääntäessä haku tiedustelua filtteriin. +chooseTypeDialog.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. chooseTypeDialog.title=Valitse Objekti -chooseTypePanel.ObjectNameValue.badOid=(tenant not found) +chooseTypePanel.ObjectNameValue.badOid=(haltijaa ei löydy) chooseTypePanel.ObjectNameValue.null=Ei mitään com.evolveum.midpoint.notifications.api.transports.MailTransport.send=Lähetä maili (ilmoitukset) com.evolveum.midpoint.notifications.api.transports.SimpleSmsTransport.send=Lähetä SMS (Ilmoitukset) @@ -225,7 +225,7 @@ ConditionalSearchFilterEditor.condition.description.label=Ehdon kuvaus ConditionalSearchFilterEditor.condition.update.label=Päivitä ehto ConditionalSearchFilterEditor.condition.type.label=Ehdon tyyppi ConditionalSearchFilterEditor.description=Kuvaus -ConditionalSearchFilterEditor.label=Edit synchronization correlation +ConditionalSearchFilterEditor.label=Muokkaa sykronisaatio vastaavussuhdetta configurationProperties=Konfiguraatio ConfigurationStep.button.testConnection=Tallenna ja testaa yhteys ConfigurationStep.title=Konfiguraatio @@ -247,20 +247,20 @@ PageDebugView.xmlYamlButton=YAML DecisionsPanel.comment=Kommentti DecisionsPanel.result=Tulos DecisionsPanel.user=Käyttäjä -DecisionsPanel.originalActor=Original actor +DecisionsPanel.originalActor=Alkuperäinen tekijä DecisionsPanel.stage=Vaihe DecisionsPanel.when=Koska -DecisionsPanel.escalation=Esc. level +DecisionsPanel.escalation=eskalointi taso DefinitionScopeObjectType.FocusType=Käyttäjät, roolit, organisaatiot ja palvelut DefinitionScopeObjectType.AbstractRoleType=Roolit, organisaatiot ja palvelut DefinitionScopeObjectType.RoleType=Roolit DefinitionScopeObjectType.UserType=Käyttäjät -DefinitionScopeObjectType.OrgType=Orgs +DefinitionScopeObjectType.OrgType=Organisaatiot DefinitionScopeObjectType.ServiceType=Palvelut deleteAllDialog.label.accountShadowsDelete=Tilin varjoja joita poistaa: {0} -deleteAllDialog.label.nonAccountShadowsDelete=Non-Account shadows to delete: {0} +deleteAllDialog.label.nonAccountShadowsDelete=Poistettavat tilittömät varjot: {0} deleteAllDialog.label.org=Org. yksiköt -deleteAllDialog.label.orgUnitsDelete=Org. units to delete: {0} +deleteAllDialog.label.orgUnitsDelete=Poistettavat org. yksiköt: {0} deleteAllDialog.label.shadow.account=Tili varjot deleteAllDialog.label.shadow.nonAccount=Tilittömät varjot deleteAllDialog.label.shadow.org=Org. yksikön varjot @@ -356,7 +356,7 @@ feedbackMessagePanel.showStack=[NÄYTÄ VIRHE PINO ] feedbackMessagePanel.times=kertaa feedtempMessagePanelbackMessagePanel.message.info=Tieto fetchStrategy.nullValid=Valitse Yksi -filter.duplicate=Filter with name '{0}' is already defined +filter.duplicate=Filtteri nimellä '{0}' on jo määritetty filter.emptyFilter=Suodatin ei voi olla tyhjä H3Header.label.error=Virhe H3Header.showMore=Näytä lisää @@ -378,7 +378,7 @@ HandlerUriActions.ACTION_UNLINK_ACCOUNT=Poista tilin linkitys (vanhentunut) HandlerUriActions.ACTION_UNLINK=Poista Linkkaus HoursValidator.range=Kentän '${label}' pitää olla ${minimum} ja ${maximum} välillä. ImportOptionsPanel.errorCount=Virhe laskuri -importOptionsPanel.fetchResourceSchema=Nouda resurssin schema +importOptionsPanel.fetchResourceSchema=Nouda resurssikaavio importOptionsPanel.keepOid=Pidä OID ImportOptionsPanel.options=Vaihtoehdot importOptionsPanel.overwriteExistingObject=Ylikirjoita olemassa oleva objekti @@ -387,18 +387,18 @@ importOptionsPanel.referentialIntegrity=Viitteellinen eheys importOptionsPanel.stopAfter=Pysäytä kun virheet ylittävät importOptionsPanel.summarizeErrors=Summaa virheet importOptionsPanel.summarizeSuccesses=Summaa onnistumiset -importOptionsPanel.validateDynamicSchema=Kelpuuta dynaaminen schema -importOptionsPanel.validateStaticSchema=Kelpuuta staattinen schema -ItemApprovalPanel.approvalSchema=Hyväksy schema -ItemApprovalPanel.currentWorkItems=Nykyiset työstettävät esineet -ItemApprovalPanel.nextStages=Following stages -ItemApprovalPanel.wholeProcess=Whole approval process +importOptionsPanel.validateDynamicSchema=Kelpuuta dynaaminen kaavio +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) +ItemApprovalPanel.approvalSchema=Hyväksy kaavio +ItemApprovalPanel.currentWorkItems=Nykyiset työ alkiot +ItemApprovalPanel.nextStages=Seuraavat vaiheet +ItemApprovalPanel.wholeProcess=Koko hyväksyntä prosessi ItemApprovalPanel.decisionsDoneWhenFinishedIs_false=Tähän mennessä tehdyt päätökset ItemApprovalPanel.decisionsDoneWhenFinishedIs_true=Tehdyt päätökset -ItemApprovalPanel.itemThatWasApproved=Tehtävä jota tarkistettiin (ja HYVÄKSYTTIIN) -ItemApprovalPanel.itemThatWasCompleted=Tehtävä joka tuli valmiiksi -ItemApprovalPanel.itemThatWasRejected=Tehtävä jota tarkistettiin (ja EI HYVÄKSYTTY) -ItemApprovalPanel.itemToBeApproved=hyväksymisjonossa oleva tehtävä. +ItemApprovalPanel.itemThatWasApproved=Alkio jota tarkistettiin (ja HYVÄKSYTTIIN) +ItemApprovalPanel.itemThatWasCompleted=Alkio joka tuli valmiiksi +ItemApprovalPanel.itemThatWasRejected=alkio jota tarkistettiin (ja EI HYVÄKSYTTY) +ItemApprovalPanel.itemToBeApproved=hyväksymisjonossa oleva alkio JasperReportConfigurationPanel.addField=Lisää kenttä JasperReportConfigurationPanel.addParameter=Lisää parametri JasperReportConfigurationPanel.deleteField=Poista kenttä @@ -407,7 +407,7 @@ JasperReportConfigurationPanel.fieldClass=Kentän luokka JasperReportConfigurationPanel.fieldName=Kentän nimi JasperReportConfigurationPanel.forPrompting=Kehotettavaksi JasperReportConfigurationPanel.parameterClass=Parametri luokka -JasperReportConfigurationPanel.nestedClass=Nested class +JasperReportConfigurationPanel.nestedClass=sisältyvä luokka JasperReportConfigurationPanel.parameterName=Parametrin nimi JasperReportConfigurationPanel.parameterProperty=Ominaisuus: {0} JasperReportConfigurationPanel.reportFields=Raportti kentät @@ -416,16 +416,16 @@ JasperReportConfigurationPanel.reportQuery=Raportoi Kysely JasperReportConfigurationPanel.errormsg=Tyhjiä arvoja ei sallitu JasperReportConfigurationPanel.properties=Ominaisuudet JasperReportConfigurationPanel.configure=Konfiguroi -JasperReportParameterProperties.property.name=Property name -JasperReportParameterProperties.property.value=Property value +JasperReportParameterProperties.property.name=Ominasuuden nimi +JasperReportParameterProperties.property.value=Ominaisuuden arvo JasperReportParameterProperties.key=Avain JasperReportParameterProperties.label=Etiketti -JasperReportParameterProperties.targetType=Target type -JasperReportParameterProperties.multivalue=Multivalue -JasperReportParameterProperties.config=Properties configuration +JasperReportParameterProperties.targetType=Kohde tyyppi +JasperReportParameterProperties.multivalue=moniarvo +JasperReportParameterProperties.config=Ominaisuuksien konfiguraatio JasperReportParameterProperties.title=Konfiguroi kind.nullValid=Valitse Yksi -Language.GROOVY=Groovy (default) +Language.GROOVY=Groovy (oletus) Language.JAVASCRIPT=Javascript Language.XPATH=XPath LimitationsEditorDialog.allow=Salli @@ -446,9 +446,9 @@ LimitationsEditorDialog.label.model=Malli LimitationsEditorDialog.label.modify=Muokkaa LimitationsEditorDialog.label.other=Muut LimitationsEditorDialog.label.presentation=Esitys -LimitationsEditorDialog.label.propertyAccess=Property access +LimitationsEditorDialog.label.propertyAccess=Ominaisuuden yhteys LimitationsEditorDialog.label.read=Lue -LimitationsEditorDialog.label.schema=Schema +LimitationsEditorDialog.label.schema=kaavio logger.duplicate=Kerääjä nimellä '{0}' on jo määritetty logger.emptyLogger=Kerääjä ei voi olla tyhjä LoggingConfigPanel.appender=Liittäjä @@ -482,13 +482,13 @@ LoggingConfigPanel.profiling.dumpInterval.placeholder=tyhjennysväli LoggingConfigPanel.profiling.dumpInterval.tooltip=Tarkenna arvo minuuteissa (Perus on 30 min.) LoggingConfigPanel.profiling.entryExit=Profilointi sisäänkirjautuminen/poistuminen LoggingConfigPanel.profiling.general=Profilointi -LoggingConfigPanel.profiling.performanceStatistics=Perfrormanssi Tilastot +LoggingConfigPanel.profiling.performanceStatistics=Suoriutumis Tilastot LoggingConfigPanel.profiling.requestFilter=Pyyntöjen suodatin LoggingConfigPanel.profiling.subsystem.model=Malli LoggingConfigPanel.profiling.subsystem.provisioning=Esivalmistelu LoggingConfigPanel.profiling.subsystem.repository=Säilö LoggingConfigPanel.profiling.subsystem.resourceObjectChangeListener=Resurssi objektin muutoksen tarkkailija -LoggingConfigPanel.profiling.subsystem.synchronizationService=Synchronization Service +LoggingConfigPanel.profiling.subsystem.synchronizationService=Synkronisaatio palvelu LoggingConfigPanel.profiling.subsystems=subsysteemien profilointi LoggingConfigPanel.profiling.subsystem.taskManager=Tehtävänhallinta LoggingConfigPanel.profiling.subsystem.ucf=Ucf @@ -524,11 +524,11 @@ MappingEditorDialog.label.passPolicyRef=Linjaus viittaus. MappingEditorDialog.label.source=Lähde MappingEditorDialog.label.strength=Vahvuus MappingEditorDialog.label.target=Kohde -MappingEditorDialog.label.timeFrom=Time from -MappingEditorDialog.label.timeTo=Time to +MappingEditorDialog.label.timeFrom=Aloitus aika +MappingEditorDialog.label.timeTo=Lopuetus aika MappingEditorDialog.message.cantSave=Ei voitu tallentaa kartoitusta. Syy: MappingEditorDialog.message.warn.emptyTarget=Sisääntuleva kartoitus tarvitsee että 'Kohde' kenttä on tarkennettu. -MappingsStatistics.AverageTime=keskiverto aika +MappingsStatistics.AverageTime=keskiarvo aika MappingsStatistics.Count=Suoritusten määrä MappingsStatistics.MaxTime=Max MappingsStatistics.MinTime=Min @@ -570,7 +570,7 @@ MyAssignmentsPanel.type.orgUnit=Org. yksikkö MyAssignmentsPanel.type.role=Rooli MyAssignmentsPanel.type.service=Palvelu MyAssignmentsPanel.type.user=Käyttäjä -MyAssignmentsPanel.type.policyRule=Policy rule +MyAssignmentsPanel.type.policyRule=Linjaus sääntö NameStep.arrowToTurotialText=Ohjeistuksen jokaiselle askeleelle on ohje! -nappi. Paina tätä nappia saadaksesi tietoa jonkun tarkan konfiguraatio askeleen tarkoitus. NameStep.connectorBundle=Nippu NameStep.connectorHost=Liittimen isäntä @@ -595,7 +595,7 @@ NodeExecutionStatus.DOWN=Sammutettu NodeExecutionStatus.ERROR=Virhe NodeExecutionStatus.PAUSED=Pysäytetty NodeExecutionStatus.RUNNING=Käynnissä -NotificationsStatistics.AverageTime=keskiverto aika +NotificationsStatistics.AverageTime=keskiarvo aika NotificationsStatistics.CountFailure=Epäonnistui NotificationsStatistics.CountSuccess=Onnistui NotificationsStatistics.MaxTime=Max @@ -609,17 +609,17 @@ objectPolicyConfigurationEditor.name.placeholder=Aseta objektin linjaus ObjectPolicyDialog.button.cancel=Peruuta ObjectPolicyDialog.button.save=Tallenna ObjectPolicyDialog.label=Muokka objektin viittaus -ObjectPolicyDialog.label.oidBound.help=Oid bound - The property value will be bound to OID. This property will be set to the value of OID and it cannot be changed. +ObjectPolicyDialog.label.oidBound.help=Oid sidos - Tämä ominaisuuden arvo sidotaan OIDhen. Tämä ominaisuus asetetaan OID arvon mukaisesti ja sitä ei voi muuttaa. ObjectPolicyDialog.propertyConstraint=Omninaisuuden rajoitus ObjectPolicyDialog.property.placeholder=Aseta ominaisuuden reitti -ObjectPolicyDialog.subtype=Object subtype +ObjectPolicyDialog.subtype=Objektin alatyyppi ObjectPolicyDialog.template=Objektin malli ObjectPolicyDialog.type=Objekti tyyppi objectSyncConfig.editorFocus.nullValid=Valitse Yksi objectSyncConfig.editorKind.nullValid=Valitse Yksi objectSyncConfig.editorObjectTemplate.nullValid=Valitse Yksi objectTemplateRef.nullValid=Valitse Yksi -ObjectTypeGuiDescriptor.abstractRole=Abstract role +ObjectTypeGuiDescriptor.abstractRole=Yhteenveto rooli ObjectTypeGuiDescriptor.accessCertificationCampaign=Yhdistä sertifikaatio kampanjaan ObjectTypeGuiDescriptor.accessCertificationDefinition=Yhdistä sertifikaation määritelmään ObjectTypeGuiDescriptor.account=Tili @@ -628,13 +628,13 @@ ObjectTypeGuiDescriptor.connectorHost=Liittimen isäntä ObjectTypeGuiDescriptor.focus=Fokus ObjectTypeGuiDescriptor.form=Form ObjectTypeGuiDescriptor.genericObject=Yleinen objekti -ObjectTypeGuiDescriptor.lookupTable=Lookup table +ObjectTypeGuiDescriptor.lookupTable=Haku taulukko ObjectTypeGuiDescriptor.node=Solmu ObjectTypeGuiDescriptor.object=Objekti ObjectTypeGuiDescriptor.objectTemplate=Objektin malli ObjectTypeGuiDescriptor.orgManager=Org. manageri ObjectTypeGuiDescriptor.org=Organisaatio -ObjectTypeGuiDescriptor.reportOutput=Ulostuonti raportti +ObjectTypeGuiDescriptor.reportOutput=Ulosanti raportti ObjectTypeGuiDescriptor.report=Raportti ObjectTypeGuiDescriptor.resource=Resurssi ObjectTypeGuiDescriptor.role=Rooli @@ -652,7 +652,7 @@ operation.com.evolveum.midpoint.common.operation.import.object=Tuo objekti operation.com.evolveum.midpoint.common.policy.PasswordPolicyUtils.passwordValidation=Salasanan varmistus vastaan salasana linjaus operation.com.evolveum.midpoint.common.validator.Validator.objectBasicsCheck=Perustarkastukset operation.com.evolveum.midpoint.common.validator.Validator.resourceNamespaceCheck=Resurssin nimitilan tarkastus -operation.com.evolveum.midpoint.common.validator.Validator.validateSchema=Schema vahvistus +operation.com.evolveum.midpoint.common.validator.Validator.validateSchema=kaavion vahvistus operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.provisioningSelfTest=Esivalmistelun testaus (malli) operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.repositorySelfTest=Säilön testaus (Malli) operation.com.evolveum.midpoint.model.api.ModelInteractionService.previewChanges=Esikatsele muutoksia (malli) @@ -687,12 +687,12 @@ operation.com.evolveum.midpoint.model.controller.ModelController.processAddDelet operation.com.evolveum.midpoint.model.controller.ModelController.searchObjectsInProvisioning=Hae objekteja esivalmistelusta operation.com.evolveum.midpoint.model.controller.ModelController.searchObjectsInRepository=Hae säilöstä objekteja  operation.com.evolveum.midpoint.model.controller.ModelController.searchObjects=Hae objekteja (Malli) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.getObject=Get object (Model) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.employeeType=Search objects - employeeType (Model) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.fullName=Search objects - fullName (Model) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.organization=Search objects - organization (Model) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable.getObject=Get object (Model) -operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable.getObject.key=Get object by row key (Model) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.getObject=Hanki objekti (malli) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.employeeType=hae objekteja - työntekijäTyyppi (Malli) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.fullName=Hae objekteja - kokoNimi(Malli) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user.searchObjects.organization=Hae objekteja -organisaatio (Malli) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable.getObject=Hanki objekti (malli) +operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable.getObject.key=Hanki objekti riviavaimella (Malli) operation.com.evolveum.midpoint.model.controller.SchemaHandler.insertUserDefinedVariables=Syötä kayttäjän määrittämät muuttujat operation.com.evolveum.midpoint.model.controller.SchemaHandler.processAttributeInbound=Prosessoi sisääntuleva attribuuti operation.com.evolveum.midpoint.model.controller.SchemaHandler.processInboundHandling=Prosessoi sisääntuleva käsittely @@ -702,12 +702,12 @@ operation.com.evolveum.midpoint.model.controller.SchemaHandler.processPropertyCo operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user=Säilön testaus, käyttäjä (Malli) operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable=Repository self test, lookup table (Model) operation.com.evolveum.midpoint.model.importer.ImportAccountsFromResourceTaskHandler.launch=Tuo tilejä resurssista -operation.com.evolveum.midpoint.model.importer.ObjectImporter.checkResourceSchema=Tarkista resurssin schema +operation.com.evolveum.midpoint.model.importer.ObjectImporter.checkResourceSchema=Tarkista resurssikaavio operation.com.evolveum.midpoint.model.importer.ObjectImporter.encryptValues=Salaus operation.com.evolveum.midpoint.model.importer.ObjectImporter.importObjectToRepository=Säilytä objekti säilössä operation.com.evolveum.midpoint.model.importer.ObjectImporter.resolveReference=Viittauksen ratkaisu -operation.com.evolveum.midpoint.model.importer.ObjectImporter.validateDynamicSchema=Kelpuuta dynaaminen schema -operation.com.evolveum.midpoint.model.importer.ObjectImporter.validateResourceConfigurationSchema=Kelpuuta resurssien konfiguraatio schema +operation.com.evolveum.midpoint.model.importer.ObjectImporter.validateDynamicSchema=Kelpuuta dynaaminen kaavio +operation.com.evolveum.midpoint.model.importer.ObjectImporter.validateResourceConfigurationSchema=Kelpuuta resurssien konfiguraatiokaavio operation.com.evolveum.midpoint.model.lens.ChangeExecutor.executeChanges=Suorita muutokset - vaihda suorittajaa (Malli) operation.com.evolveum.midpoint.model.lens.ChangeExecutor.executeDelta=Suorita delta (Malii) operation.com.evolveum.midpoint.model.lens.ChangeExecutor.execute=Suorita (Malli) @@ -748,20 +748,20 @@ operation.com.evolveum.midpoint.repo.api.RepositoryService.deleteObject=Poista o operation.com.evolveum.midpoint.repo.api.RepositoryService.getObject=Hanki objekti (Säilö) operation.com.evolveum.midpoint.repo.api.RepositoryService.modifyObject=Muokkaa objektia (Säilö) operation.com.evolveum.midpoint.repo.api.RepositoryService.searchObjects=Hae objekteja (Säilö) -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.connection=Connector connection -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.initialization=Connector initialization -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.configuration=Connector configuration -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.capabilities=Connector capabilities -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.resourceSchema=Resource schema -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.resourceSanity=Resource sanity -operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.extraTest=Extra test +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.connection=Liitin yhteys +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.initialization=Liittimen käynnistys +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.configuration=Liitin konfiguraatio +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connector.capabilities=Liittimen kyvyt +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.resourceSchema=Resurssikaavio +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.resourceSanity=Resurssin toimivuus +operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.extraTest=Lisä testi operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.testConnection=Testaa yhteys operation.com.evolveum.midpoint.task.api.TaskManager.addTask=Lisää tehtävä (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.createTaskInstance=Luo tehtävä tapahtuma (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.deactivateServiceThreads=Poista käytöstä paikalliset palveluketjut (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.deleteTask=Poista tehtävä (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.getNextRunStartTime=Hanki seuraavan tehtävän suorituksen aloitusaika (Tehtävä) -operation.com.evolveum.midpoint.task.api.TaskManager.getNextStartTimes=Get next task start times (Task) +operation.com.evolveum.midpoint.task.api.TaskManager.getNextStartTimes=Hanki seuraavan tehtävän aloitus ajat (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.getTask=Hanki tehtävä (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.onTaskCreate=Tehtävän luomisen tarkkailija (Tehtävä) operation.com.evolveum.midpoint.task.api.TaskManager.onTaskDelete=Tehtävän poistamisen tarkkailija (Tehtävä) @@ -816,7 +816,7 @@ operation.com.evolveum.midpoint.web.page.admin.help.PageSystem.testRepository=Te operation.com.evolveum.midpoint.web.page.admin.home.PageDashboard.loadAccounts=Lataa tilit (Gui) operation.com.evolveum.midpoint.web.page.admin.home.PageDashboard.loadAssignments=Lataa toimeksiannot (Gui) operation.com.evolveum.midpoint.web.page.admin.home.PageDashboard.loadUser=Lataa käyttäjä (Gui) -operation.com.evolveum.midpoint.web.page.admin.home.PageDashboard.loadWorkItems=Lataa työstettävät esineet(Gui) +operation.com.evolveum.midpoint.web.page.admin.home.PageDashboard.loadWorkItems=Lataa työ alkiot(Gui) operation.com.evolveum.midpoint.web.page.admin.home.PageMyPasswords.loadAccount=Lataa tili (Gui) operation.com.evolveum.midpoint.web.page.admin.home.PageMyPasswords.loadUser=Lataa käyttäjä (Gui) operation.com.evolveum.midpoint.web.page.admin.home.PageMyPasswords.loadUserWithAccounts=Lataa käyttäjä tilien kanssa (Gui) @@ -882,7 +882,7 @@ operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.enableUsers=Ota k operation.com.evolveum.midpoint.web.page.admin.users.PageUser.sendToSubmit=lähetä kirjattavaksi (Gui) operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.reconcileUser=Täsmäytä käyttäjä (Gui): {0} operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.reconcileUsers=Täsmäytä käyttäjät (Gui) -operation.com.evolveum.midpoint.web.page.admin.workflow.PageWorkItem.saveWorkItem=Tallenna työstetty tehtävä (Gui) +operation.com.evolveum.midpoint.web.page.admin.workflow.PageWorkItem.saveWorkItem=Tallenna työ alkio (Gui) operation.com.evolveum.midpoint.web.util.WebModelUtils.deleteObject=Poista objekti (Gui) operation.com.evolveum.midpoint.web.util.WebModelUtils.loadObject=Lataa Objekti (GUI) operation.com.evolveum.midpoint.wf.WfHook.invoke=Työnkulun kiinnitys kutsu (työnkulku) @@ -903,14 +903,14 @@ operation.org.identityconnectors.framework.api.ConnectorFacade.addAttributeValue operation.org.identityconnectors.framework.api.ConnectorFacade.create=Luo (Icf) operation.org.identityconnectors.framework.api.ConnectorFacade.delete=Poista objekti (Icf) operation.org.identityconnectors.framework.api.ConnectorFacade.getObject=ICF hanki objekti -operation.org.identityconnectors.framework.api.ConnectorFacade.schema=ICF schema +operation.org.identityconnectors.framework.api.ConnectorFacade.schema=ICF-kaavio operation.org.identityconnectors.framework.api.ConnectorFacade.update=Päivitä (lcf) -operation.com.evolveum.midpoint.web.component.wizard.resource.NameStep.saveResource=Save resource basic information -operation.com.evolveum.midpoint.web.component.wizard.resource.ConfigurationStep.saveResource=Save resource configuration -operation.com.evolveum.midpoint.web.component.wizard.resource.SchemaHandlingStep.saveSchemaHandling=Save resource schema handling -operation.com.evolveum.midpoint.web.component.wizard.resource.SynchronizationStep.saveResourceSynchronization=Save resource synchronization -operation.com.evolveum.midpoint.web.component.wizard.resource.CapabilityStep.saveCapabilities=Save resource capabilities -operation.com.evolveum.midpoint.web.page.admin.PageAdminFocus.loadShadow=Load shadow +operation.com.evolveum.midpoint.web.component.wizard.resource.NameStep.saveResource=Tallenna resurssin perustiedot +operation.com.evolveum.midpoint.web.component.wizard.resource.ConfigurationStep.saveResource=Tallenna resurssi konfiguraatio +operation.com.evolveum.midpoint.web.component.wizard.resource.SchemaHandlingStep.saveSchemaHandling=Tallenna resurssikaavion käsittely +operation.com.evolveum.midpoint.web.component.wizard.resource.SynchronizationStep.saveResourceSynchronization=Tallena resurssi synkronisaatio +operation.com.evolveum.midpoint.web.component.wizard.resource.CapabilityStep.saveCapabilities=Tallenna resurssin kyvyt +operation.com.evolveum.midpoint.web.page.admin.PageAdminFocus.loadShadow=Lataa varjo operationResultPanel.cause=Syy: operationResultPanel.context=Konteksti: operationResultPanel.count=Luku: @@ -940,7 +940,7 @@ org.apache.wicket.extensions.wizard.finish=Lopeta org.apache.wicket.extensions.wizard.last=Viime org.apache.wicket.extensions.wizard.next=Seuraava org.apache.wicket.extensions.wizard.previous=Edellinen -org.apache.wicket.extensions.wizard.validate=Validate +org.apache.wicket.extensions.wizard.validate=Kelpuuta org.apache.wicket.extensions.wizard.save=Tallenna orgUnitAddDeletePopup.button.add=Lisää Org. yksiköitä orgUnitAddDeletePopup.button.cancel=Peruuta @@ -956,7 +956,7 @@ PageAbout.allRightsReserved=©2014 Evolveum. PageAbout.button.testProvisioning=Esivalmistelun testaus PageAbout.button.cleanupActivitiProcesses=Clean-up Activiti processes PageAbout.button.testRepositoryCheckOrgClosure=Tarkista ja korjaa org. sulkemis johdonmukaisuus -PageAbout.button.reindexRepositoryObjects=Reindex repository objects +PageAbout.button.reindexRepositoryObjects=Luetteloi uudestaan säilö objektit PageAbout.button.testRepository=Säilön testaus PageAbout.message.couldntObtainJvmParams=Ei pystytty noukkimaan JVM parametrejä JMXstä. PageAbout.midPointRevision=${git.describe} @@ -988,7 +988,7 @@ pageAccount.message.cantEditAccount=Ei pystynyt lataamaan tiliä muokkausta vart pageAccount.message.cantEditProtectedAccount=Tämä on suojattu tili, sitä ei voi muokata. PageAccounts.accounts.description=Kuvaus PageAccounts.accounts.intent=Aikomus -PageAccounts.accounts.kind=Kind +PageAccounts.accounts.kind=Laji PageAccounts.accounts.name=Nimi PageAccounts.accounts.objectClass=Objekti luokka PageAccounts.accounts.failedOperationType=Operaatio epäonnistui @@ -1032,15 +1032,15 @@ pageAdmin.home=Koti PageAdmin.menu.top.certification.campaigns=Kampanjat PageAdmin.menu.top.certification.scheduling=Kampanjoiden ajastus PageAdmin.menu.top.certification=Sertifikaatio -PageAdmin.menu.top.certification.decisions=minun työstettävät esineet +PageAdmin.menu.top.certification.decisions=minun työ alkiot PageAdmin.menu.top.certification.definitions=Kampanjan kuvaukset PageAdmin.menu.top.certification.newDefinition=Uusi kampanja kuvaus PageAdmin.menu.top.certification.viewDefinition=Tarkastele kampanjan kuvausta PageAdmin.menu.top.configuration.about=Tieto PageAdmin.menu.top.configuration.basic=Systeemi -PageAdmin.menu.top.configuration.bulkActions=Bulk actions +PageAdmin.menu.top.configuration.bulkActions=Massa toiminnot PageAdmin.menu.top.configuration.repoQuery=Kysely pelikenttä -PageAdmin.menu.top.configuration.evaluateMapping=Mapping playground +PageAdmin.menu.top.configuration.evaluateMapping=Kartoitus pelikenttä PageAdmin.menu.top.configuration=Konfiguraatio PageAdmin.menu.top.configuration.configuration=Konfiguraatio PageAdmin.menu.top.configuration.development=Kehittely @@ -1065,7 +1065,7 @@ PageAdmin.menu.top.resources.new=Uusi resurssi PageAdmin.menu.top.resources.view=Katsele resurssia PageAdmin.menu.top.resources.edit=Muokkaa resurssia PageAdmin.menu.top.resources=Resurssit -PageAdmin.menu.top.connectorHosts.list=List connector hosts +PageAdmin.menu.top.connectorHosts.list=Listaa liittimen isännät PageAdmin.menu.top.roles.list=Listaa roolit PageAdmin.menu.top.roles.new=Uusi rooli PageAdmin.menu.top.roles=Roolit @@ -1079,16 +1079,16 @@ PageAdmin.menu.top.users.org.new=Uusi organisaatio PageAdmin.menu.top.users.org=Org. rakenne PageAdmin.menu.top.users.org.tree=Organisaation puu PageAdmin.menu.top.users=Käyttäjät -PageAdmin.menu.top.workItems.listClaimable=Esine jonka voin ottaa käyttöön. -PageAdmin.menu.top.workItems.list=Omistamani Esineet -PageAdmin.menu.top.workItems.listAll=All items +PageAdmin.menu.top.workItems.listClaimable=Alkio jonka voin ottaa käyttöön. +PageAdmin.menu.top.workItems.list=minun alkiot +PageAdmin.menu.top.workItems.listAll=Kaikki alkiot PageAdmin.menu.top.workItems.listProcessInstancesAll=Kaikki pyynnöt PageAdmin.menu.top.workItems.listProcessInstancesRequestedBy=Minun pyynnöt -PageAdmin.menu.top.workItems.listProcessInstancesRequestedFor=Requests about me -PageAdmin.menu.top.workItems=Work items +PageAdmin.menu.top.workItems.listProcessInstancesRequestedFor=Minuun kohdistuneet pyynnöt +PageAdmin.menu.top.workItems=Työ alkiot pageAdmin.reports.description=Vie raportteja pageAdmin.reports=Raportit -PageAdmin.menu.top.users.requestAssign=Request Assignment +PageAdmin.menu.top.users.requestAssign=Pyydä toimeksiantoa PageAdminObjectDetails.title.editUserType=Muokkaa käyttäjää '{0}' PageAdminObjectDetails.title.newUserType=Luo uusi käyttäjä PageAdminObjectDetails.title.editRoleType=Muokkaa roolia '{0}' @@ -1097,49 +1097,49 @@ PageAdminObjectDetails.title.editServiceType=Muokkaa palvelua '{0}' PageAdminObjectDetails.title.newRoleType=Luo uusi rooli PageAdminObjectDetails.title.editOrgType=Muokkaa organisaatiota '{0}' PageAdminObjectDetails.title.newOrgType=Luo uusi organisaatio -PageAdminObjectDetails.noChangesSave=There were no changes to be saved. -PageAdminObjectDetails.noChangesPreview=There are no changes to be previewed. +PageAdminObjectDetails.noChangesSave=Ei ollut tallennettavia muutoksia. +PageAdminObjectDetails.noChangesPreview=Ei ole esikatseltavia muutoksia. pageAdminFocus.basic=Perus -pageAdminFocus.message.cantEditFocus=Unknown error occurred, can't edit focus object. -pageAdminFocus.message.cantNewFocus=Unknown error occurred, can't create new focus object. -pageAdminFocus.message.illegalAccountState=Illegal shadow state '{0}'. -pageAdminFocus.message.noAssignmentsAvailable=There are currently no assignments to preview. -pageAdminFocus.message.noOrgSelected=No organization was selected. +pageAdminFocus.message.cantEditFocus=Tuntematon virhe, ei voi muokata fokus objektia +pageAdminFocus.message.cantNewFocus=Tuntematon virhe, ei voi luoda uutta fokus objektia +pageAdminFocus.message.illegalAccountState=Laiton varjon tila '{0}'. +pageAdminFocus.message.noAssignmentsAvailable=Tällä hetkellä ei ole yhtään esikatseltavaa toimeksiantoa. +pageAdminFocus.message.noOrgSelected=Organisaatiota ei valittu pageAdminFocus.menu.assignShadow=Osoita resurssi pageAdminFocus.menu.assignRole=Osoita rooli pageAdminFocus.menu.assignOrg=Osoita org. yksikkö -pageAdminFocus.menu.unassign=Unassign -pageAdminFocus.button.addShadow=Add projection +pageAdminFocus.menu.unassign=Poista osoitus +pageAdminFocus.button.addShadow=Lisää projektio pageAdminFocus.button.enable=Ota käyttöön pageAdminFocus.button.disable=Poista käytöstä -pageAdminFocus.button.unlink=Unlink +pageAdminFocus.button.unlink=Poista Linkkaus pageAdminFocus.button.unlock=Poista lukitus pageAdminFocus.button.delete=Poista pageAdminFocus.button.addToOrg=Lisää organisaatioon pageAdminFocus.focusDetails=Yksityiskohdat -pageAdminFocus.projections=Projections -pageAdminFocus.personas=Personas +pageAdminFocus.projections=Projektiot +pageAdminFocus.personas=Henkilöt pageAdminFocus.organizations=Organisaatiot -pageAdminFocus.assignments=Assignments -pageAdminFocus.policyRules=Policy Rules -pageAdminFocus.message.couldntCreateAccountNoSchema=Couldn't create projection form for '{0}', no refined schema available. Possible problem with connector configuration and/or connection. Please check logs for more information. -pageAdminFocus.message.couldntCreateAccountNoAccountSchema=Couldn't create projection form for '{0}', no schema for default 'account' object type available. Possible problem with resource configuration. Please check logs for more information. -pageAdminFocus.message.couldntCreateAccount=Couldn't create projection form for '{0}', reason: {1}. -pageAdminFocus.message.noAssignableSelected=No assignment selected. -pageAdminFocus.message.couldntAssignObject=Couldn't assign object '{0}', reason: {1}. -pageAdminFocus.message.noActivationFound=No activation found for projection '{0}'. -pageAdminFocus.message.noEnabledPropertyFound=No enabled property found for account '{0}'. -pageAdminFocus.message.noLockoutStatusPropertyFound=No lockout status property found for account '{0}'. -pageAdminFocus.message.notLocked=Account '{0}' is not locked. -pageAdminFocus.message.unlocked=Account '{0}' was marked to be unlocked. Apply by choosing 'Save'. -pageAdminFocus.message.noAccountSelected=No projection selected. -pageAdminFocus.message.noAssignmentSelected=No assignment selected. -pageAdminFocus.title.selectResource=Select resource(s) -pageAdminFocus.title.selectAssignable=Select object(s) +pageAdminFocus.assignments=Toimeksiannot +pageAdminFocus.policyRules=Linjaus säännöt +pageAdminFocus.message.couldntCreateAccountNoSchema=Ei voinut luoda projektio lomaketta '{0}'lle, tarkennettua kaaviota ei saatavilla. Mahdollinen ongelma liittimen konfiguraatio ja/tai yhteydessä. Tarkista logit saadaksesi enemmän tietoa. +pageAdminFocus.message.couldntCreateAccountNoAccountSchema=Ei voinut luoda projektio lomaketta '{0}'lle, kaaviota perus 'tili' objekti tyypillä ei saatavilla. Mahdollinen ongelma resurssi konfiguraatiossa. Tarkista logit saadaksesi enemmän tietoa. +pageAdminFocus.message.couldntCreateAccount=Ei voitu luoda projektio lomaketta '{0}', syy: {1}. +pageAdminFocus.message.noAssignableSelected=Ei toimeksiantoa valittuna. +pageAdminFocus.message.couldntAssignObject=Ei voitu osoittaa objektia '{0}', syy: {1}. +pageAdminFocus.message.noActivationFound=Ei löydy aktivointi projektiolle '{0}'. +pageAdminFocus.message.noEnabledPropertyFound=Tilille '{0}' ei löydy käyttöön otettuja ominaisuuksia. +pageAdminFocus.message.noLockoutStatusPropertyFound=Tilille '{0}' ei löytynyt lukitus tilan ominaisuutta. +pageAdminFocus.message.notLocked=tili '{0}' ei ole lukossa. +pageAdminFocus.message.unlocked=tilille '{0}' valittiin lukituksen poisto. Ota käyttöön valitsemalla 'Tallenna'. +pageAdminFocus.message.noAccountSelected=Ei projektio valittuna. +pageAdminFocus.message.noAssignmentSelected=Ei toimeksiantoa valittuna. +pageAdminFocus.title.selectResource=Valitse resurssi(t) +pageAdminFocus.title.selectAssignable=Valitse objekti(t) pageAdminFocus.task.name=Tehtävän nimi pageAdminFocus.task.category=Kategoria -pageAdminFocus.task.descriptionHasTasks=Active tasks related to this object: -pageAdminFocus.task.descriptionNoTasks=There are no active tasks related to this object. +pageAdminFocus.task.descriptionHasTasks=Aktiiviseet tehtävät liittyen tähän objektiin: +pageAdminFocus.task.descriptionNoTasks=Ei ole aktiivisia tehtäviä liittyen tähän objektiin. pageAdminFocus.task.execution=Toteutuksen tila pageAdminFocus.task.status=Tila pageAdminFocus.tasks=Tehtävät @@ -1149,8 +1149,8 @@ pageAdminFocus.button.abort=Keskeytä pageAdminFocus.button.back=Takaisin pageAdminFocus.button.continueEditing=Jatka muokkaamista pageAdminFocus.title.confirmDelete=Vahvista poista -pageAdminFocus.message.deleteAccountConfirm=Do you really want to delete {0} projection(s)? -pageAdminFocus.message.deleteAssignmentConfirm=Do you really want to delete {0} assignment(s)? +pageAdminFocus.message.deleteAccountConfirm=Oletko varma, että haluat poistaa {0} projektioa? +pageAdminFocus.message.deleteAssignmentConfirm=Oletko varma, että haluat poistaa {0} toimeksiantoa? pageAdminResources.accountDetails=Tilin yksityiskohdat pageAdminResources.contentAccounts=Sisältö pageAdmin.resources.description=Liitetyt järjestelmät @@ -1158,7 +1158,7 @@ pageAdminResources.detailsResource=Resurssin yksityiskohdat pageAdminResources.editResource=Muokkaa resurssia pageAdminResources.importResource=Tuo resurssi pageAdminResources.listResources=Listaa resurssit -pageAdminResources.message.cantLoadResource=Couldn't load resource details. +pageAdminResources.message.cantLoadResource=Ei voitu ladata resurssin yksityiskohtia. pageAdminResources.newResource=Uusi resurssi pageAdmin.resources=Resurssit pageAdmin.roles.description=Konfiguroidut roolit @@ -1167,8 +1167,8 @@ pageAdmin.serverTasks.description=Käynnissä olevat tehtävät pageAdmin.serverTasks=Palvelin tehtävät pageAdmin.users.description=Käyttäjät säilössä pageAdmin.users=Käyttäjät -pageAdmin.workItems.description=Requests, approving -pageAdmin.workItems=Work Items +pageAdmin.workItems.description=Pyyntöjä, hyväksytään +pageAdmin.workItems=Työ alkiot PageBase.button.abort=Keskeytä PageBase.button.back=Takaisin PageBase.button.cancel=Peruuta @@ -1183,45 +1183,45 @@ PageBase.button.update=Päivitä PageBase.clearCssCache=Clear less/js cache pageBase.midPointVersion=${pom.version}, ${git.describe} pageBase.unknownBuildNumber=tuntematon -PageBase.subscriptionMessage=Non-subscription. -PageBase.nonActiveSubscriptionMessage=No active subscription. Please support midPoint by purchasing a subscription. -PageBase.demoSubscriptionMessage=Demo subscription. -PageBulkAction.async=Asynchronous +PageBase.subscriptionMessage=Ei-tilaus. +PageBase.nonActiveSubscriptionMessage=Ei aktiivista tilausta. Tue midPointtia hankkimalla tilaus, kiitos. +PageBase.demoSubscriptionMessage=Demo tilaus +PageBulkAction.async=Epäsynkroninen PageBulkAction.button.start=Aloita -PageBulkAction.message.emptyString=Inserted bulk action is empty. Please provide non-empty script. +PageBulkAction.message.emptyString=Syötetty massa toimenpide on tyhjä. Toimita ei-tyhjä skripti PageBulkAction.options=Vaihtoehdot -PageBulkAction.title=User bulk actions -PageRepositoryQuery.title=Repository query -PageRepositoryQuery.button.translateAndExecute=Translate and execute -PageRepositoryQuery.button.translate=Translate to hibernate query -PageRepositoryQuery.button.useInObjectList=Use in object list +PageBulkAction.title=Käyttäjän massa toimenpiteet +PageRepositoryQuery.title=Säilö kysely +PageRepositoryQuery.button.translateAndExecute=Käännä ja suorita +PageRepositoryQuery.button.translate=Käännä nukuta kyselyyn +PageRepositoryQuery.button.useInObjectList=Käytä objektilistassa PageRepositoryQuery.button.execute=Suorita -PageRepositoryQuery.message.emptyString=Entered query string is empty. Please provide non-empty query string. +PageRepositoryQuery.message.emptyString=Syötetty kysely merkkijono on tyhjä. Syötä ei-tyhjä kysely merkkijono. PageRepositoryQuery.result=Tulos -PageRepositoryQuery.resultObjects=Result: retrieved {0} object(s) -PageRepositoryQuery.resultException=Result: {0} -PageRepositoryQuery.midPoint=MidPoint query -PageRepositoryQuery.objectType=Object type: -PageRepositoryQuery.hibernateQuery=Hibernate query -PageRepositoryQuery.hibernateParameters=Query parameters +PageRepositoryQuery.resultObjects=tulos: palautettu {0} objektia +PageRepositoryQuery.resultException=tulos: {0} +PageRepositoryQuery.midPoint=MidPoint kysely +PageRepositoryQuery.objectType=Obejekti tyyppi: +PageRepositoryQuery.hibernateQuery=Nukuta kysely +PageRepositoryQuery.hibernateParameters=Kysely parametrit PageRepositoryQuery.hibernateParametersNote=Note: The parameters are shown here only to indicate how midPoint query is translated into hibernate query. They are not used when manually executing a hibernate query, so the query you enter here should contain no references to parameters. PageRepositoryQuery.incompleteResultsNote=Because you do not have administrator rights, results shown here were probably filtered by applying additional search conditions derived from your authorizations. These additional conditions are not visible in the hibernate query shown above. -PageRepositoryQuery.chooseSample=Or use a sample: -PageRepositoryQuery.sample.ObjectType_AllObjectsInAnOrg=All objects in an organization (directly) -PageRepositoryQuery.sample.ObjectType_AllObjectsInASubtree=All objects in a subtree -PageRepositoryQuery.sample.OrgType_AllRootOrgs=All organizational roots -PageRepositoryQuery.sample.OrgType_OrgOfType1=Organizations of type "type1" +PageRepositoryQuery.chooseSample=Tai käytä näytettä: +PageRepositoryQuery.sample.ObjectType_AllObjectsInAnOrg=Kaikki objektit organisaatiossa (suoraan) +PageRepositoryQuery.sample.ObjectType_AllObjectsInASubtree=Kaikki objektit alipuussa +PageRepositoryQuery.sample.OrgType_AllRootOrgs=Kaikki organisaatio juuret +PageRepositoryQuery.sample.OrgType_OrgOfType1=Organisaatiot tyyppiä "tyyppi1" PageRepositoryQuery.sample.UserType_AllUsers=Kaikki käyttäjät -PageRepositoryQuery.sample.UserType_UsersStartingWithA=Users starting with "a" (normalized) -PageRepositoryQuery.sample.UserType_UsersContainingJack=Users containing "jack" in a name (normalized) -PageRepositoryQuery.sample.UserType_UsersNamedJack=Users with a given name of "jack" (normalized) -PageRepositoryQuery.sample.UserType_First10UsersStartingWithA=First 10 users starting with "a" -PageRepositoryQuery.sample.UserType_UsersWithAGivenMailDomain=Users with a given mail domain -PageRepositoryQuery.sample.UserType_UsersThatHaveAssignedRole=Users that have a direct assignment of a role -PageRepositoryQuery.sample.UserType_UsersThatHaveARole=Users that have active assignment of a role +PageRepositoryQuery.sample.UserType_UsersStartingWithA=Käyttäjät alkaen kirjaimella "a" (normalisoitu) +PageRepositoryQuery.sample.UserType_UsersContainingJack=Käyttäjät joiden nimestä löytyy "jack" (normalisoitu) +PageRepositoryQuery.sample.UserType_UsersNamedJack=Käyttäjät etunimeltä "jack" (normalisoitu) +PageRepositoryQuery.sample.UserType_First10UsersStartingWithA=10 ensimmäistä käyttäjää jotka alkaa "a"lla +PageRepositoryQuery.sample.UserType_UsersWithAGivenMailDomain=Käyttäjät joille myönnetty posti toimialue +PageRepositoryQuery.sample.UserType_UsersThatHaveAssignedRole=Käyttäjät joilla on suora roolin toimeksianto +PageRepositoryQuery.sample.UserType_UsersThatHaveARole=Käyttäjät joilla on aktiivinen roolin toimeksianto PageRepositoryQuery.sample.UserType_SpecifiedCostCenters=Users in cost centers 100000-999999 or X100-X999 -PageRepositoryQuery.sample.ShadowType_ShadowsOnGivenResource=Shadows on a given resource -PageRepositoryQuery.sample.UserType_UsersWithShadowOnGivenResource=Users with linked shadow on a given resource +PageRepositoryQuery.sample.ShadowType_ShadowsOnGivenResource=Varjot myönnetyssä resurssissa +PageRepositoryQuery.sample.UserType_UsersWithShadowOnGivenResource=Käyttäjät joilla linkitetty varjo myönnetyssä resurssissa PageRepositoryQuery.queryVsFilterNote=Note: midPoint query contains a filter along with paging instruction, wrapped together within the <query> element. In contrast, when used in "Advanced filter" in GUI, only the <filter> sub-element is applicable. Paging is managed by the GUI itself. PageCert.ago={0} sitten PageCertCampaign.basic=Perus @@ -1259,27 +1259,27 @@ PageCertCampaigns.menu.closeSelected=Sulje valitut kampanjat PageCertCampaigns.menu.delete=Poista kampanja PageCertCampaigns.menu.deleteSelected=Poista valitut kampanjat PageCertCampaigns.menu.startSelected=Aloita valitut kampanjat -PageCertCampaigns.message.closeCampaignConfirmMultiple=Do you really want to close selected {0} campaigns? -PageCertCampaigns.message.closeCampaignConfirmSingle=Do you really want to close campaign '{0}' ? -PageCertCampaigns.message.closeStageConfirmSingle=Do you really want to close current stage for '{0}'? -PageCertCampaigns.message.deleteCampaignConfirmMultiple=Do you really want to delete selected {0} campaigns? -PageCertCampaigns.message.deleteCampaignConfirmSingle=Do you really want to delete campaign '{0}' ? -PageCertCampaigns.message.noCampaignsSelected=No relevant campaigns selected +PageCertCampaigns.message.closeCampaignConfirmMultiple=Oletko varma, että haluat sulkea valitut {0} kampanjat? +PageCertCampaigns.message.closeCampaignConfirmSingle=Oletko varma, että haluat sulkea kampanjan '{0}' ? +PageCertCampaigns.message.closeStageConfirmSingle=Oletko varma, että haluat sulkea tämän hetkisen vaiheen '{0}'? +PageCertCampaigns.message.deleteCampaignConfirmMultiple=Oletko varma, että haluat poistaa valitut '{0}' kampanjaa? +PageCertCampaigns.message.deleteCampaignConfirmSingle=Oletko varma, että haluat poistaa kampanjan '{0}' ? +PageCertCampaigns.message.noCampaignsSelected=Relevantteja kampanjoita ei valittuna. PageCertCampaigns.nowForCampaign=(kampanja: nyt) PageCertCampaigns.nowForStage=nyt -PageCertCampaigns.table.deadline=Stage (campaign) deadline -PageCertCampaigns.table.escalationLevel=Esc. level +PageCertCampaigns.table.deadline=Vaiheen (kampanja) määräaika +PageCertCampaigns.table.escalationLevel=eskalointi taso PageCertCampaigns.table.description=Kuvaus PageCertCampaigns.table.name=Nimi PageCertCampaigns.table.stages=Vaiheet PageCertCampaigns.table.stage=Vaihe PageCertCampaigns.table.state=undefined -PageCertCampaign.stageTime=Stage time -PageCertCampaign.escalationLevel=Escalation level +PageCertCampaign.stageTime=Vaiheen aika +PageCertCampaign.escalationLevel=eskalointi taso PageCertCampaign.statistics.accept=Hyväksy PageCertCampaign.statistics.delegate=Edustaja -PageCertCampaign.statistics.items=Items -PageCertCampaign.statistics.noDecision=No decision (abstain) +PageCertCampaign.statistics.items=Alkiot +PageCertCampaign.statistics.noDecision=Ei valintaa (pidättäydy) PageCertCampaign.statistics.noResponse=Ei vastausta PageCertCampaign.statistics.reduce=Vähennä PageCertCampaign.statistics.reduceRemedied=Vähennä - oikaistu @@ -1288,150 +1288,150 @@ PageCertCampaign.statistics.response=Vastaus PageCertCampaign.statistics.revokeRemedied=Kumoa - oikaistu PageCertCampaign.statistics.revoke=Kumoa PageCertCampaign.statistics=Tilastot -PageCertCampaigns.title=Access Certification Campaigns {0} +PageCertCampaigns.title=Yhdistä sertifikaatio kampanjiin {0} PageCertCampaign.table.campaignName=Kampanja nimi PageCertCampaign.table.comments=Kommentit -PageCertCampaign.table.deadline=Deadline +PageCertCampaign.table.deadline=Määräaika PageCertCampaign.table.decision=Päätökset PageCertCampaign.table.objectName=Objekti -PageCertCampaign.table.remediedAt=Remedied at +PageCertCampaign.table.remediedAt=oikaistu PageCertCampaign.table.requested=Pyydetty PageCertCampaign.table.reviewers=Arvioijat -PageCertCampaign.table.reviewedAt=Reviewed at +PageCertCampaign.table.reviewedAt=arvioitu PageCertCampaign.table.reviewedBy=Arvioitsija PageCertCampaign.table.reviewedInStage=Vaiheessa PageCertCampaign.table.targetName=Kohde -PageCertCampaign.table.conflictingTargetName=Conflicting -PageCertCampaign.noReviewers=(none) +PageCertCampaign.table.conflictingTargetName=Ristiriitainen +PageCertCampaign.noReviewers=(ei mitään) PageCertCampaign.time=Aika -PageCertCampaign.title=Access Certification Campaign +PageCertCampaign.title=Yhdistä sertifikaatio kampanjaan PageCertDecisions.ago={0} sitten -PageCertDecisions.checkbox.showNoResponseOnly=Show "no response" cases only +PageCertDecisions.checkbox.showNoResponseOnly=Näytä vain "Ei vastausta" tapaukset PageCertDecisions.in=in {0} PageCertDecisions.menu.accept=Hyväksy -PageCertDecisions.menu.acceptSelected=Accept selected +PageCertDecisions.menu.acceptSelected=Hyväksy valitut PageCertDecisions.menu.delegate=Edustaja -PageCertDecisions.menu.delegateSelected=Delegate selected +PageCertDecisions.menu.delegateSelected=Delegoi valitut PageCertDecisions.menu.noResponse=Ei Vastausta -PageCertDecisions.menu.noResponseSelected=Mark selected as No response +PageCertDecisions.menu.noResponseSelected=Merkitse valitut "Ei vastausta"-ksi PageCertDecisions.menu.notDecided=Ei Päätetty -PageCertDecisions.menu.notDecidedSelected=Mark selected as Not decided +PageCertDecisions.menu.notDecidedSelected=Merkitse valitut "Ei päätetty" -iksi PageCertDecisions.menu.reduce=Vähennä -PageCertDecisions.menu.reduceSelected=Reduce selected +PageCertDecisions.menu.reduceSelected=Vähennä valitut PageCertDecisions.menu.revoke=Kumoa PageCertDecisions.menu.revokeSelected=Kumoa valittu -PageCertDecisions.message.noItemSelected=No item selected +PageCertDecisions.message.noItemSelected=Ei alkiota valittuna PageCertDecisions.now=nyt PageCertDecisions.table.campaignName=Kampanja nimi PageCertDecisions.table.campaignStage=Vaihe -PageCertDecisions.table.escalation=Esc +PageCertDecisions.table.escalation=Eskalointi PageCertDecisions.table.comment=Kommentti PageCertDecisions.table.deadline=Määräaika PageCertDecisions.table.decision=Päätös PageCertDecisions.table.objectName=Objekti PageCertDecisions.table.requested=Pyydetty PageCertDecisions.table.targetName=Kohde -PageCertDecisions.table.conflictingTargetName=Conflicting +PageCertDecisions.table.conflictingTargetName=Ristiriitainen PageCertDecisions.table.targetType=Tyyppi -PageCertDecisions.title=My certification work items -PageCertDefinition.basicInformation=Basic information +PageCertDecisions.title=minun sertifikointi työ alkiot +PageCertDefinition.basicInformation=Perustiedot PageCertDefinition.button.back=Takaisin PageCertDefinition.button.save=Tallenna PageCertDefinition.description=Kuvaus PageCertDefinition.name=Nimi PageCertDefinition.numberOfStages=Vaiheiden määrä -PageCertDefinition.outcomeStrategy=Strategy for deriving overall outcome from stage outcomes -PageCertDefinition.campaignsInReviewStage=Campaigns in review stage -PageCertDefinition.campaignsTotal=Campaigns total -PageCertDefinition.campaignLastStarted=Campaign last started -PageCertDefinition.campaignLastClosed=Campaign last closed +PageCertDefinition.outcomeStrategy=Strategia kokonaistuloksen päättelyyn vaihe tuloksista. +PageCertDefinition.campaignsInReviewStage=Arvointi vaiheessa olevat kampanjat +PageCertDefinition.campaignsTotal=Kampanjat yhteensä +PageCertDefinition.campaignLastStarted=Viimeksi aloitettu kampanja +PageCertDefinition.campaignLastClosed=Viimeksi suljettu kampanja PageCertDefinition.owner=Omistaja -PageCertDefinition.stopReviewOn=stop review on: +PageCertDefinition.stopReviewOn=lopeta arviointi: PageCertDefinition.stopReviewOnDefault= PageCertDefinition.stopReviewOnNone= -PageCertDefinitions.basicInformation=Basic information +PageCertDefinitions.basicInformation=Perustiedot PageCertDefinitions.button.createCampaign=Luo kampanja PageCertDefinitions.button.deleteDefinition=Poista kuvaus -PageCertDefinitions.button.editAsXml=Edit as XML +PageCertDefinitions.button.editAsXml=Muokkaa XMLnä PageCertDefinitions.button.showCampaigns=Näytä kampanjat -PageCertDefinitions.deleteDefinitionConfirmSingle=Do you really want to delete definition '{0}'? +PageCertDefinitions.deleteDefinitionConfirmSingle=Oletko varma, että haluat poistaa kuvauksen '{0}' ? PageCertDefinitions.table.description=Kuvaus PageCertDefinitions.table.name=Nimi -PageCertDefinitions.title=Access Certification Definitions +PageCertDefinitions.title=Yhdistä sertifikaation määritelmiin PageCertDefinitions.title.confirmDelete=Vahvista poista -PageCertDefinitionsxmlDefinition=XML definition -PageCertDefinition.title=Access Certification Campaign Definition +PageCertDefinitionsxmlDefinition=XML kuvaus +PageCertDefinition.title=Yhdistä sertifikaatio kampanjan määritelmään PageCertDefinition.campaigns=Kampanjat -PageCertDefinition.xmlDefinition=XML definition -PageCertDefinition.scopeDefinition=Scope definition +PageCertDefinition.xmlDefinition=XML kuvaus +PageCertDefinition.scopeDefinition=Skaalan kuvaus PageCertDefinition.basic=Perus -PageCertDefinition.scopeName=Scope name -PageCertDefinition.scopeDescription=Scope description +PageCertDefinition.scopeName=Skaalan nimi +PageCertDefinition.scopeDescription=Skaalan kuvaus PageCertDefinition.scopeObjectType=Objekti tyyppi -PageCertDefinition.scopeSearchFilter=Filter to select objects -PageCertDefinition.scopeAssignmentsInducements=Include assignments or inducements -PageCertDefinition.scopeIncludeAssignments=Assignments -PageCertDefinition.scopeIncludeInducements=Inducements -PageCertDefinition.scopeIncludeTargetTypes=Include target types +PageCertDefinition.scopeSearchFilter=Suodata objektien valintaa varten +PageCertDefinition.scopeAssignmentsInducements=Laske mukaan toimeeksiannot tai vaikuttimet +PageCertDefinition.scopeIncludeAssignments=Toimeksiannot +PageCertDefinition.scopeIncludeInducements=Vaikuttimet +PageCertDefinition.scopeIncludeTargetTypes=Laske mukaan kohde tyypit PageCertDefinition.scopeIncludeRoles=Roolit -PageCertDefinition.scopeIncludeOrgs=Orgs +PageCertDefinition.scopeIncludeOrgs=Organisaatiot PageCertDefinition.scopeIncludeServices=Palvelut PageCertDefinition.scopeIncludeResources=Resurssit -PageCertDefinition.scopeIncludeByStatus=Include by activation status -PageCertDefinition.scopeEnabledItemsOnly=Enabled items only -PageCertDefinition.stagesDefinition=Stages definition +PageCertDefinition.scopeIncludeByStatus=Laske mukaan aktivaatio statuksen mukaan +PageCertDefinition.scopeEnabledItemsOnly=Vain käyttöön otetut alkiot +PageCertDefinition.stagesDefinition=Vaiheet kuvaus PageCert.in=in {0} PageCert.message.assignment={0} of {1} {2} to {3} {4}. -PageCert.message.textAdministrativeState=Administrative state: {0}. +PageCert.message.textAdministrativeState=Hallinnon tila: {0}. PageCert.message.textAssignment=Toimeksianto PageCert.message.textDescription=Kuvaus: {0}. -PageCert.message.textExtensions=Extensions defined: {0}. -PageCert.message.textInducement=Inducement -PageCert.message.textIntent=Intent: {0}. -PageCert.message.textKind=Kind: {0}. +PageCert.message.textExtensions=Määritetyt laajennokset: {0}. +PageCert.message.textInducement=Vaikutin +PageCert.message.textIntent=Aikomus: {0}. +PageCert.message.textKind=Laji: {0}. PageCert.message.textOrder=Järjestys: {0}. PageCert.message.textOrg=Org: {0}. -PageCert.message.textRelation=Relation: {0}. -PageCert.message.textTenant=Tenant: {0}. -PageCert.message.textValidFrom=Valid from: {0}. -PageCert.message.textValidTo=Valid to: {0}. +PageCert.message.textRelation=Yhteys: {0}. +PageCert.message.textTenant=Haltija: {0}. +PageCert.message.textValidFrom=voimassa: {0}sta. +PageCert.message.textValidTo=voimassa: {0}hin. PageCert.now=nyt StageEditorPanel.stageDefinitionLabelName = Vaiheen Kuvaus # StageDefinitionPanel.stageName = Nimi StageDefinitionPanel.stageDescription = Kuvaus StageDefinitionPanel.stageDuration = Kesto StageDefinitionPanel.notifyBeforeDeadline = Ilmoita ennen määräaikaa -StageDefinitionPanel.notifyWhenNoDecision = Notify only when no decision -StageDefinitionPanel.reviewerSpecification = Reviewer specification -StageDefinitionPanel.reviewerSpecificationName = Reviewer specification name (optional) -StageDefinitionPanel.reviewerSpecificationDescription = Reviewer specification description (optional) -StageDefinitionPanel.reviewerSpecificationTarget = Reviewers based on assignment target object -StageDefinitionPanel.reviewerSpecificationObject = Reviewers based on the object being assigned to -StageDefinitionPanel.reviewerUseTargetOwner = Use target owner -StageDefinitionPanel.reviewerUseTargetApprover = Use target approver -StageDefinitionPanel.reviewerUseObjectOwner = Use object owner -StageDefinitionPanel.reviewerUseObjectApprover = Use object approver -StageDefinitionPanel.reviewerUseObjectManager = Reviewers based on the manager of object being assigned to -StageDefinitionPanel.reviewerUseObjectManagerOrgType = Type of organization relation used to determine the manager (optional) -StageDefinitionPanel.reviewerUseObjectManagerAllowSelf = Allow managers to approve their own assignments -StageDefinitionPanel.reviewerUseObjectManagerBox = Use object manager -StageDefinitionPanel.defaultReviewerRef = Default reviewer reference -StageDefinitionPanel.additionalReviewerRef = Additional reviewer reference -StageDefinitionPanel.outcomeStrategy = Decision aggregation strategy in case of more than one reviewer -StageDefinitionPanel.outcomeIfNoReviewers = Outcome if there are no reviewers allocated -StageDefinitionPanel.stopReviewOn = Stop review on +StageDefinitionPanel.notifyWhenNoDecision = Ilmoita vain jos ei valintaa +StageDefinitionPanel.reviewerSpecification = Arvioijan määrittely +StageDefinitionPanel.reviewerSpecificationName = Arvioijan määrittelyn nimi (valinnainen) +StageDefinitionPanel.reviewerSpecificationDescription = Arvioijan määrittelyn kuvaus (valinnainen) +StageDefinitionPanel.reviewerSpecificationTarget = Arvioijat perustuen kohde objektin toimeksiantoon +StageDefinitionPanel.reviewerSpecificationObject = Arvioijat perustuen mihin objektiin osoitetaan +StageDefinitionPanel.reviewerUseTargetOwner = Käytä kohteen omistajaa +StageDefinitionPanel.reviewerUseTargetApprover = Käytä kohteen hyväksyjää +StageDefinitionPanel.reviewerUseObjectOwner = Käytä objektin omistajaa +StageDefinitionPanel.reviewerUseObjectApprover = Käytä objektin hyväksyjää +StageDefinitionPanel.reviewerUseObjectManager = Arvioijat perustuen osoitettavan objektin managerin mukaan +StageDefinitionPanel.reviewerUseObjectManagerOrgType = Organisaatio suhteen tyyppi jonka mukaan manageri päätetään (valinnainen) +StageDefinitionPanel.reviewerUseObjectManagerAllowSelf = Salli managerien hyväksyä omat toimeksiantonsa +StageDefinitionPanel.reviewerUseObjectManagerBox = Käytä objektin manageria +StageDefinitionPanel.defaultReviewerRef = Perus arviojan viittaus +StageDefinitionPanel.additionalReviewerRef = Arvioijan lisäviittaus +StageDefinitionPanel.outcomeStrategy = Valnnan lisäämisstrategia jos on useampi kuin yksi arvioija +StageDefinitionPanel.outcomeIfNoReviewers = Tulos jos ei yhtään arvioijaa kohdennettu +StageDefinitionPanel.stopReviewOn = lopeta arviointi StageDefinitionPanel.remediation = Oikaisu StageDefinitionPanel.addNewStageButton = Lisää vaiheen kuvaus StageDefinitionPanel.moveStageLeftButton = Siirrä vasemmalle StageDefinitionPanel.moveStageRightButton = Siirrä oikealla StageDefinitionPanel.deleteStageButton = Poista tämä vaihe -PageContacts.title=Contacts browser +PageContacts.title=Yhteystietojen selain pageContentAccounts.button.searchButton=Etsi -pageContentAccounts.dialog.title.confirmDelete=Delete Confirmation -pageContentAccounts.identifiers=Identifiers +pageContentAccounts.dialog.title.confirmDelete=Poista Vahvistus +pageContentAccounts.identifiers=Tunnistajat pageContentAccounts.isProtected=On suojattu pageContentAccounts.intent=Aikomus -pageContentAccounts.kind=Kind +pageContentAccounts.kind=Laji pageContentAccounts.menu.changeOwner=Vaihda omistajaa pageContentAccounts.menu.deleteAccount=Poista pageContentAccounts.menu.disableAccount=Poista käytöstä @@ -1442,22 +1442,22 @@ pageContentAccounts.menu.deleteAccounts=Poista valitut pageContentAccounts.menu.disableAccounts=Poista käytöstä valitut pageContentAccounts.menu.enableAccounts=Ota käyttöön valitut pageContentAccounts.menu.importAccounts=Tuo valitut -pageContentAccounts.menu.removeOwners=Remove for selected -pageContentAccounts.message.cantImportAccount=Can't import account, oid={0} -pageContentAccounts.message.cantShowAccountDetails=Can't show details for account {0} ({1}). -pageContentAccounts.message.cantShowUserDetails=Can't show details of user {0} ({1}). -pageContentAccounts.message.deleteConfirmation=Do you really want to delete {0} account(s) from this resource? -pageContentAccounts.message.deleteConfirmationSingle=Do you really want to delete '{0}' account from this resource? -pageContentAccounts.message.noAccountSelected=No accounts has been selected. -pageContentAccounts.message.resourceOidNotDefined=Resource oid is not defined in url. +pageContentAccounts.menu.removeOwners=Valittujen poisto +pageContentAccounts.message.cantImportAccount=Ei voi tuoda tiliä, oid={0} +pageContentAccounts.message.cantShowAccountDetails=Ei voi näyttää yksityiskohtia tillille {0} ({1}). +pageContentAccounts.message.cantShowUserDetails=Ei voi näyttää yksityiskohtia tillille {0} ({1}). +pageContentAccounts.message.deleteConfirmation=Oletko varma, että haluat poistaa {0} tili(t) tästä resurssista? +pageContentAccounts.message.deleteConfirmationSingle=Oletko varma, että haluat poistaa {0} tilin tästä resurssista? +pageContentAccounts.message.noAccountSelected=Ei ole valittuna tilejä. +pageContentAccounts.message.resourceOidNotDefined=Oid resurssia ei määritelty url:ssa. pageContentAccounts.name=Nimi pageContentAccounts.objectClass=Objekti luokka pageContentAccounts.owner=Omistaja pageContentAccounts.search=Etsi pageContentAccounts.situation=Tilanne -PageContentAccounts.title=Resource objects on '{0}' -pageContentEntitlements.entitlements=Entitlements -pageContentEntitlements.message.resourceOidNotDefined=Resource oid is not defined in url. +PageContentAccounts.title=Resurssi objektit '{0}'ssa +pageContentEntitlements.entitlements=Oikeutukset +pageContentEntitlements.message.resourceOidNotDefined=Oid resurssia ei määritelty url:ssa. PageContentEntitlements.title={0} pageCreatedReports.button.delete=Poista pageCreatedReports.button.download=Lataa @@ -1468,13 +1468,13 @@ pageCreatedReports.filter.filetype=Tiedostotyyppi pageCreatedReports.filter.reportType=Raportti Tyyppi pageCreatedReports.inlineMenu.deleteAll=Poista kaikki pageCreatedReports.inlineMenu.deleteSelected=Poista Valitut -pageCreatedReports.message.deleteAll=Do you really want to delete all created report outputs? -pageCreatedReports.message.deleteOutputConfirmed=Do you really want to delete selected {0} Created report(s)? -pageCreatedReports.message.deleteOutputSingle=Do you really want to delete Created report '{0}'? -pageCreatedReports.message.downloadError=Could not download Report. -pageCreatedReports.message.fileNotFound=File with report was not found. -pageCreatedReports.message.nothingSelected=No reports have been selected. -pageCreatedReports.message.queryError=Error occurred during translation search query to filter. +pageCreatedReports.message.deleteAll=Oletko varma että haluat poistaa kaikki luodut raportti ulosannit? +pageCreatedReports.message.deleteOutputConfirmed=Oletko varma että haluat poistaa valitut {0} Luodut raportit? +pageCreatedReports.message.deleteOutputSingle=Haluatko varmasti poistaa Luodun raportin '{0}'? +pageCreatedReports.message.downloadError=Ei voinut imuroida Raporttia. +pageCreatedReports.message.fileNotFound=Ei löytynyt tiedostoa jossa raportti on. +pageCreatedReports.message.nothingSelected=Yhtään raporttia ei ole valittuna. +pageCreatedReports.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. pageCreatedReports.table.author=Julkaisija pageCreatedReports.table.description=Kuvaus pageCreatedReports.table.filetype=Tiedostotyyppi @@ -1485,63 +1485,63 @@ PageCreatedReports.title=Luodut Raportit PageDashboard.accounts=Minun tilini PageDashboard.activeTasks=Aktiiviset Tehtävät PageDashboard.activeUsers=Aktiiviset Käyttäjät -PageDashboard.assignments=My assignments -PageDashboard.personalInfo=Personal info -PageDashboard.serverLoad=Server Load +PageDashboard.assignments=Minun toimeksiantoni +PageDashboard.personalInfo=Henkilökohtaiset tiedot +PageDashboard.serverLoad=Palvelin Kuorma PageDashboard.systemInfo=Systeemin tila PageDashboard.title=Kojelauta PageDashboard.usedRam=Käytetty RAM -PageDashboard.workItems=My work items +PageDashboard.workItems=minun työ alkioni PageDashboard.infobox.users.label=Käyttäjät PageDashboard.infobox.users.number=otettu käyttöön -PageDashboard.infobox.users.total=total +PageDashboard.infobox.users.total=Yhteensä PageDashboard.infobox.users.archived=arkistoitu PageDashboard.infobox.orgs.label=Organisaatio yksiköt PageDashboard.infobox.orgs.number=otettu käyttöön -PageDashboard.infobox.orgs.total=total +PageDashboard.infobox.orgs.total=Yhteensä PageDashboard.infobox.orgs.archived=arkistoitu PageDashboard.infobox.roles.label=Roolit PageDashboard.infobox.roles.number=otettu käyttöön -PageDashboard.infobox.roles.total=total +PageDashboard.infobox.roles.total=Yhteensä PageDashboard.infobox.roles.archived=arkistoitu PageDashboard.infobox.services.label=Palvelut PageDashboard.infobox.services.number=otettu käyttöön -PageDashboard.infobox.services.total=total +PageDashboard.infobox.services.total=Yhteensä PageDashboard.infobox.services.archived=arkistoitu PageDashboard.infobox.resources.label=Resurssit PageDashboard.infobox.resources.number=ylhäällä -PageDashboard.infobox.resources.total=total +PageDashboard.infobox.resources.total=Yhteensä PageDashboard.infobox.tasks.label=Tehtävät PageDashboard.infobox.tasks.number=Aktivoi -PageDashboard.infobox.tasks.total=total +PageDashboard.infobox.tasks.total=Yhteensä pageDebugList.button.clear=Tyhjennä pageDebugList.button.search=Etsi pageDebugList.description=Kuvaus pageDebugList.dialog.title.confirmDelete=Vahvista poista -pageDebugList.dialog.title.deleteAll=Delete All Objects -pageDebugList.menu.deleteAllIdentities=Delete all identities -pageDebugList.menu.deleteAllType=Delete all of selected type +pageDebugList.dialog.title.deleteAll=Poista kaikki objektit +pageDebugList.menu.deleteAllIdentities=Poista kaikki identiteetit +pageDebugList.menu.deleteAllType=Poista kaikki valitun tyyppiset pageDebugList.menu.deleteSelected=Poista valitut -pageDebugList.menu.deleteShadowsOnResource=Delete all shadows on resource -pageDebugList.menu.exportShadowsOnResource=Export all shadows on resource -pageDebugList.menu.exportAll=Export all objects -pageDebugList.menu.exportAllSelectedType=Export all of selected type -pageDebugList.menu.exportSelected=Export selected -pageDebugList.message.countSearchProblem=Couldn't perform search operation on users/shadows/org. units -pageDebugList.message.createFileException=Couldn't create file for download. -pageDebugList.message.deleteAllType=Do you really want to delete all objects of type "{0}"? -pageDebugList.message.deleteObjectConfirm=Do you really want to delete "{0}"? -pageDebugList.message.deleteSelectedConfirm=Do you really want to delete {0} objects? -pageDebugList.message.laxativeProblem=Drop all identities operation has not performed successfully -pageDebugList.message.nothingSelected=No object has been selected. -pageDebugList.message.queryException=Couldn't create query for name substring, reason: {0} -pageDebugList.message.resourceNotSelected=Resource not selected. -pageDebugList.message.singleOrgDeleteProblem=Couldn't delete org. unit -pageDebugList.message.singleShadowDeleteProblem=Couldn't delete shadow -pageDebugList.message.singleUserDeleteProblem=Couldn't delete user -pageDebugList.messsage.deleteAllOfType=Deleting objects of type {0}. -pageDebugList.messsage.deleteAllResourceShadows=Do you really want to delete all shadows on resource {0}? -pageDebugList.messsage.deleteAllShadowsStarted=Task which deletes all shadows on resource {0} was started. +pageDebugList.menu.deleteShadowsOnResource=Poista kaikki varjot resurssista +pageDebugList.menu.exportShadowsOnResource=Vie kaikki varjot resurssista +pageDebugList.menu.exportAll=Vie kaikki objektit +pageDebugList.menu.exportAllSelectedType=Vie kaikki valittun tyyppiset +pageDebugList.menu.exportSelected=Vie valitut +pageDebugList.message.countSearchProblem=Ei voinut suorittaa haku operaatiota tileistä/varjoista/org. yksiköistä +pageDebugList.message.createFileException=Ei pystynyt luomaan tiedostoa imuroitavaksi. +pageDebugList.message.deleteAllType=Haluatko varmasti poistaa kaikki tyyppiä "{0}" olevat objektit? +pageDebugList.message.deleteObjectConfirm=Haluatko varmasti poistaa "{0}"? +pageDebugList.message.deleteSelectedConfirm=Haluatko varmasti poistaa "{0}" objektia? +pageDebugList.message.laxativeProblem=Tiputa kaikki identiteetit operaatio ei suoriutunut onnistuneesti +pageDebugList.message.nothingSelected=Objekteja ei ole valittu. +pageDebugList.message.queryException=Ei voinut luoda kyselyä nimi alimerkkijonolle, syy: {0} +pageDebugList.message.resourceNotSelected=Resurssia ei valittuna. +pageDebugList.message.singleOrgDeleteProblem=Ei pystytty poistaa org. yksikköä +pageDebugList.message.singleShadowDeleteProblem=Ei pystytty poistamaan varjoa +pageDebugList.message.singleUserDeleteProblem=Ei pystytty poistamaan käyttäjää +pageDebugList.messsage.deleteAllOfType=Poistetaan {0} tyyppisiä objekteja. +pageDebugList.messsage.deleteAllResourceShadows=Haluatko varmasti poistaa kaikki varjot resurssista {0}? +pageDebugList.messsage.deleteAllShadowsStarted=Tehtävä joka poistaa kaikki varjot resurssista {0} aloitettu. pageDebugList.name=Nimi pageDebugList.oid=Oid pageDebugList.objectType=Objekti tyyppi @@ -1550,202 +1550,202 @@ pageDebugList.resourceName=Resurssin nimi pageDebugList.resource=Resurssi pageDebugList.resourceType=Resurssi tyyppi pageDebugList.searchTextPlaceholder=Nimi -PageDebugList.title=Raw objects -pageDebugList.zipCheck=Use zip +PageDebugList.title=Raw objektit +pageDebugList.zipCheck=Käytä zip pageDebugView.button.back=Takaisin pageDebugView.button.save=Tallenna pageDebugView.edit=Muokkaa -pageDebugView.encrypt=Protected by encryption -pageDebugView.message.cantSaveEmpty=Can't save empty xml. -pageDebugView.message.oidNotDefined=Object oid is not defined. +pageDebugView.encrypt=Suojattu salauksella +pageDebugView.message.cantSaveEmpty=Ei pysty tallentamaan tyhjää XML-tiedostoa. +pageDebugView.message.oidNotDefined=Oid objektia ei määritelty. pageDebugView.options=Vaihtoehdot -pageDebugView.reevaluateSearchFilters=Reevaluate search filters -pageDebugView.saveAsRaw=Save in raw mode -pageDebugView.switchToPlainText=Switch to plain text -PageDebugView.title='{0}' details -pageDebugView.validateSchema=Validate schema +pageDebugView.reevaluateSearchFilters=Arvioi uudestaan haku filtterit +pageDebugView.saveAsRaw=Tallenna raw tilaan +pageDebugView.switchToPlainText=Vaihda perus tekstiin +PageDebugView.title='{0}' yksityiskohdat +pageDebugView.validateSchema=Kelpuuta kaavio PageError403.title=Kielletty (403) PageError404.title=Ei löydy (404) -PageError401.title=Unauthorized (401) -PageError410.title=Gone (410) +PageError401.title=Luvaton (401) +PageError410.title=Kadonnut (410) PageError.button.back=Takaisin -PageError.message=Unexpected error occurred, if necessary please contact system administrator. -PageError403.message=You don't have rights to see the required page, if necessary please contact system administrator. +PageError.message=Odottamaton virhe, ottakaa yheys järjestelmänvalvojaan jos tarvis. +PageError403.message=Sinulla ei ole oikeuksi nähdäksesi tarvittavaa sivua, ota yhteyttä järjestelmään jos tarvitsee. PageError.title=Sisäinen virhe (500) PageFindUsers.title=Etsi käyttäjiä PageForgetPassword.email=Sähköposti -pageForgetPassword.message.ContactAdminQuestionsNotSet=You have not set any security questions yet. Please Contact Your Administrator to reset Your Password. +pageForgetPassword.message.ContactAdminQuestionsNotSet=Et ole asettanut yhtään turvallisuus kysymystä vielä. Ota yhteyttä järjestemänvalvojaa nollataksesi salasanasi. pageForgetPassword.message.usernotfound=Käyttäjää Ei Löydy PageForgetPassword.password=Salasana PageForgetPassword.resetPassword=Aseta salasana uudelleen PageForgotPassword.title=Unohtunut Salasana PageForgetPassword.username=Käyttänimi -PageForgotPassword.unsupported.reset.type=Unsupported password reset type -PageForgotPassword.send.nonce.failed=User's password couldn't be reset. Please contact system administrator. +PageForgotPassword.unsupported.reset.type=Ei tuettu salasanan uudelleen asettamisen tyyppi +PageForgotPassword.send.nonce.failed=Käyttäjän salasanaa ei pystytty nollaamaan. Ota yhteyttä järjestmänvalvojaan. PageImportObject.button.import=Tuo objekti -PageImportObject.embeddedEditor=Embedded editor +PageImportObject.embeddedEditor=Sisäinen editori PageImportObject.file=Tiedosto PageImportObject.getObjectsFrom=Get objects from -pageImportObject.message.emptyXml=Can't save empty xml. -PageImportObject.message.help=Choose XML file for import. -pageImportObject.message.nullFile=Uploaded file is null. +pageImportObject.message.emptyXml=Ei pysty tallentamaan tyhjää XML-tiedostoa. +PageImportObject.message.help=Valitse XML, JSON tai YAML tiedosto tuotavaksi. +pageImportObject.message.nullFile=Lähetetty tiedosto on tyhjä. PageImportObject.title=Tuo objekteja PageInternals.button.changeTime=Muuta aika -PageInternals.button.resetTimeChange=Reset to using system time -PageInternals.consistencyChecks=Check consistency -PageInternals.encryptionChecks=Check encryption -PageInternals.readEncryptionChecks=Check read encryption -PageInternals.detailedDebugDump=Detailed debug dump -PageInternals.message.debugUpdatePerformed=Debug util updated. New value: {0} +PageInternals.button.resetTimeChange=aseta uudelleen käyttämään järjestelmän aikaa +PageInternals.consistencyChecks=Tarkista johdonmukaisuus +PageInternals.encryptionChecks=Tarkista salaus +PageInternals.readEncryptionChecks=Tarkista lue salaus +PageInternals.detailedDebugDump=Yksityiskohtainen virheen tarkistus vedos +PageInternals.message.debugUpdatePerformed=Virheen tarkistus työkalu päivitetty. Uusi arvo: {0} PageInternals.message.internalsConfigUpdate=Internals config update. consistencyChecks: {0},encryptionChecks: {1}, readEncryptionChecks: {2}, QNameUtil.tolerateUndeclaredPrefixes: {3} -PageInternals.offset=Offset -PageInternals.title.debugUtil=Debug util -PageInternals.title.internalsConfig=Internals config -PageInternals.title=Internals configuration -PageInternals.title.timeChange=Time change -PageInternals.tolerateUndeclaredPrefixes=Tolerate undeclared prefixes in QNames and paths -PageInternals.title.counters=Performance counters -PageInternals.title.traces=Performance traces -InternalOperationClasses.resourceSchemaOperations=Resource schema operations -InternalOperationClasses.connectorOperations=Connector operations -InternalOperationClasses.shadowFetchOperations=Shadow fetch operations -InternalOperationClasses.repositoryOperations=Repository operations -InternalOperationClasses.prismObjectClone=Prism object clones -InternalOperationClasses.roleEvaluations=Role evaluations -InternalCounters.resourceSchemaParseCount=Resource schema parse -InternalCounters.resourceSchemaFetchCount=Resource schema fetch -InternalCounters.connectorInstanceInitializationCount=Connector instance initialization -InternalCounters.connectorSchemaParseCount=Connector schema parse -InternalCounters.connectorCapabilitiesFetchCount=Connector capabilities fetch -InternalCounters.scriptCompileCount=Script compile -InternalCounters.scriptExecutionCount=Script execution -InternalCounters.connectorOperationCount=Connector operation -InternalCounters.connectorSimulatedPagingSearchCount=Connector simulated paging search -InternalCounters.shadowFetchOperationCount=Shadow fetch operation -InternalCounters.shadowChangeOperationCount=Shadow change operation -InternalCounters.provisioningAllExtOperationCount=All external provisioning operations -InternalCounters.repositoryReadCount=Repository read -InternalCounters.prismObjectCompareCount=Prism object compare -InternalCounters.prismObjectCloneCount=Prism object clone -InternalCounters.roleEvaluationCount=Role evaluation count -InternalCounters.roleEvaluationSkipCount=Role evaluation skip count -InternalCounters.projectorRunCount=Projector run count -pageLogging.appender=Appender: -pageLogging.appenders=Appenders -pageLogging.appenders.appending=Appending +PageInternals.offset=Poikkeama +PageInternals.title.debugUtil=viirheen tarkistus työkalu +PageInternals.title.internalsConfig=Sisäisien konfiguraatio +PageInternals.title=Sisäisien konfiguraatio +PageInternals.title.timeChange=Ajan muutos +PageInternals.tolerateUndeclaredPrefixes=Siedä julistamattomia etuliitteitä Qnames:ssä ja poluissa +PageInternals.title.counters=Suoritus laskurit +PageInternals.title.traces=Suoriutumis jäljitykset +InternalOperationClasses.resourceSchemaOperations=Resurssikaavio operaatiot +InternalOperationClasses.connectorOperations=Liitin operaatiot +InternalOperationClasses.shadowFetchOperations=Varjo nouto operaatiot +InternalOperationClasses.repositoryOperations=Säilö operaatiot +InternalOperationClasses.prismObjectClone=Särmiö objektin kloonit +InternalOperationClasses.roleEvaluations=Rooli arvioinnit +InternalCounters.resourceSchemaParseCount=Resurssikaavion jäsennys +InternalCounters.resourceSchemaFetchCount=Resurssikaavion nouto +InternalCounters.connectorInstanceInitializationCount=Liitintapahtuman aloitus +InternalCounters.connectorSchemaParseCount=Liitin kaavio jäsennys +InternalCounters.connectorCapabilitiesFetchCount=Liittimen kykyjen nouto +InternalCounters.scriptCompileCount=Ohjelmakoodi kokoa +InternalCounters.scriptExecutionCount=Ohjelmakoodin suoritus +InternalCounters.connectorOperationCount=Liitin operaatio +InternalCounters.connectorSimulatedPagingSearchCount=liittimen simuloitu kutsunnan haku +InternalCounters.shadowFetchOperationCount=Varjo nouto operaatio +InternalCounters.shadowChangeOperationCount=Varjo vaihda operaatio +InternalCounters.provisioningAllExtOperationCount=Kaikki ulkoiset esivalmistelu operaatiot +InternalCounters.repositoryReadCount=Säilön luku +InternalCounters.prismObjectCompareCount=Särmiö objekti vertaile +InternalCounters.prismObjectCloneCount=Särmiö objektin klooni +InternalCounters.roleEvaluationCount=roolin arviointi lasku +InternalCounters.roleEvaluationSkipCount=Roolin arviointi sivuuta lasku +InternalCounters.projectorRunCount=Projektori suoritus määrä +pageLogging.appender=Liittäjä: +pageLogging.appenders=Liittäjät +pageLogging.appenders.appending=Liittäminen pageLogging.appenders.filePath=Tiedostopolku -pageLogging.appenders.filePattern=File pattern +pageLogging.appenders.filePattern=Tiedosto kuvio pageLogging.appenders.maxFileSize=Max. tiedosto koko [kB] pageLogging.appenders.maxHistory=Max. historia pageLogging.appenders.name=Nimi pageLogging.appenders.pattern=Kuvio pageLogging.audit=Auditoi -pageLogging.auditLog=Audit to log file: -pageLogging.button.addClassLogger=Add logger -pageLogging.button.addComponentLogger=Add component logger -pageLogging.button.addConsoleAppender=Add console appender -pageLogging.button.addFileAppender=Add file appender +pageLogging.auditLog=Auditoi logi-tiedostoon: +pageLogging.button.addClassLogger=Lisää kerääjä +pageLogging.button.addComponentLogger=Lisää komponenttien kerääjä +pageLogging.button.addConsoleAppender=Lisää konsolin liittäjä +pageLogging.button.addFileAppender=Lisää tiedostojen liittäjä pageLogging.button.addFilter=Lisää suodatin -pageLogging.button.advanced=Advanced -pageLogging.button.deleteAppender=Delete appender +pageLogging.button.advanced=Edistynyt +pageLogging.button.deleteAppender=Poista liittäjä pageLogging.button.deleteFilter=Poista suodatin -pageLogging.button.deleteLogger=Delete logger +pageLogging.button.deleteLogger=Poista kerääjä pageLogging.button.reset=Aseta uudelleen pageLogging.button.save=Tallenna -pageLogging.details=Details: -pageLogging.dumpInterval=Dump interval: +pageLogging.details=Yksityiskohdat: +pageLogging.dumpInterval=Tyhjennysväli: pageLogging.filter.ALL=Kaikki pageLogging.filter=Suodatin -pageLogging.filter.GUI=Web filter +pageLogging.filter.GUI=Verkko suodatin pageLogging.filter.MODEL=Malli suodatin -pageLogging.filter.NOTIFICATIONS=Notification filter -pageLogging.filter.PROVISIONING=Provisioning filter -pageLogging.filter.REPOSITORY=Repository filter -pageLogging.filter.RESOURCEOBJECTCHANGELISTENER=Resource object change listener filter -pageLogging.filtersTable=Filters table -pageLogging.filter.TASKMANAGER=Task manager filter -pageLogging.filter.WORKFLOWS=Workflow filter +pageLogging.filter.NOTIFICATIONS=Ilmoitus suodatin +pageLogging.filter.PROVISIONING=Esivalmistelu suodatin +pageLogging.filter.REPOSITORY=Säilö suodatin +pageLogging.filter.RESOURCEOBJECTCHANGELISTENER=Resurssi objektin muutoksen tarkkailija suodatin +pageLogging.filtersTable=Suodatin taulukko +pageLogging.filter.TASKMANAGER=Tehtävänhallinta suodatin +pageLogging.filter.WORKFLOWS=Työnkulku suodatin pageLogging.logger.ALL=Kaikki -pageLogging.logger.GUI=Web logger -pageLogging.logger=Logger -pageLogging.logger.MODEL=Model logger -pageLogging.logger.NOTIFICATIONS=Notifications logger -pageLogging.logger.PROVISIONING=Provisioning logger -pageLogging.logger.REPOSITORY=Repository logger -pageLogging.logger.RESOURCEOBJECTCHANGELISTENER=Resource object change listener logger -pageLogging.loggersAppender=Appender +pageLogging.logger.GUI=Verkko kerääjä +pageLogging.logger=Kerääjä +pageLogging.logger.MODEL=Malli kerääjä +pageLogging.logger.NOTIFICATIONS=Ilmoituksien kerääjä +pageLogging.logger.PROVISIONING=Esivalmistelun kerääjä +pageLogging.logger.REPOSITORY=Säilö kerääjä +pageLogging.logger.RESOURCEOBJECTCHANGELISTENER=Resurssi objektin muutoksen tarkkailija kerääjä +pageLogging.loggersAppender=Liittäjä pageLogging.loggersLevel=Taso -pageLogging.loggers=Loggers -pageLogging.loggersTable=Loggers table -pageLogging.logger.TASKMANAGER=Task manager logger -pageLogging.logger.WORKFLOWS=Workflow module logger -pageLogging.logSubsystemEntryExit=Log subsystem entry/exit -pageLogging.performanceStatistics=Performance statistics: -pageLogging.profiling=Profiling -pageLogging.requestFilter=Request filter: -pageLogging.rootAppender=Root appender: -pageLogging.rootLevel=Root logger: -pageLogging.subsystem.appender=Appender +pageLogging.loggers=Kerääjät +pageLogging.loggersTable=Kerääjät taulukko +pageLogging.logger.TASKMANAGER=Tehtävänhallinta kerääjä +pageLogging.logger.WORKFLOWS=Työnkulku moduuli kerääjä +pageLogging.logSubsystemEntryExit=Login alijärjestelmän sisäänmeno/ulostulo +pageLogging.performanceStatistics=Suoriutumis Tilastot: +pageLogging.profiling=Profilointi +pageLogging.requestFilter=Pyydä filtteri: +pageLogging.rootAppender=Juureen liittäjä: +pageLogging.rootLevel=Juureen kerääjä: +pageLogging.subsystem.appender=Liittäjä pageLogging.subsystem.level=Taso pageLogging.subsystem.model=Malli -pageLogging.subsystem.provisioning=Provisioning -pageLogging.subsystem.repository=Repository -pageLogging.subsystem.resourceObjectChangeListener=Resource object change listener -pageLogging.subsystems=Subsystems: -pageLogging.subsystem..taskManager=Task manager +pageLogging.subsystem.provisioning=Esivalmistelu +pageLogging.subsystem.repository=Säilö +pageLogging.subsystem.resourceObjectChangeListener=Resurssin objektin muutoksen tarkkailija +pageLogging.subsystems=Alijärjestelmä: +pageLogging.subsystem..taskManager=Tehtävänhallinta pageLogging.subsystem.ucf=Ucf -pageLogging.subsystem.workflow=Workflow -PageLogging.title=Logging Management +pageLogging.subsystem.workflow=Työnkulku +PageLogging.title=Keräilyn hallinta PageLogin.forgetPassword=Unohda Salasana -pageLogin.message.ForgetPasswordSettingsWrong=Forget Passwords settings are wrong. Please Contact Your Administrator for changing your password. +pageLogin.message.ForgetPasswordSettingsWrong=Unohda Salasanat -asetukset ovat väärin. Ota yhteyttä järjestelmänvalvojaanne salasanasi vaihtoa varten. PageLogin.password=Salasana PageLogin.signIn=Kirjaudu sisään PageLogin.title=Kirjaudu PageLogin.username=Käyttänimi -PageMyPasswordQuestions.title=My Password Questions -PageMyPasswords.accountMidpoint=Identity Manager +PageMyPasswordQuestions.title=Salasana kysymykseni +PageMyPasswords.accountMidpoint=Identiteetti manageri PageMyPasswords.accounts=Tilit PageMyPasswords.button.back=Takaisin PageMyPasswords.button.save=Tallenna -PageMyPasswords.couldntResolve=Couldn't resolve resource. +PageMyPasswords.couldntResolve=Ei voinut ratkaista resurssia. PageMyPasswords.enabled=Otettu käyttöön -PageMyPasswords.importantNote=If selected, user password and all accounts' credentials will be updated based on policies defined in resources definitions. +PageMyPasswords.importantNote=Jos valittuna, käyttäjän salasana ja kaikki tilien tunnukset päivitetään resurssin yksityiskohdissa tarkennettujen linjausten mukaisesti. PageMyPasswords.name=Nimi -PageMyPasswords.noAccountSelected=Password not changed. No account was selected. +PageMyPasswords.noAccountSelected=Salasanaa ei muutettu. Tiliä ei valittuna. PageMyPasswords.password=Salasana -PageMyPasswords.resourceMidpoint=Identity Repository +PageMyPasswords.resourceMidpoint=Identiteetti Säilö PageMyPasswords.resourceName=Resurssi PageMyPasswords.title=Minun salasanani PageNewReport.button.import=Tuo raportti -PageNewReport.embeddedEditor=Embedded editor +PageNewReport.embeddedEditor=Sisäinen editori PageNewReport.file=Tiedosto -PageNewReport.getObjectsFrom=Create report from -PageNewReport.message.emptyXml=Can't save empty xml. -PageNewReport.message.help=Choose XML file for import. -PageNewReport.message.nullFile=Uploaded file is null. -PageNewReport.title=Import Jasper report -PageOrgTree.message.noOrgStructDefined=No org. structure defined. -PageOrgTree.title=Organization tree -pageOrgUnit.accounts=Projections -PageOrgUnit.extension=Extension -PageOrgUnit.message.cantCreateExtensionDelta=Can't create delta for org. unit extension -PageOrgUnit.parentOrgRef=Parent +PageNewReport.getObjectsFrom=Luo raportti +PageNewReport.message.emptyXml=Ei pysty tallentamaan tyhjää XML-tiedostoa. +PageNewReport.message.help=valitse tuotava XML-tiedosto. +PageNewReport.message.nullFile=Lähetetty tiedosto on tyhjä. +PageNewReport.title=Tuo Jasper raportti +PageOrgTree.message.noOrgStructDefined=Organisaatio rakennetta ei tarkennettu. +PageOrgTree.title=Organisaation puu +pageOrgUnit.accounts=Projektiot +PageOrgUnit.extension=Laajennos +PageOrgUnit.message.cantCreateExtensionDelta=Ei pysty luomaan deltaa org. yksikön laajennukselle +PageOrgUnit.parentOrgRef=ylähakemisto PageOrgUnit.title.approvers=Hyväksyjät -PageOrgUnit.title.assignments=Assignments -PageOrgUnit.title.authorizations=Authorizations +PageOrgUnit.title.assignments=Toimeksiannot +PageOrgUnit.title.authorizations=Valtuutukset PageOrgUnit.title.basic=Perus -PageOrgUnit.title.exclusions=Exclusions -PageOrgUnit.title.inducements=Inducements -PageOrgUnit.title=New org. unit -PageOrgUnit.title.parentOrgUnit=Parent(s) +PageOrgUnit.title.exclusions=Poissulut +PageOrgUnit.title.inducements=Vaikuttimet +PageOrgUnit.title=Uusi org. yksikkö +PageOrgUnit.title.parentOrgUnit=Ylähakemisto(t) pageProcessInstance.button.back=Takaisin -pageProcessInstances.active=Currently active +pageProcessInstances.active=Tällä hetkellä aktiivinen pageProcessInstances.before=ennen pageProcessInstances.button.back=Takaisin -pageProcessInstances.button.stop=Stop process instance(s) -pageProcessInstances.button.delete=Delete process instance(s) -pageProcessInstances.finished=Recently finished -pageProcessInstances.item.finished=Finished +pageProcessInstances.button.stop=Pysäytä prosessitapahtuma(t) +pageProcessInstances.button.delete=Poista prosessitapahtuma(t) +pageProcessInstances.finished=Lähiaikoina valmistuneet +pageProcessInstances.item.finished=Valmistunut pageProcessInstances.item.name=Nimi pageProcessInstances.item.owner=Omistaja pageProcessInstances.item.result=Tulos @@ -1755,424 +1755,424 @@ pageProcessInstances.item.target=Kohde pageProcessInstances.item.state=Tila pageProcessInstances.item.stage=Vaihe pageProcessInstances.item.status=Asema -pageProcessInstances.message.noStoppableItemSelected=No process instance that could be stopped has been selected. -pageProcessInstances.message.noItemSelected=No process instance has been selected. +pageProcessInstances.message.noStoppableItemSelected=Ei valittuna prosessointitapahtumaa jonka voisi keskeyttää. +pageProcessInstances.message.noItemSelected=Ei prosessointitapahtumaa valittuna. pageProcessInstances.notYet=ei vielä -PageProcessInstancesAll.title=All approval requests -PageProcessInstancesRequestedBy.title=My approval requests -PageProcessInstancesRequestedFor.title=Approval requests about me +PageProcessInstancesAll.title=Kaikki hyväksyntä pyynnöt +PageProcessInstancesRequestedBy.title=Minun hyväksyntä pyynnöt +PageProcessInstancesRequestedFor.title=Minua koskevat hyväksyntä pyynnöt PageReport.basic=Konfiguraatio PageReport.fullXml=Täysi xml -PageReport.jasperTemplate=Jasper template -PageReport.jasperTemplateStyle=Jasper template style -PageReport.message.cantSaveEmpty=Can't save empty report. -PageReport.message.cantSerializeFromObjectToString=Can't serialize object to XML. +PageReport.jasperTemplate=Jasper malli +PageReport.jasperTemplateStyle=Jasmer malli tyyli +PageReport.message.cantSaveEmpty=Ei voi tallentaa tyhjää raporttia. +PageReport.message.cantSerializeFromObjectToString=Ei pysty sarjallistamaan objektia XMLään PageReports.button.configure=Konfiguroi PageReports.button.run=Suorita -PageReports.message.jasperError=Error occurred during creating Jasper report. -PageReports.message.queryError=Error occurred during translation search query to filter. -PageReports.message.resourceNotDefined=Resource not defined. +PageReports.message.jasperError=Virhe tapahtui Jasper reporting luonnin aikana. +PageReports.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. +PageReports.message.resourceNotDefined=Resurssia ei ole määrtelty. PageReports.message.unknownReport=Tuntematon raportti. -PageReports.report.auditDescription=Report made from audit records. -PageReports.report.auditName=Audit logs -PageReports.report.reconciliationDescription=Reconciliation report for selected resource. -PageReports.report.reconciliationName=Reconciliation -PageReports.report.usersDescription=Users listed in Identity Manager. -PageReports.report.usersName=Users in Identity Manager -PageReports.search.showSubreports=Show subreports +PageReports.report.auditDescription=Reporrti tehty auditointi tallenteista. +PageReports.report.auditName=Auditointi logit +PageReports.report.reconciliationDescription=Täsmäytys raportti valitusta resurssista. +PageReports.report.reconciliationName=Täsmäyttäminen +PageReports.report.usersDescription=Identiteetti managerissa olevien käyttäjien listaus. +PageReports.report.usersName=Identiteetti managerissa olevat käyttäjät +PageReports.search.showSubreports=Näytä aliraportit PageReports.table.description=Kuvaus PageReports.table.name=Nimi -PageReports.title.auditPopup=Audit report parameters -PageReports.title=Available reports -PageReports.title.reconciliationPopup=Reconciliation report parameters -PageReports.title.userPopup=User report parameters -PageReport.title=Report configuration -PageResource.resource.mappings=Mappings +PageReports.title.auditPopup=Auditoi raportti parametrit +PageReports.title=saatavilla olevat raportit +PageReports.title.reconciliationPopup=Täsmäytys raportti parametrit +PageReports.title.userPopup=Käyttäjä raportti parametrit +PageReport.title=Raportoi konfiguraatio +PageResource.resource.mappings=Kartoitukset PageResource.resource.source=Lähde PageResource.resource.target=Kohde PageResource.resource.sourceAndTarget=Lähde ja Kohde -PageResource.resource.noMappings=No mappings -PageResource.resource.sync=Synchronization defined +PageResource.resource.noMappings=Ei kartoituksia +PageResource.resource.sync=Synkronisaatio määritelty PageResource.resource.up=Resurssi on YLHÄÄLLÄ PageResource.resource.down=Resurssi on ALHAALLA PageResource.resource.broken=Resurssi on RIKKI PageResource.resource.availabilityUnknown=Resurssin tila on tuntematon PageResource.resource.objectTypes=Objekti tyyppit -PageResource.resource.schemaDefinitions=schema definitions +PageResource.resource.schemaDefinitions=Kaavion kuvaukset PageResource.resource.schema=Schema PageResource.resource.noSchema=Ei schemaa PageResource.resource.schemaError=Schema virhe PageResource.tab.details=Yksityiskohdat pageResource.bundle=Nippu pageResource.button.back=Takaisin -pageResource.button.editXml=Edit XML -pageResource.button.refreshSchema=Päivitä schema -pageResource.button.wizard=Wizard +pageResource.button.editXml=muokaa XML +pageResource.button.refreshSchema=Päivitä kaavio +pageResource.button.wizard=Avustaja pageResource.button.configurationEdit=Muokkaa konfiguraatiota -pageResource.button.wizardShow=Show using wizard -pageResource.button.wizardEdit=Edit using wizard +pageResource.button.wizardShow=Näytä avustajan avulla +pageResource.button.wizardEdit=Muokka avustajan avulla pageResource.button.importAccounts=Tuo tilejä -pageResource.refreshSchema.failed=Failed to refresh resource schema +pageResource.refreshSchema.failed=Resurssikaavion päivitys epäonnistui pageResource.button.save=Tallenna pageResource.button.test=Testaa yhteys -pageResource.capabilities=Capabilities -pageResource.conConnection=Connector connection -pageResource.confValidation=Configuration validation -pageResource.conInitialization=Connection initialization -pageResource.conSanity=Connector sanity -pageResource.conSchema=Connector schema -pageResource.deleteSyncToken=Delete Sync. Token +pageResource.capabilities=Kyvyt +pageResource.conConnection=Liitin yhteys +pageResource.confValidation=Konfiguraation kelpuutus +pageResource.conInitialization=Yhteyden aloitus +pageResource.conSanity=Littimen toimivuus +pageResource.conSchema=Liitin kaavio +pageResource.deleteSyncToken=Poista Synk. Merkki pageResourceEdit.edit=Muokkaa -pageResourceEdit.message.emptyXml=Can't save empty xml as resource. +pageResourceEdit.message.emptyXml=Ei pysty tallentamaan tyhjää XML-tiedostoa resurssina. pageResourceEdit.options=Vaihtoehdot pageResource.editResource=Muokkaa resurssia PageResourceEdit.title=Uusi resurssi pageResource.import=Tuo -pageResource.message.invalidTaskSearch=Synchronization task search did not perform correctly. -pageResource.message.oidNotDefined=Resource oid not defined in request. +pageResource.message.invalidTaskSearch=Synkronisaatio tehtävän etsintä ei toiminut oikein. +pageResource.message.oidNotDefined=Oid resurssi ei ole määritelty pyynnössä. pageResource.name=Nimi pageResource.objectTypes.displayName=Näyttönimi pageResource.objectTypes.help=Apua -pageResource.objectTypes.nativeObjectClass=Native object class +pageResource.objectTypes.nativeObjectClass=Paikallinen objekti luokka pageResource.objectTypes=Objekti tyyppi pageResource.objectTypes.type=Tyyppi pageResource.oid=Oid -pageResource.overallStatus=Overall status -pageResource.progress=Progress +pageResource.overallStatus=Kokonaistilanne +pageResource.progress=Edistyminen pageResource.resource=Resurssi -pageResource.synchronizationTasks=Synchronization tasks +pageResource.synchronizationTasks=Symkronisaatio tehtävät pageResources.bundle=Nippu -pageResources.connectorType=Connector type +pageResources.connectorType=Liitin tyyppi pageResources.button.discoveryRemote=Löytö -pageResources.button.editAsXml=Edit XML +pageResources.button.editAsXml=muokaa XML pageResources.button.search=Etsi -pageResources.connector.hostname=Hostname -pageResources.connectorHosts=Connector hosts +pageResources.connector.hostname=Isännän nimi +pageResources.connectorHosts=Littimen isännät pageResources.connector.name=Nimi pageResources.connector.port=Portti pageResources.connector.protectConnection=Suojattu -pageResources.connector.timeout=Timeout +pageResources.connector.timeout=Aika loppu pageResources.content=Sisältö pageResources.dialog.title.confirmDelete=Vahvista poista pageResources.import=Tuo -pageResources.inlineMenuItem.deleteSyncToken=Delete sync. token -pageResources.inlineMenuItem.editResource=Edit using wizard -pageResources.message.deleteHostConfirm=Do you really want to delete host '{0}'? -pageResources.message.deleteHostsConfirm=Do you really want to delete {0} hosts? -pageResources.message.deleteResourceConfirm=Do you really want to delete resource '{0}'? -pageResources.message.deleteResourcesConfirm=Do you really want to delete {0} resources? -pageResources.message.noHostSelected=No connector host has been selected. -pageResources.message.noResourceSelected=No resource has been selected. -pageResources.message.queryError=Error occurred during translation search query to filter. +pageResources.inlineMenuItem.deleteSyncToken=Poista Synk. Merkki +pageResources.inlineMenuItem.editResource=Muokka avustajan avulla +pageResources.message.deleteHostConfirm=Haluatko varmasti poistaa isännän "{0}"? +pageResources.message.deleteHostsConfirm=Haluatko varmasti poistaa "{0}" isäntää? +pageResources.message.deleteResourceConfirm=Haluatko varmasti poistaa resurssin "{0}"? +pageResources.message.deleteResourcesConfirm=Haluatko varmasti poistaa "{0}" resurssit? +pageResources.message.noHostSelected=Liittimen isäntää ei ole valittu. +pageResources.message.noResourceSelected=Resurssia ei ole valittu. +pageResources.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. pageResources.name=Nimi -pageResources.progress=Progress +pageResources.progress=Edistyminen pageResources.resources=Resurssit pageResources.searchText.placeholder=Nimi -pageResources.status=Last status +pageResources.status=Viimeinen tila pageResource.status=Tila PageResources.title=Resurssit Lista pageResources.version=Versio pageResource.sync=Synkronoi -PageResource.title=Resource details +PageResource.title=Resurssin yksityiskohdat pageResource.type=Tyyppi pageResource.version=Versio PageResourceWizard.title=Uusi resurssi PageResourceWizard.title.edit=Muokkaa resurssia '{0}' pageRole.members=Jäsenet -pageRole.governance=Governance -PageRoleEditor.extension=Extension +pageRole.governance=Hallinto +PageRoleEditor.extension=Laajennos PageRoleEditor.label.approverRef=Hyväksyjä PageRoleEditor.label.approverRef.placeholder=Aseta hyväksyjä -PageRoleEditor.label.assignmentConstraint.placeholder=Set assignment policy +PageRoleEditor.label.assignmentConstraint.placeholder=Aseta toimeeksianto linjaus PageRoleEditor.label.description=Kuvaus PageRoleEditor.label.displayName=Näyttönimi -PageRoleEditor.label.identifier=Identifier -PageRoleEditor.label.maxAssignments=Max. assignments -PageRoleEditor.label.minAssignments=Min. assignments +PageRoleEditor.label.identifier=Tunnistaja +PageRoleEditor.label.maxAssignments=Max. toimeksiannot +PageRoleEditor.label.minAssignments=min. toimeksiannot PageRoleEditor.label.name=Nimi PageRoleEditor.label.ownerRef=Omistaja PageRoleEditor.label.ownerRef.placeholder=Aseta omistaja PageRoleEditor.label.requestable=Pyydettävissä PageRoleEditor.label.riskLevel=Riskitaso PageRoleEditor.label.type=Tyyppi -PageRoleEditor.message.addApproverOk=Approver with name: '{0}' was added successfully. -PageRoleEditor.message.addOwnerOk=Owner with name: '{0}' was added successfully. -PageRoleEditor.message.cantAddOwner=Can't setup the selected owner. -PageRoleEditor.message.cantCreateExtensionDelta=Can't create delta for role extension +PageRoleEditor.message.addApproverOk=Hyväksyjä nimellä: '{0}' lisättiin onnistuneesti. +PageRoleEditor.message.addOwnerOk=Omistaja nimellä: '{0}' lisättiin onnistuneesti. +PageRoleEditor.message.cantAddOwner=Ei voi asentaa valittua omistajaa. +PageRoleEditor.message.cantCreateExtensionDelta=Ei pysty luomaan deltaa roolin laajennokselle PageRoleEditor.subtitle.activation=Aktivointi PageRoleEditor.subtitle.basic=Perus PageRoleEditor.subtitle.editingRole=rooli '{0}' -PageRoleEditor.subtitle.extension=Extension +PageRoleEditor.subtitle.extension=Laajennos PageRoleEditor.subtitle.newRole=Uusi rooli -PageRoleEditor.title.assignments=Assignments +PageRoleEditor.title.assignments=Toimeksiannot PageRoleEditor.title.editingRole=Muokkaa -PageRoleEditor.title.inducements=Inducements +PageRoleEditor.title.inducements=Vaikuttimet PageRoleEditor.title.newRole=Luo pageRoles.button.delete=Poista pageRoles.dialog.title.confirmDelete=Vahvista poista -pageRoles.message.confirmationMessageForMultipleObject=Do you really want to {0} selected {1} role(s)? -pageRoles.message.confirmationMessageForSingleObject=Do you really want to {0} role '{1}'? -pageRoles.message.confirmationMessageForMultipleObject.members=Do you really want to {0} selected {1} role(s)? Some of the roles have member(s). -pageRoles.message.confirmationMessageForSingleObject.members=Do you really want to {0} role '{1}'? Selected role has member(s). -pageRoles.message.nothingSelected=No role has been selected. -pageRoles.message.queryError=Error occurred during translation search query to filter. -pageRoles.requestable=Requestable +pageRoles.message.confirmationMessageForMultipleObject=Haluatko varmasti {0} valitut '{1}' rooli(t)? +pageRoles.message.confirmationMessageForSingleObject=Haluatko varmasti {0} roolin '{1}'? +pageRoles.message.confirmationMessageForMultipleObject.members=Haluatko varmasti {0} valitut {1} rooli(t)? Joissakjin rooleissa on jäsen(iä). +pageRoles.message.confirmationMessageForSingleObject.members=Haluatko varmasti {0} rooli {1} ? Valitussa roolissa on jäsen(iä). +pageRoles.message.nothingSelected=Roolia ei ole valittu. +pageRoles.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. +pageRoles.requestable=Pyydettävissä PageRoles.title=Listaa roolit -pageSecurityQuestions.message.WrongAnswer=Questions Not Answered Correctly -pageSecurityQuestions.message.noPolicySet=No password policy is set -PageSecurityQuestions.title=Security Questions -PageShowPassword.message=Your new password is: -PageShowPassword.success=New password has been successfully created +pageSecurityQuestions.message.WrongAnswer=Kysymyksiin ei vastattu oikein +pageSecurityQuestions.message.noPolicySet=Salasanan linjausta ei ole asetettu +PageSecurityQuestions.title=Turvakysymykset +PageShowPassword.message=Uusi salasanasi on: +PageShowPassword.success=Uusi salasana on luotu onnistuneesti PageShowPassword.title=Uusi Salasana -PageSizePopover.title=Page size +PageSizePopover.title=Sivun koko pageSystemConfiguration.assignmentPolicyEnforcement.value.full=Täysi -pageSystemConfiguration.assignmentPolicyEnforcement.value.legalize=Relative +pageSystemConfiguration.assignmentPolicyEnforcement.value.legalize=Suhteellinen pageSystemConfiguration.assignmentPolicyEnforcement.value.mark=Merkkaa pageSystemConfiguration.assignmentPolicyEnforcement.value.none=Ei mitään pageSystemConfiguration.assignmentPolicyEnforcement.value.positive=Positiivinen -pageSystemConfiguration.logging.title=Logging +pageSystemConfiguration.logging.title=Kerääminen pageSystemConfiguration.notifications.title=Ilmoitukset -pageSystemConfiguration.profiling.title=Profiling -pageSystemConfiguration.adminGui.title=Admin GUI +pageSystemConfiguration.profiling.title=Profilointi +pageSystemConfiguration.adminGui.title=Järjestelmänvalvoja GUI pageSystemConfiguration.system.title=Systeemi PageSystemConfiguration.title=Konfiguraatio -AdminGuiConfigPanel.dashboardLinksConfig=Dashboard links configuration -AdminGuiConfigPanel.additionalMenuItemConfig=Additional menu items -AdminGuiConfigPanel.title=Admin GUI configuration -AdminGuiConfigPanel.dashboardLinkDialogTitle.title=Configure dashboard link -AdminGuiConfigPanel.additionalMenuItemDialog.title=Configure additional menu item +AdminGuiConfigPanel.dashboardLinksConfig=Kojelaudan linkkien configuraatio +AdminGuiConfigPanel.additionalMenuItemConfig=Menun lisäkohdat +AdminGuiConfigPanel.title=Järjestelmänvalvojan GUI konfiguraatio +AdminGuiConfigPanel.dashboardLinkDialogTitle.title=Konfiguroi kojelauta linkki +AdminGuiConfigPanel.additionalMenuItemDialog.title=Konfiguroi menun lisäkohta RichHyperlinkConfigDialog.label=Etiketti RichHyperlinkConfigDialog.targetUrl=Kohde URL RichHyperlinkConfigDialog.color=Väri -RichHyperlinkConfigDialog.authorization=Authorization -RichHyperlinkConfigDialog.icon=Icon (css class) +RichHyperlinkConfigDialog.authorization=Valtuutus +RichHyperlinkConfigDialog.icon=Ikoni (css luokka) RichHyperlinkConfigDialog.description=Kuvaus -RichHyperlinkConfigDialog.message.badUpdate=Can't show empty dashboard link config. +RichHyperlinkConfigDialog.message.badUpdate=Ei voi näyttää tyhjää kojelaudan linkin konfiguraatiota. PageTaskAdd.title=Uusi tehtävä -pageTask.advancedOption=Advanced option +pageTask.advancedOption=Edistynyt vaihtoehto pageTask.basic=Perus -pageTask.boundHelp=Tightly bound tasks are used to run short actions, which are repeating quite often (e.g. in intervals less than 1 minute). A typical example is the live synchronization. Cron-like specification is not supported for these tasks; you have to specify the time interval. -pageTask.bound=Tightly bound (use if recurring task runs often) +pageTask.boundHelp=Kireästi sidottuja tehtäviä käytetään suorittaessa lyhyitä tomintoja, joita toistetaan melko usein (esim. alle 1 minuutin intervalleissa). Tyypillinen esimerkiksi olis live synkronisaatio. Cron-tyyppisiä määrittelyjä ei tueta näissä tehtävissä; Sinun pitää tarkentaa aikaväli. +pageTask.bound=Kireä sidos (käytä jos toistuva tehtävä suoritetaan usein) pageTask.browse=Selaa -pageTask.category.BulkActions=Bulk actions +pageTask.category.BulkActions=Massa toiminnot pageTask.category.Demo=Demo -pageTask.category.ImportFromFile=Import from file -pageTask.category.ImportingAccounts=Importing accounts -pageTask.category.LiveSynchronization=Live synchronization -pageTask.category.Recomputation=Recomputation -pageTask.category.Reconciliation=Reconciliation -pageTask.category.UserRecomputation=User recomputation -pageTask.category.Workflow=Workflow -pageTask.createSuspended=Create in SUSPENDED state +pageTask.category.ImportFromFile=Tuo tiedostosta +pageTask.category.ImportingAccounts=Tilien tuonti +pageTask.category.LiveSynchronization=Live synkronisaatio +pageTask.category.Recomputation=Uudelleenlaskeminen +pageTask.category.Reconciliation=Täsmäyttäminen +pageTask.category.UserRecomputation=Käyttäjä uudellenlaskeminen +pageTask.category.Workflow=Työnkulku +pageTask.createSuspended=Luo KESKEYTETYSSÄ tilassa pageTask.cronHelp=Cron-like specification is in the form: SECONDS MINUTES HOURS DAY-OF-MONTH MONTH DAY-OF-WEEK YEAR (optional), e.g. '0 0 12 ? * WED' which means 'every Wednesday at 12:00:00 pm'. -pageTask.cronHelpLink=For more information, please see -pageTask.cronHelpLinkTutorial=tutorial -pageTask.cronSpec=Schedule cron-like specification -pageTask.dryRun=Dry run -pageTask.focusType=Applicable to type +pageTask.cronHelpLink=Lisätietoja varten, katso +pageTask.cronHelpLinkTutorial=tutoriaali +pageTask.cronSpec=Ajasta cron-tyyppinen määrittely +pageTask.dryRun=Kuivaharjoitus +pageTask.focusType=Sovellettavissa tyyppiin pageTaskEdit.basic=Perus -pageTaskEdit.work=Work to do -pageTaskEdit.boundHelp=Tightly bound tasks are used to run short actions, which are repeating quite often (e.g. in intervals less than 1 minute). A typical example is the live synchronization. Cron-like specification is not supported for these tasks; you have to specify the time interval. -pageTaskEdit.bound=Tightly bound (use if recurring task runs often) -pageTaskEdit.binding=Binding +pageTaskEdit.work=tehtävät työt +pageTaskEdit.boundHelp=Kireästi sidottuja tehtäviä käytetään suorittaessa lyhyitä tomintoja, joita toistetaan melko usein (esim. alle 1 minuutin intervalleissa). Tyypillinen esimerkiksi olis live synkronisaatio. Cron-tyyppisiä määrittelyjä ei tueta näissä tehtävissä; Sinun pitää tarkentaa aikaväli. +pageTaskEdit.bound=Kireä sidos (käytä jos toistuva tehtävä suoritetaan usein) +pageTaskEdit.binding=Sitova pageTaskEdit.button.back=Takaisin -pageTaskEdit.button.cancelEditing=Cancel editing +pageTaskEdit.button.cancelEditing=Peru muokkaus pageTaskEdit.button.edit=Muokkaa pageTaskEdit.button.resume=Jatka pageTaskEdit.button.runNow=Suorita nyt -pageTaskEdit.button.stopApprovalProcess=Stop approval process +pageTaskEdit.button.stopApprovalProcess=Pysäytä hyväksyntä prosessi pageTaskEdit.button.save=Tallenna pageTaskEdit.button.suspend=Keskeytä pageTaskEdit.category=Kategoria pageTaskEdit.cronHelp=Cron-like specification is in the form: SECONDS MINUTES HOURS DAY-OF-MONTH MONTH DAY-OF-WEEK YEAR (optional), e.g. '0 0 12 ? * WED' which means 'every Wednesday at 12:00:00 pm'. -pageTaskEdit.cronHelpLink=For more information, please see -pageTaskEdit.cronHelpLinkTutorial=tutorial -pageTaskEdit.cronSpec=Schedule cron-like specification +pageTaskEdit.cronHelpLink=Lisätietoja varten, katso +pageTaskEdit.cronHelpLinkTutorial=tutoriaali +pageTaskEdit.cronSpec=Ajasta cron-tyyppinen määrittely pageTaskEdit.description=Kuvaus -pageTaskEdit.dryRun=Dry run -pageTaskEdit.executeInRawMode=Execute in raw mode -pageTaskEdit.execution=Execution status -pageTaskEdit.handlerUri=Handler URI -pageTaskEdit.identifier=Identifier -pageTaskEdit.intent=Intent -pageTaskEdit.kind=Kind -pageTaskEdit.lastFinished=Task run last finished -pageTaskEdit.lastStarted=Task run last started -pageTaskEdit.message.cantTaskDetails=Couldn't load task details. -pageTaskEdit.message.node=- at node {0} -pageTaskEdit.misfire=Misfire action -pageTaskEdit.modelOperationStatusLabel=Model operation status +pageTaskEdit.dryRun=Kuivaharjoitus +pageTaskEdit.executeInRawMode=Suorita raw tilassa +pageTaskEdit.execution=Toteutuksen tila +pageTaskEdit.handlerUri=Käsittelijä URI +pageTaskEdit.identifier=Tunnistaja +pageTaskEdit.intent=Aikomus +pageTaskEdit.kind=Laji +pageTaskEdit.lastFinished=Viimeisin suoritettu tehtävä +pageTaskEdit.lastStarted=Viimeksi aloitettu tehtävän suoritus +pageTaskEdit.message.cantTaskDetails=Ei voitu ladata tehtävän yksityiskohtia. +pageTaskEdit.message.node=solmussa {0} +pageTaskEdit.misfire=Katkennut toiminto +pageTaskEdit.modelOperationStatusLabel=Malli operaation tilanne pageTaskEdit.name=Tehtävän nimi -pageTaskEdit.nextRun=Next scheduled task run +pageTaskEdit.nextRun=Seuraava ajastettu tehtävän suoritus pageTaskEdit.nextRetry=Seuraava yritys pageTaskEdit.notStartAfter=Do not start after pageTaskEdit.notStartBefore=Do not start before pageTaskEdit.objectClass=Objekti luokka pageTaskEdit.objectDelta=Objekti delta -pageTaskEdit.bulkAction=Bulk action +pageTaskEdit.bulkAction=Massa toiminto pageTaskEdit.objectType=Objekti tyyppi -pageTaskEdit.objectQuery=Object query -pageTaskEdit.objectRef=Object reference -pageTaskEdit.token=Synchronization token -pageTaskEdit.retryUnhandledErr=Retry unhandled errors -pageTaskEdit.resourceRef=Resource reference +pageTaskEdit.objectQuery=Onjekti kysely +pageTaskEdit.objectRef=Objektin viittaus +pageTaskEdit.token=Synkronisaatio merkki +pageTaskEdit.retryUnhandledErr=kokeile uudestaan käsittelemättömiä virheitä +pageTaskEdit.resourceRef=Resurssi viite pageTaskEdit.oid=OID pageTaskEdit.opResult.message=Viesti pageTaskEdit.opResult.operation=Operaatio pageTaskEdit.opResult.status=Tila -pageTaskEdit.opResult.token=Token +pageTaskEdit.opResult.token=Merkki pageTaskEdit.options=Vaihtoehdot -pageTaskEdit.parent=Parent task +pageTaskEdit.parent=Ylätehtävä pageTaskEdit.owner=Tehtävän omistaja -pageTaskEdit.recurring=Recurring task -pageTaskEdit.recurrence=Recurrence -pageTaskEdit.runUntilNodeDown=Run only until node down -pageTaskEdit.scheduleHelp=For one-time tasks, enter neither schedule interval nor cron-like specification. For recurring tasks, enter exactly one of these. -pageTaskEdit.scheduleInterval=Schedule interval (seconds) -pageTaskEdit.scheduleTitle=Scheduling -pageTaskEdit.approvals=Approvals -pageTaskEdit.operation=Operation context -pageTaskEdit.performance=Environmental performance -pageTaskEdit.progress=Progress -pageTaskEdit.subtasksAndThreads=Subtasks and threads -pageTaskEdit.statesAndActions=States and actions +pageTaskEdit.recurring=Toistuva tehtävä +pageTaskEdit.recurrence=Toistuvuus +pageTaskEdit.runUntilNodeDown=Suorita vain kunnes solmu alhaalla +pageTaskEdit.scheduleHelp=Älä syötä ajastusväliä taikka cron-tyyppistä tarkennusta kerran suoritettaviin tehtäviin . Toistuviin tehtäviin syötä jompi kumpi näistä. +pageTaskEdit.scheduleInterval=Ajastus aikaväli (sekunneissa) +pageTaskEdit.scheduleTitle=Ajastus +pageTaskEdit.approvals=Hyväksynnät +pageTaskEdit.operation=operaation asiayhteys +pageTaskEdit.performance=Ympäristö suoriutuminen +pageTaskEdit.progress=Edistyminen +pageTaskEdit.subtasksAndThreads=Alitehtävät ja ketjut +pageTaskEdit.statesAndActions=Tilat ja toiminnot pageTaskEdit.result=Tulos pageTaskEdit.errors=Virheet -pageTaskEdit.subtasksLabel=Subtasks -pageTaskEdit.suspendReq=For editing is necessary to suspend the task -pageTaskEdit.taskState=Task state -pageTaskEdit.threadAction=Thread action -pageTaskEdit.threadStop=Thread stop action -pageTaskEdit.requiredCapability=Required capability (e.g. node name) -pageTaskEdit.tightlyBound=Tightly bound -pageTaskEdit.title.edit=Details for '{0}' -PageTaskEdit.title=Task details -PageTaskEdit.title.wfOperation=Change operation details -PageTaskEdit.title.wfRequest=Approval request details -pageTaskEdit.workerThreads=Configured worker threads -pageTaskEdit.workflowInformationLabel=Workflow information -pageTaskEdit.displayResultInteractive=Display result in an interactive way. +pageTaskEdit.subtasksLabel=Alitehtävät +pageTaskEdit.suspendReq=Muokkausta varten on tarpeellista keskeyttää tehtävä +pageTaskEdit.taskState=Tehtävän tilanne +pageTaskEdit.threadAction=Ketju toiminto +pageTaskEdit.threadStop=Ketju pysäytä toiminto +pageTaskEdit.requiredCapability=Tarpeellinen kyky (esim. solmun nimi) +pageTaskEdit.tightlyBound=Kireä sidos +pageTaskEdit.title.edit='{0}'stä yksityiskohtia +PageTaskEdit.title=Tehtävä yksityiskohdat +PageTaskEdit.title.wfOperation=Muuta operaation yksityiskohtia +PageTaskEdit.title.wfRequest=Hyväksyntä pyynnön yksityiskohdat +pageTaskEdit.workerThreads=Konfiguroidut työntekijä ketjut +pageTaskEdit.workflowInformationLabel=Työnkulun tiedot +pageTaskEdit.displayResultInteractive=Näytä tulos interaktiivisella tavalla. pageTaskEdit.taskErros.objectName=Nimi pageTaskEdit.taskErros.status=Asema pageTaskEdit.taskErros.message=Viesti -pageTask.intent=Intent -pageTask.kind=Kind -pageTask.misfire=Misfire action +pageTask.intent=Aikomus +pageTask.kind=Laji +pageTask.misfire=Katkennut toiminto pageTask.name=Tehtävän nimi pageTask.notStartAfter=Do not start after pageTask.notStartBefore=Do not start before pageTask.notStartBefore.error1='Do not start before' is later than 'Do not start after' pageTask.now=Nyt pageTask.objectClass=Objekti luokka -pageTask.objectRef=Resource reference +pageTask.objectRef=Resurssi viite pageTask.options=Vaihtoehdot -pageTask.recurring=Recurring task -pageTask.runUntilNodeDown.error1=Compatible data for 'Thread stop action' are: Close, Suspend -pageTask.runUntilNodeDown.error2=Compatible data for 'Thread stop action' are: Restart, Reschedule -pageTask.runUntilNodeDown=Run only until node down -pageTasks.alreadyPassed=already passed -pageTasks.alreadyPassedForNotRunningTasks=(already passed) -pageTasks.button.deactivateServiceThreads=Stop all threads +pageTask.recurring=Toistuvat tehtävät +pageTask.runUntilNodeDown.error1=Yhteensopiva data 'Ketju pysäytä tominto'lle on: Sulje, Keskeytä +pageTask.runUntilNodeDown.error2=Yhteensopiva data 'Ketju pysäytä tominto'lle on: uudelleen käynnistys, uudelleen ajastus +pageTask.runUntilNodeDown=Suorita vain kunnes solmu alhaalla +pageTasks.alreadyPassed=Läpäisty jo +pageTasks.alreadyPassedForNotRunningTasks=(Läpäisty jo) +pageTasks.button.deactivateServiceThreads=Pysäytä kaikki ketjut pageTasks.button.deleteNode=Poista pageTasks.button.deleteTask=Poista pageTasks.button.deleteAllClosedTasks=Poista kaikki suljetut tehtävät -pageTasks.button.reactivateServiceThreads=Start all threads -pageTasks.button.refreshTasks=Refresh tasks +pageTasks.button.reactivateServiceThreads=Aloita kaikki ketjut +pageTasks.button.refreshTasks=Päivitä tehtävät pageTasks.button.resumeTask=Jatka pageTasks.button.scheduleTask=Suorita nyt pageTasks.button.startScheduler=Aloita -pageTasks.button.stopSchedulerAndTasks=Stop scheduler + tasks -pageTasks.button.stopScheduler=Stop scheduler +pageTasks.button.stopSchedulerAndTasks=Pysöytä ajastin + tehtävät +pageTasks.button.stopScheduler=Pysäytä ajastin pageTasks.button.suspendTask=Keskeytä -pageTasks.button.synchronizeTasks=Synchronize tasks -pageTasks.button.synchronizeWorkflowRequests=Synchronize approval requests -pageTasks.category.AccessCertification=Access certification -pageTasks.category.AllCategories=All categories -pageTasks.category.BulkActions=Bulk actions +pageTasks.button.synchronizeTasks=Synkronoi tehtävät +pageTasks.button.synchronizeWorkflowRequests=Synkronisoi hyväksyntä pyynnöt +pageTasks.category.AccessCertification=Yhdistä sertifikaatioon +pageTasks.category.AllCategories=Kaikki kategoriat +pageTasks.category.BulkActions=Massa toiminnot pageTasks.category=Kategoria -pageTasks.category.Cleanup=Cleanup +pageTasks.category.Cleanup=Puhdistus pageTasks.category.Demo=Demo -pageTasks.category.ImportFromFile=Import from file -pageTasks.category.ImportingAccounts=Importing accounts -pageTasks.category.LiveSynchronization=Live synchronization -pageTasks.category.null=(undefined) -pageTasks.category.Recomputation=Recomputation -pageTasks.category.Reconciliation=Reconciliation +pageTasks.category.ImportFromFile=Tuo tiedostosta +pageTasks.category.ImportingAccounts=Tilien tuonti +pageTasks.category.LiveSynchronization=Live synkronisaatio +pageTasks.category.null=(määrittelemätön) +pageTasks.category.Recomputation=Uudelleenlaskeminen +pageTasks.category.Reconciliation=Täsmäyttäminen pageTasks.category.Report=Raportti pageTasks.category.System=Systeemi -pageTasks.category.UserRecomputation=User recomputation -pageTasks.category.Utility=Utility -pageTasks.category.Workflow=Workflow -pageTasks.category.ExecuteChanges=Execute changes -pageTasks.message.suspendAction=suspend +pageTasks.category.UserRecomputation=Käyttäjä uudellenlaskeminen +pageTasks.category.Utility=Työkalu +pageTasks.category.Workflow=Työnkulku +pageTasks.category.ExecuteChanges=Toteuta muutokset +pageTasks.message.suspendAction=keskeytä pageTasks.message.resumeAction=jatka pageTasks.message.runNowAction=suorita nyt pageTasks.message.deleteAction=poista pageTasks.message.deleteAllClosedTasksAction=poista kaikki suljetut tehtävät pageTasks.message.startAction=aloita pageTasks.message.scheduleTaskAction=ajasta tehtävä -pageTasks.message.stopSchedulerAction=stop scheduler for -pageTasks.message.startSchedulerAction=start scheduler for -pageTasks.message.stopSchedulerTasksAction=stop scheduler+tasks for -pageTasks.message.confirmationMessageForSingleTaskObject=Do you really want to {0} task '{1}'? -pageTasks.message.confirmationMessageForMultipleTaskObject=Do you really want to {0} selected {1} task(s)? -pageTasks.message.confirmationMessageForSingleNodeObject=Do you really want to {0} node '{1}'? -pageTasks.message.confirmationMessageForMultipleNodeObject=Do you really want to {0} selected {1} node(s)? -pageTask.scheduleHelp=For one-time tasks, enter neither schedule interval nor cron-like specification. For recurring tasks, enter exactly one of these. -pageTask.scheduleInterval=Schedule interval (seconds) -pageTask.scheduleTitle=Scheduling -pageTask.scheduleValidation.bothIntervalAndCron='Schedule interval' and 'Cron-like specification' may not be both present. -pageTask.scheduleValidation.intervalNotPositive='Schedule interval' must be a positive number. -pageTask.scheduleValidation.invalidCronSpecification='Cron-like specification' is not valid. -pageTask.scheduleValidation.neitherIntervalNorCron=Exactly one of 'Schedule interval' and 'Cron-like specification' must be specified. -pageTask.scheduleValidation.noInterval='Schedule interval' must be specified. +pageTasks.message.stopSchedulerAction=Pysäytä ajastin +pageTasks.message.startSchedulerAction=Aloita ajastin +pageTasks.message.stopSchedulerTasksAction=Pysäytä ajastin+tehtävät +pageTasks.message.confirmationMessageForSingleTaskObject=Haluatko varmasti {0} tehtävän '{1}'? +pageTasks.message.confirmationMessageForMultipleTaskObject=Haluatko varmasti {0} valitut '{1}' tehtävä(t)? +pageTasks.message.confirmationMessageForSingleNodeObject=Haluatko varmasti {0} solmun '{1}'? +pageTasks.message.confirmationMessageForMultipleNodeObject=Haluatko varmasti {0} valitut '{1}' solmu(t)? +pageTask.scheduleHelp=Älä syötä ajastusväliä taikka cron-tyyppistä tarkennusta kerran suoritettaviin tehtäviin . Toistuviin tehtäviin syötä jompi kumpi näistä. +pageTask.scheduleInterval=Ajastus aikaväli (sekunneissa) +pageTask.scheduleTitle=Ajastus +pageTask.scheduleValidation.bothIntervalAndCron='Ajastus aikaväli' ja 'Cron-tyyppinen määrittely' ei voi olla käytössä samaan aikaan. +pageTask.scheduleValidation.intervalNotPositive='Ajastus aikaväli'n on pakko olla positiivinen numero. +pageTask.scheduleValidation.invalidCronSpecification='Cron-tyyppinen määrittely' ei ole voimassa. +pageTask.scheduleValidation.neitherIntervalNorCron=Joko 'Ajastus aikaväli' tai 'cron-tyyppinen määrittely' täytyy olla määritelty. +pageTask.scheduleValidation.noInterval='Ajastus aikaväli' täytyy määrittää. pageTasks.dialog.title.confirmDelete=Vahvista poista pageTasks.inForNotRunningTasks=(in {0}) pageTasks.in=in {0} -pageTasks.retryIn=retry in {0} -pageTasks.message.alreadyResumed=Task '{0}' can't be resumed, it's already running or closed. -pageTasks.message.alreadySuspended=Task '{0}' is already suspended or closed. -pageTasks.message.couldntCreateQuery=Couldn't create query for task list. -pageTasks.message.deleteTaskConfirm=Do you really want to delete task '{0}'? -pageTasks.message.deleteAllClosedTasksConfirm=Do you really want to delete all closed tasks? -pageTasks.message.deleteTasksConfirm=Do you really want to delete {0} tasks? -pageTasks.message.noNodeSelected=No node has been selected. -pageTasks.message.noTaskSelected=No task has been selected. -pageTasks.node.clustered=Clustered +pageTasks.retryIn=Uudelleen yritys {0} +pageTasks.message.alreadyResumed=Tehtävää '{0}' ei voida jatkaa, se on jo toiminnassa tai suljettu. +pageTasks.message.alreadySuspended=Tehtävä '{0}' on jo keskeytetty tai suljettu. +pageTasks.message.couldntCreateQuery=Tehtäväliställe ei saatu luotua kyselyä. +pageTasks.message.deleteTaskConfirm=Haluatko varmasti poistaa tehtävän '{0}'? +pageTasks.message.deleteAllClosedTasksConfirm=Haluatko varmasti poistaa kaikki suljetut tehtävät? +pageTasks.message.deleteTasksConfirm=Haluatko varmasti poistaa '{0}' tehtävät? +pageTasks.message.noNodeSelected=Solmua ei valittuna. +pageTasks.message.noTaskSelected=Tehtävää ei valittuna. +pageTasks.node.clustered=Ryhmitetty pageTasks.node.executionStatus=Tila -pageTasks.node.lastCheckInTime=Last check-in time -pageTasks.node.managementPort=Management port +pageTasks.node.lastCheckInTime=Viimeinen check-in aika +pageTasks.node.managementPort=Hallinto portti pageTasks.node.name=Nimi -pageTasks.nodes=Nodes -pageTasks.node.statusMessage=Status message +pageTasks.nodes=Solmut +pageTasks.node.statusMessage=Tila viesti pageTasks.nowForNotRunningTasks=(nyt) pageTasks.now=nyt -pageTasks.runsContinually=runs continually -pageTasks.stalledSince=STALLED since {0} at {1} +pageTasks.runsContinually=Suorittaa jatkuvasti +pageTasks.stalledSince=VIIVÄSTYNYT sitten {0} {1}ssa pageTasks.state=Tila -pageTasks.subtasks=Show subtasks +pageTasks.subtasks=Näytä alitehtävät pageTasks.task.category=Kategoria -pageTasks.task.currentRunTime=Current run time +pageTasks.task.currentRunTime=Tämän hetkinen suoritus aika pageTasks.task.detail=Yksityiskohdat -pageTasks.task.executingAt=Executing at +pageTasks.task.executingAt=suoritetaan pageTasks.task.execution=Suoritus pageTasks.task.name=Nimi -pageTasks.task.objectRef=Object reference -pageTasks.task.progress=Progress -pageTasks.task.scheduledToRunAgain=Scheduled to start again +pageTasks.task.objectRef=Objektin viittaus +pageTasks.task.progress=Edistyminen +pageTasks.task.scheduledToRunAgain=Ajastettu alkamaan uudestaan pageTasks.tasks=Tehtävät pageTasks.task.status=Asema PageTasks.title=Tehtävät -pageTasks.unknownRefName=Unknown object -pageTask.threadStop=Thread stop action -pageTask.title.edit=Details for '{0}' +pageTasks.unknownRefName=Tuntematon objekti +pageTask.threadStop=Ketju pysäytä toiminto +pageTask.title.edit='{0}'stä yksityiskohtia pageTask.type=Tyyppi: page.title.edit={0} page.title.editResource=Muokkaa resurssia pageUser.accounts=Tilit pageUser.assignment.active=Aktiivinen pageUser.assignment.name=Nimi -pageUser.assignments=Assignments +pageUser.assignments=Toimeksiannot pageAdminFocus.request=Pyydä roolia pageAdminFocus.objectHistory=Historia pageUser.assignment.type=Tyyppi @@ -2182,39 +2182,39 @@ pageUser.button.back=Takaisin pageUser.button.delete=Poista pageUser.button.disable=Poista käytöstä pageUser.button.enable=Ota käyttöön -pageUser.button.recompute.assignments=Show all assignments +pageUser.button.recompute.assignments=Näytä kaikki toimeksiannot pageUser.button.save=Tallenna pageUser.button.submit=Esikatsele muutoksia -pageUser.button.unlink=Unlink -pageUser.button.unlock=Unlock -pageUser.description=User in repository -pageUser.menu.assignAccount=Assign account -pageUser.menu.assignOrg=Assign org. unit +pageUser.button.unlink=Poista Linkkaus +pageUser.button.unlock=Poista lukitus +pageUser.description=Käyttäjä säilössä +pageUser.menu.assignAccount=Osoita tili +pageUser.menu.assignOrg=Osoita org. yksikkö pageUser.menu.assignRole=Osoita rooli -pageUser.menu.unassign=Unassign +pageUser.menu.unassign=Poista osoitus pageUser.message.cantCreateUser=Luo käyttäjä epäonnistui -pageUser.message.cantEditUser=Couldn't load form for editing user. -pageUser.message.cantNewUser=Couldn't load form for new user. -pageUser.message.cantSubmitUser=Couldn't send user for submit +pageUser.message.cantEditUser=Ei pystytty lataamaan lomaketta käyttäjän muokkausta varten. +pageUser.message.cantNewUser=Ei pystytty lataamaan lomaketta uutta käyttäjää varten. +pageUser.message.cantSubmitUser=Ei pystytty lähettämään käyttäjää kirjattavaksi pageUser.message.cantUpdateUser=Päivitä käyttäjä epäonnistui -pageUser.message.couldntAssignObject=Couldn't assign object '{0}', reason: {1}. -pageUser.message.couldntCreateAccount=Couldn't create account form for '{0}', reason: {1}. -pageUser.message.couldntCreateAccountNoSchema=Couldn't create account form for '{0}', no refined schema available. Possible problem with connector configuration and/or connection. Please check logs for more information. -pageUser.message.deleteAccountConfirm=Do you really want to delete {0} account(s)? -pageUser.message.deleteAssignmentConfirm=Do you really want to delete {0} assignment(s)? -pageUser.message.deleteAssignmentRowConfirm=Do you really want to delete assignment {0}? -pageUser.message.illegalAccountState=Illegal account state '{0}'. -pageUser.message.illegalAssignmentState=Illegal assignment state '{0}'. +pageUser.message.couldntAssignObject=Ei voitu osoittaa objektia '{0}', syy: {1}. +pageUser.message.couldntCreateAccount=Ei voitu luoda tili lomaketta '{0}', syy: {1}. +pageUser.message.couldntCreateAccountNoSchema=Ei voinut luoda tili lomaketta '{0}'lle, tarkennettua kaaviota ei saatavilla. Mahdollinen ongelma liittimen konfiguraatio ja/tai yhteydessä. Tarkista logit saadaksesi enemmän tietoa. +pageUser.message.deleteAccountConfirm=Haluatko varmasti poistaa tili(t) {0}? +pageUser.message.deleteAssignmentConfirm=Oletko varma, että haluat poistaa {0} toimeksiantoa? +pageUser.message.deleteAssignmentRowConfirm=Oletko varma, että haluat poistaa toimeksiannon {0} ? +pageUser.message.illegalAccountState=Laiton tilin tila '{0}'. +pageUser.message.illegalAssignmentState=Laiton toimeksiannon tila '{0}'. pageUser.message.noAccountSelected=Ei tiliä valittuna. -pageUser.message.noActivationFound=No activation found for account '{0}'. -pageUser.message.noAssignableSelected=No assignable object selected. -pageUser.message.noAssignmentsAvailable=There are currently no assignments to preview. -pageUser.message.noAssignmentSelected=No assignment selected. -pageUser.message.noEnabledPropertyFound=No enabled property found for account '{0}'. -pageUser.message.noPassword=Password is not entered. -pageUser.message.noResourceSelected=No resource selected. -pageUser.message.noUserName=It is not possible to compute assignments on unnamed user object. Please provide a name. -pageUser.message.unsupportedState=Unsupported user form state '{0}'. +pageUser.message.noActivationFound=Ei löydy aktivointia tilille '{0}'. +pageUser.message.noAssignableSelected=Osoitettavaa objektia ei valittu. +pageUser.message.noAssignmentsAvailable=Tällä hetkellä ei ole yhtään esikatseltavaa toimeksiantoa. +pageUser.message.noAssignmentSelected=Ei toimeksiantoa valittuna. +pageUser.message.noEnabledPropertyFound=Tilille '{0}' ei löydy käyttöön otettuja ominaisuuksia. +pageUser.message.noPassword=Salasanaa ei kirjoitettu. +pageUser.message.noResourceSelected=Resurssia ei valittuna. +pageUser.message.noUserName=Ei ole mahdollista laskea toimeksiantoja nimeämätömälle käyttäjä objectille. Anna sille nimi. +pageUser.message.unsupportedState=Ei tuettu käyttäjä lomake tila '{0}'. pageUsers.accounts=Tilit pageUsers.dialog.title.confirmDelete=Vahvista poista pageUsers.menu.delete=Poista @@ -2223,18 +2223,18 @@ pageUsers.menu.disable=Poista käytöstä pageUsers.menu.enable=Ota käyttöön pageUsers.menu.reconcile=Sovita pageUsers.menu.unlock=Poista lukitus -pageUsers.message.deleteUserConfirm=Do you really want to delete selected {0} user(s)? -pageUsers.message.deleteUserConfirmSingle=Do you really want to delete user '{0}'? -pageUsers.message.confirmationMessageForSingleObject=Do you really want to {0} user '{1}'? -pageUsers.message.confirmationMessageForMultipleObject=Do you really want to {0} selected {1} user(s)? +pageUsers.message.deleteUserConfirm=Oletko varma että haluat poistaa valitut {0} käyttäjät? +pageUsers.message.deleteUserConfirmSingle=Haluatko varmasti poistaa käyttäjän '{0}'? +pageUsers.message.confirmationMessageForSingleObject=Haluatko varmasti {0} käyttäjän '{1}'? +pageUsers.message.confirmationMessageForMultipleObject=haluatko varmasti {0} valitut {1} käyttäjä(t)? pageUsers.message.enableAction=ota käyttöön pageUsers.message.disableAction=poista käytöstä -pageUsers.message.reconcileAction=reconcile +pageUsers.message.reconcileAction=Sovita pageUsers.message.unlockAction=Poista lukitus pageUsers.message.deleteAction=poista -pageUsers.message.confirmActionPopupTitle=Confirm action -pageUsers.message.nothingSelected=No user has been selected. -pageUsers.message.queryError=Error occurred during translation search query to filter. +pageUsers.message.confirmActionPopupTitle=Vahvista toiminta +pageUsers.message.nothingSelected=Käyttäjää ei valittuna. +pageUsers.message.queryError=Virhe tapahtui kääntäessä haku tiedustelua filtteriin. PageUsers.title=Käyttäjä Lista pageUser.task.category=Kategoria pageUser.task.execution=Toteutuksen tila @@ -2245,162 +2245,162 @@ pageUser.title.confirmDelete=Vahvista poista pageUser.title.editing={0} pageUser.title.editUser=Muokkaa pageUser.title.newUser=Luo -pageUser.title.selectAssignable=Select object(s) -pageUser.title.selectResource=Select resource(s) -pageUser.userDetails=User details -MultipleAssignmentSelectorPanel.availableRoles=Available roles +pageUser.title.selectAssignable=Valitse objekti(t) +pageUser.title.selectResource=Valitse resurssi(t) +pageUser.userDetails=Käyttäjä yksityiskohdat +MultipleAssignmentSelectorPanel.availableRoles=Vapaat roolit MultipleAssignmentSelectorPanel.parameters=Parametrit MultipleAssignmentSelectorPanel.currentRoles=Nykyiset roolit -MultipleAssignmentSelector.filterByUser=Filter by user -MultipleAssignmentSelector.tenant=Tenant -MultipleAssignmentSelector.orgUnit=Org. unit -pageWorkItem.accordionLabel.additionalData=Related data (technical information) -pageWorkItem.accordionLabel.objectNew=Object after proposed change (technical information) -pageWorkItem.accordionLabel.objectOld=Object before change (technical information) -pageWorkItem.accordionLabel.processInstance=Process instance information -pageWorkItem.accordionLabel.requester=Requester (technical information) -pageWorkItem.additionalData.description=Related data -pageWorkItem.additionalInfo=Supplementary information +MultipleAssignmentSelector.filterByUser=Suodatus käyttäjän mukaan +MultipleAssignmentSelector.tenant=Haltija +MultipleAssignmentSelector.orgUnit=Org. yksikkö +pageWorkItem.accordionLabel.additionalData=Liittyvä data (Tekniset tiedot) +pageWorkItem.accordionLabel.objectNew=Objekti ehdotetun muutoksen jälkeen (Tekniset tiedot) +pageWorkItem.accordionLabel.objectOld=Objekti ennen muutosta (Tekniset tiedot) +pageWorkItem.accordionLabel.processInstance=Prosessitapahtuman tiedot +pageWorkItem.accordionLabel.requester=Pyytäjä (Tekniset tiedot) +pageWorkItem.additionalData.description=Liittyvä data +pageWorkItem.additionalInfo=täydentävät tiedot pageWorkItem.button.approve=Hyväksy pageWorkItem.button.cancel=Takaisin -pageWorkItem.button.claim=Claim +pageWorkItem.button.claim=Väittämä pageWorkItem.button.reject=Hylkää pageWorkItem.button.delegate=Edustaja pageWorkItem.button.release=Vapauta -pageWorkItem.delta=Delta to be approved -pageWorkItem.description=Work Item -pageWorkItem.label.showTechnicalInformation=Show technical information -pageWorkItem.mainInfo=Basic information -pageWorkItem.objectNew.description=Object after proposed change -pageWorkItem.objectOld.description=Object before change +pageWorkItem.delta=Hyväksytyksessä oleva Delta +pageWorkItem.description=Työ alkio +pageWorkItem.label.showTechnicalInformation=Näytä tekniset tiedot +pageWorkItem.mainInfo=Perustiedot +pageWorkItem.objectNew.description=Objekti ehdotetun muutoksen jälkeen +pageWorkItem.objectOld.description=Objekti ennen muutosta pageWorkItem.options=Vaihtoehdot -pageWorkItem.requestCommon.description=General information about the request -pageWorkItem.requestedBy=Requested by: -pageWorkItem.requestedOn=Requested on: +pageWorkItem.requestCommon.description=Perustiedot pyynnöstä +pageWorkItem.requestedBy=Pyytäjä: +pageWorkItem.requestedOn=Pyyntö aika: pageWorkItem.requester.description=Pyytäjä pageWorkItem.requestSpecific.description=Teidän päätös -workItemPanel.originallyAllocatedTo=Originally allocated to: -workItemPanel.currentlyAllocatedTo=Currently allocated to: -workItemPanel.candidateActors=Candidate actors: -workItemPanel.stage=Approval stage: -workItemPanel.escalationLevel=Escalation level: -workItemPanel.requesterComment=Requester comment: -workItemPanel.delta=Delta to be approved -workItemPanel.mainInfo=Basic information +workItemPanel.originallyAllocatedTo=Alunperin kohdennettu: +workItemPanel.currentlyAllocatedTo=Tällä hetkellä kohdennettu: +workItemPanel.candidateActors=Tekijä ehdokkaat: +workItemPanel.stage=Hyväkayntä vaihe: +workItemPanel.escalationLevel=eskalointi taso: +workItemPanel.requesterComment=Pyytäjän kommentti; +workItemPanel.delta=Hyväksytyksessä oleva Delta +workItemPanel.mainInfo=Perustiedot workItemPanel.options=Vaihtoehdot -workItemPanel.requestedBy=Requested by: -workItemPanel.requestedOn=Requested on: -workItemPanel.workItemCreatedOn=This work item created on: -workItemPanel.workItemDeadline=Deadline: +workItemPanel.requestedBy=Pyytäjä: +workItemPanel.requestedOn=Pyyntö aika: +workItemPanel.workItemCreatedOn=Tämä työ alkio luotu: +workItemPanel.workItemDeadline=Määräaika: workItemPanel.requester.description=Pyytäjä -workItemPanel.subTitle=work item details -workItemPanel.title=Work to do: -workItemPanel.changesToBeApproved=Changes to be approved -workItemPanel.additionalAttributes=Additional attributes -workItemPanel.approvalHistory=Approval history for this request +workItemPanel.subTitle=työ alkio yksityiskohdat +workItemPanel.title=Tehtävät työt: +workItemPanel.changesToBeApproved=Hyväksytyksessä olevat muutokset +workItemPanel.additionalAttributes=Lisä attribuutit +workItemPanel.approvalHistory=tämän pyynnön hyväksymis historia workItemPanel.approvalHistoryHelp=Decisions that have been done so far in the process of approving the changes displayed here. TaskWfChildPanel.approvalHistoryHelp=Decisions that have been done so far in the process of approving the changes displayed here. workItemPanel.otherWorkItemsHelp=Work items for the changes shown here that are currently active (in addition to the work item displayed on this page). TaskWfChildPanel.currentWorkItemsHelp=Work items for the changes displayed here that are currently active. -TaskWfChildPanel.showNextStagesHelp=Displays the preview of the following approval stages. -TaskWfChildPanel.nextStagesHelp=This is a preview of the following approval stages. -TaskWfChildPanel.showWholeProcessHelp=Displays the whole approval process: stages already completed, current stage, as well as any expected following stages. -TaskWfChildPanel.wholeProcessHelp=This is an information on the whole approval process: stages already completed, current stage, as well as any expected following stages. +TaskWfChildPanel.showNextStagesHelp=Näyttää seuraavien hyväksyntä vaiheiden esikatselun. +TaskWfChildPanel.nextStagesHelp=Tämä on seuraavien hyväksyntä vaiheiden esikatselu. +TaskWfChildPanel.showWholeProcessHelp=Näyttää koko hyväksyntä prosessin: Jo tehdyt vaiheet, tämän hetkinen vaihe ja myös mitkä tahansa odotettavissa olevat vaiheet. +TaskWfChildPanel.wholeProcessHelp=Tässä on tiedot koko hyväksyntä prosessista: Jo tehdyt vaiheet, tämän hetkinen vaihe ja myös mitkä tahansa odotettavissa olevat vaiheet. workItemPanel.relatedRequestsHelp=List of approval requests that have been created along with this one. Each request has its own approval process, and therefore can be approved or rejected independently of other ones. They were all started by a single change operation attempt, which contained several simpler changes. TaskWfChildPanel.relatedRequestsHelp=List of approval requests that have been created along with this one. Each request has its own approval process, and therefore can be approved or rejected independently of other ones. They were all started by a single change operation attempt, which contained several simpler changes. workItemPanel.showRequestHelp=Displays the approval request and the corresponding approval process for changes shown here. TaskWfChildPanel.showParentHelp=Displays the whole attempted operation that consists of one or more changes requiring approval. -TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here. -workItemPanel.otherWorkItems=Other work items for this request +TaskWfParentPanel.requestsHelp=Kaikki muutosten hyväksyntä prosessit näytetään täällä. +workItemPanel.otherWorkItems=Muut työ alkiot tässä pyyynnössä workItemPanel.requests=Pyynnöt -workItemPanel.relatedRequests=Related requests -workItemPanel.approverComment=Approver comment -workItemPanel.approverInstruction=Approver instruction +workItemPanel.relatedRequests=Liittyvät pyynnöt +workItemPanel.approverComment=Hyväksyjän kommentti +workItemPanel.approverInstruction=Hyväksyjän ohjeistus pageWorkItems.button.approve=Hyväksy -pageWorkItems.button.claim=Claim +pageWorkItems.button.claim=Väittämä pageWorkItems.button.reject=Hylkää pageWorkItems.button.release=Vapauta -PageWorkItemsClaimable.title=Work items claimable by me -pageWorkItems.item.created=Created on +PageWorkItemsClaimable.title=Alkio jonka voin ottaa käyttöön. +pageWorkItems.item.created=Luotu pageWorkItems.item.name=Nimi pageWorkItems.item.owner=Omistaja pageWorkItems.item.status=Asema -pageWorkItems.message.noItemSelected=No work item has been selected. -PageWorkItemsAll.title=All work items -PageWorkItemsAllocatedToMe.title=Work items allocated to me -PageWorkItem.title=Work item details -PageWorkItem.subTitle=work item details -pageWorkItem.title=Work to do: -pageWorkItem.trackingData.description=Tracking (diagnostic) data -pageWorkItem.trackingData=Tracking data -pageWorkItem.workItemCreatedOn=This work item created on: -passwordPanel.error=Passwords don't match. +pageWorkItems.message.noItemSelected=Tyä alkiota ei valittuna. +PageWorkItemsAll.title=Kaikki työ alkiot +PageWorkItemsAllocatedToMe.title=Minulle määrätyt työ alkiot +PageWorkItem.title=Työ alkio yksityiskohdat +PageWorkItem.subTitle=työ alkio yksityiskohdat +pageWorkItem.title=Tehtävät työt: +pageWorkItem.trackingData.description=jäljitys (diagnostiikka) data +pageWorkItem.trackingData=jäljitys data +pageWorkItem.workItemCreatedOn=Tämä työ alkio luotu: +passwordPanel.error=Salasanat ei täsmää. passwordPanel.passwordChange=Vaihda passwordPanel.passwordRemove=Poista -passwordPanel.passwordSet=password is set -passwordPanel.passwordRemoveLabel=password will be removed +passwordPanel.passwordSet=salasana on asetettu +passwordPanel.passwordRemoveLabel=Salasana tullaan poistamaan. past.ChangeType.ADD=Lisätty past.ChangeType.DELETE=Poistettu past.ChangeType.MODIFY=Muokattu PersonalInfoPanel.lastFail.date=Päivämäärä PersonalInfoPanel.lastFail.from=From -PersonalInfoPanel.lastFail=Last unsuccessful login +PersonalInfoPanel.lastFail=Viime epäonnistunut kirjautuminen PersonalInfoPanel.lastLogin.date=Päivämäärä PersonalInfoPanel.lastLogin.from=From PersonalInfoPanel.lastLogin=Viime kirjautuminen PersonalInfoPanel.never=Ei koskaan PersonalInfoPanel.other=Muut -PersonalInfoPanel.passwordExp=Account expiration date +PersonalInfoPanel.passwordExp=Tilin päättymispäivä PersonalInfoPanel.undefined=Ei määritetty policyRef.nullValid=Valitse Yksi prismContainer.mainPanelDisplayName=Ominaisuudet -prismContainer.shadow.associations=Associations +prismContainer.shadow.associations=Assosiaatiot prismContainer.shadow.mainPanelDisplayName=Attribuutit -PrismObjectPanel.hideEmpty=Hide empty fields +PrismObjectPanel.hideEmpty=Piilota tyhjät kentät PrismObjectPanel.maximize=Suurenna PrismObjectPanel.minimize=Pienennä -PrismObjectPanel.protectedAccount=Protected account -PrismObjectPanel.showEmpty=Show empty fields -PrismObjectPanel.sortProperties=Sort properties -PrismObjectPanel.showMetadata=Show metadata -PrismObjectPanel.hideMetadata=Hide metadata -prismOptionButtonPanel.hideEmpty=Hide empty fields +PrismObjectPanel.protectedAccount=Suojattu tili +PrismObjectPanel.showEmpty=Näytä tyhjät kentät +PrismObjectPanel.sortProperties=Lajittele ominaisuudet +PrismObjectPanel.showMetadata=Näytä metadata +PrismObjectPanel.hideMetadata=Piilota metadata +prismOptionButtonPanel.hideEmpty=Piilota tyhjät kentät prismOptionButtonPanel.maximize=Suurenna prismOptionButtonPanel.minimize=Pienennä -prismOptionButtonPanel.showEmpty=Show empty fields -prismPropertyPanel.hasOutbound=Has outbound mapping -prismPropertyPanel.hasPendingModification=Has pending modification +prismOptionButtonPanel.showEmpty=Näytä tyhjät kentät +prismPropertyPanel.hasOutbound=Sisältää ulosmenevää kartoistusta +prismPropertyPanel.hasPendingModification=Sisältää avoimen muutoksen prismPropertyPanel.name.credentials.password=Salasana prismPropertyPanel.required=Vaadittu prismValuePanel.add=Lisää prismValuePanel.delete=Poista prismValuePanel.message.association.attributes=Attribuutit: -processInstancePanel.details=Other information: -processInstancePanel.finished=Finished: -processInstancePanel.message.cantGetDetails=Couldn't get process instance details. -processInstancePanel.message.noTasks=none -processInstancePanel.name=Process instance name: -processInstancePanel.pid=Instance ID: +processInstancePanel.details=Muuta tietoa: +processInstancePanel.finished=Valmistunut: +processInstancePanel.message.cantGetDetails=Ei pystynyt saamaan prosessitapahtuman yksityiskohtia. +processInstancePanel.message.noTasks=Ei mitään +processInstancePanel.name=Prosessitapahtuman nimi: +processInstancePanel.pid=Tapahtuman ID: processInstancePanel.started=Aloitettu: -processInstancePanel.taskAlreadyRemoved=(was already removed) -processInstancePanel.task=System task: -processInstancePanel.tasks=Currently active work items: -processInstancePanel.title.edit=Details for '{0}' -ProfilingLevel.ARGUMENTS=Arguments -ProfilingLevel.ENTRY_EXIT=Entry/Exit +processInstancePanel.taskAlreadyRemoved=(on jo poistettu) +processInstancePanel.task=järjestelmä tehtävä: +processInstancePanel.tasks=Tällä hetkellä aktiiviset työ alkiot: +processInstancePanel.title.edit='{0}'stä yksityiskohtia +ProfilingLevel.ARGUMENTS=Argumentit +ProfilingLevel.ENTRY_EXIT=Sisäänkäynti/ulosmeno ProfilingLevel.OFF=Off -ProgressPanel.ExecutionTimeWhenFinished=Operation executed in {0} milliseconds. -ProgressPanel.ExecutionTimeWhenRunning=Operation executing for {0} second(s). -ProgressTableHeader.Activity=Activity -ProgressTableHeader.ResourceObject=Resource object (if applicable) +ProgressPanel.ExecutionTimeWhenFinished=Operaatio suoritettu {0} millisekunnissa. +ProgressPanel.ExecutionTimeWhenRunning=Operaatiota suoritetaan {0} sekunnin ajan. +ProgressTableHeader.Activity=Toiminta +ProgressTableHeader.ResourceObject=Resurssi objekti (jos sovellettavissa) ProgressTableHeader.Status=Asema -ProvisioningStatistics.AverageTime=Avg time +ProvisioningStatistics.AverageTime=keskiarvo aika ProvisioningStatistics.CreateFailure=Epäonnistui ProvisioningStatistics.CreateSuccess=Luonti OK ProvisioningStatistics.DeleteFailure=Epäonnistui ProvisioningStatistics.DeleteSuccess=Poisto OK ProvisioningStatistics.GetFailure=Epäonnistui -ProvisioningStatistics.GetSuccess=Get OK +ProvisioningStatistics.GetSuccess=Hanki OK ProvisioningStatistics.MaxTime=Max ProvisioningStatistics.MinTime=Min ProvisioningStatistics.ObjectClass=Objekti luokka @@ -2410,116 +2410,116 @@ ProvisioningStatistics.Resource=Resurssi ProvisioningStatistics.ScriptFailure=Epäonnistui ProvisioningStatistics.ScriptSuccess=Scripti OK ProvisioningStatistics.SearchFailure=Epäonnistui -ProvisioningStatistics.SearchSuccess=Search OK +ProvisioningStatistics.SearchSuccess=haku OK ProvisioningStatistics.SyncFailure=Epäonnistui ProvisioningStatistics.SyncSuccess=Synkronointi OK ProvisioningStatistics.TotalOperationsCount=Kaikki operaatiot -ProvisioningStatistics.TotalTime=Total time +ProvisioningStatistics.TotalTime=Yhteensä aika ProvisioningStatistics.UpdateFailure=Epäonnistui ProvisioningStatistics.UpdateSuccess=Päivitys OK -QNameEditor.label.localPart=Local part name -QNameEditor.label.namespace=Namespace +QNameEditor.label.localPart=Paikallisen osan nimi +QNameEditor.label.namespace=Nimitila QNameEditor.tooltip.attribute=TODO: QNameEditor.tooltip.attribute -QNameEditor.tooltip.localPart=Local part of QName -QNameEditor.tooltip.namespace=Namespace of QName +QNameEditor.tooltip.localPart=QNamen paikallinen osa +QNameEditor.tooltip.namespace=Qnamen nimitila RangeValidator.range=Field '${label}' have to be between ${minimum} and ${maximum}. -ReconciliationPopupPanel.exportFileType=Export Type +ReconciliationPopupPanel.exportFileType=Vie Tyyppi DownloadButtonPanel.download=Lataa ReconciliationPopupPanel.resource=Resurssi -ReconciliationPopupPanel.title.basic=Basic Reconciliation Report Configuration +ReconciliationPopupPanel.title.basic=Perus Täsmäyttämisraportin Konfiguraatio repeater.input.nullValid=Valitse Yksi ReportConfigurationPanel.title.basic=Perus -ReportConfigurationPanel.title.advanced=Advanced +ReportConfigurationPanel.title.advanced=Edistynyt Requestable.ALL=Kaikki -Requestable.NON_REQUESTABLE=Non-Requestable -Requestable.REQUESTABLE=Requestable -ResourceActivationEditor.label.administrativeStatus=Administrative status -ResourceActivationEditor.label=Edit resource activation -ResourceActivationEditor.label.existence=Existence -ResourceActivationEditor.label.fetchStrategy=Fetch strategy -ResourceActivationEditor.label.inbound=Inbound -ResourceActivationEditor.label.outbound=Outbound -ResourceActivationEditor.label.validFrom=Valid from -ResourceActivationEditor.label.validTo=Valid to -ResourceAssociationEditor.label.allow=Non-schema ref. -ResourceAssociationEditor.label.association=Association specific attributes -ResourceAssociationEditor.label.associationAttribute=Association attribute +Requestable.NON_REQUESTABLE=Ei pyydettävissä +Requestable.REQUESTABLE=Pyydettävissä +ResourceActivationEditor.label.administrativeStatus=Hallinnon tila: +ResourceActivationEditor.label=Muokkaa resurssin aktivointia +ResourceActivationEditor.label.existence=Olemassaolo +ResourceActivationEditor.label.fetchStrategy=Nouda strategia +ResourceActivationEditor.label.inbound=Sisääntuleva +ResourceActivationEditor.label.outbound=Ulosmenevä +ResourceActivationEditor.label.validFrom=voimassa alkaen +ResourceActivationEditor.label.validTo=voimassa asti +ResourceAssociationEditor.label.allow=Kaavioton viittaus +ResourceAssociationEditor.label.association=assosiaatio kohtaiset atribuutit +ResourceAssociationEditor.label.associationAttribute=assosiaatio atribuutti ResourceAssociationEditor.label.description=Kuvaus ResourceAssociationEditor.label.direction=Suunta ResourceAssociationEditor.label.displayName=Näyttönimi -ResourceAssociationEditor.label.edit=Edit association -ResourceAssociationEditor.label.exclusiveStrong=Exclusive strong -ResourceAssociationEditor.label.explicitRefIntegrity=Explicit ref. integrity -ResourceAssociationEditor.label.fetchStrategy=Fetch strategy -ResourceAssociationEditor.label.inbound=Inbound mapping -ResourceAssociationEditor.label.intent=Target intent -ResourceAssociationEditor.label.intolerantVP=Intolerant pattern -ResourceAssociationEditor.label.kind=Target kind -ResourceAssociationEditor.label.limitations=Limitations -ResourceAssociationEditor.label.matchingRule=Matching rule -ResourceAssociationEditor.label.new=Create new association -ResourceAssociationEditor.label.outbound=Outbound mapping -ResourceAssociationEditor.label.reference=Ref. -ResourceAssociationEditor.label.resourceItem=ResourceItem specific attributes -ResourceAssociationEditor.label.tolerant=Tolerant -ResourceAssociationEditor.label.tolerantVP=Tolerant pattern -ResourceAssociationEditor.label.valueAttribute=Value attribute -ResourceAssociationEditor.message.cantParseSchema=Couldn't parse resource schema -ResourceAttributeEditor.label.allow=Non-schema attribute +ResourceAssociationEditor.label.edit=Muokkaa assosiaatio +ResourceAssociationEditor.label.exclusiveStrong=Eksklusiivinen vahva +ResourceAssociationEditor.label.explicitRefIntegrity=Tarkka viitteellinen eheys +ResourceAssociationEditor.label.fetchStrategy=Nouda strategia +ResourceAssociationEditor.label.inbound=Sisääntuleva kartoitus +ResourceAssociationEditor.label.intent=Kohteen aikomus +ResourceAssociationEditor.label.intolerantVP=Intolerantti kuvio +ResourceAssociationEditor.label.kind=Kohde laji +ResourceAssociationEditor.label.limitations=Rajoitukset +ResourceAssociationEditor.label.matchingRule=Sopivuus sääntö +ResourceAssociationEditor.label.new=Luo uusi assosiaatio +ResourceAssociationEditor.label.outbound=Ulosmenevä kartoitus +ResourceAssociationEditor.label.reference=Viit. +ResourceAssociationEditor.label.resourceItem=ResurssiAlkio kohtaiset atribuutit +ResourceAssociationEditor.label.tolerant=Salliva +ResourceAssociationEditor.label.tolerantVP=Saliva kuvio +ResourceAssociationEditor.label.valueAttribute=Arvon atribuutti +ResourceAssociationEditor.message.cantParseSchema=Ei pystytty jäsentää resurssi kaaviota +ResourceAttributeEditor.label.allow=Kaavioton atribuutti ResourceAttributeEditor.label.description=Kuvaus ResourceAttributeEditor.label.displayName=Näyttönimi ResourceAttributeEditor.label.edit=Muokkaa attribuuttia -ResourceAttributeEditor.label.exclusiveStrong=Exclusive strong -ResourceAttributeEditor.label.fetchStrategy=Fetch Strategy -ResourceAttributeEditor.label.inbound=Inbound mappings -ResourceAttributeEditor.label.intolerantVP=Intolerant pattern +ResourceAttributeEditor.label.exclusiveStrong=Eksklusiivinen vahva +ResourceAttributeEditor.label.fetchStrategy=Nouda strategia +ResourceAttributeEditor.label.inbound=Sisääntulevat kartoitukset +ResourceAttributeEditor.label.intolerantVP=Intolerantti kuvio ResourceAttributeEditor.label.limitations=Rajoitukset -ResourceAttributeEditor.label.matchingRule=Matching rule -ResourceAttributeEditor.label.unknownMatchingRule=Unknown matching rule: {0} -ResourceAttributeEditor.label.new=Create new attribute -ResourceAttributeEditor.label.outbound=Outbound mappings +ResourceAttributeEditor.label.matchingRule=Sopivuus sääntö +ResourceAttributeEditor.label.unknownMatchingRule=Tuntematon sopivuus sääntö: {0} +ResourceAttributeEditor.label.new=Luo uusi atribuutti +ResourceAttributeEditor.label.outbound=Ulosmenevät kartoitukset ResourceAttributeEditor.label.reference=Attribuutti -ResourceAttributeEditor.label.tolerant=Tolerant -ResourceAttributeEditor.label.tolerantVP=Tolerant pattern -ResourceAttributeEditor.message.cantParseSchema=Couldn't parse resource schema +ResourceAttributeEditor.label.tolerant=Salliva +ResourceAttributeEditor.label.tolerantVP=Saliva kuvio +ResourceAttributeEditor.message.cantParseSchema=Ei pystytty jäsentää resurssi kaaviota ResourceAttributeEditor.title.delete=Poista ResourceAttributeEditor.title.edit=Muokkaa -ResourceCredentialsEditor.label=Edit Resource Credentials -ResourceCredentialsEditor.label.fetchStrategy=Fetch strategy -ResourceCredentialsEditor.label.inbound=Inbound -ResourceCredentialsEditor.label.outbound=Outbound -ResourceCredentialsEditor.label.passwordPolicyRef=Password policy -ResourceDependencyEditor.label.button.add=Add resource dependency -ResourceDependencyEditor.label=Edit Dependencies -ResourceDependencyEditor.label.intent=Dependency intent -ResourceDependencyEditor.label.kind=Dependency kind +ResourceCredentialsEditor.label=Muokkaa Resurssi Tunnukset +ResourceCredentialsEditor.label.fetchStrategy=Nouda strategia +ResourceCredentialsEditor.label.inbound=Sisääntuleva +ResourceCredentialsEditor.label.outbound=Ulosmenevä +ResourceCredentialsEditor.label.passwordPolicyRef=Salasana linjaus +ResourceDependencyEditor.label.button.add=Lisää resurssi riippuvuus +ResourceDependencyEditor.label=Muokkaa Riippuvuudet +ResourceDependencyEditor.label.intent=Riippuvuus aikomus +ResourceDependencyEditor.label.kind=Riippuvuus laji ResourceDependencyEditor.label.order=Järjestys -ResourceDependencyEditor.label.resourceRef=Dependency resource -ResourceDependencyEditor.label.strictness=Strictness +ResourceDependencyEditor.label.resourceRef=Riippuvuus resurssi +ResourceDependencyEditor.label.strictness=Tarkkuus ResourceIterationEditor.label.description=Kuvaus -ResourceIterationEditor.label=Edit resource iteration configuration -ResourceIterationEditor.label.expressionEvaluator=Expression evaluator -ResourceIterationEditor.label.expression=Expression -ResourceIterationEditor.label.expressionType=Expression type -ResourceIterationEditor.label.extension=Extension +ResourceIterationEditor.label=Muokkaa resurssin kertaamis konfiguraatiota +ResourceIterationEditor.label.expressionEvaluator=Lauseke arvioija +ResourceIterationEditor.label.expression=Lauseke +ResourceIterationEditor.label.expressionType=Lauseke tyyppi +ResourceIterationEditor.label.extension=Laajennos ResourceIterationEditor.label.language=Kieli -ResourceIterationEditor.label.maxIteration=Max iteration -ResourceIterationEditor.label.policyRef=Policy ref. -ResourceIterationEditor.label.postIterationCondition=Post-iteration condition -ResourceIterationEditor.label.preIterationCondition=Pre-iteration condition -ResourceIterationEditor.label.returnMultiplicity=Return multiplicity -ResourceIterationEditor.label.stringFilter=String filter -ResourceIterationEditor.label.tokenExpression=Token expression +ResourceIterationEditor.label.maxIteration=Max kertaus +ResourceIterationEditor.label.policyRef=Linjaus viittaus. +ResourceIterationEditor.label.postIterationCondition=Kertauksen jälkeinen ehto +ResourceIterationEditor.label.preIterationCondition=Kertausta edeltävä ehto +ResourceIterationEditor.label.returnMultiplicity=Palauta monikäyttöisyys +ResourceIterationEditor.label.stringFilter=Merkkijono suodatin +ResourceIterationEditor.label.tokenExpression=Merkki Lauseke ResourceIterationEditor.label.variable=Muuttuja -resource.nullValid=Choose resource... +resource.nullValid=Valitse resurssi... resourcePopup.bundle=Nippu -resourcePopup.button.add=Add resource(s) +resourcePopup.button.add=Lisää resurssi(t) resourcePopup.name=Nimi resourcePopup.version=Versio -ResourceProtectedEditor.button.add=Add protected account +ResourceProtectedEditor.button.add=Lisää suojattu tili ResourceProtectedEditor.label.description=Kuvaus -ResourceProtectedEditor.label=Edit protected accounts -ResourceProtectedEditor.label.filterClause=Filter clause +ResourceProtectedEditor.label=Muokkaa suojattuja tilejä +ResourceProtectedEditor.label.filterClause=Suodata ehto ResourceProtectedEditor.label.filter=Suodatin ResourceProtectedEditor.label.name=Nimi ResourceProtectedEditor.label.uid=Uid @@ -2529,84 +2529,84 @@ ResourceStatus.NOT_TESTED=Ei testattu ResourceStatus.SUCCESS=Onnistui ResourceStatus.UP=Ylös ResourceStatus.WARNING=Varoitus -ResourceType.isSync=Synchronization +ResourceType.isSync=synkronisaatio ResourceType.tasks=Tehtävät -ResourceWizard.expression.tooltip.expression=The XML representation of the expression. This is the actual expression code that will be interpreted. -ResourceWizard.expression.tooltip.language=Programming language in which is the expression script written. -ResourceWizard.expression.tooltip.policyRef=Reference to a value policy object. The specified value policy will be used as a template to generate a value. -ResourceWizard.expression.tooltip.type=The type of expression. This specifies whether the expression is a script, value generator or something else. -ResourceWizard.help.capabilityStep=

Resource capabilities are the things that the resource can do. Not all the resource are equal in their capabilities. E.g. one resource supports account activation (enabling and disabling accounts) but other does not. One resource provides read-write access while other can support read-only access. One resource supports real-time synchronization while other does not. The capabilities define what features the resource supports so system can behave accordingly.

All the capabilities can be disabled (i.e. turned off). Disabling the capability will cause that system will not use that part of the connector and resource. The capabilities are usually disabled if they are faulty. E.g. if there is a bug in a connector or on the resource then the bug might be circumvented if appropriate capability is disabled. But the capabilities may be disabled also for administrative reasons. E.g. disabling Create, Update and Delete capabilities makes the resource efficiently read-only.

Some capabilities can be simulated. It means that system can pretend that the resource has specific capability even though it does not have it. E.g. an activation capability can be simulated by setting a specific account attribute to a specific value to disable an account. Such simulated capabilities usually require some configuration. This can also be configured on this page.

See Resource Capabilities wiki page for more details. -ResourceWizard.help.configurationStep=

This stage of the wizard configures connector configuration properties. They usually define network parameters used to access the resource such as hostname and port numbers. Additional connection parameters such as operation network timeouts and connection pooling configuration can be specified here.

There connector configuration properties are unique for each connector. The specific set of configuration properties are determined by connector configuration schema. Therefore the content of this page depends on the connector type that was selected in the previous page.

-ResourceWizard.help.nameStep=

This stage of the wizard configures basic properties of the resource. It can be used to configure resource name and description. Connector name is mandatory and must be unique. Connector that will be used to access the resource must also be configured. Connectors are deployed on connector hosts. If the connector host is left empty then connectors deployed directly in the system instance will be used.

See Resource Configuration wiki page for detailed explanation of resource configuration.

-ResourceWizard.help.schemaHandlingStep=

This step is used to provide configuration for handling of resource schema. The configuration displayed on this page tells system what to do with resource object classes and attributes. It contains the configuration of mappings between user properties and account attributes, configuration of account types, groups, provisioning dependencies, password mapping and so on.

The configuration is grouped into object types. Each object type defines the behavior for specific account type, entitlement type, OU, etc. The object type is uniquely identified by the combination of kind and intent. The kind defines what kind of the object it is:

  • kind=account means that the object is an account, i.e. that it represents a user.
  • kind=entitlement is applied to groups, roles, privileges, ACIs and similar objects that can be associated with accounts and which give privileges or access rights to the account.
  • kind=generic applies to other objects such as organizational units (OUs), domains, etc.
Intent is a plain string that can be used to distinguish several object types. E.g. it can be used to define several account types, e.g. "default user account", "administration account", "testing account" and so on. See Kind, Intent and ObjectClass wiki page for more details.

More details about schema handling configuration are provided on Resource Schema Handling wiki page. -ResourceWizard.help.schemaStep=

This page shows resource schema. The resource schema defines object classes that the connector can manage, e.g. accounts, groups, organizational units and so on. The schema defines a set of attributes for each object class. The schema is presented here in read-only form so you can inspect it and familiarize yourself with the data model that the resource provides.

The resource schema presented at this page is usually retrieved from the resource and automatically generated by system. Resource schema defines what the resource can do, i.e. what object classes it defines and what attributes are used in the object classes. Therefore the schema is read-only. It is not a configuration. It does not defines how system uses the object classes and attributes. That is configured in next steps of the wizard.

See Resource Schema wiki page for detailed explanation of resource schema concepts

-ResourceWizard.help.synchronizationStep=

The synchronization configuration defines how Identity Manager reacts when it discovers that resource object has changed. E.g. it defines how system reacts when it discovers new account, when it discovers that a group that should exist does not and so on. It is usually does not matter how system discovers the change the reaction is usually the same (although exceptions are possible by using channel specification). Therefore the policy that is configured here usually applies to live synchronization, reconciliation, import, discovery (consistency mechanism) and possible also other mechanisms that may come in the future.

See Synchronization Configuration wiki page for more details. -ResourceWizard.saveAndVisualize=Save and visualize -ResourceWizard.visualize=Visualize +ResourceWizard.expression.tooltip.expression=Lausekkeen XML representaatio. Tämä on se varsinainen lauseke koodi jota tullaan käyttämään. +ResourceWizard.expression.tooltip.language=Ohjelmointi kieli jolla lausekkeen ohjelmakoodi on kirjoitettu. +ResourceWizard.expression.tooltip.policyRef=Viittaus arvon linjaus objektiin. Valittua arvon linjausta tullaan käyttämään muottina arvon luomiseen. +ResourceWizard.expression.tooltip.type=Lauseke tyyppi. Tämä määrittää josko lauseke on ohjelmakoodi, arvon luoja vai jokin muu. +ResourceWizard.help.capabilityStep=

resurssin kyvytovat ne asiat jotka kyky kykenee tekemään. Kaikilla resursseilla ei ole samoja kykyjä. Esim. jokin resurssi tukee tilin aktivointia (tilin käyttöön otto ja käytöstä poisto) mutta toinen ei. Jokin resurssi tarjoaa kirjoitus-luku yhteyden kun taas toinen voi tukea vain luku yhteyttä. kyvytmäärittää mitä asioita resurssi tukee jotta järjestelmä voi toimia sen mukaisesti.

Kaikki kyvyt voidaan kytkeä päältä(toisin sanoen pois päältä). Kyvyn postaminen käytöstä tekee sen, että järjestelmä ei käytä liittimen sitä osaa eikä resurssia. Kyvyt ovat yleensä pois käytöstä jos ne ovat viallisia, esim. jos liittimessä tai resurssissa on virhe niin se voidaan kiertää jos oikea kyky on poistettu käytöstä. Mutta kyvyt voi olla poistettuna käytöstä hallinnolisista syistä. Esim Luo,Päivitä ja Poistakykyjen pois käytöstä ottaminen tekee resurssista tehokkaasti vain luettavan.

Jotkut kyvyt voivat olla simuloituja. Se tarkoitaa, että järjestelmä pystyy esittämään että resurssilla on tietty kyky vaikkei sillä olisikaan. Esim. aktivointikyky voidaan simuloida asettamalla tietty tili atribuutti tiettyyn arvoon poistaaksesi tilin käytöstä. Tämmöiset simuloidut kyvyt yleensä tarvitsee jonkun verran konfigurointia. Tämä pystytään myös konfiguroimaan tällä sivulla.

KatsoResurssien kyvyt wiki sivua lisätietoja varten. +ResourceWizard.help.configurationStep=

Avustuksen tämä osa konfiguroi liittimen konfiguraatio ominaisuudet. Nämä yleensä määrittävät verkko parametrit joita käytetään resurssiin yhdistämiseen, kuten isännän nimi j a portti numerot. Muita yhdistämisparametrejä kuten operaation verkko keskeytys ja yhteyden varaamis konfiguraation pystyy tarkentamaan täällä.

Nämä liittimen konfiguraatio ominaisuudet ovat uniikkeja jokaiselle liittimelle. Tarkka konfiguraatio ominaisuudet pvat määriteltyinä liitimen konfiguraatio kaavio. Näin ollen tämän sivun sisältö riippuu edelliseltä sivulta vallitusta liitin tyypistä.

+ResourceWizard.help.nameStep=

Tämä avustuksen osa auttaa konfiguroinaan resurssin perus ominaisuudet. Sitä voidaan käyttää konfiguroimaan resurssin nimi ja kuvaus. Littimen nimi on pakollinen ja sen on pakko olla uniikki. Liitin, jolla otetaan yhteyttä resurssiin pitää myös olla konfiguroitu. Liitimet on sijoitettu liitin isäntiin. Jos liiin isäntä on jätetty tyhjäksi niin käytetään liittimiä jotka on sijoitettu suoraan järjestelmän instanssiin.

KatsoResurssin konfiguraatio wiki sivulta tarkkaa selitustä resurrsiin konfiguroinnista.

+ResourceWizard.help.schemaHandlingStep=

Tätä askelta käytetään resurssin kaavion käsittelyn konfiguraation toimittamiseen. Tällä sivulla näytetty konfiguraatio kertoo järjestelmälle mitä tehdä resurssi objektin luokille ja atribuuteille. Se sisältää käyttäjä ominaisuuksien ja tili atribuuttien kartoitusten konfiguraation, tilityyppien konfiguraation, esivalmistelun riippuvuudet, salasana kartoitus ja niin edelleen.

Konfiguraatio on ryhmitetty objekti tyyppeihin. Jokainen objekti tyyppi määrittää käyttäytymisen tietylle tili tyypille, oikeutus tyypit, OY, jne. Objekti tyyppi on uniikisti tunnistettavissa laji ja tarkoituksen sekoituksesta. Laji määrittää minkälainen objekti on kyseessä:

  • laji=tili tarkoittaa että objekti on tili, eli esittää käyttäjää.
  • laji=oikeutus käytetään ryhmien, roolien, etuoikeuksien, ACIen ja samanlaisten objektien joita voi assosioida tileihin ja antavat etuikeuksia tai yhdistämis oikeuksia tilille.
  • laji=yleinen käytetään toisiin objekteihin kuten organisaatio yksikköihin (OYt), domaineihin, jne
Tarkoitus on simppeli merkkijono jota voi köyttää erotellakseen monia objektityyppiä. Esim. sitä voi käyttää määrittääkseen useutä tilityyppejä, esim. "Oletus käyttäjätili", "hallinnointitili", Testitili" ja niiin edelleen. Katso laji, Tarkoitus ja ObjektiLuokka wiki sivulta lisätietoja varten.

Lisätietoja Kaavion käsittelyn konfiguroinnista löytyy Resurssi Kaavion Käsittely wiki sivulta. +ResourceWizard.help.schemaStep=

Tämä sivu näyttää resurssikaavion. Resurssikaavio määrittää objekti luokat joita liitin voi hallita, kuten tilit, ryhmät, organisaatio yksiköt, jne. Kaavio määrittää ryhmän attribuutteja jokaiselle objekti luokalle. Tässä esitelty kaavio on vain luku muodossa jotta sitä voi tutkia ja tutustua siihen data malliin jonka resurssi toimittaa.

Tällä sivulla esitylty resurssikaavio yleensä saadaan resurssista ja se on järjestelmän automaattisesti luoma. Resurssikaavio määrittää mitä resurssi voi tehdä, toisin sanoen mitä objekti luokkia se määrittää ja mitä atribuutteja käytetää objekti luokissa. Tämn vuoksi kaavio on vain luku muodossa. Se ei ole konfiguraatio. se ei määritä kuinka järjestelmä käyttää objekti luokkia ja atribuutteja. Se konfiguroidaan avustuksen seuraavissa askelissa.

Katso Resurssikaavion wiki sivusto resurssikaavion konseptien yksityiskohtaista selitystä varten.

+ResourceWizard.help.synchronizationStep=

Synkronisaatio konfiguraatio määrittä kuinka Identiteetin hallinta reagoi kun se huomaa, että resurssi objekti on muuttunut. Esim. se määrittää miten järjestelmä reagoi kun se löytää uuden tilin, kun se huomaa että ryhmä jonka pitäisi löytyä ei löydykkäänja niin edelleen. Yleensä sillä ei ole väliä miten järjestelmä huomaa muutoksen, reaktio on yleensä sama (vaikka poikkeukset ovat mahdollisia käyttämäll kanava määritystä). Tämän takia tähän kondiguroiti linjaus pätee yleensä live synkronointiin, täsmäyttämiseen,tuontiin, löytämiseen(johdonmukaisuus mekanismi) ja mandollisesti muita mekanismeja jotka tulevat tulevaisuudessa.

Katso Synkronisaation konfigurointi wiki sivulta lisätietoja varten. +ResourceWizard.saveAndVisualize=Tallenna ja visualisoi +ResourceWizard.visualize=Visualisoi runReportPopupContent.button.run=Suorita raportti -runReportPopupContent.param.class=Parameter type -runReportPopupContent.param.name.eventStage = Event Stage +runReportPopupContent.param.class=Parametri tyyppi +runReportPopupContent.param.name.eventStage = Tapahtuma Vaihe runReportPopupContent.param.name.eventType = Tapahtuma Tyyppi -runReportPopupContent.param.name.from = Date From -runReportPopupContent.param.name.initiatorName = Initiator Name +runReportPopupContent.param.name.from = Päiväys alkaen +runReportPopupContent.param.name.initiatorName = Aloittajan Nimi runReportPopupContent.param.name.outcome = Tulos -runReportPopupContent.param.name=Parameter name +runReportPopupContent.param.name=Parametrin nimi runReportPopupContent.param.name.targetName = Kohteen nimi -runReportPopupContent.param.name.filter=Filter resulting roles? true/false (default is false) -runReportPopupContent.param.name.to = Date To -runReportPopupContent.param.value=Parameter value -runReportPopupContent.param.name.alsoClosedCampaigns=Also closed campaigns? (default is false) +runReportPopupContent.param.name.filter=Suodata rooli tulokset? tosi/epätosi (oletus on epätosi) +runReportPopupContent.param.name.to = Lopetus päiväys +runReportPopupContent.param.value=Parametrin arvo +runReportPopupContent.param.name.alsoClosedCampaigns=Myös suljetut kampanjat? (perustila on Epätosi) runReportPopupContent.param.name.campaignName=Kampanja nimi runReportPopupContent.param.name.resource=Resurssi -runReportPopupContent.param.name.intent=Intent +runReportPopupContent.param.name.intent=Aikomus runReportPopupContent.param.name.objectClass=Objektin nimi -runReportPopupContent.param.name.kind=Kind +runReportPopupContent.param.name.kind=Laji runReportPopupContent.param.name.situation=Tilanne runReportPopupContent.param.name.activation=Aktivointi runReportPopupContent.param.name.organization=Organisaatio runReportPopupContent.param.name.role=Rooli runReportPopupContent.param.name.roleOids=Roolit runReportPopupContent.param.name.users=Käyttäjät -runReportPopupContent.param.name.stageNumber=Stage number (default is to take all stages) -runReportPopupContent.param.name.referencedRolesNames=Referenced Roles -RunReportPopupPanel.title=Report configuration before run -runUntilNodeDown.error1=Compatible data for 'Thread stop action' are: Close, Suspend -runUntilNodeDown.error2=Compatible data for 'Thread stop action' are: Restart, Reschedule -SchemaHandlingStep.activation.tooltip.fetchStrategy=How to fetch the attribute when it is needed. Implicit: the attribute is returned by default, it does not need to be requested; Explicit: the attribute is not returned by default, always request it explicitly. -SchemaHandlingStep.activation.tooltip.inbound=Inbound mappings map values from the resource (usually an account) to the Identity Manager (usually a user). -SchemaHandlingStep.activation.tooltip.outbound=Outbound mappings map values from Identity Manager (usually a user) to the resource (usually an account). -SchemaHandlingStep.association.label.associationName=Association name -SchemaHandlingStep.association.label.associationNamespace=Namespace -SchemaHandlingStep.association.tooltip.associationAttribute=Name of the attribute that "holds" the association. I.e. an attribute which contains the identifier of the associated object. This is usually an attribute such as "member", "groups", "roles", etc. In subject-to-object associations this is an attribute of a subject (e.g. account attribute "groups"). In object-to-subject associations this is an attribute of an object (e.g. group attribute "members"). +runReportPopupContent.param.name.stageNumber=Vaiheen numero (Perustila on ottaa kaikki vaiheet) +runReportPopupContent.param.name.referencedRolesNames=Viitatut roolit +RunReportPopupPanel.title=Raportoi konfiguraatio ennen suoritusta +runUntilNodeDown.error1=Yhteensopiva data 'Ketju pysäytä tominto'lle on: Sulje, Keskeytä +runUntilNodeDown.error2=Yhteensopiva data 'Ketju pysäytä tominto'lle on: uudelleen käynnistys, uudelleen ajastus +SchemaHandlingStep.activation.tooltip.fetchStrategy=Kuinta noutaa atribuutti kun on tarvis. Epäsuora: atribuutti palautetaan oletuksena, sitä ei tarvitse pyytää; Suora: atribuuttia ei palauteta oletuksena, pitää aina pyytää erikseen. +SchemaHandlingStep.activation.tooltip.inbound=Sisääntulevat kartoitukset kartoittavat arvot resurssista (yleensä tili) Identiteetti Managerille (yleensä käyttäjä) +SchemaHandlingStep.activation.tooltip.outbound=Ulosmenevät kartoitukset kartoittaa arvoja Identiteetti managerista (yleensä käyttäjä) resurssiin (yleensä tili). +SchemaHandlingStep.association.label.associationName=Assosiaation nimi +SchemaHandlingStep.association.label.associationNamespace=Nimitila +SchemaHandlingStep.association.tooltip.associationAttribute=Atribuutin nimi joka "hallitsee" assosiaatiota. toisin sanoen atribuutti joka sisältää yhdistetyn objektin tunnistajan. Tämä on yleensä sellainen atribuutti kuin "jäsen", "ryhmät", "roolit", jne. Kohteesta objektiin assosiaatioissa tämä on kohteen atribuutti (esim. tili atribuutti ryhmät"). Objektista kohteeseen assosiaatioissa tämä on objektin atribuutti (esim. ryhmä attribuutti "jäsenet"). SchemaHandlingStep.association.tooltip.associationLocalPart=TODO: SchemaHandlingStep.association.tooltip.associationLocalPart SchemaHandlingStep.association.tooltip.associationNamespace=TODO: SchemaHandlingStep.association.tooltip.associationNamespace -SchemaHandlingStep.association.tooltip.direction=Defines the direction of the association. Object-to-subject: Object (e.g. group) has an attribute that contains identifier of the subject (e.g. account); Subject-to-object: Subject (e.g. account) has an attribute that contains identifier of the object (e.g. group). -SchemaHandlingStep.association.tooltip.explicitRefIntegrity=Explicit referential integrity. If set to false then system assumes that the resource implements referential integrity. E.g. system assumes that the resource automatically updates the association identifiers if an account is renamed and system does not need to do anything. If set to true then system will do referential integrity explicitly. In this case system will explicitly update the association attributes if an account is renamed. -SchemaHandlingStep.association.tooltip.intent=Intent of the association target object type. Target kind and intent identify an object type which is association target, e.g. a group, privilege, role, etc. -SchemaHandlingStep.association.tooltip.kind=Kind of the association target object type. This is usually "entitlement". Target kind and intent identify an object type which is association target, e.g. a group, privilege, role, etc. -SchemaHandlingStep.association.tooltip.valueAttribute=Name of the attribute that is the source of a value for the association. The value of this attribute will be taken and stored into the association attribute to form an association. This is usually an attribute that contains an identifier or name such as "uid", "id", "name", etc. In subject-to-object associations this is an attribute of an object (e.g. group). In object-to-subject associations this is an attribute of a subject (e.g. account). +SchemaHandlingStep.association.tooltip.direction=Määrittää assosiaation suunnan. Objektista subjektiin: Objektissa (esim. ryhmä) on atribuutti joka sisältää subjektin tunnistajan (esim tili); Subjektista objektiin: Subjektissa (esim. tili) on atribuutti joka sisältää objektin tunnistajan (esim. ryhmä). +SchemaHandlingStep.association.tooltip.explicitRefIntegrity=Suora viitteellinen eheys. Jos asettu epätodeksi niin järjestelmä olettaa että resurssi käyttää viitteellistä eheytystä. Esim. järjestelmä olettaa että resurssi automaattisesti päivittää assosiaatio tunnistimet jos tili uudelleen nimetään ja järjestelmän ei tarvitse tehdä mitään. Jos asetettu todeksi niin järjestelmä tekee viitteellisen eheytyksen suorasti. Siinä tapauksessa järjestelmä suoraan päivittää assosiaatio atribuutit jos tili uudelleen nimetään. +SchemaHandlingStep.association.tooltip.intent=Assosiaatio kohde objekti tyypin aikomus. kohdista laji ja aikomus tunnista objekti tyyppi joka on assosiaation kohde, esim. ryhmä, etuoikeus, rooli, jne. +SchemaHandlingStep.association.tooltip.kind=Assosiaatio kohde objekti tyypin laji. tämä on yleensä "oikeutus". Kondista laji ja aikomus tunnista objekti tyyppi joka on assosiaation kohde, esim. ryhmä, etuoikeus, rooli, jne. +SchemaHandlingStep.association.tooltip.valueAttribute=Atribuutin nimi joka on assosioidun arvon lähde. Atribuutin arvo otetaan ja tallenetaan assosisaaatio atribuuttiin assosiaation luomiseksi. Tämä on yleensä atribuutti joka sisältää tunnistimen tai nimen kuten "uid", "id", "nimi", jne. Subjektista objektiin assosiaatioissa tämä on objektin atribuutti (esim. ryhmä). Objekstista subjektiin assosiaatiossa tämä on subjektin atribuutti (esim. tili). SchemaHandlingStep.attribute.label.attributeName=Attribuutin nimi -SchemaHandlingStep.attribute.label.attributeNamespace=Attribute namespace -SchemaHandlingStep.attribute.tooltip.allow=If checked allows to specify an attribute which is not in the original resource schema. This can be used to fix faulty connectors that do not provide a complete resource schema, which hides some attributes, etc. +SchemaHandlingStep.attribute.label.attributeNamespace=Atribuutin nimitila +SchemaHandlingStep.attribute.tooltip.allow=Jos valittu niin sallii sellaisen atribuutin tarkennuksen jota ei löydy alkuperäisessä resurssikaaviossa. Tätä voi käyttää korjataksesi virheellisiä liittimiä jotka eivät anna täyttä resurssikaaviota, joka piilottaa osan atribuuteista, jne. SchemaHandlingStep.attribute.tooltip.attributeLocalPart=TODO: SchemaHandlingStep.attribute.tooltip.attributeLocalPart SchemaHandlingStep.attribute.tooltip.attributeNamespace=TODO: SchemaHandlingStep.attribute.tooltip.attributeNamespace -SchemaHandlingStep.attribute.tooltip.exclusiveStrong=When set to false then both strong and normal mapping values are merged to produce the final set of values. When set to true only strong values are used if there is at least one strong mapping. Normal values are used if there is no strong mapping. -SchemaHandlingStep.attribute.tooltip.fetchStrategy=How to fetch the attribute when it is needed. Implicit: the attribute is returned by default, it does not need to be requested; Explicit: the attribute is not returned by default, always request it explicitly. -SchemaHandlingStep.attribute.tooltip.inbound=Inbound mappings map values from the resource (usually an account) to the system (usually a user). -SchemaHandlingStep.attribute.tooltip.intolerantVP=A value that matches this pattern will NOT be tolerated. I.e. it will be erased from the attribute value even if it is not a result of system processing (mappings). -SchemaHandlingStep.attribute.tooltip.limitations=Specify attribute limitations such as multiplicity, ability to read or write it, etc. -SchemaHandlingStep.attribute.tooltip.matchingRule=A rule that determines if two attribute values have the same meaning. E.g. setting this to 'stringIgnoreCase' will make this attribute efficiently case insensitive. -SchemaHandlingStep.attribute.tooltip.outbound=Outbound mappings map values from system (usually a user) to the resource (usually an account). -SchemaHandlingStep.attribute.tooltip.reference=Name of the attribute to configure. All the settings and mappings below apply to this attribute. -SchemaHandlingStep.attribute.tooltip.tolerant=Tolerant attributes tolerate values that are set outside of system. Non-tolerant attributes will only allow values that are defined in system (e.g. by resource or role mappings). -SchemaHandlingStep.attribute.tooltip.tolerantVP=A value that matches this pattern will be tolerated. I.e. it will remain as the attribute value even if it is not a result of system processing (mappings). +SchemaHandlingStep.attribute.tooltip.exclusiveStrong=Kun asetettu epätodeksi niin vahva ja normaali kartoitus arvot yhdistetään lopullisten arvojen saamiseksi. Kun asetettu todeksi vain vahvoja arvoja käytetään jos on yksikin vahva kartoitus. Normaaleja arvoja käytetään jos ei ole yhtään vahavaa kartoitusta. +SchemaHandlingStep.attribute.tooltip.fetchStrategy=Kuinta noutaa atribuutti kun on tarvis. Epäsuora: atribuutti palautetaan oletuksena, sitä ei tarvitse pyytää; Suora: atribuuttia ei palauteta oletuksena, pitää aina pyytää erikseen. +SchemaHandlingStep.attribute.tooltip.inbound=Sisääntulevat kartoitukset kartoittavat arvot resurssista (yleensä tili) järjestelmään (yleensä käyttäjä) +SchemaHandlingStep.attribute.tooltip.intolerantVP=Arvo joka täsmää tämän kuvion kanssa EI sallita. Toisin sanoen se poistetaan atribuutin arvosta vaikka se ei olisi järjestelmän prosessin tulos (kartoitukset) +SchemaHandlingStep.attribute.tooltip.limitations=Tarkenna attribuutin rajat kuten monikäyttöisyys, kyky lukea tai kirjoittaa, jne +SchemaHandlingStep.attribute.tooltip.matchingRule=Sääntö joka määrittää josko kahdella atribuutti arvolla on sama merkitys. Esim. tämoän asettaminen 'MerkkijonoJätähuomoittaKoko' tekee tästä atribuutista semmoisen, joka ei välitä isosta tai pienestä kirjaimesta. +SchemaHandlingStep.attribute.tooltip.outbound=Ulosmenevät kartoitukset kartoittaa arvoja järjestelmästä (yleensä käyttäjä) resurssiin (yleensä tili). +SchemaHandlingStep.attribute.tooltip.reference=Konfiguroitavan attribuutin nimi. Kaikki alla olevat asetukset ja kartoitukset vaikuttavat tähän atribuuttiin. +SchemaHandlingStep.attribute.tooltip.tolerant=Sietokykyiset atribuutit sietävät arvoja jotka tulevat järjestelmän ulkopuolelta. Sietokyvyttömät atribuutit sallivat vain arvoja, jotka on määritelty järjestelmässä (esim resurssin tai rooli kartoituksen kautta). +SchemaHandlingStep.attribute.tooltip.tolerantVP=Arvo joka täsmää tämän kuvion kanssa sallitaan. Toisin sanoen se jää atribuutin arvoksi vaikka se ei olisi järjestelmän prosessin tulos (kartoitukset) SchemaHandlingStep.button.add=Lisää objekti tyyppi -SchemaHandlingStep.credentials.tooltip.fetchStrategy=How to fetch the credentials value when it is needed. Implicit: the value is returned by default, it does not need to be requested; Explicit: the value is not returned by default, always request it explicitly. -SchemaHandlingStep.credentials.tooltip.inbound=Inbound mappings map values from the resource (usually an account) to the system (usually a user). -SchemaHandlingStep.credentials.tooltip.outbound=Outbound mappings map values from system (usually a user) to the resource (usually an account). -SchemaHandlingStep.credentials.tooltip.passwordPolicyRef=Password policy to apply to this credential. This setting overrides other settings, e.g. default password policy defined in system configuration. If no password policy is defined here then the usual default will be used. -SchemaHandlingStep.dependency.tooltip.intent=Intent of the object on which we depend. -SchemaHandlingStep.dependency.tooltip.kind=Kind of the object on which we depend. +SchemaHandlingStep.credentials.tooltip.fetchStrategy=Kuinta noutaa tunnusten arvo kun on tarvis. Epäsuora: arvo palautetaan oletuksena, sitä ei tarvitse pyytää; Suora: arvoa ei palauteta oletuksena, pitää aina pyytää erikseen. +SchemaHandlingStep.credentials.tooltip.inbound=Sisääntulevat kartoitukset kartoittavat arvot resurssista (yleensä tili) järjestelmään (yleensä käyttäjä). +SchemaHandlingStep.credentials.tooltip.outbound=Ulosmenevät kartoitukset kartoittaa arvoja järjestelmästä (yleensä käyttäjä) resurssiin (yleensä tili). +SchemaHandlingStep.credentials.tooltip.passwordPolicyRef=Salasana linjaus tälle tunnukselle. Tämä asetus korvaa muut asetukset, esim perus salasana linjaukset jotka määritetaan järjestelmä konfiguraatiossa. Jos tässä ei ole määritelty linjausta niin normaali oletus linjausta käytetään. +SchemaHandlingStep.dependency.tooltip.intent=Objektin tarkoitus johon nojaamme. +SchemaHandlingStep.dependency.tooltip.kind=Objektin laji johon nojaamme. SchemaHandlingStep.dependency.tooltip.order=Normally zero. Can specify an integer that determines the ordering of dependencies that form a cycle and could not be otherwise be resolved (a.k.a. high-order dependencies). SchemaHandlingStep.dependency.tooltip.resourceRef=Resource on which we depend. SchemaHandlingStep.dependency.tooltip.strictness=Specifies how strictly will be the dependency resolved. Lax: if the dependency is not there continue as normal (only used to impose operation ordering); Relaxed: refuse to do operation unless the dependency is tried first, but if that fails then continue anyway; Strict: proceed only is the dependency is tried first and it succeeds. @@ -2614,17 +2614,17 @@ SchemaHandlingStep.iteration.tooltip.maxIteration=Maximum number of iterations t SchemaHandlingStep.iteration.tooltip.returnMultiplicity=TODO: SchemaHandlingStep.iteration.tooltip.returnMultiplicity SchemaHandlingStep.iteration.tooltip.variable=TODO: SchemaHandlingStep.iteration.tooltip.variable SchemaHandlingStep.label.activation=Aktivointi -SchemaHandlingStep.label.assignmentPolicyRef=Assignment policy -SchemaHandlingStep.label.associations=Associations +SchemaHandlingStep.label.assignmentPolicyRef=toimeeksianto linjaus +SchemaHandlingStep.label.associations=Assosiaatiot SchemaHandlingStep.label.attributes=Attribuutit SchemaHandlingStep.label.credentials=Tunnukset -SchemaHandlingStep.label.default=Default +SchemaHandlingStep.label.default=Oletus SchemaHandlingStep.label.dependency=Riippuvuudet SchemaHandlingStep.label.description=Kuvaus SchemaHandlingStep.label.displayName=Näyttönimi SchemaHandlingStep.label.intent=Aikomus -SchemaHandlingStep.label.iteration=Iteration -SchemaHandlingStep.label.kind=Kind +SchemaHandlingStep.label.iteration=Kertaus +SchemaHandlingStep.label.kind=Laji SchemaHandlingStep.label.newObjectType=Uusi objekti tyyppi SchemaHandlingStep.label.objectClass=Objekti luokka SchemaHandlingStep.label.objectTypes=Objekti tyyppit @@ -2634,7 +2634,7 @@ SchemaHandlingStep.limitations.tooltip.layers=System layers to which this limita SchemaHandlingStep.limitations.tooltip.maxOccurs=Maximum number of occurrences of the attribute. A value of one means single-value attribute, value of "unbounded" means multi-value attribute. A value which is specified here overrides the value taken from resource schema. SchemaHandlingStep.limitations.tooltip.minOccurs=Minimum number of occurrences of the attribute. A value of zero means optional attribute, value of one means mandatory attribute. A value which is specified here overrides the value taken from resource schema. SchemaHandlingStep.limitations.tooltip.other=TODO: REMOVE THIS TOOLTIP -SchemaHandlingStep.limitations.tooltip.propertyAccess=The type of access which is allowed or denied. +SchemaHandlingStep.limitations.tooltip.propertyAccess=Yhteys tyyppi joka joko sallitaan tai estetään. SchemaHandlingStep.mapping.tooltip.authoritative=Authoritative mappings both add and remove specified value. Non-authoritative mappings only add the value. E.g. if a role with an authoritative mapping is removed the value that the mapping implied is also removed. If a role with non-authoritative mapping is removed then the value remains. SchemaHandlingStep.mapping.tooltip.channel=Limits application of this mapping only to specific channel. E.g. to changes coming from live sync, reconciliation or GUI. If the channel is listed then the mapping will be applied. If it is not then it will not be applied. If no channel is specified then no limitations apply and the mapping will be applied for all channels. SchemaHandlingStep.mapping.tooltip.conditionLanguage=Programming language in which is the condition script written. @@ -2674,26 +2674,26 @@ SchemaHandlingStep.tooltip.objectClass=Object class from the schema that will be SchemaHandlingStep.tooltip.protected=Specification of protected instances of this object type. System can see protected instances but they cannot be touched. Any attempt to modify them will fail. This is used to protect emergency administration accounts such as "root" or "administrator". SchemaHandlingStep.duplicateObjectTypeWarning=There are more definitions for kind/intent: {0}. SchemaHandlingStep.in=in: {0} -SchemaHandlingStep.out=out +SchemaHandlingStep.out=ulos SchemaHandlingStep.dup=DUP {0} SchemaListPanel.attributes=Attribuutit -SchemaListPanel.details.default=Default +SchemaListPanel.details.default=Oletus SchemaListPanel.details.description=Kuvaus SchemaListPanel.details=Yksityiskohdat SchemaListPanel.details.displayName=Näyttönimi SchemaListPanel.details.intent=Aikomus -SchemaListPanel.details.kind=Kind +SchemaListPanel.details.kind=Laji SchemaListPanel.details.nativeObjectClass=Native obj. class SchemaListPanel.displayName=Näyttönimi SchemaListPanel.displayOrder=Järjestys -SchemaListPanel.message.couldntParseSchema=Couldn't parse resource schema +SchemaListPanel.message.couldntParseSchema=Ei pystytty jäsentää resurssi kaaviota SchemaListPanel.minMax=Min/max occurs SchemaListPanel.name=Nimi SchemaListPanel.nativeAttributeName=Native attribute name SchemaListPanel.objectClasses=Objekti luokat SchemaListPanel.objectClass=Objekti luokka -SchemaListPanel.returnedByDefault=Returned by default -SchemaStep.button.reload=Reload +SchemaListPanel.returnedByDefault=Palautettu oletusarvoisesti +SchemaStep.button.reload=uudelleen lataus SchemaStep.message.reload.fail=Schema for resource '{0}' was not reloaded. SchemaStep.message.reload.ok=Schema for resource '{0}' was reloaded successfully. SchemaStep.schema=Schema @@ -2733,7 +2733,7 @@ StandardLoggerType.AUTHORIZATION=Authorization (c.e.m.security.impl.SecurityEnfo StandardLoggerType.SCRIPT_EXPRESSION=Script expression (c.e.m.common.expression.script.ScriptExpression) SubtasksPanel.label.category=Kategoria SubtasksPanel.label.detail=Yksityiskohdat -SubtasksPanel.label.executionState=Execution state +SubtasksPanel.label.executionState=Toteutuksen tila SubtasksPanel.label.name=Tehtävän nimi SubtasksPanel.label.result=Tulos SynchronizationActionEditorDialog.button.cancel=Peruuta @@ -2741,15 +2741,15 @@ SynchronizationActionEditorDialog.button.save=Tallenna SynchronizationActionEditorDialog.button.apply=Käytä SynchronizationActionEditorDialog.label.description=Kuvaus SynchronizationActionEditorDialog.label=Edit Synchronization Action -SynchronizationActionEditorDialog.label.handlerUri=Action +SynchronizationActionEditorDialog.label.handlerUri=Toiminta SynchronizationActionEditorDialog.label.name=Nimi SynchronizationActionEditorDialog.label.order=Järjestys SynchronizationExpressionEditor.label.condition=Edit synchronization condition SynchronizationExpressionEditor.label.confirmation=Edit synchronization confirmation -SynchronizationInformationPanel.count=Count +SynchronizationInformationPanel.count=Luku SynchronizationInformationPanel.deleted=Poistettu -SynchronizationInformationPanel.disputed=Disputed -SynchronizationInformationPanel.linked=Linked +SynchronizationInformationPanel.disputed=Kiistanalainen +SynchronizationInformationPanel.linked=Linkitetty SynchronizationInformationPanel.noSynchronizationPolicy=No sync policy SynchronizationInformationPanel.notApplicableForTask=Not applicable for task SynchronizationInformationPanel.protected=Suojattu @@ -2758,8 +2758,8 @@ SynchronizationInformationPanel.synchronizationDisabled=Sync disabled SynchronizationInformationPanel.title=States of processed objects (before operation) SynchronizationInformationPanel.titleAfter=States of processed objects (after operation) SynchronizationInformationPanel.discoveryWarning=(The following numbers may include processing triggered by the discovery mechanism.) -SynchronizationInformationPanel.unlinked=Unlinked -SynchronizationInformationPanel.unmatched=Unmatched +SynchronizationInformationPanel.unlinked=Linkkautumaton +SynchronizationInformationPanel.unmatched=Yhdistämätön ActionsExecutedInformationPanel.title=Actions executed ActionsExecutedInformationPanel.showingResultingActionsOnly=Showing "resulting actions" only. E.g. user ADD and MODIFY in one synchronization operation is shown as ADD. ActionsExecutedInformationPanel.showingAllActions=Showing all executed actions. @@ -2767,15 +2767,15 @@ ActionsExecutedInformationPanel.changeShowingActions=Change it. ActionsExecutedInformationPanel.objectType=Objekti tyyppi ActionsExecutedInformationPanel.operation=Operaatio ActionsExecutedInformationPanel.channel=Kanava -ActionsExecutedInformationPanel.successCount=Count (OK) +ActionsExecutedInformationPanel.successCount=Luku (OK) ActionsExecutedInformationPanel.lastSuccessObject=Last (OK) ActionsExecutedInformationPanel.lastSuccessTimestamp=Aika ActionsExecutedInformationPanel.failureCount=Count (failure) SynchronizationPolicyDecision.ADD=Lisää SynchronizationPolicyDecision.DELETE=Poista SynchronizationPolicyDecision.KEEP=No change -SynchronizationPolicyDecision.UNLINK=Unlink -SynchronizationReactionEditor.label.action=Action +SynchronizationPolicyDecision.UNLINK=Poista Linkkaus +SynchronizationReactionEditor.label.action=Toiminta SynchronizationReactionEditor.label.channel=Kanava SynchronizationReactionEditor.label.description=Kuvaus SynchronizationReactionEditor.label.edit=Edit reaction @@ -2784,24 +2784,24 @@ SynchronizationReactionEditor.label.new=Create new reaction SynchronizationReactionEditor.label.objectTemplateRef=Object template ref. SynchronizationReactionEditor.label.reconcile=Sovita SynchronizationReactionEditor.label.situation=Tilanne -SynchronizationReactionEditor.label.synchronize=Synchronize +SynchronizationReactionEditor.label.synchronize=Synkronoi SynchronizationStep.action.tooltip.handlerUri=The explicit action to execute. Please note that most actions are designed to work with the default Identity Manager's synchronization algorithm and that this algorithm will be executed unless it was explicitly disabled (and then the result may be an error). Also note that even if no explicit action is selected system will still do the default synchronization algorithm if the "synchronize" option was selected. SynchronizationStep.action.tooltip.order=Whether the explicit action is executed before Identity Manager's default synchronization algorithms or after them. Most built-in actions are designed to be executed before system synchronization as they only set up the model context and then they let system to do the real work. However some custom action may need to be executed after the synchronization, e.g. to deliver notifications, clean up, etc. SynchronizationStep.button.add=Add synchronization object SynchronizationStep.label.condition=Ehto -SynchronizationStep.label.confirmation=Confirmation +SynchronizationStep.label.confirmation=Vahvistus SynchronizationStep.label.correlation=Correlation SynchronizationStep.label.description=Kuvaus SynchronizationStep.label.editSyncObject=Muokkaa '{0}' SynchronizationStep.label.enabled=Otettu käyttöön -SynchronizationStep.label.focus=Focus -SynchronizationStep.label.intent=Intent -SynchronizationStep.label.kind=Kind +SynchronizationStep.label.focus=Fokus +SynchronizationStep.label.intent=Aikomus +SynchronizationStep.label.kind=Laji SynchronizationStep.label.name=Nimi SynchronizationStep.label.newObjectType=New sync. object type -SynchronizationStep.label.notSpecified=(name not specified) +SynchronizationStep.label.notSpecified=(nimi ei tarkennettu) SynchronizationStep.label.objectClass=Objekti luokka -SynchronizationStep.label.objectTemplate=Object template +SynchronizationStep.label.objectTemplate=Objektin malli SynchronizationStep.label.opportunistic=Opportunistic SynchronizationStep.label.reaction=Reaction SynchronizationStep.label.reconcile=Sovita @@ -2816,7 +2816,7 @@ SynchronizationStep.reaction.tooltip.objectTemplateRef=Object template that will SynchronizationStep.reaction.tooltip.reconcile=If set to true then the reconciliation step will be forced for this synchronization event. The attributes will be explicitly fetched if they are not present. If set to false then the reconciliation will be automatic. In that case the reconciliation happens only if the attributes are already present in the synchronization event. If the attributes are not present they will not be explicitly fetched and the reconciliation will be skipped. SynchronizationStep.reaction.tooltip.situation=Synchronization situation. If the situation of the event matches the situation specified here then the reaction will be applied. It will be ignored otherwise. SynchronizationStep.reaction.tooltip.synchronize=If set to true then the usual synchronization algorithms will be applied (a.k.a. clockwork and projector) in addition to explicit action specified below. This is the usual case. If set to false then the synchronization algorithms will be skipped and only the explicit action will be executed. -SynchronizationStep.title=Synchronization +SynchronizationStep.title=synkronisaatio SynchronizationStep.tooltip.condition=The synchronization setting will be applied only if this condition returns true. The condition is used mostly to sort the object of the same kind into intents. E.g. the condition may decide whether the username starts with "T". If is does then it can sort out accounts to intent "test" and if it does not then the account will have default intent. SynchronizationStep.tooltip.confirmation=Confirmation expression. Each result of the correlation expression will be passed to confirmation expression. If the confirmation expression returns true then the objects will be linked. If no confirmation expression is specified then all the objects returned from the correlation query are accepted by default. Confirmation expression may be reasonable resource-intensive because it will be executed only for objects that are returned from the correlation query. SynchronizationStep.tooltip.correlation=Correlation expression. The correlation expression is used to link focal objects (e.g. User) and shadows (e.g. account) that belong together. The correlation expression results in a search filter that is executed over the focal objects (usually users). The query returns candidate objects for linking. Correlation expression must be very efficient otherwise the synchronization performance will suffer. @@ -2831,17 +2831,17 @@ SynchronizationStep.tooltip.reaction=Specifies how system reacts to this synchro SynchronizationStep.tooltip.reconcile=If set to true then the reconciliation step will be forced for this synchronization event. The attributes will be explicitly fetched if they are not present. If set to false then the reconciliation will be automatic. In that case the reconciliation happens only if the attributes are already present in the synchronization event. If the attributes are not present they will not be explicitly fetched and the reconciliation will be skipped. SystemConfigPanel.assignmentPolicyEnforcement=Assignment policy enforcement SystemConfigPanel.cleanupPolicy.auditRecords=Audit records cleanup interval -SystemConfigPanel.cleanupPolicy=Cleanup Policy +SystemConfigPanel.cleanupPolicy=Puhdistus Linjaus SystemConfigPanel.cleanupPolicy.closedTasks=Closed tasks cleanup interval -SystemConfigPanel.cleanupPolicy.placeholder=Insert interval +SystemConfigPanel.cleanupPolicy.placeholder=Syötä väli SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=Uusi Konfiguraatio -SystemConfigPanel.mail.debug=Debug +SystemConfigPanel.mail.debug=Virheen tarkistus SystemConfigPanel.mail.defaultFrom=Default from SystemConfigPanel.mail.host=Isäntä SystemConfigPanel.mail.password=Salasana SystemConfigPanel.mail.password.placeholder.empty=Aseta salasana -SystemConfigPanel.mail.password.placeholder.set=Password is set +SystemConfigPanel.mail.password.placeholder.set=Salasana on asetettu SystemConfigPanel.mail.port=Portti SystemConfigPanel.mail.server=Mail Server SystemConfigPanel.mail.server.remove.warn=Could not delete selected mail server configuration. Changes made to selected configuration prevent the removal. Please re-select the configuration you wish to remove. @@ -2849,7 +2849,7 @@ SystemConfigPanel.mail.server.tooltip=Select the mail server to configure it. To SystemConfigPanel.mail.transportSecurity=Transport security SystemConfigPanel.mail.username=Käyttänimi SystemConfigPanel.misc.enableExperimentalCode=Enable experimental code -SystemConfigPanel.notification.redirectToFile.placeholder=Filename +SystemConfigPanel.notification.redirectToFile.placeholder=Tiedoston nimi SystemConfigPanel.notification.redirectToFile=Redirect to file SystemConfigPanel.title.accountSynchronization=Global account synchronization settings SystemConfigPanel.title.basic=Perus @@ -2859,7 +2859,7 @@ SystemConfigPanel.title.modelHooks=Model hooks SystemConfigPanel.title.notification=Ilmoitukset SystemConfigPanel.title.passwordPolicy=Global password policy SystemConfigPanel.title.securityPolicy=Global security policy -SystemConfigPanel.title.userTemplate=Default user template +SystemConfigPanel.title.userTemplate=oletus käyttäjä malli SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months SystemInfoPanel.cpuUsage=CPU käyttö SystemInfoPanel.heapMemory=Heap memory (used/committed/max) @@ -2867,7 +2867,7 @@ SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) SystemInfoPanel.threads=Threads (live/peak/total) TaskDtoExecutionStatus.CLOSED=Suljettu TaskDtoExecutionStatus.CLOSED.withTimestamp=Closed at ${} -TaskDtoExecutionStatusFilter.ALL=All execution states +TaskDtoExecutionStatusFilter.ALL=Kaikki toteutuksen tilat TaskDtoExecutionStatusFilter.CLOSED=Suljettu TaskDtoExecutionStatusFilter.NOT_CLOSED=Ei suljettu TaskDtoExecutionStatusFilter.RUNNING_OR_RUNNABLE=Runnable or running @@ -2915,8 +2915,8 @@ TaskStatePanel.objectsProcessedFailure=Objects failed to be processed TaskStatePanel.objectsProcessedSuccess=Objects successfully processed TaskStatePanel.objectsTotal=Total objects processed TaskStatePanel.opResult=Operaatio tulos -TaskStatePanel.progress=Progress -TaskStatePanel.statistics=Environmental performance statistics +TaskStatePanel.progress=Edistyminen +TaskStatePanel.statistics=Ympäristö suoriutuminen tilastot TaskStatePanel.subtaskName=Nimi TaskStatePanel.subtaskObjectsProcessed=Objects processed TaskStatePanel.subtaskState=Tila @@ -2924,21 +2924,21 @@ TaskStatePanel.updated=Päivitetty: TaskStatePanel.workerThreads=Lightweight subtasks (worker threads) tempMessagePanel.cause=Syy: tempMessagePanel.context=Konteksti: -tempMessagePanel.count=Count: -tempMessagePanel.message.debug=Debug +tempMessagePanel.count=Luku: +tempMessagePanel.message.debug=Virheen tarkistus tempMessagePanel.message.error=Virhe -tempMessagePanel.message.expectedError=Expected error +tempMessagePanel.message.expectedError=Odotettu virhe tempMessagePanel.message.fatalError=Kohtalokas virhe -tempMessagePanel.message.inProgress=In progress -tempMessagePanel.message.notApplicable=Not applicable +tempMessagePanel.message.inProgress=Käynnissä +tempMessagePanel.message.notApplicable=Ei sovellettavissa tempMessagePanel.message.partialError=Osittainen virhe tempMessagePanel.message.success=Onnistui tempMessagePanel.message.undefined=Määrittelemätön tempMessagePanel.message.unknown=Tuntematon tempMessagePanel.message.warn=Varoitus -tempMessagePanel.param=Param: +tempMessagePanel.param=Parametri: tempMessagePanel.times=kertaa -TextDetailsPanel.title=Association Details +TextDetailsPanel.title=Assosiaation yksityiskohdat TextField.universal.placeholder=Syötä arvo ThreeStateBooleanPanel.false=False ThreeStateBooleanPanel.true=True @@ -2961,14 +2961,14 @@ TreeTablePanel.members=Jäsenet TreeTablePanel.menu.addManager=Lisää manageri TreeTablePanel.menu.addMember=Lisää jäsen TreeTablePanel.menu.deleteMember=Poista jäsen -TreeTablePanel.menu.deleteAllMembers=Delete all (focus) members +TreeTablePanel.menu.deleteAllMembers=Poista kaiki (fokus) jäsenet TreeTablePanel.menu.addOrgUnit=Add org. unit TreeTablePanel.menu.addToHierarchy=Add to org. unit TreeTablePanel.menu.delete=Poista TreeTablePanel.menu.disable=Poista käytöstä TreeTablePanel.menu.enable=Ota käyttöön TreeTablePanel.menu.move=Siirrä -TreeTablePanel.menu.recompute=Recompute +TreeTablePanel.menu.recompute=Uudelleenlaske TreeTablePanel.menu.removeFromHierarchy=Remove from org. unit TreeTablePanel.message.warn.deleteTreeObjectConfirm=Warning! {0} has members. Do you really want to delete this org. unit? TreeTablePanel.message.deleteTreeObjectConfirm=Do you really want to delete org. unit "{0}"? @@ -2981,8 +2981,8 @@ TreeTablePanel.recomputeRoot=Recompute root TreeTablePanel.recomputeTask=Recompute users in organization {0} TreeTablePanel.search.scope.one=One level TreeTablePanel.search.scope.subtree=Subtree -TreeTablePanel.fullName.displayName=Fullname/Display name -TreeTablePanel.identifier.description=Identifier/Description +TreeTablePanel.fullName.displayName=Koko nimi/Näyttö nimi +TreeTablePanel.identifier.description=Tunnistaja/Kuvaus TreeTablePanel.warning.childrenExist=Organization which is going to be deleted has members. Do you really want to delete it? Type.AUDIT=Auditoi type.nullValid=Valitse Yksi @@ -3019,10 +3019,10 @@ UserOrgReferenceChoosePanel.type=Omistaja tyyppi UserOrgReferenceChoosePanel.type.user=Käyttäjä UserReportConfigPanel.dateFrom=From UserReportConfigPanel.dateTo=To -UserReportConfigPanel.exportFileType=Export Type +UserReportConfigPanel.exportFileType=Vie Tyyppi UserReportConfigPanel.title.basic=Basic User Report Configuration user.enduser=loppukäyttäjä -user.noAssignments=No assignments +user.noAssignments=Ei toimeksiantoja user.superuser=Superuser user.orgManager=Manageri user.orgMember=Jäsen @@ -3031,28 +3031,28 @@ validFromFetchStrategy.nullValid=Valitse Yksi validToFetchStrategy.nullValid=Valitse Yksi valueAttribute.nullValid=Valitse Yksi WebModelUtils.couldntLoadObject=Couldn't load object. -WebModelUtils.couldntSaveObject=Couldn't save object. -WebModelUtils.couldntSearchObjects=Couldn't search objects. -WebModelUtils.couldntDeleteObject=Couldn't delete object. -WebModelUtils.couldntCountObjects=Couldn't count objects. +WebModelUtils.couldntSaveObject=Ei pystytty tallentamaan objektia. +WebModelUtils.couldntSearchObjects=Ei pystytty poistamaan objekteja. +WebModelUtils.couldntDeleteObject=Ei pystytty poistamaan objektia. +WebModelUtils.couldntCountObjects=Ei pystytty laskea objekteja. web.security.provider.access.denied=Access denied. You don't have permission to access, please contact Identity Manager's administrators. web.security.provider.denied=Permission denied. web.security.provider.disabled=Käyttäjä on poistettu käytöstä web.security.provider.invalid=Invalid username and/or password. -web.security.provider.invalid.link=Invalid link +web.security.provider.invalid.link=voimassaolematon linkki web.security.provider.locked=User is locked, please wait. web.security.provider.password.bad=User doesn't have defined password. web.security.provider.password.encoding=Couldn't authenticate user, reason: couldn't encode password. web.security.provider.unavailable=Currently we are unable to process your request. Kindly try again later. -web.security.ldap.access.denied=Access denied. You don't have permission to access, please contact Identity Manager's administrators. -web.security.ldap.denied=Permission denied. -web.security.ldap.disabled=User is disabled. -web.security.ldap.invalid=Invalid username and/or password. -web.security.ldap.invalid.link=Invalid link +web.security.ldap.access.denied=Yhteys evättiin. Sinulla ei ole oikeutta yhteyteen, ota yhteys identiteetti managerin järjestelmänvalvojaan. +web.security.ldap.denied=Oikeus evättiin. +web.security.ldap.disabled=Käyttäjä on poistettu käytöstä +web.security.ldap.invalid=Väärä käyttäjänimi ja/tai salasana. +web.security.ldap.invalid.link=voimassaolematon linkki web.security.ldap.locked=Käyttäjä on lukittu, ole hyvä ja odota -web.security.ldap.password.bad=User doesn't have defined password. -web.security.ldap.password.encoding=Couldn't authenticate user, reason: couldn't encode password. -web.security.ldap.unavailable=Currently we are unable to process your request. Kindly try again later. +web.security.ldap.password.bad=Käyttäjällä ei ole määritettyä salasanaa. +web.security.ldap.password.encoding=Ei pystytty todentaa käyttäjää, syy: ei pystytty koodata salasanaa. +web.security.ldap.unavailable=Tällä hetkellä emme pysty prosessoimaan pyyntöänne. Yrittäkää uudestaan myöhemmin. WfDeltasPanel.label.deltaIn=Process input: delta(s) to be approved WfDeltasPanel.label.deltaOutListEmpty=(none) WfDeltasPanel.label.deltaOut=Process output: delta(s) resulting from the approval @@ -3061,19 +3061,19 @@ WfHistoryPanel.label.timestamp=Aika WizardHelpDialog.button.ok=Ok, Got It! WizardHelpDialog.label=Get Help With Resource Wizard! Wizard.message.cancel=Resource editing was canceled -Wizard.correctErrorsFirst=Please correct the errors before saving. +Wizard.correctErrorsFirst=Korjaa virheet ennen tallentamista. Wizard.Issues=Issues Wizard.Notes=Huomiot WizardStep.title= -WorkItemsPanel.actors=Actor(s) +WorkItemsPanel.actors=Tekijä(t) WorkItemsPanel.object=Objekti WorkItemsPanel.target=Kohde WorkItemsPanel.name=Nimi WorkItemsPanel.stage=Vaihe WorkItemsPanel.started=Process started WorkItemsPanel.created=Luotu -WorkItemsPanel.deadline=Deadline -WorkItemsPanel.escalationLevel=Esc. level +WorkItemsPanel.deadline=Määräaika +WorkItemsPanel.escalationLevel=eskalointi taso PageAdmin.menu.dashboard=Kojelauta PageAdmin.menu.selfDashboard=Koti PageAdmin.menu.selfService=SELF SERVICE @@ -3097,9 +3097,9 @@ MyRequestsPanel.started = Aloitettu MyRequestsPanel.rejected = Hylätty MyRequestsPanel.approved = Hyväksytty MyRequestsPanel.inProgress = Käynnissä -MyRequestsPanel.unknown = Unknown -MyRequestsPanel.future = Future -MyRequestsPanel.cancelled = Cancelled +MyRequestsPanel.unknown = Tuntematon +MyRequestsPanel.future = Tulevaisuus +MyRequestsPanel.cancelled = Peruttu MyRequestsPanel.name = Nimi PageSelfProfile.title=Muokkaa profiilia PageSelfDashboard.title=Koti @@ -3119,7 +3119,7 @@ PageSelfCredentials.passwordLabel2=Vahvista salasana PageSelfCredentials.accountMidpoint=Identity Manager PageSelfCredentials.resourceMidpoint=Identity Repository PageSelfCredentials.noAccountSelected=Password not changed. No account was selected. -PageSelfCredentials.emptyPasswordFiled=New password fields values are to be specified. +PageSelfCredentials.emptyPasswordFiled=Uudet salasana kenttien arvot täytyy tarkentaa. PageSelfCredentials.incorrectOldPassword=Password not changed. Old password is incorrect. PageSelfCredentials.specifyOldPasswordMessage=Please, specify old password value ChangePasswordPanel.accountsTable.header=Password propagation @@ -3129,7 +3129,7 @@ ChangePasswordPanel.enabled=Tili otettu käyttöön ChangePasswordPanel.legendMessage.selected= - Password will be changed ChangePasswordPanel.legendMessage.propagated= - Automatic password propagation (based on policies defined in resources definitions) ChangePasswordPanel.legendMessage.deselected= - Password will not be changed -ChangePasswordPanel.legendMessage.no.password.capability= - Password capability is not supported by resource +ChangePasswordPanel.legendMessage.no.password.capability= - Resurssi ei tue salasana kykyä ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls how the password change will be propagated to each individual system. The first line defines whether the password will be changed in the Identity Manager itself. Following lines represent each system for which the password can be changed. The password propagation is controlled by the icons:

  • Password will be changed. Password for this system will be changed to the value specified in the password dialog above.
  • Automatic password propagation. The password might be changed. Whether the password is changed or not depends on the policies set up by identity administrator. This usually means that the password will be changed if it makes sense for the current situation and settings. This is the reasonable default choice.
  • Password will not be changed for this system.
  • Password capability is not supported for this system. As the result, password will not be changed for this system.

You can adjust the password propagation settings by clicking on the icons and thus fine-tune how the password change is propagated to each individual system.

ChangePasswordPanel.helpPopupTitle=Password propagation help PageBase.button.tooltip.clearSearch=Tyhjennä @@ -3139,19 +3139,19 @@ PageSelfCredentials.couldntResolve=Couldn't resolve resource. roleMemberPanel.type=Tyyppi: roleMemberPanel.tenant=Tenant: roleMemberPanel.project=Org/Project: -roleMemberPanel.indirectMembers=Include indirect members -roleMemberPanel.allRelations=Show all relations +roleMemberPanel.indirectMembers=Laske mukaan epäsuorat jäsenet +roleMemberPanel.allRelations=Näytä kaikki yhteydet roleMemberPanel.menu.createOwner=Luo omistaja roleMemberPanel.menu.assignOwners=Määrää omistajat -roleMemberPanel.menu.createApprover=Create approver -roleMemberPanel.menu.assignApprovers=Assign approvers -roleMemberPanel.relation=Relation +roleMemberPanel.menu.createApprover=Luo hyväksyjä +roleMemberPanel.menu.assignApprovers=Osoita hyväksyjät +roleMemberPanel.relation=Yhteys SearchPanel.more=Lisää... SearchPanel.add=Lisää SearchPanel.close=Sulje SearchPanel.properties=Ominaisuudet -SearchPanel.fullText=Full text -SearchPanel.fullTextSearch=Full text search +SearchPanel.fullText=Koko teksti +SearchPanel.fullTextSearch=Koko teksti haku SearchItemPanel.all=Kaikki SearchItemPanel.update=Päivitä SearchItemPanel.close=Sulje @@ -3186,107 +3186,107 @@ operation.com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta=Exec operation.com.evolveum.midpoint.task.api.Task.listSubtasksDeeply=List subtasks deeply (Task) operation.com.evolveum.midpoint.task.api.Task.listSubtasksRaw=List subtasks raw (Task) operation.com.evolveum.midpoint.web.page.self.PageSelfCredentials.savePassword=Change password (GUI) -operation.com.evolveum.midpoint.web.page.self.PageRequestRole.save=Changes were successfully saved -operation.com.evolveum.midpoint.web.page.self.PageRequestRole.taskCreated=The process of assigning a role is waiting for the approval. +operation.com.evolveum.midpoint.web.page.self.PageRequestRole.save=muutokset tallentuivat onnistuneesti +operation.com.evolveum.midpoint.web.page.self.PageRequestRole.taskCreated=Roolin asettamis prosessi odottaa hyväksyntää. PageError.button.home=Koti PageResource.tab.connector=Liitin PageResource.tab.connector.connectorLabel=Liitin -PageResource.tab.connector.connectorPoolLabel=Connector pool +PageResource.tab.connector.connectorPoolLabel=Liitin varanto PageResource.tab.content.account=Tilit -PageResource.tab.content.entitlement=Entitlements +PageResource.tab.content.entitlement=Oikeutukset PageResource.tab.content.generic=Yleiset -PageResource.tab.content.others=Uncategorized -PageResource.tab.content.tasks=Defined Tasks -ResourceContentTabPanel.searchType.repository=Repository +PageResource.tab.content.others=Kategorisoimattomat +PageResource.tab.content.tasks=Määritetyt tehtävät +ResourceContentTabPanel.searchType.repository=Säilö ResourceContentTabPanel.searchType.resource=Resurssi -ResourceContentTabPanel.searchType=Search In: -PagePreviewChanges.primaryChangesOne=Primary changes: {0} object -PagePreviewChanges.primaryChangesMore=Primary changes: {0} objects -PagePreviewChanges.secondaryChangesOne=Secondary changes: {0} object -PagePreviewChanges.secondaryChangesMore=Secondary changes: {0} objects -PagePreviewChanges.policyViolationMessages=Policy violation messages -PagePreviewChanges.approvalsRequired=Approvals required +ResourceContentTabPanel.searchType=Etsi paikasta: +PagePreviewChanges.primaryChangesOne=Ensisijaiset muutokset: {0} objekti +PagePreviewChanges.primaryChangesMore=Ensisijaiset muutokset: {0} objektia +PagePreviewChanges.secondaryChangesOne=Toissijaiset muutokset: {0} objekti +PagePreviewChanges.secondaryChangesMore=Toissijaiset muutokset: {0} objektia +PagePreviewChanges.policyViolationMessages=Linjauksen rikkomus viestit +PagePreviewChanges.approvalsRequired=Hyväksymisiä tarvitaan PagePreviewChanges.button.continueEditing=Jatka muokkaamista PagePreviewChanges.button.save=Tallenna ScenePanel.object={0} objektit ScenePanel.objects={0} objektit -ScenePanel.item=Item +ScenePanel.item=Alkio ScenePanel.oldValue=Vanha arvo ScenePanel.newValue=Uusi arvo ScenePanel.value=Arvo SceneItemLinePanel.removedValue=Poistettu arvo SceneItemLinePanel.addedValue=Lisätty arvo -SceneItemLinePanel.unchangedValue=Unchanged value +SceneItemLinePanel.unchangedValue=Muuttamaton arvo SceneItemLinePanel.unknownLabel=(tuntematon) -operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.changeOwner=Change owner (GUI) +operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.changeOwner=Vaihda omistajaa (GUI) TaskSummaryPanel.progressWithTotalKnown=Progress: {0} out of {1} -TaskSummaryPanel.progressWithTotalUnknown=Progress: {0} -TaskSummaryPanel.progressIfSuspended=(suspended) +TaskSummaryPanel.progressWithTotalUnknown=Edistyminen: {0} +TaskSummaryPanel.progressIfSuspended=(keskeytetty) TaskSummaryPanel.progressIfWaiting=(odottaa) TaskSummaryPanel.progressIfClosed=(suljettu) -TaskSummaryPanel.progressIfStalled=(stalled since {0}) -TaskSummaryPanel.lastProcessed=Last object processed: {0} -ResourceContentResourcePanel.showExisting=Show existing +TaskSummaryPanel.progressIfStalled=(jumissa sitten {0})½ +TaskSummaryPanel.lastProcessed=Viimeisin prosessoitu objekti: {0} +ResourceContentResourcePanel.showExisting=Näytä olemassaoleva ResourceContentResourcePanel.newTask=Luo uusi -SearchPanel.advanced=Advanced +SearchPanel.advanced=Edistynyt SearchPanel.basic=Perus SearchPanel.search=Etsi -SearchPanel.debug=Debug -ResourceContentResourcePanel.realSearch=(In fact) Searching by: -typedAssignablePanel.selectedOrgs=Orgs: +SearchPanel.debug=Virheen tarkistus +ResourceContentResourcePanel.realSearch=(tosiassa) Haetaan nimellä: +typedAssignablePanel.selectedOrgs=Organisaatiot: typedAssignablePanel.selectedResources=Resurssit: typedAssignablePanel.selectedRoles=Roolit: typedAssignablePanel.selectedServices=Palvelut: -SearchPanel.insertFilterXml=Insert filter xml (SearchFilterType) +SearchPanel.insertFilterXml=Syötä suodatus xml (HaeSuodatusTyyppi) autoRefreshPanel.refreshNow=Päivitä nyt -autoRefreshPanel.resumeRefreshing=Resume refreshing -autoRefreshPanel.pauseRefreshing=Pause refreshing -autoRefreshPanel.refreshingEach=Refreshing each {0} sec -autoRefreshPanel.noRefreshing=(no refreshing) +autoRefreshPanel.resumeRefreshing=Jatka päivitystä +autoRefreshPanel.pauseRefreshing=Keskeytä päivitys +autoRefreshPanel.refreshingEach=Päivitetään joka {0} sek +autoRefreshPanel.noRefreshing=(ei päivittämistä) PageAdmin.menu.top.services=Palvelut PageAdmin.menu.top.services.list=Listaa palvelut PageAdmin.menu.top.services.new=Uusi palvelu PageAdmin.menu.top.services.edit=Muokkaa palvelua -taskShowAdvancedFeaturesPanel.label=Show advanced features -taskWfParentPanel.changesNotRequiringApproval=Changes not requiring approval +taskShowAdvancedFeaturesPanel.label=Näytä edistyneet toiminnot +taskWfParentPanel.changesNotRequiringApproval=Hyväksyntää tarvitsemattomat muutokset taskOtherChangesPanel.label.state=Tila: -taskOtherChangesPanel.state.FINAL=Changes have been applied (successfully or not) -taskOtherChangesPanel.state.PRIMARY=Changes are waiting to be applied -taskOtherChangesPanel.state.SECONDARY=Changes are waiting to be applied -taskWfChildPanel.showParent=Show request in a context of the whole operation. -taskWfChildPanel.showNextStages=Show following stages -taskWfChildPanel.showWholeProcess=Show the whole process -TaskSummaryPanel.requestedBy=Requested by: {0} -TaskSummaryPanel.requestedByWithFullName=Requested by: {0} ({1}) -TaskSummaryPanel.requestedOn=Requested on: {0} +taskOtherChangesPanel.state.FINAL=Muutokset otettu käyttöön (onnistuneesti tai ei) +taskOtherChangesPanel.state.PRIMARY=Muutokset odottavat käyttöönottoa +taskOtherChangesPanel.state.SECONDARY=Muutokset odottavat käyttöönottoa +taskWfChildPanel.showParent=Näytä pyyntö asiayhteydessä koko operaatioon. +taskWfChildPanel.showNextStages=Näytä seuraavat vaiheet +taskWfChildPanel.showWholeProcess=Näytä koko prosessi +TaskSummaryPanel.requestedBy=Pyytäjä: {0} +TaskSummaryPanel.requestedByWithFullName=Pyytäjä: {0} ({1}) +TaskSummaryPanel.requestedOn=Pyydetty: {0} TaskSummaryPanel.requestedByAndOn=Requested by {0} on {1} -TaskSummaryPanel.stage=Stage: {0} +TaskSummaryPanel.stage=Vaihe: {0} TaskSummaryPanel.rejected=Hylätty TaskSummaryPanel.approved=Hyväksytty -operation.com.evolveum.midpoint.web.page.admin.resources.PageResource.refreshSchema=Refresh schema (GUI) -TaskDto.changesApplied=Changes applied (successfully or not) -TaskDto.changesBeingApplied=Changes being applied -TaskDto.changesWaitingToBeApplied=Changes waiting to be applied -TaskDto.changesWaitingToBeApproved=Changes waiting to be approved -TaskDto.changesRejected=Changes rejected +operation.com.evolveum.midpoint.web.page.admin.resources.PageResource.refreshSchema=Päivitä kaavio (GUI) +TaskDto.changesApplied=Käyttöön otetut muutokset (onnistuneesti tai ei) +TaskDto.changesBeingApplied=muutokset joita otetaan käyttöön +TaskDto.changesWaitingToBeApplied=Käyttöönottoa odottavat muutokset +TaskDto.changesWaitingToBeApproved=Hyväksyntää odottavat muutokset +TaskDto.changesRejected=Muutokset hylätty TaskDto.changesCanceled=Muutokset peruttu PageServices.title=Palvelulista -PageServices.message.deleteServicesConfirm=Do you really want to delete selected {0} service(s)? -PageServices.message.confirmationMessageForMultipleObject=Do you really want to {0} selected {1} service(s)? -PageServices.message.confirmationMessageForSingleObject=Do you really want to {0} service '{1}'? +PageServices.message.deleteServicesConfirm=haluatko varmasti poistaa valitut {0} palvelut? +PageServices.message.confirmationMessageForMultipleObject=haluatko varmasti {0} valitut {1} palvelu(t)? +PageServices.message.confirmationMessageForSingleObject=Haluatko varmasti {0} palvelun '{1}'? PageServices.message.nothingSelected=Ei palveluita valittuna. PageServices.message.buttonDelete=Poista -LiveSyncHandlerPanel.deleteToken=Delete token -ScannerHandlerPanel.lastScanTimestamp=Last scan timestamp +LiveSyncHandlerPanel.deleteToken=Poista merkki +ScannerHandlerPanel.lastScanTimestamp=Viimeisen skannauksen aikaleima ScriptExecutionHandlerPanel.script=Scripti QueryBasedHandlerPanel.objectType=Objekti tyyppi QueryBasedHandlerPanel.query=Kysely -DeleteHandlerPanel.executeInRawMode=Execute in raw mode +DeleteHandlerPanel.executeInRawMode=Suorita raw tilassa ExecuteChangesHandlerPanel.change=Vaihda ExecuteChangesHandlerPanel.options=Vaihtoehdot -ReportCreateHandlerPanel.downloadCreatedReport=Download created report +ReportCreateHandlerPanel.downloadCreatedReport=Imuroi luotu raportti ReportCreateHandlerPanel.reportParameters=Raportti parametrit -OperationResultPanel.showTask=(show task) +OperationResultPanel.showTask=(näytä tehtävä) PageResources.inlineMenuItem.test=Testaa yhteys PageRequestRole.title=Pyydä roolia MainObjectListPanel.refresh=Päivitä @@ -3296,31 +3296,31 @@ MainObjectListPanel.export=Vie MainObjectListPanel.exportFileName=vie TreeTablePanel.menu.createMember=Luo jäsen TreeTablePanel.menu.createManager=Luo manageri -TreeTablePanel.menu.addMembers=Assign members -TreeTablePanel.menu.addManagers=Assign managers -TreeTablePanel.menu.unassignMembersSelected=Unassign selected members -TreeTablePanel.menu.unassignMembersAll=Unassign all members -TreeTablePanel.menu.removeManagersAll=Unassign all managers -TreeTablePanel.menu.recomputeMembersSelected=Recompute selected members -TreeTablePanel.menu.recomputeMembersAll=Recompute all members -TreeTablePanel.menu.recomputeMembersAllDirect=Recompute direct members -TreeTablePanel.menu.recomputeManagersAll=Recompute all managers +TreeTablePanel.menu.addMembers=Osoita jäsenet +TreeTablePanel.menu.addManagers=Osoita managerit +TreeTablePanel.menu.unassignMembersSelected=Poista valittujen jäsenten osoitus +TreeTablePanel.menu.unassignMembersAll=Poista kaikkien jäsenten osoitus +TreeTablePanel.menu.removeManagersAll=Poista kaikkien managerien osoitus +TreeTablePanel.menu.recomputeMembersSelected=Laske uudelleen valitut jäsenet +TreeTablePanel.menu.recomputeMembersAll=Laske uudelleen kaikki jäsenet +TreeTablePanel.menu.recomputeMembersAllDirect=Laske uudelleen suorat jäsenet +TreeTablePanel.menu.recomputeManagersAll=Laske uudelleen kaikki managerit TreeTablePanel.menu.deleteManagersAll=Poista kaikki managerit TreeTablePanel.menu.deleteManager.confirm=Are you sure you want to delete selected manager from system? This change is permanent. TreeTablePanel.menu.deleteManagersAll.confirm=All defined managers will be permanently removed from system. Are you sure to perform this action? TreeTablePanel.move=Siirrä TreeTablePanel.makeRoot=Tee juuri TreeTablePanel.delete=Poista -TreeTablePanel.recompute=Recompute +TreeTablePanel.recompute=Uudelleenlaske TreeTablePanel.edit=Muokkaa -TreeTablePanel.viewDetails=View details -TreeTablePanel.createChild=Create child -WorkItemSummaryPanel.allocated=Allocated -WorkItemSummaryPanel.notAllocated=Not allocated +TreeTablePanel.viewDetails=Katso yksityiskohdat +TreeTablePanel.createChild=Luo alijäsen +WorkItemSummaryPanel.allocated=Kohdennettu +WorkItemSummaryPanel.notAllocated=Ei kohdennettu WorkItemPanel.showRequest=Siirrä vasemmalle DefinitionStagesPanel.confirmDelete=Vahvista poista -DefinitionStagesPanel.confirmDeleteText=Do you really want to delete stage '{0}'? -PageCertDefinition.outcomeStrategyHelpLabel=Please see also +DefinitionStagesPanel.confirmDeleteText=Haluatko varmasti poistaa vaiheen '{0}'? +PageCertDefinition.outcomeStrategyHelpLabel=Katso myös PageCertDefinition.outcomeStrategyHelpLink=tämä dokumentti PageCertDefinition.outcomeStrategyHelp=How is the overall outcome for a case determined, based on outcomes in individual stages? Note: 'Stop review on:' field shows outcomes that prevent a case from being advanced to the next stage. Usually you need not change the default value. If necessary, you could do that through the XML configuration. PageCertDefinition.campaignLastStartedHelp=When was last campaign created according to this definition started? @@ -3347,7 +3347,7 @@ StageDefinitionPanel.configurationHelpLabel=For more information about configuri StageDefinitionPanel.configurationHelpLink=tämä dokumentti NameStep.configurationWillBeLost=The selected connector configuration schema is different from the current one. Configuration properties will be lost if you will proceed. resultsHandlerConfiguration=Results handlers -enableFilteredResultsHandler=Enable additional filtering of results +enableFilteredResultsHandler=Salli tulosten lisä suodatus enableFilteredResultsHandlerHelp=This handler filters results retrieved from the resource by the connector, at the level of connector framework. It is used by connector implementations that do not provide complete filtering by themselves. Enabling this handler has some drawbacks e.g. in the area of paging. So it is to be used only if really necessary. If not sure, it is advisable to use filtering in validation mode. Default value for current version of ConnId: enabled. filteredResultsHandlerInValidationMode=Perform filtering in validation mode only filteredResultsHandlerInValidationModeHelp=Switches the result filtering into validation mode: all data produced by the connector are checked by the connector framework to see if they are properly filtered. In case of improper filtering, an exception is raised. This mode is to be used for connectors that are expected to provide complete filtering, but their functionality in this area has to be verified. Default value for current version of ConnId: disabled. @@ -3358,64 +3358,64 @@ enableNormalizingResultsHandlerHelp=This handler normalizes each attribute that enableAttributesToGetSearchResultsHandler=Enable 'attributes to get' results handler enableAttributesToGetSearchResultsHandlerHelp=This handler is used to implement 'attributes to get' option. It is advisable to keep the default setting of 'enabled' (in current version of ConnId). PageResourceWizard.autoSaveWarning=The resource is automatically saved on each transition between wizard steps. -PageResourceWizard.readOnlyNote=Resource is in read-only mode. -PageResourceWizard.readOnlySwitch=Click here to enable editing. -operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.recompute=Recompute (GUI) +PageResourceWizard.readOnlyNote=Resurssi on vain luku tilassa. +PageResourceWizard.readOnlySwitch=Paina tästä salliaksesi muokkauksen. +operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.recompute=Uudelleenlaske (GUI) Button.ok=OK -Button.assign=Assign +Button.assign=Aseta Note=Huomaa Warning=Varoitus ProfilingConfigPanel.profilingMustBeEnabled=In order to use profiling, the 'profilingEnabled' system configuration parameter (in config.xml file) must be set to 'true'. OperationResultPanel.result=Tulos -ResourceTasksPanel.definedTasks=Defined tasks -ResourceTasksPanel.noTasksSelected=No tasks were selected. +ResourceTasksPanel.definedTasks=Määritetyt tehtävät +ResourceTasksPanel.noTasksSelected=Tehtäviä ei valittuina. ObjectBrowserPanel.chooseObject=Valitse objekti -TypedAssignablePanel.selectObjects=Select object(s) -OrgTreeAssignablePanel.selectOrg=Select organization(s) +TypedAssignablePanel.selectObjects=Valitse objekti(t) +OrgTreeAssignablePanel.selectOrg=Valitse organisaatio(t) ChooseFocusTypeDialogPanel.chooseType=Valitse tyyppi -TestConnectionResultPanel.testConnection.result=Test connection result(s) -TestConnectionResultPanel.message=Test is running, please, wait for results. -operation.com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration.updateSystemConfiguration=Update system configuration (GUI) -peration.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Save task (GUI) +TestConnectionResultPanel.testConnection.result=Testaa yhteys tulokset +TestConnectionResultPanel.message=Testia suoritetaan, odota tuloksia, kiitos. +operation.com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration.updateSystemConfiguration=Päivitä järjestelmän konfiguraatio (GUI) +peration.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Tallenna tehtävä (Gui) operation.com.evolveum.midpoint.notifications.impl.notifiers.GeneralNotifier.processEvent=Process event (Notification) operation.com.evolveum.midpoint.model.impl.lens.ChangeExecutor.execute.focus.OrgType=Execute OrgType (Model) TreeTablePanel.menu.deleteMember.confirm=All selected members (users, organizations, services, roles) will be permanently deleted from system. Are you sure to perform this action? TreeTablePanel.menu.deleteAllMembers.confirm=All focus members (users, organizations, services, roles) will be permanently deleted from system. Are you sure to perform this action? -PageTasksCertScheduling.title=Certification scheduling +PageTasksCertScheduling.title=Sertifikoinnin ajastus PageResourceVisualization.title=Visualization of mappings for {0} PageResourceVisualization.dotMessage=Rendering of DOT graph could not be carried out. Please check the error message below, and make sure that: PageResourceVisualization.dot1=DOT rendering software is installed at your server. The recommended one is Graphviz PageResourceVisualization.dot2=The path to DOT rendering executable is correctly set in you config.xml file. -PageResourceVisualization.moreInformation=For more information, please see -PageResourceVisualization.moreInformationLink=this article -PageResourceVisualization.errorMessage=Error message: -PageResourceVisualization.seeOnline=You can also try to use an online DOT renderer, for example +PageResourceVisualization.moreInformation=Lisätietoja varten, katso +PageResourceVisualization.moreInformationLink=Tämä artikkeli +PageResourceVisualization.errorMessage=virhe viesti: +PageResourceVisualization.seeOnline=esimerkiksi voit myös kokeilla käyttää verkko DOT renderoijaa PageResourceVisualization.seeOnlineLink=webgraphviz.com -PageResourceVisualization.copyInstruction=Simply paste the following DOT code into it. -OrgMemberPanel.editUserTitle=Edit/View details -OrgMemberPanel.unlinkTitle=Unlink manager +PageResourceVisualization.copyInstruction=Liitä DOT koodi siihen +OrgMemberPanel.editUserTitle=Muokkaa/Katso yksityiskohtia +OrgMemberPanel.unlinkTitle=Poista managerin linkitys OrgMemberPanel.deleteTitle=Poista manageri PagePreviewChanges.title=Esikatsele muutoksia operation.com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails.previewChanges=Esikatsele muutoksia operation.com.evolveum.midpoint.task.api.Task.run=Suorita tehtävä operation.com.evolveum.midpoint.web.util.TaskOperationUtils.runNowTask=Suorita tehtävä -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinition.saveDefinition=Save definition +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinition.saveDefinition=Tallena kuvaus operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.advanceLifecycle=Kampanja tila operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.openNextStage=Avaa seuraava vaihe operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.closeStage=Sulje vaihe operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.closeCampaign=Sulje kampanja -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.startRemediation=Start remediation +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertCampaign.startRemediation=Aloita oikaisu operation.com.evolveum.midpoint.certification.api.CertificationManager.openNextStage=Avaa seuraava vaihe operation.com.evolveum.midpoint.certification.api.CertificationManager.closeCampaign=Sulje kampanja operation.com.evolveum.midpoint.certification.api.CertificationManager.createCampaign=Luo kampanja -operation.com.evolveum.midpoint.certification.api.CertificationManager.closeCurrentStage=Close current stage -operation.com.evolveum.midpoint.certification.api.CertificationManager.recordDecision=Record decision -operation.com.evolveum.midpoint.certification.api.CertificationManager.searchDecisionsToReview=Search decisions to review -operation.com.evolveum.midpoint.certification.api.CertificationManager.getCampaignStatistics=Get campaign statistics +operation.com.evolveum.midpoint.certification.api.CertificationManager.closeCurrentStage=Sulje tämänhetkinen vaihe +operation.com.evolveum.midpoint.certification.api.CertificationManager.recordDecision=taltioi valinta +operation.com.evolveum.midpoint.certification.api.CertificationManager.searchDecisionsToReview=Hae esikatseltavia valintoja +operation.com.evolveum.midpoint.certification.api.CertificationManager.getCampaignStatistics=Hanki kampajan tilastot -operation.com.evolveum.midpoint.repo.api.RepositoryService.searchContainers=Search for containers -operation.com.evolveum.midpoint.repo.api.RepositoryService.searchObjectsIterative=Search for objects (iterative) +operation.com.evolveum.midpoint.repo.api.RepositoryService.searchContainers=Hae kontteja +operation.com.evolveum.midpoint.repo.api.RepositoryService.searchObjectsIterative=Hae objekteja (kertaava) operation.PageCertCampaigns.startCampaign=Aloita kampanja operation.PageCertCampaigns.closeStage=Sulje vaihe @@ -3423,21 +3423,21 @@ operation.PageCertCampaigns.openNextStage=Avaa seuraava vaihe operation.PageCertCampaigns.startRemediation=Aloita oikaisu operation.PageCertCampaigns.closeCampaign=Sulje kampanja -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDecisions.recordAction=Record action -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDecisions.recordActionSelected=Record selected actions +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDecisions.recordAction=Taltioi toiminta +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDecisions.recordActionSelected=Taltioi valitut toiminnat -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinition.loadDefinition=Load definition +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinition.loadDefinition=Lataa kuvaus -operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions.createCampaign=Create campaign +operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions.createCampaign=Luo kampanja operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions.deleteDefinition=Poista kuvaus -SceneDto.unnamed=(unnamed) -LockoutStatusPanel.undoButtonLabel=Undo -LockoutStatusPanel.unlockButtonLabel=Set to "Normal" -LockoutStatusPanel.changesSaving=(will be applied after Save button click) -operation.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Save task (GUI) -operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.unlockUsers=Unlock user -operation.com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstances.stopProcessInstance=Stop process instance +SceneDto.unnamed=(nimeämätön) +LockoutStatusPanel.undoButtonLabel=Kumoa +LockoutStatusPanel.unlockButtonLabel=aseta "Normaali":in +LockoutStatusPanel.changesSaving=(otetaan käyttöön Tallenna napin painalluksen jälkeen) +operation.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Tallenna tehtävä (Gui) +operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.unlockUsers=Poista lukitus käyttäjästä +operation.com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstances.stopProcessInstance=Pysäytä prosessitapahtuma #values for icon title on Users list page. The name of the property key #is generated in the following way: @@ -3445,7 +3445,7 @@ operation.com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstances.sto ColumnUtils.getUserIconColumn.createTitleModel.normal=normaali ColumnUtils.getUserIconColumn.createTitleModel.disabled=poistettu käytöstä ColumnUtils.getUserIconColumn.createTitleModel.archived=arkistoitu -ColumnUtils.getUserIconColumn.createTitleModel.privileged=privileged +ColumnUtils.getUserIconColumn.createTitleModel.privileged=etuoikeutettu ColumnUtils.getUserIconColumn.createTitleModel.end-user=loppukäyttäjä ColumnUtils.getUserIconColumn.createTitleModel.manager=manageri ColumnUtils.getUserIconColumn.createTitleModel.broken=rikki @@ -3455,242 +3455,243 @@ FocusListInlineMenuHelper.menu.delete=Poista FocusListInlineMenuHelper.menu.disable=Poista käytöstä FocusListInlineMenuHelper.menu.enable=Ota käyttöön FocusListInlineMenuHelper.menu.reconcile=Sovita -FocusListInlineMenuHelper.message.deleteObjectConfirm=Do you really want to delete selected {0} object(s)? -FocusListInlineMenuHelper.message.deleteObjectConfirmSingle=Do you really want to delete object '{0}'? -FocusListInlineMenuHelper.message.nothingSelected=No object has been selected. -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.enableObjects=Enable roles (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.enableObject=Enable role (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.disableObjects=Disable roles (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.disableObject=Disable role (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.reconcileObjects=Reconcile roles (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.reconcileObject=Reconcile role (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteObjects=Delete roles (GUI) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteObject=Delete role (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.enableObjects=Enable services (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.enableObject=Enable service (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.disableObjects=Disable services (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.disableObject=Disable service (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.reconcileObjects=Reconcile services (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.reconcileObject=Reconcile service (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObjects=Delete services (GUI) -operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObject=Delete service (GUI) -operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.importObject=Import object (GUI) -PageConnectorHosts.title=Connector hosts -operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.checkQuery=Check query (GUI) -operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.translateQuery=Translate query (GUI) -operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.executeQuery=Execute query (GUI) -operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.executeRepositoryQuery=Execute repository query (Model diagnostic service) -operation.com.evolveum.midpoint.repo.api.RepositoryService.executeQueryDiagnostics=Execute query diagnostics (Repository) -PageEvaluateMapping.title=Evaluate mapping -PageEvaluateMapping.button.evaluateMapping=Evaluate mapping -PageEvaluateMapping.message.emptyString=Please provide a mapping to execute. +FocusListInlineMenuHelper.message.deleteObjectConfirm=Oletko varma että haluat poistaa valitut {0} objektit? +FocusListInlineMenuHelper.message.deleteObjectConfirmSingle=Haluatko varmasti poistaa objektin "{0}"? +FocusListInlineMenuHelper.message.nothingSelected=Objekteja ei ole valittu. +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.enableObjects=Ota käyttöön roolit (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.enableObject=Ota käyttöön rooli (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.disableObjects=Poista käytöstä roolit (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.disableObject=Poista käytöstä rooli (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.reconcileObjects=Täsmäytä roolit (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.reconcileObject=Täsmäytä rooli (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteObjects=Poista roolit (GUI) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteObject=Poista rooli (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.enableObjects=Ota käyttöön palvelut (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.enableObject=Ota käyttöön palvelu (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.disableObjects=Poista käytöstä palvelut (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.disableObject=Poista käytöstä palvelu (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.reconcileObjects=Täsmäytä palvelut (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.reconcileObject=Täsmäytä palvelu (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObjects=Poista palvelut (GUI) +operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObject=Poista palvelu (GUI) +operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.importObject=Tuo objekti (GUI) +PageConnectorHosts.title=Littimen isännät +operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.checkQuery=Tarkista kysely (GUI) +operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.translateQuery=Käännä kysely (GUI) +operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.executeQuery=Suorita kysely (GUI) +operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.executeRepositoryQuery=Suorita säilö kysely (Diagnostinen palvelu malli) +operation.com.evolveum.midpoint.repo.api.RepositoryService.executeQueryDiagnostics=Suority kyselyn diagnostiikka (Säilö) +PageEvaluateMapping.title=Arvioi kartoitus +PageEvaluateMapping.button.evaluateMapping=Arvioi kartoitus +PageEvaluateMapping.message.emptyString=Syötä suoritettava kartoitus PageEvaluateMapping.result=Tulos -PageEvaluateMapping.mapping=Mapping +PageEvaluateMapping.mapping=Kartoitus PageEvaluateMapping.request=Pyyntö -PageEvaluateMapping.chooseSample=Or use a sample: -PageEvaluateMapping.sample.FullName_NoDelta=Full name mapping (no change) -PageEvaluateMapping.sample.FullName_Delta=Full name mapping (change in givenName) -PageEvaluateMapping.sample.FullName_Delta_Ref=Full name mapping (change in givenName); source from repository -PageEvaluateMapping.sample.FullName_Delta_Cond=Full name mapping with condition (change in givenName) -PageEvaluateMapping.sample.OrgName=Deriving attribute from parent org's name -PageAssignmentShoppingKart.title=Assignment request -PageAssignmentShoppingKart.roleCatalogIsNotConfigured=Role catalog is not configured in the system configuration xml -AssignmentConflictPanel.existingAssignmentLabelMessage=(which user already has) -AssignmentConflictPanel.addedAssignmentLabelMessage=(which is added to shopping cart) -AssignmentConflictPanel.conflictMessage=conflicts with +PageEvaluateMapping.chooseSample=Tai käytä näytettä: +PageEvaluateMapping.sample.FullName_NoDelta=Koko nimen kartoitus (ei muutosta) +PageEvaluateMapping.sample.FullName_Delta=Koko nimen kartoitus (muuttunut etuNimi) +PageEvaluateMapping.sample.FullName_Delta_Ref=Koko nimen kartoitus (muuttunut etuNimi); Lähteenä säilö +PageEvaluateMapping.sample.FullName_Delta_Cond=Koko nimen kartoitus ehdolla (muuttunut etuNimi) +PageEvaluateMapping.sample.OrgName=Päätellään atribuutti yläluokan organisaation nimestä +PageAssignmentShoppingKart.title=Toimeksianto pyyntö +PageAssignmentShoppingKart.roleCatalogIsNotConfigured=Rooli katalogia ei ole configuroitu järjestelmän konfiguraatio xml:ään +AssignmentConflictPanel.existingAssignmentLabelMessage=(mikä on jo käyttäjällä) +AssignmentConflictPanel.addedAssignmentLabelMessage=(joka lisätään ostoskoriin) +AssignmentConflictPanel.conflictMessage=ristiriidassa AssignmentConflictPanel.removeButton=Poista -AssignmentConflictPanel.unselectButton=Unselect -AssignmentConflictPanel.undoAction=Undo -PageAssignmentConflicts.title=Assignments conflicts +AssignmentConflictPanel.unselectButton=valinnan poisto +AssignmentConflictPanel.undoAction=Kumoa +PageAssignmentConflicts.title=Toimeksiantojen ristiriidat PageAssignmentConflicts.back=Takaisin -PageAssignmentConflicts.submit=Submit -AssignmentCatalogPanel.selectTargetUser=Select target user -AssignmentCatalogPanel.selectAssignmentsUserOwner=Select assignments user owner -AssignmentCatalogPanel.requestForMe=Target user: me -AssignmentCatalogPanel.requestFor=Target user: -AssignmentCatalogPanel.requestForMultiple={0} users selected -AssignmentCatalogPanel.assignmentsOwner={0}'s assignments -MultiButtonPanel.plusIconTitle=Add item to shopping cart -MultiButtonPanel.assignmentDetailsPopupTitle=Assignment details +PageAssignmentConflicts.submit=Kirjaa +AssignmentCatalogPanel.selectTargetUser=Valitse kohteen käyttäjä +AssignmentCatalogPanel.selectAssignmentsUserOwner=Valitse toimeksiantojen käyttäjän omistaja +AssignmentCatalogPanel.requestForMe=Kohteen käyttäjä: minä +AssignmentCatalogPanel.requestFor=Kohteen käyttäjä: +AssignmentCatalogPanel.requestForMultiple={0} käyttäjää valittuina +AssignmentCatalogPanel.assignmentsOwner={0}n toimeksiannot +MultiButtonPanel.plusIconTitle=Lisää tavara ostoskoriin +MultiButtonPanel.assignmentDetailsPopupTitle=Toimeksiannon yksityiskohdat MultiButtonPanel.detailsLink=Ominaisuudet MultiButtonPanel.addToCartLink=Lisää koriin -MultiButtonPanel.alreadyAssignedIconTitle=Assigned as -PageAssignmentDetails.title=Assignment details +MultiButtonPanel.alreadyAssignedIconTitle=Asetettu +PageAssignmentDetails.title=Toimeksiannon yksityiskohdat PageAssignmentDetails.backButton=Takaisin PageAssignmentDetails.addToCartButton=Lisää koriin -PageAssignmentsList.submitButton=Submit -PageAssignmentsList.resolveConflicts=Resolve conflicts +PageAssignmentsList.submitButton=Kirjaa +PageAssignmentsList.resolveConflicts=Ratkaise ristiriidat PageAssignmentsList.commentHere=Kommentoi tähän... -PageAssignmentsList.requestComment=Request comment (optional) -AssignmentShoppingCartPanel.treeTitle=Role catalog -AssignmentViewType.ROLE_CATALOG_VIEW=Role catalog view -AssignmentViewType.ROLE_TYPE=All roles view -AssignmentViewType.ORG_TYPE=All organizations view -AssignmentViewType.SERVICE_TYPE=All services view -AssignmentViewType.USER_TYPE=User's assignments +PageAssignmentsList.requestComment=Pyydä kommentti (valinnainen) +AssignmentShoppingCartPanel.treeTitle=Rooli katalogi +AssignmentViewType.ROLE_CATALOG_VIEW=Rooli katalogin katselu +AssignmentViewType.ROLE_TYPE=Kaikkien roolien katselu +AssignmentViewType.ORG_TYPE=Kaikkien organisaatioiden katselu +AssignmentViewType.SERVICE_TYPE=Kaikken palvelujen katselu +AssignmentViewType.USER_TYPE=Käyttäjän toimeksiannot PageAssignmentsList.requestButton = Pyyntö -operation.com.evolveum.midpoint.web.page.self.PageAssignmentsList.requestAssignments=Request assignment -com.evolveum.midpoint.web.page.self.PageAssignmentsList.requestAssignments=Request assignments -PageAssignmentsList.title=New assignments list -PageAuditLogViewer.title=Audit Log Viewer -PageAuditLogViewer.menuName=Audit Log Viewer +operation.com.evolveum.midpoint.web.page.self.PageAssignmentsList.requestAssignments=Pyydä toimeksiantoa +com.evolveum.midpoint.web.page.self.PageAssignmentsList.requestAssignments=Pyydä toimeksiantoja +PageAssignmentsList.title=Uudet toimeksiannot lista +PageAuditLogViewer.title=Auditointi Login Katselija +PageAuditLogViewer.menuName=Auditointi Login Katselija PageAuditLogViewer.timeLabel=Aika PageAuditLogViewer.fromLabel=From -PageAuditLogViewer.toLabel=To -PageAuditLogViewer.initiatorNameLabel=Initiator +PageAuditLogViewer.toLabel=Mihin +PageAuditLogViewer.initiatorNameLabel=Aloittaja PageAuditLogViewer.channelLabel=Kanava -PageAuditLogViewer.hostIdentifierLabel=Host Identifier +PageAuditLogViewer.hostIdentifierLabel=Isännän tunnistaja PageAuditLogViewer.targetNameLabel=Kohde PageAuditLogViewer.targetTypeLabel=Kohde Tyyppi PageAuditLogViewer.targetOwnerNameLabel=Kohteen Omistaja -PageAuditLogViewer.eventTypeLabel=Event Type +PageAuditLogViewer.eventTypeLabel=Tapahtuma Tyyppi PageAuditLogViewer.eventTypeShortLabel=Tyyppi -PageAuditLogViewer.eventStageLabel=Event Stage +PageAuditLogViewer.eventStageLabel=Tapahtuma Vaihe PageAuditLogViewer.eventStageShortLabel=Vaihe PageAuditLogViewer.outcomeLabel=Tulos -PageAuditLogViewer.changedItem=Item changed -PageAuditLogViewer.valueRefTargetNamesLabel=Reference Target -AuditLogViewerPanel.dateValidatorMessage=From date must be before To date. +PageAuditLogViewer.changedItem=Alkion muutos +PageAuditLogViewer.valueRefTargetNamesLabel=Viittauksen kohde +AuditLogViewerPanel.dateValidatorMessage=Aloitus päivämäärä pitää olla ennen lopetus päivämäärää. AuditEventRecordType.timestamp=Aika -AuditEventRecordType.initiatorRef=Initiator -AuditEventRecordType.taskIdentifier=Task Identifier +AuditEventRecordType.initiatorRef=Aloittaja +AuditEventRecordType.taskIdentifier=Tehtävän tunnistaja AuditEventRecordType.channel=Kanava AuditEventRecordType.delta=Delta AuditEventRecordType.targetRef=Kohde AuditEventRecordType.targetOwnerRef=Kohteen Omistaja -PageAuditLogDetails.title=Audit Log Details -PageAuditLogDetails.eventTimestamp=Timestamp -PageAuditLogDetails.eventIdentifier=Event Identifier -PageAuditLogDetails.eventType=Event Type -PageAuditLogDetails.eventStage=Event Stage -PageAuditLogDetails.eventInitiatorRef=Initiator -PageAuditLogDetails.eventTargetRef=Target ref. -PageAuditLogDetails.eventTargetOwnerRef= Target Owner ref. +PageAuditLogDetails.title=Auditointi login yksityiskohdat +PageAuditLogDetails.eventTimestamp=Aikaleima +PageAuditLogDetails.eventIdentifier=Tapahtuman tunnistaja +PageAuditLogDetails.eventType=Tapahtuma Tyyppi +PageAuditLogDetails.eventStage=Tapahtuma Vaihe +PageAuditLogDetails.eventInitiatorRef=Aloittaja +PageAuditLogDetails.eventTargetRef=Kohde viittaus +PageAuditLogDetails.eventTargetOwnerRef= Kohteen Omistaja viittaus PageAuditLogDetails.eventResult=Tulos PageAuditLogDetails.eventOutcome=Tulos -PageAuditLogDetails.sessionIdentifier=Session Identifier -PageAuditLogDetails.taskIdentifier=Task Identifier +PageAuditLogDetails.sessionIdentifier=Session tunnistaja +PageAuditLogDetails.taskIdentifier=Tehtävän tunnistaja PageAuditLogDetails.taskOID=Tehtävä oid -PageAuditLogDetails.hostIdentifier=Host Identifier -PageAuditLogDetails.nodeIdentifier=Node -PageAuditLogDetails.remoteHostAddress=Remote Host +PageAuditLogDetails.hostIdentifier=Isännän tunnistaja +PageAuditLogDetails.nodeIdentifier=Solmu +PageAuditLogDetails.remoteHostAddress=Etäisäntä PageAuditLogDetails.channel=Kanava -PageAuditLogDetails.parameter=Parameter +PageAuditLogDetails.parameter=Parametri PageAuditLogDetails.message=Viesti -PageAuditLogDetails.deltaKey=Delta List +PageAuditLogDetails.deltaKey=Delta lista ObjectDeltaOperationType.resourceName=Resurssin nimi ObjectDeltaOperationType.objectName=Objektin nimi -ObjectDeltaOperationType.executionResult=Execution result -PageMergeObjects.noMergeResultObjectWarning=Merge preview object wasn't found +ObjectDeltaOperationType.executionResult=Suorituksen tulos +PageMergeObjects.noMergeResultObjectWarning=Esikatselun yhdistämis objektia ei löytynyt PageMergeObjects.title=Yhdistä objekteja -PageMergeObjects.tabTitle=Merge preview -PageMergeObjects.switchDirectionButton=Switch direction +PageMergeObjects.tabTitle=Yhdistä esikatselu +PageMergeObjects.switchDirectionButton=Vaihda suunta PageMergeObjects.mergeButton=Yhdistä -PageMergeObjects.mergeDeltaPreviewButton=Merge delta preview +PageMergeObjects.mergeDeltaPreviewButton=Yhdistä delta esikatselu PageMergeObjects.backButton=Takaisin -PageMergeObjects.mergeType=Merge type -MergeObjectsPanel.switchDirection=Switch direction -MergeType.DEFAULT=default -MergeType.EXPRESSION=expression -MergeType.ALL_RIGHT=allRight -MergeType.ALL_LEFT=allLeft +PageMergeObjects.mergeType=Yhdistä tyyppi +MergeObjectsPanel.switchDirection=Vaihda suunta +MergeType.DEFAULT=oletus +MergeType.EXPRESSION=Lauseke +MergeType.ALL_RIGHT=kaikkiOikea +MergeType.ALL_LEFT=kaikkiVasen MergeType.EMPTY=tyhjä -PageMergeObjects.warningMessage=Two objects' oids should be specified +PageMergeObjects.warningMessage=Kaksi objektien OIDia pitäisi tarkentaa PageSelfRegistration.register=Rekisteröi -PageSelfRegistration.registration.success=Registration was successful -PageSelfRegistration.registration.error=Registration failed : {0} +PageSelfRegistration.registration.success=Rekisteröinti onnistui +PageSelfRegistration.registration.error=Rekisteröinti epäonnistui: {0} PageSelfRegistration.registration.confirm.message=Congratulation! \n\n\n You have been successfully registered. To activate your account check your email and confirm your registration. PageRegistrationConfirmation.confirmation.error=Failed to confirm your registration. We are sorry, but probably you'll need to contact system administrator. -PageRegistrationConfirmation.continueToLogin=Continue to login page -PageRegistrationConfirmation.confirmation.successful=Confirmation successful +PageRegistrationConfirmation.continueToLogin=Jatka sisäänkirjautumis sivulle +PageRegistrationConfirmation.confirmation.successful=Vahvistus onnistui PageSelfRegistration.title=Rekisteröinti PageRegistrationConfirmation.title=Vahvista rekiströinti -PageSelfRegistration.reload=Reload -PageSelfRegistration.captcha.validation.failed=CAPTCHA validation failed, try again +PageSelfRegistration.reload=uudelleen lataus +PageSelfRegistration.captcha.validation.failed=CAPTCHA kelpuutus epäonnistui, yritä uudestaan ObjectType.name=Nimi -ObjectType.lifecycleState=Lifecycle state +ObjectType.lifecycleState=Elinkaari tila ObjectType.description=Kuvaus -PageUserHistory.title='{0}' historical data {1} -PageXmlDataReview.title=Historical data -PageXmlDataReview.aceEditorPanelTitle='{0}' historical xml data {1} -PageLogin.selfRegistration=Sign up -PageSelfRegistration.registration.failed.unsatisfied.registration.configuration=Registration process not allowed. Please contact system administrator. -ObjectHistoryTabPanel.viewHistoricalObjectDataTitle=View object data -ObjectHistoryTabPanel.viewHistoricalObjectXmlTitle=View object xml -PageRegistrationConfirmation.bad.credentials=Invalid username or password -PageSelfRegistration.invalid.registration.link=Registration link is not valid -PageSelfRegistration.welcome.message=Welcome to midPoint registration +PageUserHistory.title='{0}' historiallinen data {1} +PageXmlDataReview.title=historiallinen data +PageXmlDataReview.aceEditorPanelTitle='{0}' historiallinen XML data {1} +PageLogin.selfRegistration=Tilaa +PageSelfRegistration.registration.failed.unsatisfied.registration.configuration=Rekisteröinti prosessi ei sallittu. Ota yhteys järjestelmänvalvojaan. +ObjectHistoryTabPanel.viewHistoricalObjectDataTitle=Katso objektin dataa +ObjectHistoryTabPanel.viewHistoricalObjectXmlTitle=Katso objekti xml +PageRegistrationConfirmation.bad.credentials=Väärä käyttäjänimi ja/tai salasana +PageSelfRegistration.invalid.registration.link=Rekisteröinti linkki ei ole oikea +PageSelfRegistration.welcome.message=Tervetuloia midPoint rekisteröintiin PageSelfRegistration.additional.message= PageSelfRegistration.password.policy= -PageResetPassword.reset.successful=New password was set successfully. Continue with login. -PageForgotPassword.form.submited.message=Confirmation link was sent to the email provided. To reset your password, click on the confirmation link and follow instructions. -pageForgetPassword.message.policy.not.found=Reset password not allowed -PageAbstractSelfCredentials.save.password.failed=Failed to change password: {0} +PageResetPassword.reset.successful=Uuso salasana asetettu onnistuneesti. Jatka sisäänkirjautumista. +PageForgotPassword.form.submited.message=Varmistuslinkki lähetettiin annettuun sähköpostiin. Nollataksesi salasanasi, paina varmistuslinkkiä ja seuraa ohjeita. +pageForgetPassword.message.policy.not.found=Salasanan nollausta ei sallita. +PageAbstractSelfCredentials.save.password.failed=Salasanan vaihto epäonnistui: {0} PageResetPassword.title=Aseta salasana uudelleen -PageResetPasswordConfirmation.title=Reset password confirmation -PageResetPasswordConfirmation.confirmation.error=Reset password is not allowed. We are sorry, but probably you'll need to contact system administrator. -PageResetPasswordConfirmation.authnetication.failed=Incorrect username and/or password -ItemPathSegmentPanel.itemToSearch=Search for {0} -DecisionDto.automaticallyApproved=(automatically approved) -DecisionDto.automaticallyRejected=(automatically rejected) -DecisionDto.approvedDueToTimeout=(approved due to the timeout) -DecisionDto.rejectedDueToTimeout=(rejected due to the timeout) -DecisionDto.AUTO_APPROVAL_CONDITION=(auto-approval condition) -DecisionDto.AUTO_COMPLETION_CONDITION=(auto-completion condition) -DecisionDto.NO_ASSIGNEES_FOUND=(no approvers found) +PageResetPasswordConfirmation.title=Salasanan uudelleen asettamisen vahvistus +PageResetPasswordConfirmation.confirmation.error=Salasanan nollausta ei sallita. Olemme pahoillamme, mutta joutunette ottamaan yhteyttä järjestelmänvalvojaan. +PageResetPasswordConfirmation.authnetication.failed=Väärä käyttäjänimi ja/tai salasana +ItemPathSegmentPanel.itemToSearch=Hae {0} +DecisionDto.automaticallyApproved=(Automaattisesti hyväksytty) +DecisionDto.automaticallyRejected=(automaattisesti hylätty) +DecisionDto.approvedDueToTimeout=(hyväksytty ajan loppumisen vuoksi) +DecisionDto.rejectedDueToTimeout=(hylätty ajan loppumisen vuoksi) +DecisionDto.AUTO_APPROVAL_CONDITION=(automaattisen hyväksynnän ehto) +DecisionDto.AUTO_COMPLETION_CONDITION=(automaattisen valmistumisen ehto) +DecisionDto.NO_ASSIGNEES_FOUND=(hyväksyjää ei löydy) wf.comment=Kommentti wf.object=Objekti wf.target=Kohde -wf.originalAssignee=Original assignee -wf.currentAssignee=Current assignee(s) -wf.stageNumber=Stage number -wf.stageCount=Stage count -wf.stageName=Stage name -wf.stageDisplayName=Stage display name -wf.escalationLevelNumber=Escalation level number -wf.escalationLevelName=Escalation level name -wf.escalationLevelDisplayName=Escalation level display name -wf.workItemId=Work item ID -wf.processInstanceId=Process instance ID -wf.requesterComment=Requester comment -wf.causeType=Cause type -wf.causeName=Cause name -wf.causeDisplayName=Cause display name -PageAccountActivation.account.activation.successful=Activation of accounts was successful -PageAccountActivation.account.activation.failed=Failed to activate accounts. Please, contact system administrator -PageAccountActivation.activated.shadows=Activated shadows: +wf.originalAssignee=alkuperäinen valtuutettu +wf.currentAssignee=Tämän hetkiset valtuutetut +wf.stageNumber=Vaiheen numero +wf.stageCount=Vaihe lasku +wf.stageName=Vaiheen nimi +wf.stageDisplayName=Vaiheen näyttönimi +wf.escalationLevelNumber=Eskalointi tason numero +wf.escalationLevelName=Eskalointi tason nimi +wf.escalationLevelDisplayName=Eskalointi tason näyttönimi +wf.workItemId=Työ alkio ID +wf.processInstanceId=Prosessi tapahtuman ID +wf.requesterComment=Pyytäjä kommentti +wf.causeType=Syy tyyppi +wf.causeName=Syy nimi +wf.causeDisplayName=Syy näyttönimi +PageAccountActivation.account.activation.successful=Tilien aktivointi onnistui +PageAccountActivation.account.activation.failed=tilien aktivointi epäonnistui. Ota yhteys järhestelmänvalvojaan +PageAccountActivation.activated.shadows=Aktivoidut varjot: PageAccountActivation.button.activate=Aktivoi -PageAccountActivation.activate.accounts.label=Account activation for user '{0}'. -PageAccountActivation.provide.password=Please, provide your password to activate accounts. +PageAccountActivation.activate.accounts.label=Tilin aktivointi käyttäjälle '{0}'. +PageAccountActivation.provide.password=Syötä salana aktivoidaksesi tilit. PageAccountActivation.title=Tili aktivointi -PageAccountActivation.nothing.to.activate=Unexpected problem occurs while trying to activate account. Please contact system administrator -PageAccountActivation.authentication.failed=Authentication failed -operation.com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports.deleteReportOutput=Delete report (GUI) -operation.com.evolveum.midpoint.report.impl.ReportManagerImpl.deleteReportOutput=Delete report (Report) -operation.com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports.downloadReport=Download report (GUI) -operation..com.evolveum.midpoint.report.impl.ReportManagerImpl.getReportOutputData=Load report (Report) -PageWorkItem.couldNotGetWorkItem=Couldn't get work item. It might have been already completed or deleted. +PageAccountActivation.nothing.to.activate=Odottamaton virhe yrittäessä aktivoida tiliä. Ota yhteys järjestelmänvalvojaan. +PageAccountActivation.authentication.failed=Todennus epäonnistui +operation.com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports.deleteReportOutput=Poista raportti (GUI) +operation.com.evolveum.midpoint.report.impl.ReportManagerImpl.deleteReportOutput=Poista raportti (Raportti) +operation.com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports.downloadReport=Imuroi raportti (GUI) +operation..com.evolveum.midpoint.report.impl.ReportManagerImpl.getReportOutputData=Lataa raportti (Raportti) +PageWorkItem.couldNotGetWorkItem=Ei pystytty hankkimaan työalkiota. Se on voitu jo tehdä valmiiksi tai poistettu. PageWorkItem.noRequest=Couldn't display the work item, as it is not associated with any approval request. Please execute 'Clean-up Activiti processes' if the problem persists. -CsvDownloadButtonPanel.export=CSV export -CsvDownloadButtonPanel.confirmationMessage=CSV export size is limited to {0} entries. Continue? -AssignmentEditorDto.policyRuleTitle=Policy rule +CsvDownloadButtonPanel.export=CSV vienti +CsvDownloadButtonPanel.confirmationMessage=CSV vienti koko on rajoitettu {0} kirjaukseen. Jatka? +AssignmentEditorDto.policyRuleTitle=Linjaus sääntö AssignmentDataTablePanel.targetColumnName=Kohde AssignmentDataTablePanel.validityColumnName=Voimassaolo -AssignmentDataTablePanel.organizationColumnName=Organization -AssignmentDataTablePanel.tenantColumnName=Tenant +AssignmentDataTablePanel.organizationColumnName=Organisaatio +AssignmentDataTablePanel.tenantColumnName=Haltija AssignmentDataTablePanel.lifecycleColumnName=LifecycleAssignmentsUtil.createAssignmentIconTitleModel(AssignmentDataTablePanel.this, rowModel.getObject().getType()) AssignmentDataTablePanel.activationColumnName=Aktivointi AssignmentDataTablePanel.descriptionColumnName=Kuvaus -PolicyRulesPanel.imageTitle=Policy rule +PolicyRulesPanel.imageTitle=Linjaus sääntö PolicyRulesPanel.nameColumn=Nimi -PolicyRulesPanel.constraintsColumn=Constraints +PolicyRulesPanel.constraintsColumn=Rajoitukset PolicyRulesPanel.situationColumn=Tilanne -PolicyRulesPanel.actionColumn=Action +PolicyRulesPanel.actionColumn=Toiminta PolicyRulesPanel.orderColumn=Järjestys -PolicyRule.constraintsLabel=Constraints +PolicyRule.constraintsLabel=Rajoitukset PolicyRule.situationLabel=Tilanne -PolicyRule.actionLabel=Action +PolicyRule.actionLabel=Toiminta AbstractAssignmentDetailsPanel.doneButton=Tehty -ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} -ApprovalProcessesPreviewPanel.process=Approval process -ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +ApprovalProcessesPreviewPanel.processRelatedTo={0}n liittyvä hyväksyntä prosessi +ApprovalProcessesPreviewPanel.process=Hyväksyntä prosessi +ApprovalProcessExecutionInformationPanel.stage=Vaihe {0}/{1} +PageImportResource.title=Tuo resurssin kuvaus diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties index ca5ec1f7e5c..007a603b138 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Stop after errors exceed importOptionsPanel.summarizeErrors=Summarize errors importOptionsPanel.summarizeSuccesses=Summarize successes importOptionsPanel.validateDynamicSchema=Validate dynamic schema -importOptionsPanel.validateStaticSchema=Validate static schema +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Approval schema ItemApprovalPanel.currentWorkItems=Current work items ItemApprovalPanel.nextStages=Following stages @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Embedded editor PageImportObject.file=File PageImportObject.getObjectsFrom=Get objects from pageImportObject.message.emptyXml=Can't save empty xml. -PageImportObject.message.help=Choose XML file for import. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Uploaded file is null. PageImportObject.title=Import objects PageInternals.button.changeTime=Change time @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties index 7785314a65b..0a3a68d2c8e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties @@ -387,11 +387,11 @@ importOptionsPanel.stopAfter=Zatrzymaj po przekroczeniu błędów importOptionsPanel.summarizeErrors=Podsumowanie błędów importOptionsPanel.summarizeSuccesses=Podsumowanie sukcesów importOptionsPanel.validateDynamicSchema=Waliduj dynamiczny schemat -importOptionsPanel.validateStaticSchema=Waliduj statyczny schemat +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Polityka zatwierdzania ItemApprovalPanel.currentWorkItems=Bieżące zadania do wykonania -ItemApprovalPanel.nextStages=Following stages -ItemApprovalPanel.wholeProcess=Whole approval process +ItemApprovalPanel.nextStages=Następujące etapy +ItemApprovalPanel.wholeProcess=Cały proces zatwierdzania ItemApprovalPanel.decisionsDoneWhenFinishedIs_false=Decyzje podjęte do tej pory ItemApprovalPanel.decisionsDoneWhenFinishedIs_true=Podjęte decyzje ItemApprovalPanel.itemThatWasApproved=Pozycja, która została uznana za (i została ZATWIERDZONA) @@ -1120,7 +1120,7 @@ pageAdminFocus.projections=Projekcje pageAdminFocus.personas=Persona pageAdminFocus.organizations=Organizacje pageAdminFocus.assignments=Przypisania -pageAdminFocus.policyRules=Policy Rules +pageAdminFocus.policyRules=Reguły polityki pageAdminFocus.message.couldntCreateAccountNoSchema=Nie można utworzyć formularza projekcji dla '{0}', schemat niedostępny. Możliwy problem z konfiguracją konektora i/lub z połączeniem. Proszę zajrzeć w logi po więcej informacji. pageAdminFocus.message.couldntCreateAccountNoAccountSchema=Nie można utworzyć formularza projekcji dla '{0}', brak schematu dla domyślnego obiektu typu 'konto'. Możliwy problem z konfiguracją systemu. Proszę zajrzeć w logi po więcej informacji. pageAdminFocus.message.couldntCreateAccount=Nie można utworzyć formularza projekcji dla '{0}', powód: {1}. @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Osadzony edytor PageImportObject.file=Plik PageImportObject.getObjectsFrom=Pobierz obiekt z pageImportObject.message.emptyXml=Nie można zapisać pustego XML -PageImportObject.message.help=Wybierz plik XML do importu. +PageImportObject.message.help=Wybierz plik XML, JSON lub YAML do importu. pageImportObject.message.nullFile=Wczytany plik jest pusty. PageImportObject.title=Import obiektów PageInternals.button.changeTime=Zmiana czasu @@ -2042,7 +2042,7 @@ pageTaskEdit.suspendReq=Do edycji wymagane jest zatrzymanie zadania pageTaskEdit.taskState=Stan zadania pageTaskEdit.threadAction=Działanie wątku pageTaskEdit.threadStop=Reakcja na zatrzymanie wątku -pageTaskEdit.requiredCapability=Required capability (e.g. node name) +pageTaskEdit.requiredCapability=Wymagana funkcjonalność (np. nazwa węzła) pageTaskEdit.tightlyBound=Często powtarzane pageTaskEdit.title.edit=Szczegóły '{0}' PageTaskEdit.title=Szczegóły zadania @@ -2301,10 +2301,10 @@ workItemPanel.approvalHistoryHelp=Tutaj wyświetlone są decyzje podjęte do tej TaskWfChildPanel.approvalHistoryHelp=Tutaj wyświetlone są decyzje podjęte do tej pory w procesie zatwierdzania zmian. workItemPanel.otherWorkItemsHelp=Zadania do wykonania dla zmian wyświetlonych tutaj, które obecnie są aktywne (uzależnione od zadań do wykonania wyświetlonych na tej stronie). TaskWfChildPanel.currentWorkItemsHelp=Zadania do wykonania dla zmian wyświetlonych tutaj, które obecnie są aktywne. -TaskWfChildPanel.showNextStagesHelp=Displays the preview of the following approval stages. -TaskWfChildPanel.nextStagesHelp=This is a preview of the following approval stages. -TaskWfChildPanel.showWholeProcessHelp=Displays the whole approval process: stages already completed, current stage, as well as any expected following stages. -TaskWfChildPanel.wholeProcessHelp=This is an information on the whole approval process: stages already completed, current stage, as well as any expected following stages. +TaskWfChildPanel.showNextStagesHelp=Pokazuje podgląd następujących etapów zatwierdzania. +TaskWfChildPanel.nextStagesHelp=To jest podgląd następujących etapów zatwierdzania. +TaskWfChildPanel.showWholeProcessHelp=Pokazuje cały proces zatwierdzania: etapy już ukończone, etap bieżący, jak również spodziewane następne etapy. +TaskWfChildPanel.wholeProcessHelp=To jest informacja na temat całego procesu zatwierdzania: etapy już ukończone, etap bieżący, jak również spodziewane następne etapy. workItemPanel.relatedRequestsHelp=Lista wniosków o zatwierdzenie, które zostały utworzone wraz z tym jednym. Każdy wniosek ma swój własny proces zatwierdzania, a zatem mogą być zatwierdzone lub odrzucone niezależnie od pozostałych. Wszystkie one zostały uruchomione przez jedną próbę wykonania zmiany, która zawiera kilka prostszych zmian. TaskWfChildPanel.relatedRequestsHelp=Lista wniosków o zatwierdzenie, które zostały utworzone wraz z tym jednym. Każdy wniosek ma swój własny proces zatwierdzania, a zatem mogą być zatwierdzone lub odrzucone niezależnie od pozostałych. Wszystkie one zostały uruchomione przez jedną próbę wykonania zmiany, która zawiera kilka prostszych zmian. workItemPanel.showRequestHelp=Wyświetla wnioski o zatwierdzenie oraz korespondujące z nimi procesy akceptacji zmian pokazane tutaj. @@ -3096,9 +3096,9 @@ MyRequestsPanel.started = Rozpoczęty MyRequestsPanel.rejected = Odrzucony MyRequestsPanel.approved = Zatwierdzony MyRequestsPanel.inProgress = W trakcie -MyRequestsPanel.unknown = Unknown -MyRequestsPanel.future = Future -MyRequestsPanel.cancelled = Cancelled +MyRequestsPanel.unknown = Nieznany +MyRequestsPanel.future = Przyszłość +MyRequestsPanel.cancelled = Anulowane MyRequestsPanel.name = Nazwa PageSelfProfile.title=Edycja profilu PageSelfDashboard.title=Strona domowa @@ -3203,8 +3203,8 @@ PagePreviewChanges.primaryChangesOne=Zmiany pierwotne: {0} obiekt PagePreviewChanges.primaryChangesMore=Zmiany pierwotne: {0} obiektów PagePreviewChanges.secondaryChangesOne=Wtórne zmiany: {0} obiekt PagePreviewChanges.secondaryChangesMore=Wtórne zmiany: {0} obiektów -PagePreviewChanges.policyViolationMessages=Policy violation messages -PagePreviewChanges.approvalsRequired=Approvals required +PagePreviewChanges.policyViolationMessages=Powiadomienia o naruszeniu polityki +PagePreviewChanges.approvalsRequired=Wymagane zatwierdzenia PagePreviewChanges.button.continueEditing=Kontynuuj edycję PagePreviewChanges.button.save=Zapisz ScenePanel.object={0} obiekt @@ -3253,8 +3253,8 @@ taskOtherChangesPanel.state.FINAL=Zmiany zostały wykonane (z powodzeniem lub be taskOtherChangesPanel.state.PRIMARY=Zmiany oczekujące na wykonanie taskOtherChangesPanel.state.SECONDARY=Zmiany oczekujące na wykonanie taskWfChildPanel.showParent=Pokaż wniosek w kontekście całej operacji. -taskWfChildPanel.showNextStages=Show following stages -taskWfChildPanel.showWholeProcess=Show the whole process +taskWfChildPanel.showNextStages=Pokaż następujące etapy +taskWfChildPanel.showWholeProcess=Pokaż cały proces TaskSummaryPanel.requestedBy=Wnioskowany przez: {0} TaskSummaryPanel.requestedByWithFullName=Wnioskowany przez: {0} ({1}) TaskSummaryPanel.requestedOn=Data wniosku: {0} @@ -3680,16 +3680,17 @@ AssignmentDataTablePanel.tenantColumnName=Podmiot AssignmentDataTablePanel.lifecycleColumnName=LifecycleAssignmentsUtil.createAssignmentIconTitleModel(AssignmentDataTablePanel.this, rowModel.getObject().getType()) AssignmentDataTablePanel.activationColumnName=Aktywacja AssignmentDataTablePanel.descriptionColumnName=Opis -PolicyRulesPanel.imageTitle=Policy rule -PolicyRulesPanel.nameColumn=Name -PolicyRulesPanel.constraintsColumn=Constraints -PolicyRulesPanel.situationColumn=Situation -PolicyRulesPanel.actionColumn=Action -PolicyRulesPanel.orderColumn=Order -PolicyRule.constraintsLabel=Constraints -PolicyRule.situationLabel=Situation -PolicyRule.actionLabel=Action -AbstractAssignmentDetailsPanel.doneButton=Done -ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} -ApprovalProcessesPreviewPanel.process=Approval process -ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PolicyRulesPanel.imageTitle=Reguła polityki +PolicyRulesPanel.nameColumn=Nazwa +PolicyRulesPanel.constraintsColumn=Ograniczenia +PolicyRulesPanel.situationColumn=Sytuacja +PolicyRulesPanel.actionColumn=Akcja +PolicyRulesPanel.orderColumn=Kolejność +PolicyRule.constraintsLabel=Ograniczenia +PolicyRule.situationLabel=Sytuacja +PolicyRule.actionLabel=Akcja +AbstractAssignmentDetailsPanel.doneButton=Zrobione +ApprovalProcessesPreviewPanel.processRelatedTo=Proces zatwierdzania związany z {0} +ApprovalProcessesPreviewPanel.process=Proces zatwierdzania +ApprovalProcessExecutionInformationPanel.stage=Etap {0}/{1} +PageImportResource.title=Import definicji systemu diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties index 33dccdda51e..2e4172d29df 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Parar após erros exceder importOptionsPanel.summarizeErrors=Sumarizar erros importOptionsPanel.summarizeSuccesses=Sumarizar sucessos importOptionsPanel.validateDynamicSchema=Validar esquema dinâmico -importOptionsPanel.validateStaticSchema=Validar esquema estático +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Aprovar esquema ItemApprovalPanel.currentWorkItems=Itens de trabalho atuais ItemApprovalPanel.nextStages=Following stages @@ -1589,7 +1589,7 @@ PageImportObject.embeddedEditor=Editor embutido PageImportObject.file=Arquivo PageImportObject.getObjectsFrom=Obter objetos de pageImportObject.message.emptyXml=Não é possível salvar xml vazio. -PageImportObject.message.help=Escolher arquivo XML para importar. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Arquivo carregado está nulo. PageImportObject.title=Importar objetos PageInternals.button.changeTime=Alterar hora @@ -3698,3 +3698,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties index 47fa6b31e5b..ae8b20057b6 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Остановить после обнаружен importOptionsPanel.summarizeErrors=Суммировать ошибки importOptionsPanel.summarizeSuccesses=Суммировать число успешных завершений importOptionsPanel.validateDynamicSchema=Подтверждение динамической схемы -importOptionsPanel.validateStaticSchema=Подтверждение статической схемы +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Схема утверждения ItemApprovalPanel.currentWorkItems=Текущие элементы ItemApprovalPanel.nextStages=Following stages @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Встроенный редактор PageImportObject.file=Файл PageImportObject.getObjectsFrom=Получить объекты от pageImportObject.message.emptyXml=Не могу сохранить пустой xml -PageImportObject.message.help=Выберите XML файл для импорта. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Загруженный файл пустой PageImportObject.title=Импорт объектов PageInternals.button.changeTime=Изменить время @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties index 9710c6fe2a5..760e443809a 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Zastaviť po prekročení chýb importOptionsPanel.summarizeErrors=Summarizovať chyby importOptionsPanel.summarizeSuccesses=Summarizovať úspechy importOptionsPanel.validateDynamicSchema=Validovať dynamickú schému -importOptionsPanel.validateStaticSchema=Validovať statickú schému +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Schválenie schémy ItemApprovalPanel.currentWorkItems=Aktuálne pracovné položky ItemApprovalPanel.nextStages=Following stages @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Vstavaný editor PageImportObject.file=Súbor PageImportObject.getObjectsFrom=Načítať objekty z pageImportObject.message.emptyXml=Nie je možné uložit prázdne xml. -PageImportObject.message.help=Choose XML file for import. +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Posielaný súbor je null. PageImportObject.title=Importovať objekty PageInternals.button.changeTime=Zmeniť čas @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties index beee80cad21..55e20237602 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -AbstractRoleType.delegable=Delegable +AbstractRoleType.delegable=Devredilebilir AbstractRoleType.requestable=Talep edilebilir ACAttributePanel.button.showExprEditor=İfadeyi göster ACAttributePanel.hasOutbound=Dış kaynak eşlemesi var @@ -113,7 +113,7 @@ AssignmentTablePanel.message.noAssignmentSelected=Hiç bir atama seçilmedi. AssignmentTablePanel.message.noDelegationsSelected=No delegation selected. AssignmentTablePanel.modal.message.delete={0} atama(ları) gerçekten kaldırmak istyor musunuz? AssignmentTablePanel.modal.message.deleteDelegation=Do you really want to delete {0} delegation(s)? -AssignmentTablePanel.modal.message.noDelegationWarning=User doesn't have any delegable item +AssignmentTablePanel.modal.message.noDelegationWarning=Kullanıcının herhangi bir devredilebilir öğesi yok. AssignmentTablePanel.modal.title.confirmDeletion=Silmeyi onayla AssignmentTablePanel.modal.title.selectAssignment=Nesne(leri) seç associationAttribute.nullValid=Birini Seçiniz @@ -260,7 +260,7 @@ DefinitionScopeObjectType.ServiceType=Servisler deleteAllDialog.label.accountShadowsDelete=Account shadows to delete: {0} deleteAllDialog.label.nonAccountShadowsDelete=Non-Account shadows to delete: {0} deleteAllDialog.label.org=Org. Birimleri -deleteAllDialog.label.orgUnitsDelete=Org. units to delete: {0} +deleteAllDialog.label.orgUnitsDelete=Silinecek org. üniteleri: {0} deleteAllDialog.label.shadow.account=Hesap gölgeleri deleteAllDialog.label.shadow.nonAccount=Hesap olmayan gölgeler deleteAllDialog.label.shadow.org=Org. birimi gölgeleri @@ -387,7 +387,7 @@ importOptionsPanel.stopAfter=Hata sayısı aşınca dur importOptionsPanel.summarizeErrors=Hataları özetle importOptionsPanel.summarizeSuccesses=Başarımları özetle importOptionsPanel.validateDynamicSchema=Dinamik şemayı doğrula -importOptionsPanel.validateStaticSchema=Statik şemayı doğrula +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=Onaylama Şeması ItemApprovalPanel.currentWorkItems=Mevcut iş öğeleri ItemApprovalPanel.nextStages=Following stages @@ -1484,7 +1484,7 @@ PageCreatedReports.title=Geçmişte oluşturulan raporlar PageDashboard.accounts=Hesaplarım PageDashboard.activeTasks=Aktif görevler PageDashboard.activeUsers=Aktif kullanıcılar -PageDashboard.assignments=My assignments +PageDashboard.assignments=Atamalarım PageDashboard.personalInfo=Kişisel bilgilerim PageDashboard.serverLoad=Sunucu Yükü PageDashboard.systemInfo=Sistem durumu @@ -1586,7 +1586,7 @@ PageImportObject.embeddedEditor=Bütünleşik editor PageImportObject.file=Dosya PageImportObject.getObjectsFrom=Nesneleri getir pageImportObject.message.emptyXml=Boş xml dosyası kaydedilemez. -PageImportObject.message.help=İçe aktarmak için xml dosyası seç +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=Yüklenen dosya boş PageImportObject.title=Nesneleri içe aktar PageInternals.button.changeTime=Zamanı değiştir @@ -2173,7 +2173,7 @@ pageUser.assignment.active=Aktif pageUser.assignment.name=İsim pageUser.assignments=Atamalar pageAdminFocus.request=Rol talep et -pageAdminFocus.objectHistory=History +pageAdminFocus.objectHistory=Tarihçe pageUser.assignment.type=Tip pageUser.button.abort=İptal pageUser.button.addAccount=Hesap ekle @@ -3010,7 +3010,7 @@ userBrowserDialog.title=Kullanıcı seç userBrowserDialog.type=Tip User.disabled=Pasif UserMenuPanel.editPasswordQuestions=Şifre Sorularım -UserMenuPanel.editProfile=Profil +UserMenuPanel.editProfile=Profili düzenle UserMenuPanel.logout=Çıkış yap UserMenuPanel.resetPasswords=Şifre Değiştir UserOrgReferenceChoosePanel.type.org=Org. Ünitesi @@ -3078,7 +3078,7 @@ PageAdmin.menu.selfDashboard=Ana sayfa PageAdmin.menu.selfService=SELFSERVİS PageAdmin.menu.mainNavigation=YÖNETİM PageAdmin.menu.additional=EK OLARAK -PageAdmin.menu.profile=Kullanıcı Profil +PageAdmin.menu.profile=Kullanıcı Profili PageAdmin.menu.assignments=Atamalar PageAdmin.menu.credentials=Şifre PageAdmin.menu.request=Rol talep et @@ -3100,7 +3100,7 @@ MyRequestsPanel.unknown = Unknown MyRequestsPanel.future = Future MyRequestsPanel.cancelled = Cancelled MyRequestsPanel.name = İsim -PageSelfProfile.title=Profil +PageSelfProfile.title=Profili düzen PageSelfDashboard.title=Ana sayfa PageSelfDashboard.workItems=İş öğelerim PageSelfDashboard.myRequests=Taleplerim @@ -3607,7 +3607,7 @@ PageRegistrationConfirmation.title=Confirm registration PageSelfRegistration.reload=Yeniden Y�kle PageSelfRegistration.captcha.validation.failed=CAPTCHA validation failed, try again ObjectType.name=İsim -ObjectType.lifecycleState=Lifecycle state +ObjectType.lifecycleState=Yaşam döngüsü durumu ObjectType.description=Açıklama PageUserHistory.title='{0}' historical data {1} PageXmlDataReview.title=Historical data @@ -3693,3 +3693,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties index a5b77efc64f..8e5c9d391ad 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties @@ -388,7 +388,7 @@ importOptionsPanel.stopAfter=错误发生后停止 importOptionsPanel.summarizeErrors=汇总错误 importOptionsPanel.summarizeSuccesses=汇总结果 importOptionsPanel.validateDynamicSchema=验证动态架构 -importOptionsPanel.validateStaticSchema=验证静态架构 +importOptionsPanel.validateStaticSchema=Validate static schema (XML only) ItemApprovalPanel.approvalSchema=审批架构 ItemApprovalPanel.currentWorkItems=当前工作项 ItemApprovalPanel.nextStages=Following stages @@ -1587,7 +1587,7 @@ PageImportObject.embeddedEditor=内置编辑器 PageImportObject.file=文件 PageImportObject.getObjectsFrom=获取对象 pageImportObject.message.emptyXml=不能保存空的XML。 -PageImportObject.message.help=选择要导出的XML文件。 +PageImportObject.message.help=Choose XML, JSON or YAML file for import. pageImportObject.message.nullFile=删除的文件为空。 PageImportObject.title=导入对象 PageInternals.button.changeTime=修改时间 @@ -3694,3 +3694,4 @@ AbstractAssignmentDetailsPanel.doneButton=Done ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} +PageImportResource.title=Import resource definition diff --git a/gui/admin-gui/src/main/webapp/WEB-INF/web.xml b/gui/admin-gui/src/main/webapp/WEB-INF/web.xml index ec8d3a337c4..fd08345a627 100644 --- a/gui/admin-gui/src/main/webapp/WEB-INF/web.xml +++ b/gui/admin-gui/src/main/webapp/WEB-INF/web.xml @@ -98,7 +98,7 @@ org.apache.wicket.protocol.http.WicketFilter configuration - + deployment diff --git a/infra/common/pom.xml b/infra/common/pom.xml index 7606e09b357..bf43fecd6e9 100644 --- a/infra/common/pom.xml +++ b/infra/common/pom.xml @@ -86,7 +86,6 @@ org.codehaus.staxmate staxmate - 2.0.1 diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/LoggingConfigurationManager.java b/infra/common/src/main/java/com/evolveum/midpoint/common/LoggingConfigurationManager.java index fb026c0578a..ac13de54dbc 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/LoggingConfigurationManager.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/LoggingConfigurationManager.java @@ -271,8 +271,13 @@ private static void prepareFileAppenderConfiguration(StringBuilder sb, FileAppen prepareCommonAppenderHeader(sb, appender, config, appenderClass); - appendProp(sb, "file", fileName); - appendProp(sb, "append", appender.isAppend()); + if(!appender.isPrudent()){ + appendProp(sb, "file", fileName); + appendProp(sb, "append", appender.isAppend()); + }else{ + appendProp(sb, "prudent", appender.isPrudent()); + } + if (isRolling) { //rolling policy sb.append("\t\t\n"); diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java b/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java index 84e5ed6dc7a..9b7e86069a2 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java @@ -17,10 +17,9 @@ package com.evolveum.midpoint.common; import org.apache.commons.lang.StringUtils; -import org.jetbrains.annotations.Nullable; import org.w3c.dom.Element; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -43,7 +42,7 @@ public static String getPropertyName(String name) { } public static Element fillPropertyReference(String resolve) { - XPathHolder xpath = new XPathHolder( + ItemPathHolder xpath = new ItemPathHolder( Utils.getPropertyName(resolve)); return xpath.toElement(SchemaConstants.NS_C, "property"); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java index 1e76ed3a451..734f5ec3e10 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java @@ -262,8 +262,8 @@ public boolean isDefault() { } @Override - public ResourceType getResourceType() { - return structuralObjectClassDefinition.getResourceType(); + public String getResourceOid() { + return structuralObjectClassDefinition.getResourceOid(); } @Override @@ -321,23 +321,23 @@ public boolean matches(ShadowType shadowType) { return structuralObjectClassDefinition.matches(shadowType); } - public T getEffectiveCapability(Class capabilityClass) { - return structuralObjectClassDefinition.getEffectiveCapability(capabilityClass); + public T getEffectiveCapability(Class capabilityClass, ResourceType resourceType) { + return structuralObjectClassDefinition.getEffectiveCapability(capabilityClass, resourceType); } @Override - public PagedSearchCapabilityType getPagedSearches() { - return structuralObjectClassDefinition.getPagedSearches(); + public PagedSearchCapabilityType getPagedSearches(ResourceType resourceType) { + return structuralObjectClassDefinition.getPagedSearches(resourceType); } @Override - public boolean isPagedSearchEnabled() { - return structuralObjectClassDefinition.isPagedSearchEnabled(); + public boolean isPagedSearchEnabled(ResourceType resourceType) { + return structuralObjectClassDefinition.isPagedSearchEnabled(resourceType); } @Override - public boolean isObjectCountingEnabled() { - return structuralObjectClassDefinition.isObjectCountingEnabled(); + public boolean isObjectCountingEnabled(ResourceType resourceType) { + return structuralObjectClassDefinition.isObjectCountingEnabled(resourceType); } @Override @@ -486,11 +486,6 @@ public void merge(ComplexTypeDefinition otherComplexTypeDef) { throw new UnsupportedOperationException("TODO implement if needed"); } - @Override - public String getResourceNamespace() { - return structuralObjectClassDefinition.getResourceNamespace(); - } - // TODO @Override public Class getTypeClassIfKnown() { diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java index a01ce5d9eaa..18fd1020d49 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java @@ -45,7 +45,8 @@ * */ public class LayerRefinedObjectClassDefinitionImpl implements LayerRefinedObjectClassDefinition { - + private static final long serialVersionUID = 1L; + private RefinedObjectClassDefinition refinedObjectClassDefinition; private LayerType layer; /** @@ -247,7 +248,7 @@ public LayerRefinedAttributeDefinition findAttributeDefinition(@NotNull Q @Override public LayerRefinedAttributeDefinition findAttributeDefinition(String elementLocalname) { - return findAttributeDefinition(new QName(getResourceNamespace(), elementLocalname)); // todo or should we use ns-less matching? + return LayerRefinedAttributeDefinitionImpl.wrap(refinedObjectClassDefinition.findAttributeDefinition(elementLocalname), layer); } @Override @@ -291,8 +292,8 @@ public boolean containsAttributeDefinition(ItemPathType pathType) { } @Override - public ResourceType getResourceType() { - return refinedObjectClassDefinition.getResourceType(); + public String getResourceOid() { + return refinedObjectClassDefinition.getResourceOid(); } @Override @@ -432,23 +433,23 @@ public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) } @Override - public T getEffectiveCapability(Class capabilityClass) { - return (T) refinedObjectClassDefinition.getEffectiveCapability(capabilityClass); + public T getEffectiveCapability(Class capabilityClass, ResourceType resourceType) { + return (T) refinedObjectClassDefinition.getEffectiveCapability(capabilityClass, resourceType); } @Override - public PagedSearchCapabilityType getPagedSearches() { - return refinedObjectClassDefinition.getPagedSearches(); + public PagedSearchCapabilityType getPagedSearches(ResourceType resourceType) { + return refinedObjectClassDefinition.getPagedSearches(resourceType); } @Override - public boolean isPagedSearchEnabled() { - return refinedObjectClassDefinition.isPagedSearchEnabled(); + public boolean isPagedSearchEnabled(ResourceType resourceType) { + return refinedObjectClassDefinition.isPagedSearchEnabled(resourceType); } @Override - public boolean isObjectCountingEnabled() { - return refinedObjectClassDefinition.isObjectCountingEnabled(); + public boolean isObjectCountingEnabled(ResourceType resourceType) { + return refinedObjectClassDefinition.isObjectCountingEnabled(resourceType); } @Override @@ -564,11 +565,6 @@ public RefinedObjectClassDefinition deepClone(Map return new LayerRefinedObjectClassDefinitionImpl(refinedObjectClassDefinition.deepClone(ctdMap), layer); } - @Override - public String getResourceNamespace() { - return refinedObjectClassDefinition.getResourceNamespace(); - } - @Override public ResourceObjectReferenceType getBaseContext() { return refinedObjectClassDefinition.getBaseContext(); diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index 9a8fde594b8..cf3324f535e 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -114,9 +114,7 @@ default Collection> getAllIdentifiers() ObjectClassComplexTypeDefinition getObjectClassDefinition(); - ResourceType getResourceType(); - - String getResourceNamespace(); + String getResourceOid(); boolean isDefault(); @@ -171,13 +169,13 @@ default PrismObject createBlankShadow() { //region Capabilities ======================================================== - T getEffectiveCapability(Class capabilityClass); + T getEffectiveCapability(Class capabilityClass, ResourceType resourceType); - PagedSearchCapabilityType getPagedSearches(); + PagedSearchCapabilityType getPagedSearches(ResourceType resourceType); - boolean isPagedSearchEnabled(); + boolean isPagedSearchEnabled(ResourceType resourceType); - boolean isObjectCountingEnabled(); + boolean isObjectCountingEnabled(ResourceType resourceType); //endregion diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java index 28c2a7d3ebf..b3542d823e0 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java @@ -65,7 +65,7 @@ public class RefinedObjectClassDefinitionImpl implements RefinedObjectClassDefin @NotNull private final ObjectClassComplexTypeDefinition originalObjectClassDefinition; @NotNull private final List auxiliaryObjectClassDefinitions = new ArrayList<>(); - @NotNull private final ResourceType resourceType; + private final String resourceOid; private ResourceObjectTypeDefinitionType schemaHandlingObjectTypeDefinitionType; private String intent; private ShadowKindType kind; @@ -86,8 +86,8 @@ public class RefinedObjectClassDefinitionImpl implements RefinedObjectClassDefin */ private PrismObjectDefinition objectDefinition = null; - private RefinedObjectClassDefinitionImpl(@NotNull ResourceType resourceType, @NotNull ObjectClassComplexTypeDefinition objectClassDefinition) { - this.resourceType = resourceType; + private RefinedObjectClassDefinitionImpl(String resourceOid, @NotNull ObjectClassComplexTypeDefinition objectClassDefinition) { + this.resourceOid = resourceOid; this.originalObjectClassDefinition = objectClassDefinition; } @@ -251,15 +251,9 @@ public ObjectClassComplexTypeDefinition getObjectClassDefinition() { return originalObjectClassDefinition; } - @NotNull @Override - public ResourceType getResourceType() { - return resourceType; - } - - @Override - public String getResourceNamespace() { - return ResourceTypeUtil.getResourceNamespace(getResourceType()); + public String getResourceOid() { + return resourceOid; } @Override @@ -345,10 +339,11 @@ public PrismObject createBlankShadow(RefinedObjectClassDefinition de } ShadowType accountShadowType = accountShadow.asObjectable(); - accountShadowType.setIntent(getIntent()); - accountShadowType.setKind(getKind()); - accountShadowType.setObjectClass(getObjectClassDefinition().getTypeName()); - accountShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(getResourceType())); + accountShadowType + .intent(getIntent()) + .kind(getKind()) + .objectClass(getObjectClassDefinition().getTypeName()) + .resourceRef(getResourceOid(), ResourceType.COMPLEX_TYPE); // Setup definition PrismObjectDefinition newDefinition = accountShadow.getDefinition().cloneWithReplacedDefinition( @@ -360,7 +355,7 @@ public PrismObject createBlankShadow(RefinedObjectClassDefinition de @Override public ResourceShadowDiscriminator getShadowDiscriminator() { - return new ResourceShadowDiscriminator(getResourceType().getOid(), getKind(), getIntent()); + return new ResourceShadowDiscriminator(getResourceOid(), getKind(), getIntent()); } @Override @@ -516,23 +511,23 @@ public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) //region Capabilities ======================================================== @Override - public T getEffectiveCapability(Class capabilityClass) { - return ResourceTypeUtil.getEffectiveCapability(getResourceType(), schemaHandlingObjectTypeDefinitionType, capabilityClass); + public T getEffectiveCapability(Class capabilityClass, ResourceType resourceType) { + return ResourceTypeUtil.getEffectiveCapability(resourceType, schemaHandlingObjectTypeDefinitionType, capabilityClass); } @Override - public PagedSearchCapabilityType getPagedSearches() { - return getEffectiveCapability(PagedSearchCapabilityType.class); + public PagedSearchCapabilityType getPagedSearches(ResourceType resourceType) { + return getEffectiveCapability(PagedSearchCapabilityType.class, resourceType); } @Override - public boolean isPagedSearchEnabled() { - return getPagedSearches() != null; // null means nothing or disabled + public boolean isPagedSearchEnabled(ResourceType resourceType) { + return getPagedSearches(resourceType) != null; // null means nothing or disabled } @Override - public boolean isObjectCountingEnabled() { - return getEffectiveCapability(CountObjectsCapabilityType.class) != null; + public boolean isObjectCountingEnabled(ResourceType resourceType) { + return getEffectiveCapability(CountObjectsCapabilityType.class, resourceType) != null; } //endregion @@ -540,7 +535,7 @@ public boolean isObjectCountingEnabled() { @NotNull @Override public RefinedObjectClassDefinitionImpl clone() { - RefinedObjectClassDefinitionImpl clone = new RefinedObjectClassDefinitionImpl(resourceType, originalObjectClassDefinition); + RefinedObjectClassDefinitionImpl clone = new RefinedObjectClassDefinitionImpl(resourceOid, originalObjectClassDefinition); copyDefinitionData(clone); shared = false; return clone; @@ -567,11 +562,10 @@ private void copyDefinitionData(RefinedObjectClassDefinitionImpl clone) { @Override public RefinedObjectClassDefinition deepClone(Map ctdMap) { // TODO TODO TODO (note that in original implementation this was also missing...) - RefinedObjectClassDefinitionImpl clone = new RefinedObjectClassDefinitionImpl(resourceType, originalObjectClassDefinition.deepClone(ctdMap)); + RefinedObjectClassDefinitionImpl clone = new RefinedObjectClassDefinitionImpl(resourceOid, originalObjectClassDefinition.deepClone(ctdMap)); copyDefinitionData(clone); shared = false; return clone; - } private Collection cloneAssociations(Collection origAsoc) { @@ -618,10 +612,11 @@ public boolean isAuxiliary() { return getObjectClassDefinition().isAuxiliary(); } + @Override public PrismContext getPrismContext() { - return getResourceType().asPrismObject().getPrismContext(); + return originalObjectClassDefinition.getPrismContext(); } - + @Nullable @Override public Class getCompileTimeClass() { @@ -839,7 +834,7 @@ public static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTyp RefinedResourceSchema rSchema, PrismContext prismContext, String contextDescription) throws SchemaException { - RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType, objectClassDef); + RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType.getOid(), objectClassDef); String intent = objectClassDef.getIntent(); if (intent == null && objectClassDef.isDefaultInAKind()) { @@ -886,31 +881,33 @@ private static RefinedObjectClassDefinition parseRefinedObjectClass(ResourceObje throw new SchemaException("Definition of "+typeDesc+" type " + schemaHandlingObjDefType.getIntent() + " does not have objectclass, in " + contextDescription); } - RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType, objectClassDef); + RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType.getOid(), objectClassDef); rOcDef.setKind(kind); - rOcDef.schemaHandlingObjectTypeDefinitionType = schemaHandlingObjDefType; - rOcDef.setIntent(intent); + rOcDef.setIntent(intent); + // clone here to disassociate this definition from the resource. So this definition can be serialized without the need to serialize + // entire resource. If we do not clone then the resource will be present here through parent in the schemaHandlingObjDefType + rOcDef.schemaHandlingObjectTypeDefinitionType = schemaHandlingObjDefType.clone(); - if (schemaHandlingObjDefType.getDisplayName() != null) { - rOcDef.setDisplayName(schemaHandlingObjDefType.getDisplayName()); + if (rOcDef.schemaHandlingObjectTypeDefinitionType.getDisplayName() != null) { + rOcDef.setDisplayName(rOcDef.schemaHandlingObjectTypeDefinitionType.getDisplayName()); } else { if (objectClassDef.getDisplayName() != null) { rOcDef.setDisplayName(objectClassDef.getDisplayName()); } } - if (schemaHandlingObjDefType.getDescription() != null) { - rOcDef.setDescription(schemaHandlingObjDefType.getDescription()); + if (rOcDef.schemaHandlingObjectTypeDefinitionType.getDescription() != null) { + rOcDef.setDescription(rOcDef.schemaHandlingObjectTypeDefinitionType.getDescription()); } - if (schemaHandlingObjDefType.isDefault() != null) { - rOcDef.setDefault(schemaHandlingObjDefType.isDefault()); + if (rOcDef.schemaHandlingObjectTypeDefinitionType.isDefault() != null) { + rOcDef.setDefault(rOcDef.schemaHandlingObjectTypeDefinitionType.isDefault()); } else { rOcDef.setDefault(objectClassDef.isDefaultInAKind()); } - if (schemaHandlingObjDefType.getBaseContext() != null) { - rOcDef.setBaseContext(schemaHandlingObjDefType.getBaseContext()); + if (rOcDef.schemaHandlingObjectTypeDefinitionType.getBaseContext() != null) { + rOcDef.setBaseContext(rOcDef.schemaHandlingObjectTypeDefinitionType.getBaseContext()); } return rOcDef; @@ -1126,7 +1123,7 @@ public int hashCode() { result = prime * result + originalObjectClassDefinition.hashCode(); result = prime * result + ((objectDefinition == null) ? 0 : objectDefinition.hashCode()); result = prime * result + ((protectedObjectPatterns == null) ? 0 : protectedObjectPatterns.hashCode()); - result = prime * result + resourceType.hashCode(); + result = prime * result + resourceOid.hashCode(); result = prime * result + ((schemaHandlingObjectTypeDefinitionType == null) ? 0 : schemaHandlingObjectTypeDefinitionType.hashCode()); result = prime * result + ((secondaryIdentifiers == null) ? 0 : secondaryIdentifiers.hashCode()); @@ -1219,7 +1216,7 @@ public boolean equals(Object obj) { } else if (!protectedObjectPatterns.equals(other.protectedObjectPatterns)) { return false; } - if (!resourceType.equals(other.resourceType)) { + if (!resourceOid.equals(other.resourceOid)) { return false; } if (schemaHandlingObjectTypeDefinitionType == null) { diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java b/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java index fe47a2a6162..66654002432 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java @@ -67,8 +67,7 @@ public class Validator { private static final Trace LOGGER = TraceManager.getTrace(Validator.class); private static final String INPUT_STREAM_CHARSET = "utf-8"; private static final String OPERATION_PREFIX = Validator.class.getName() + "."; - private static final String OPERATION_RESOURCE_NAMESPACE_CHECK = OPERATION_PREFIX - + "resourceNamespaceCheck"; + private static final String OPERATION_RESOURCE_NAMESPACE_CHECK = OPERATION_PREFIX + "resourceNamespaceCheck"; private static final String OPERATION_RESOURCE_BASICS_CHECK = OPERATION_PREFIX + "objectBasicsCheck"; private static final String START_LINE_NUMBER = "startLineNumber"; private static final String END_LINE_NUMBER = "endLineNumber"; @@ -76,14 +75,12 @@ public class Validator { private boolean validateSchemas = true; private boolean allowAnyType = false; private EventHandler handler; - private DOMConverter domConverter = new DOMConverter(); - private Unmarshaller unmarshaller = null; private PrismContext prismContext; private Schema midPointJavaxSchema; private javax.xml.validation.Validator xsdValidator; - long progress = 0; - long errors = 0; - long stopAfterErrors = 0; + private long progress = 0; + private long errors = 0; + private long stopAfterErrors = 0; public Validator(PrismContext prismContext) { this.prismContext = prismContext; @@ -161,7 +158,7 @@ public long getErrors() { public void validate(String lexicalRepresentation, OperationResult validationResult, String objectResultOperationName) { try { - try (ByteArrayInputStream is = new ByteArrayInputStream(lexicalRepresentation.getBytes("utf-8"))) { + try (ByteArrayInputStream is = new ByteArrayInputStream(lexicalRepresentation.getBytes(INPUT_STREAM_CHARSET))) { validate(is, validationResult, objectResultOperationName); } } catch (IOException e) { @@ -169,10 +166,11 @@ public void validate(String lexicalRepresentation, OperationResult validationRes } } - public void validate(InputStream inputStream, OperationResult validatorResult, - String objectResultOperationName) { + public void validate(InputStream inputStream, OperationResult validatorResult, String objectResultOperationName) { - XMLStreamReader stream = null; + DOMConverter domConverter = new DOMConverter(); + + XMLStreamReader stream; try { Map rootNamespaceDeclarations = new HashMap(); @@ -189,10 +187,9 @@ public void validate(InputStream inputStream, OperationResult validatorResult, progress++; objectResult.addContext(OperationResult.CONTEXT_PROGRESS, progress); - EventResult cont = null; + EventResult cont; try { - cont = readFromStreamAndValidate(stream, objectResult, - rootNamespaceDeclarations, validatorResult); + cont = readFromStreamAndValidate(stream, objectResult, rootNamespaceDeclarations, validatorResult, domConverter); } catch (RuntimeException e) { // Make sure that unexpected error is recorded. objectResult.recordFatalError(e); @@ -200,7 +197,7 @@ public void validate(InputStream inputStream, OperationResult validatorResult, } if (!cont.isCont()) { - String message = null; + String message; if (cont.getReason() != null) { message = cont.getReason(); } else { @@ -232,11 +229,11 @@ public void validate(InputStream inputStream, OperationResult validatorResult, progress++; objectResult.addContext(OperationResult.CONTEXT_PROGRESS, progress); - EventResult cont = null; + EventResult cont; try { // Read and validate individual object from the stream cont = readFromStreamAndValidate(stream, objectResult, - rootNamespaceDeclarations, validatorResult); + rootNamespaceDeclarations, validatorResult, domConverter); } catch (RuntimeException e) { if (objectResult.isUnknown()) { // Make sure that unexpected error is recorded. @@ -288,7 +285,8 @@ public void validate(InputStream inputStream, OperationResult validatorResult, } private EventResult readFromStreamAndValidate(XMLStreamReader stream, OperationResult objectResult, - Map rootNamespaceDeclarations, OperationResult validatorResult) { + Map rootNamespaceDeclarations, OperationResult validatorResult, + DOMConverter domConverter) { objectResult.addContext(START_LINE_NUMBER, stream.getLocation().getLineNumber()); @@ -376,14 +374,13 @@ private EventResult validateObjectInternal(Element objectElement, OperationResul Objectable objectType = null; if (object != null) { objectType = object.asObjectable(); + objectResult.addContext(OperationResult.CONTEXT_OBJECT, object.toString()); } if (verbose) { LOGGER.trace("Processing OID " + objectType.getOid()); } - objectResult.addContext(OperationResult.CONTEXT_OBJECT, objectType); - validateObject(objectType, objectResult); if (handler != null) { @@ -528,12 +525,12 @@ void checkUri(Objectable object, String value, String propertyName, OperationRes } void error(String message, Objectable object, OperationResult subResult) { - subResult.addContext(OperationResult.CONTEXT_OBJECT, object); + subResult.addContext(OperationResult.CONTEXT_OBJECT, object.toString()); subResult.recordFatalError(message); } void error(String message, Objectable object, String propertyName, OperationResult subResult) { - subResult.addContext(OperationResult.CONTEXT_OBJECT, object); + subResult.addContext(OperationResult.CONTEXT_OBJECT, object.toString()); subResult.addContext(OperationResult.CONTEXT_ITEM, propertyName); subResult.recordFatalError("<" + propertyName + ">: " + message); } diff --git a/infra/prism/pom.xml b/infra/prism/pom.xml index 2c53396aab3..470c7bc5b48 100644 --- a/infra/prism/pom.xml +++ b/infra/prism/pom.xml @@ -133,6 +133,10 @@ org.codehaus.woodstox stax2-api + + org.codehaus.staxmate + staxmate + + + + u1 + + + u2 + + + r1 + + diff --git a/infra/prism/src/test/resources/common/xml/objects-3-ns.xml b/infra/prism/src/test/resources/common/xml/objects-3-ns.xml new file mode 100644 index 00000000000..b35a65b0945 --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-3-ns.xml @@ -0,0 +1,27 @@ + + + + + u1 + + + u2 + + + r1 + + diff --git a/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.json b/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.json new file mode 100644 index 00000000000..2b8bc197bdc --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.json @@ -0,0 +1,18 @@ +{ + "objects" : [ { + "user" : { + "name" : "u1", + "@ns" : "http://b/" + } + }, { + "user" : { + "name" : "u2", + "@ns" : "http://c/" + } + }, { + "role" : { + "name" : "r1", + "@ns" : "http://d/" + } + } ] +} diff --git a/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.xml b/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.xml new file mode 100644 index 00000000000..3e0f9280427 --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-4-no-root-ns.xml @@ -0,0 +1,27 @@ + + + + + u1 + + + u2 + + + r1 + + diff --git a/infra/prism/src/test/resources/common/xml/objects-5-error.json b/infra/prism/src/test/resources/common/xml/objects-5-error.json new file mode 100644 index 00000000000..779eb8bf92b --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-5-error.json @@ -0,0 +1,17 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "user" : { + "name" : "u1" + } + }, { + "user" : { + "name" : "u2" + dsae41io432io432io43i2o43i2432 this is an error + } + }, { + "role" : { + "name" : "r1" + } + } ] +} diff --git a/infra/prism/src/test/resources/common/xml/objects-5-error.xml b/infra/prism/src/test/resources/common/xml/objects-5-error.xml new file mode 100644 index 00000000000..4056a7e7a00 --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-5-error.xml @@ -0,0 +1,28 @@ + + + + + u1 + + + u2 + <<<<<<<<<<<<<<<<< + + + r1 + + diff --git a/infra/prism/src/test/resources/common/xml/objects-6-single.xml b/infra/prism/src/test/resources/common/xml/objects-6-single.xml new file mode 100644 index 00000000000..1e84cfe9b6a --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-6-single.xml @@ -0,0 +1,23 @@ + + + + u1 + u2 + g1 + g2 + f1 + diff --git a/infra/prism/src/test/resources/common/xml/objects-7-single.xml b/infra/prism/src/test/resources/common/xml/objects-7-single.xml new file mode 100644 index 00000000000..7ee9993d905 --- /dev/null +++ b/infra/prism/src/test/resources/common/xml/objects-7-single.xml @@ -0,0 +1,22 @@ + + + + + u1 + g1 + f1 + diff --git a/infra/prism/src/test/resources/common/yaml/objects-1.yaml b/infra/prism/src/test/resources/common/yaml/objects-1.yaml new file mode 100644 index 00000000000..d0722c5f607 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-1.yaml @@ -0,0 +1,12 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + name: "u1" +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + name: "u2" +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +role: + name: "r1" diff --git a/infra/prism/src/test/resources/common/yaml/objects-10-list-of-lists.yaml b/infra/prism/src/test/resources/common/yaml/objects-10-list-of-lists.yaml new file mode 100644 index 00000000000..bd67a61d98c --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-10-list-of-lists.yaml @@ -0,0 +1,9 @@ +--- +- + - user: { name : u1 } + - + - + - user: { name : u2 } + - + - + - user: { name : u3 } diff --git a/infra/prism/src/test/resources/common/yaml/objects-2-wrong-2.yaml b/infra/prism/src/test/resources/common/yaml/objects-2-wrong-2.yaml new file mode 100644 index 00000000000..2d5b74e9c9b --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-2-wrong-2.yaml @@ -0,0 +1,9 @@ +--- +objects: +- user: + name: "u1" +- user: + name: "u2" +- role: + name: "r1" +other: abcdefgh diff --git a/infra/prism/src/test/resources/common/yaml/objects-2-wrong.yaml b/infra/prism/src/test/resources/common/yaml/objects-2-wrong.yaml new file mode 100644 index 00000000000..c3cf2bf214c --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-2-wrong.yaml @@ -0,0 +1,9 @@ +--- +objects: +- user: + name: "u1" +- user: + name: "u2" +- role: + name: "r1" +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" diff --git a/infra/prism/src/test/resources/common/yaml/objects-3-ns.yaml b/infra/prism/src/test/resources/common/yaml/objects-3-ns.yaml new file mode 100644 index 00000000000..9b0a6543a58 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-3-ns.yaml @@ -0,0 +1,11 @@ +--- +objects: +- http://a/#user: + name: "u1" + '@ns': "http://b/" +- http://a/#user: + name: "u2" + '@ns': "http://c/" +- http://a/#role: + name: "r1" + '@ns': "http://d/" diff --git a/infra/prism/src/test/resources/common/yaml/objects-4-no-root-ns.yaml b/infra/prism/src/test/resources/common/yaml/objects-4-no-root-ns.yaml new file mode 100644 index 00000000000..ef27ed80755 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-4-no-root-ns.yaml @@ -0,0 +1,11 @@ +--- +objects: +- user: + name: "u1" + '@ns': "http://b/" +- user: + name: "u2" + '@ns': "http://c/" +- role: + name: "r1" + '@ns': "http://d/" diff --git a/infra/prism/src/test/resources/common/yaml/objects-5-error.yaml b/infra/prism/src/test/resources/common/yaml/objects-5-error.yaml new file mode 100644 index 00000000000..56e1862df34 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-5-error.yaml @@ -0,0 +1,11 @@ +--- +objects: +- user: + name: "u1" +- user: + '@ns': http://a/ + name: "u2" + @#@!#@!#@ # this is an error + givenName: abcdef +- role: + name: "r1" diff --git a/infra/prism/src/test/resources/common/yaml/objects-6-single.yaml b/infra/prism/src/test/resources/common/yaml/objects-6-single.yaml new file mode 100644 index 00000000000..5e42e907253 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-6-single.yaml @@ -0,0 +1,10 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + name: + - "u1" + - "u2" + givenName: + - "g1" + - "g2" + familyName: "f1" \ No newline at end of file diff --git a/infra/prism/src/test/resources/common/yaml/objects-7-single.yaml b/infra/prism/src/test/resources/common/yaml/objects-7-single.yaml new file mode 100644 index 00000000000..17ba0c446d5 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-7-single.yaml @@ -0,0 +1,7 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + - + name: u1 + givenName: g1 + familyName: f1 diff --git a/infra/prism/src/test/resources/common/yaml/objects-8-multi-document.yaml b/infra/prism/src/test/resources/common/yaml/objects-8-multi-document.yaml new file mode 100644 index 00000000000..bb21748bfa0 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-8-multi-document.yaml @@ -0,0 +1,13 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- user: + name: u1 +- user: + name: u2 +--- +- user: + name: u3 +- '@ns': "http://a/" + user: + name: u4 diff --git a/infra/prism/src/test/resources/common/yaml/objects-9-list-single.yaml b/infra/prism/src/test/resources/common/yaml/objects-9-list-single.yaml new file mode 100644 index 00000000000..a689949fb27 --- /dev/null +++ b/infra/prism/src/test/resources/common/yaml/objects-9-list-single.yaml @@ -0,0 +1,5 @@ +--- +- user: + name: u1 + givenName: g1 + familyName: f1 diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java index 6b95b6ac235..e1f5d2a1e44 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java @@ -67,6 +67,7 @@ public PrismContext createPrismContext() throws SchemaException, FileNotFoundExc PrismContextImpl context = PrismContextImpl.create(schemaRegistry); context.setDefinitionFactory(createDefinitionFactory()); context.setDefaultRelation(SchemaConstants.ORG_DEFAULT); + context.setObjectsElementName(SchemaConstants.C_OBJECTS); if (InternalsConfig.isPrismMonitoring()) { context.setMonitor(new InternalMonitor()); } @@ -78,6 +79,7 @@ public PrismContext createEmptyPrismContext() throws SchemaException, FileNotFou PrismContextImpl context = PrismContextImpl.createEmptyContext(schemaRegistry); context.setDefinitionFactory(createDefinitionFactory()); context.setDefaultRelation(SchemaConstants.ORG_DEFAULT); + context.setObjectsElementName(SchemaConstants.C_OBJECTS); return context; } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/PagingTypeFactory.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/PagingTypeFactory.java index 32680f848b3..0bbdffb3628 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/PagingTypeFactory.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/PagingTypeFactory.java @@ -18,7 +18,7 @@ import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import org.apache.commons.lang.StringUtils; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; import com.evolveum.prism.xml.ns._public.query_3.OrderDirectionType; import com.evolveum.prism.xml.ns._public.query_3.PagingType; @@ -55,7 +55,7 @@ public static PagingType createPaging(int offset, int maxSize, OrderDirectionTyp } private static ItemPathType fillPropertyReference(String resolve) { - XPathHolder xpath = new XPathHolder(resolve); + ItemPathHolder xpath = new ItemPathHolder(resolve); return new ItemPathType(xpath.toItemPath()); } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index f7b548ef71e..760238ad989 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -229,6 +229,8 @@ public abstract class SchemaConstants { ResourceType.F_OPERATIONAL_STATE, OperationalStateType.F_LAST_AVAILABILITY_STATUS); public static final ItemPath PATH_ATTRIBUTES = new ItemPath(C_ATTRIBUTES); public static final ItemPath PATH_ASSIGNMENT = new ItemPath(FocusType.F_ASSIGNMENT); + public static final ItemPath PATH_ASSIGNMENT_ACTIVATION = new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION); + public static final ItemPath PATH_ASSIGNMENT_ACTIVATION_EFFECTIVE_STATUS = new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS); public static final ItemPath PATH_ASSOCIATION = new ItemPath(C_ASSOCIATION); public static final ItemPath PATH_TRIGGER = new ItemPath(ObjectType.F_TRIGGER); public static final ItemPath PATH_CREDENTIALS_PASSWORD_FAILED_LOGINS = new ItemPath( diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java index e7cb5956d2b..1eb82f1237d 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java @@ -19,24 +19,38 @@ import java.util.*; import java.util.Map.Entry; +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.util.DebugUtil; + +import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; +import org.w3c.dom.Document; import org.w3c.dom.Element; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.util.ParamsTypeUtil; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.CommonException; +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.LocalizedMessageType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; /** @@ -59,6 +73,7 @@ public class OperationResult implements Serializable, DebugDumpable, Cloneable { private static final long serialVersionUID = -2467406395542291044L; + private static final String VARIOUS_VALUES = "[various values]"; private static final String INDENT_STRING = " "; /** @@ -85,6 +100,7 @@ public class OperationResult implements Serializable, DebugDumpable, Cloneable { public static final String PARAM_OBJECT = "object"; public static final String PARAM_QUERY = "query"; public static final String PARAM_PROJECTION = "projection"; + public static final String PARAM_LANGUAGE = "language"; public static final String RETURN_COUNT = "count"; public static final String RETURN_BACKGROUND_TASK_OID = "backgroundTaskOid"; @@ -92,9 +108,14 @@ public class OperationResult implements Serializable, DebugDumpable, Cloneable { private static long TOKEN_COUNT = 1000000000000000000L; private String operation; private OperationResultStatus status; - private Map params; - private Map context; - private Map returns; + + // Values of the following maps should NOT be null. But in reality it does happen. + // If there is a null value, it should be stored as a single-item collection, where the item is null. + // But the collection should not be null. TODO; fix this + private Map> params; + private Map> context; + private Map> returns; + private long token; private String messageCode; private String message; @@ -151,31 +172,31 @@ public OperationResult(String operation, OperationResultStatus status, long toke this(operation, null, status, token, messageCode, message, null, cause, null); } - public OperationResult(String operation, Map params, OperationResultStatus status, + public OperationResult(String operation, Map> params, OperationResultStatus status, long token, String messageCode, String message) { this(operation, params, status, token, messageCode, message, null, null, null); } - public OperationResult(String operation, Map params, OperationResultStatus status, + public OperationResult(String operation, Map> params, OperationResultStatus status, long token, String messageCode, String message, List subresults) { this(operation, params, status, token, messageCode, message, null, null, subresults); } - public OperationResult(String operation, Map params, OperationResultStatus status, + public OperationResult(String operation, Map> params, OperationResultStatus status, long token, String messageCode, String message, String localizationMessage, Throwable cause, List subresults) { this(operation, params, status, token, messageCode, message, localizationMessage, null, cause, subresults); } - public OperationResult(String operation, Map params, OperationResultStatus status, + public OperationResult(String operation, Map> params, OperationResultStatus status, long token, String messageCode, String message, String localizationMessage, List localizationArguments, Throwable cause, List subresults) { this(operation, params, null, null, status, token, messageCode, message, localizationMessage, null, cause, subresults); } - public OperationResult(String operation, Map params, Map context, Map returns, OperationResultStatus status, + public OperationResult(String operation, Map> params, Map> context, Map> returns, OperationResultStatus status, long token, String messageCode, String message, String localizationMessage, List localizationArguments, Throwable cause, List subresults) { if (StringUtils.isEmpty(operation)) { @@ -422,7 +443,7 @@ public boolean isError() { (status == OperationResultStatus.PARTIAL_ERROR); } - public boolean isFatalError(){ + public boolean isFatalError() { return (status == OperationResultStatus.FATAL_ERROR); } @@ -709,92 +730,292 @@ public void recordNotApplicableIfUnknown() { status = OperationResultStatus.NOT_APPLICABLE; } } + + public boolean isMinor() { + return minor; + } /** * Method returns {@link Map} with operation parameters. Parameters keys are * described in module interface for every operation. - * - * @return never returns null */ - public Map getParams() { + public Map> getParams() { if (params == null) { params = new HashMap<>(); } return params; } - - public void addParam(String paramName, Serializable paramValue) { - getParams().put(paramName, paramValue); + + public Collection getParam(String name) { + return getParams().get(name); + } + + public String getParamSingle(String name) { + Collection values = getParams().get(name); + if (values == null) { + return null; + } + if (values.isEmpty()) { + return null; + } + if (values.size() > 1) { + throw new IllegalStateException("More than one parameter "+name+" in "+this); + } + return values.iterator().next(); } - public void addArbitraryObjectAsParam(String paramName, Object paramValue) { - addParam(paramName, String.valueOf(paramValue)); - } + public void addParam(String name, String value) { + getParams().put(name, collectionize(value)); + } + + public void addParam(String name, PrismObject value) { + getParams().put(name, collectionize(stringify(value))); + } + + public void addParam(String name, ObjectType value) { + getParams().put(name, collectionize(stringify(value))); + } - // Copies a collection to a OperationResult's param field. Primarily used to overcome the fact that Collection is not Serializable - public void addCollectionOfSerializablesAsParam(String paramName, Collection paramValue) { - addParam(paramName, paramValue != null ? new ArrayList<>(paramValue) : null); - } + public void addParam(String name, boolean value) { + getParams().put(name, collectionize(stringify(value))); + } + + public void addParam(String name, long value) { + getParams().put(name, collectionize(stringify(value))); + } + + public void addParam(String name, int value) { + getParams().put(name, collectionize(stringify(value))); + } + + @SuppressWarnings("unchecked") + public void addParam(String name, Class value) { + if (ObjectType.class.isAssignableFrom(value)) { + getParams().put(name, collectionize(ObjectTypes.getObjectType((Class)value).getObjectTypeUri())); + } else { + getParams().put(name, collectionize(stringify(value))); + } + } + + public void addParam(String name, QName value) { + getParams().put(name, collectionize(value == null ? null : QNameUtil.qNameToUri(value))); + } + + public void addParam(String name, PolyString value) { + getParams().put(name, collectionize(value == null ? null : value.getOrig())); + } + + public void addParam(String name, ObjectQuery value) { + getParams().put(name, collectionize(stringify(value))); + } + + public void addParam(String name, ObjectDelta value) { + getParams().put(name, collectionize(stringify(value))); + } + + + public void addParam(String name, String... values) { + getParams().put(name, collectionize(values)); + } - public void addCollectionOfSerializablesAsReturn(String name, Collection value) { - addReturn(name, value != null ? new ArrayList<>(value) : null); + public void addArbitraryObjectAsParam(String paramName, Object paramValue) { + getParams().put(paramName, collectionize(stringify(paramValue))); } - public void addArbitraryCollectionAsParam(String paramName, Collection values) { - if (values != null) { - ArrayList valuesAsStrings = new ArrayList<>(); - for (Object value : values) { - valuesAsStrings.add(String.valueOf(value)); - } - addParam(paramName, valuesAsStrings); - } else { - addParam(paramName, null); - } + public void addArbitraryObjectCollectionAsParam(String name, Collection value) { + getParams().put(name, stringifyCol(value)); } - - public void addParams(String[] names, Serializable... objects) { - if (names.length != objects.length) { - throw new IllegalArgumentException("Bad result parameters size, names '" + names.length - + "', objects '" + objects.length + "'."); - } - - for (int i = 0; i < names.length; i++) { - addParam(names[i], objects[i]); - } - } - - public Map getContext() { + public Map> getContext() { if (context == null) { context = new HashMap<>(); } return context; } - + + public void addContext(String name, String value) { + getContext().put(name, collectionize(value)); + } + + public void addContext(String name, PrismObject value) { + getContext().put(name, collectionize(stringify(value))); + } + + public void addContext(String name, ObjectType value) { + getContext().put(name, collectionize(stringify(value))); + } + + public void addContext(String name, boolean value) { + getContext().put(name, collectionize(stringify(value))); + } + + public void addContext(String name, long value) { + getContext().put(name, collectionize(stringify(value))); + } + + public void addContext(String name, int value) { + getContext().put(name, collectionize(stringify(value))); + } + @SuppressWarnings("unchecked") - public T getContext(Class type, String contextName) { - return (T) getContext().get(contextName); + public void addContext(String name, Class value) { + if (ObjectType.class.isAssignableFrom(value)) { + getContext().put(name, collectionize(ObjectTypes.getObjectType((Class)value).getObjectTypeUri())); + } else { + getContext().put(name, collectionize(stringify(value))); + } } - - public void addContext(String contextName, Serializable value) { - getContext().put(contextName, value); + + public void addContext(String name, QName value) { + getContext().put(name, collectionize(value == null ? null : QNameUtil.qNameToUri(value))); } + + public void addContext(String name, PolyString value) { + getContext().put(name, collectionize(value == null ? null : value.getOrig())); + } + + public void addContext(String name, ObjectQuery value) { + getContext().put(name, collectionize(stringify(value))); + } + + public void addContext(String name, ObjectDelta value) { + getContext().put(name, collectionize(stringify(value))); + } + + + public void addContext(String name, String... values) { + getContext().put(name, collectionize(values)); + } + + public void addArbitraryObjectAsContext(String name, Object value) { + getContext().put(name, collectionize(stringify(value))); + } - public Map getReturns() { + public void addArbitraryObjectCollectionAsContext(String paramName, Collection paramValue) { + getContext().put(paramName, stringifyCol(paramValue)); + } + + public Map> getReturns() { if (returns == null) { returns = new HashMap<>(); } return returns; } + + public Collection getReturn(String name) { + return getReturns().get(name); + } + + public String getReturnSingle(String name) { + Collection values = getReturns().get(name); + if (values == null) { + return null; + } + if (values.isEmpty()) { + return null; + } + if (values.size() > 1) { + throw new IllegalStateException("More than one return "+name+" in "+this); + } + return values.iterator().next(); + } - public void addReturn(String returnName, Serializable value) { - getReturns().put(returnName, value); + public void addReturn(String name, String value) { + getReturns().put(name, collectionize(value)); + } + + public void addReturn(String name, PrismObject value) { + getReturns().put(name, collectionize(stringify(value))); + } + + public void addReturn(String name, ObjectType value) { + getReturns().put(name, collectionize(stringify(value))); + } + + public void addReturn(String name, boolean value) { + getReturns().put(name, collectionize(stringify(value))); + } + + public void addReturn(String name, long value) { + getReturns().put(name, collectionize(stringify(value))); + } + + public void addReturn(String name, int value) { + getReturns().put(name, collectionize(stringify(value))); + } + + @SuppressWarnings("unchecked") + public void addReturn(String name, Class value) { + if (ObjectType.class.isAssignableFrom(value)) { + getReturns().put(name, collectionize(ObjectTypes.getObjectType((Class)value).getObjectTypeUri())); + } else { + getReturns().put(name, collectionize(stringify(value))); + } + } + + public void addReturn(String name, QName value) { + getReturns().put(name, collectionize(value == null ? null : QNameUtil.qNameToUri(value))); + } + + public void addReturn(String name, PolyString value) { + getReturns().put(name, collectionize(value == null ? null : value.getOrig())); + } + + public void addReturn(String name, ObjectQuery value) { + getReturns().put(name, collectionize(stringify(value))); } + + public void addReturn(String name, ObjectDelta value) { + getReturns().put(name, collectionize(stringify(value))); + } + + + public void addReturn(String name, String... values) { + getReturns().put(name, collectionize(values)); + } + + public void addArbitraryObjectAsReturn(String name, Object value) { + getReturns().put(name, collectionize(stringify(value))); + } - public Serializable getReturn(String returnName) { - return getReturns().get(returnName); + public void addArbitraryObjectCollectionAsReturn(String paramName, Collection paramValue) { + getReturns().put(paramName, stringifyCol(paramValue)); + } + + private String stringify(Object value) { + if (value == null) { + return null; + } else { + return value.toString(); + } + } + + private Collection collectionize(String value) { + Collection out = new ArrayList<>(1); + out.add(value); + return out; + } + + private Collection collectionize(String... values) { + return Arrays.asList(values); + } + + private Collection stringifyCol(Collection values) { + if (values == null) { + return null; + } + Collection out = new ArrayList<>(values.size()); + for (Object value: values) { + if (value == null) { + out.add(null); + } else { + out.add(value.toString()); + } + } + return out; } + /** * @return Contains random long number, for better searching in logs. */ @@ -993,21 +1214,14 @@ public List getDetail() { return details; } - @Override - public String toString() { - return "R(" + operation + " " + status + " " + message + ")"; - } - - - - public static OperationResult createOperationResult(OperationResultType result) { + public static OperationResult createOperationResult(OperationResultType result) throws SchemaException { if (result == null) { return null; } - Map params = ParamsTypeUtil.fromParamsType(result.getParams()); - Map context = ParamsTypeUtil.fromParamsType(result.getContext()); - Map returns = ParamsTypeUtil.fromParamsType(result.getReturns()); + Map> params = ParamsTypeUtil.fromParamsType(result.getParams()); + Map> context = ParamsTypeUtil.fromParamsType(result.getContext()); + Map> returns = ParamsTypeUtil.fromParamsType(result.getReturns()); List subresults = null; if (!result.getPartialResults().isEmpty()) { @@ -1025,6 +1239,7 @@ public static OperationResult createOperationResult(OperationResultType result) OperationResultStatus.parseStatusType(result.getStatus()), result.getToken(), result.getMessageCode(), result.getMessage(), localizedMessage, localizedArguments, null, subresults); + opResult.setMinor(BooleanUtils.isTrue(result.isMinor())); if (result.getCount() != null) { opResult.setCount(result.getCount()); } @@ -1039,18 +1254,21 @@ public OperationResultType createOperationResultType() { } private OperationResultType createOperationResultType(OperationResult opResult) { - OperationResultType result = new OperationResultType(); - result.setToken(opResult.getToken()); - result.setStatus(OperationResultStatus.createStatusType(opResult.getStatus())); + OperationResultType resultType = new OperationResultType(); + resultType.setToken(opResult.getToken()); + resultType.setStatus(OperationResultStatus.createStatusType(opResult.getStatus())); + if (opResult.isMinor()) { + resultType.setMinor(true); + } if (opResult.getCount() != 1) { - result.setCount(opResult.getCount()); + resultType.setCount(opResult.getCount()); } if (opResult.getHiddenRecordsCount() != 0) { - result.setHiddenRecordsCount(opResult.getHiddenRecordsCount()); + resultType.setHiddenRecordsCount(opResult.getHiddenRecordsCount()); } - result.setOperation(opResult.getOperation()); - result.setMessage(opResult.getMessage()); - result.setMessageCode(opResult.getMessageCode()); + resultType.setOperation(opResult.getOperation()); + resultType.setMessage(opResult.getMessage()); + resultType.setMessageCode(opResult.getMessageCode()); if (opResult.getCause() != null || !opResult.details.isEmpty()) { StringBuilder detailsb = new StringBuilder(); @@ -1077,7 +1295,7 @@ private OperationResultType createOperationResultType(OperationResult opResult) } } - result.setDetails(detailsb.toString()); + resultType.setDetails(detailsb.toString()); } if (StringUtils.isNotEmpty(opResult.getLocalizationMessage())) { @@ -1086,18 +1304,18 @@ private OperationResultType createOperationResultType(OperationResult opResult) if (opResult.getLocalizationArguments() != null) { message.getArgument().addAll(opResult.getLocalizationArguments()); } - result.setLocalizedMessage(message); + resultType.setLocalizedMessage(message); } - result.setParams(ParamsTypeUtil.toParamsType(opResult.getParams())); - result.setContext(ParamsTypeUtil.toParamsType(opResult.getContext())); - result.setReturns(ParamsTypeUtil.toParamsType(opResult.getReturns())); + resultType.setParams(ParamsTypeUtil.toParamsType(opResult.getParams())); + resultType.setContext(ParamsTypeUtil.toParamsType(opResult.getContext())); + resultType.setReturns(ParamsTypeUtil.toParamsType(opResult.getReturns())); for (OperationResult subResult : opResult.getSubresults()) { - result.getPartialResults().add(opResult.createOperationResultType(subResult)); + resultType.getPartialResults().add(opResult.createOperationResultType(subResult)); } - return result; + return resultType; } public void summarize() { @@ -1197,29 +1415,35 @@ private void merge(OperationResult target, OperationResult source) { target.incrementCount(); } - private void mergeMap(Map targetMap, Map sourceMap) { - for (Entry targetEntry: targetMap.entrySet()) { + private void mergeMap(Map> targetMap, Map> sourceMap) { + for (Entry> targetEntry: targetMap.entrySet()) { String targetKey = targetEntry.getKey(); - Serializable targetValue = targetEntry.getValue(); - if (targetValue instanceof VariousValues) { + Collection targetValues = targetEntry.getValue(); + if (targetValues != null && targetValues.contains(VARIOUS_VALUES)) { continue; } - Serializable sourceValue = sourceMap.get(targetKey); - if (MiscUtil.equals(targetValue, sourceValue)) { + Collection sourceValues = sourceMap.get(targetKey); + if (MiscUtil.equals(targetValues, sourceValues)) { // Entries match, nothing to do continue; } // Entries do not match. The target entry needs to be marked as VariousValues - targetEntry.setValue(new VariousValues()); + targetEntry.setValue(createVariousValues()); } - for (Entry sourceEntry: sourceMap.entrySet()) { + for (Entry> sourceEntry: sourceMap.entrySet()) { String sourceKey = sourceEntry.getKey(); if (!targetMap.containsKey(sourceKey)) { - targetMap.put(sourceKey, new VariousValues()); + targetMap.put(sourceKey, createVariousValues()); } } } + private Collection createVariousValues() { + List out = new ArrayList<>(1); + out.add(VARIOUS_VALUES); + return out; + } + private OperationResult findSimilarSubresult(OperationResult subresult) { OperationResult similar = null; for (OperationResult sub: getSubresults()) { @@ -1324,7 +1548,7 @@ private void dumpIndent(StringBuilder sb, int indent, boolean printStackTrace) { } sb.append("\n"); - for (Map.Entry entry : getParams().entrySet()) { + for (Map.Entry> entry : getParams().entrySet()) { DebugUtil.indentDebugDump(sb, indent + 2); sb.append("[p]"); sb.append(entry.getKey()); @@ -1333,7 +1557,7 @@ private void dumpIndent(StringBuilder sb, int indent, boolean printStackTrace) { sb.append("\n"); } - for (Map.Entry entry : getContext().entrySet()) { + for (Map.Entry> entry : getContext().entrySet()) { DebugUtil.indentDebugDump(sb, indent + 2); sb.append("[c]"); sb.append(entry.getKey()); @@ -1342,7 +1566,7 @@ private void dumpIndent(StringBuilder sb, int indent, boolean printStackTrace) { sb.append("\n"); } - for (Map.Entry entry : getReturns().entrySet()) { + for (Map.Entry> entry : getReturns().entrySet()) { DebugUtil.indentDebugDump(sb, indent + 2); sb.append("[r]"); sb.append(entry.getKey()); @@ -1376,19 +1600,17 @@ private void dumpIndent(StringBuilder sb, int indent, boolean printStackTrace) { } } - private String dumpEntry(int indent, Serializable value) { - if (value instanceof Element) { - Element element = (Element)value; - if (SchemaConstants.C_VALUE.equals(DOMUtil.getQName(element))) { - try { - String cvalue = SchemaDebugUtil.prettyPrint(XmlTypeConverter.toJavaValue(element)); - return DebugUtil.fixIndentInMultiline(indent, INDENT_STRING, cvalue); - } catch (Exception e) { - return DebugUtil.fixIndentInMultiline(indent, INDENT_STRING, "value: " + element.getTextContent()); - } - } + private String dumpEntry(int indent, Collection values) { + if (values == null) { + return null; + } + if (values.size() == 0) { + return "(empty)"; + } + if (values.size() == 1) { + return values.iterator().next(); } - return DebugUtil.fixIndentInMultiline(indent, INDENT_STRING, SchemaDebugUtil.prettyPrint(value)); + return values.toString(); } private void dumpInnerCauses(StringBuilder sb, Throwable innerCause, int indent) { @@ -1419,8 +1641,7 @@ public void setBackgroundTaskOid(String oid) { } public String getBackgroundTaskOid() { - Object oid = getReturns().get(RETURN_BACKGROUND_TASK_OID); - return oid != null ? String.valueOf(oid) : null; + return getReturnSingle(RETURN_BACKGROUND_TASK_OID); } public void setMinor(boolean value) { @@ -1473,9 +1694,9 @@ public OperationResult clone() { OperationResult clone = new OperationResult(operation); clone.status = status; - clone.params = CloneUtil.clone(params); - clone.context = CloneUtil.clone(context); - clone.returns = CloneUtil.clone(returns); + clone.params = cloneParams(params); + clone.context = cloneParams(context); + clone.returns = cloneParams(returns); clone.token = token; clone.messageCode = messageCode; clone.message = message; @@ -1502,6 +1723,11 @@ public OperationResult clone() { return clone; } + private Map> cloneParams(Map> map) { + // TODO: implement more efficient clone + return CloneUtil.clone(map); + } + public static int getSubresultStripThreshold() { return subresultStripThreshold; } @@ -1510,4 +1736,161 @@ public static int getSubresultStripThreshold() { public static void setSubresultStripThreshold(Integer value) { subresultStripThreshold = value != null ? value : DEFAULT_SUBRESULT_STRIP_THRESHOLD; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((asynchronousOperationReference == null) ? 0 : asynchronousOperationReference.hashCode()); + result = prime * result + ((cause == null) ? 0 : cause.hashCode()); + result = prime * result + ((context == null) ? 0 : context.hashCode()); + result = prime * result + count; + result = prime * result + ((details == null) ? 0 : details.hashCode()); + result = prime * result + hiddenRecordsCount; + result = prime * result + ((localizationArguments == null) ? 0 : localizationArguments.hashCode()); + result = prime * result + ((localizationMessage == null) ? 0 : localizationMessage.hashCode()); + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + ((messageCode == null) ? 0 : messageCode.hashCode()); + result = prime * result + (minor ? 1231 : 1237); + result = prime * result + ((operation == null) ? 0 : operation.hashCode()); + result = prime * result + ((params == null) ? 0 : params.hashCode()); + result = prime * result + ((returns == null) ? 0 : returns.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((subresults == null) ? 0 : subresults.hashCode()); + result = prime * result + (summarizeErrors ? 1231 : 1237); + result = prime * result + (summarizePartialErrors ? 1231 : 1237); + result = prime * result + (summarizeSuccesses ? 1231 : 1237); + result = prime * result + (int) (token ^ (token >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + OperationResult other = (OperationResult) obj; + if (asynchronousOperationReference == null) { + if (other.asynchronousOperationReference != null) { + return false; + } + } else if (!asynchronousOperationReference.equals(other.asynchronousOperationReference)) { + return false; + } + if (cause == null) { + if (other.cause != null) { + return false; + } + } else if (!cause.equals(other.cause)) { + return false; + } + if (context == null) { + if (other.context != null) { + return false; + } + } else if (!context.equals(other.context)) { + return false; + } + if (count != other.count) { + return false; + } + if (details == null) { + if (other.details != null) { + return false; + } + } else if (!details.equals(other.details)) { + return false; + } + if (hiddenRecordsCount != other.hiddenRecordsCount) { + return false; + } + if (localizationArguments == null) { + if (other.localizationArguments != null) { + return false; + } + } else if (!localizationArguments.equals(other.localizationArguments)) { + return false; + } + if (localizationMessage == null) { + if (other.localizationMessage != null) { + return false; + } + } else if (!localizationMessage.equals(other.localizationMessage)) { + return false; + } + if (message == null) { + if (other.message != null) { + return false; + } + } else if (!message.equals(other.message)) { + return false; + } + if (messageCode == null) { + if (other.messageCode != null) { + return false; + } + } else if (!messageCode.equals(other.messageCode)) { + return false; + } + if (minor != other.minor) { + return false; + } + if (operation == null) { + if (other.operation != null) { + return false; + } + } else if (!operation.equals(other.operation)) { + return false; + } + if (params == null) { + if (other.params != null) { + return false; + } + } else if (!params.equals(other.params)) { + return false; + } + if (returns == null) { + if (other.returns != null) { + return false; + } + } else if (!returns.equals(other.returns)) { + return false; + } + if (status != other.status) { + return false; + } + if (subresults == null) { + if (other.subresults != null) { + return false; + } + } else if (!subresults.equals(other.subresults)) { + return false; + } + if (summarizeErrors != other.summarizeErrors) { + return false; + } + if (summarizePartialErrors != other.summarizePartialErrors) { + return false; + } + if (summarizeSuccesses != other.summarizeSuccesses) { + return false; + } + if (token != other.token) { + return false; + } + return true; + } + + @Override + public String toString() { + return "R(" + operation + " " + status + " " + message + ")"; + } + } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java index cf66837fe3b..c7101adf1ee 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java @@ -18,8 +18,8 @@ import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; -import com.evolveum.midpoint.prism.marshaller.XPathSegment; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; +import com.evolveum.midpoint.prism.marshaller.PathHolderSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectFilter; @@ -400,11 +400,11 @@ public static void setXsdSchemaDefinition(PrismProperty de definitionProperty.setRealValue(schemaDefinition); } - public static XPathHolder createXPathHolder(QName property) { - XPathSegment xpathSegment = new XPathSegment(property); - List segmentlist = new ArrayList(1); + public static ItemPathHolder createXPathHolder(QName property) { + PathHolderSegment xpathSegment = new PathHolderSegment(property); + List segmentlist = new ArrayList(1); segmentlist.add(xpathSegment); - XPathHolder xpath = new XPathHolder(segmentlist); + ItemPathHolder xpath = new ItemPathHolder(segmentlist); return xpath; } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ParamsTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ParamsTypeUtil.java index 3a3acd98d08..2d5ac829d54 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ParamsTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ParamsTypeUtil.java @@ -1,75 +1,67 @@ +/** + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.evolveum.midpoint.schema.util; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.Set; import java.util.Map.Entry; +import java.util.Set; import javax.xml.bind.JAXBElement; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.xnode.RootXNode; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.SerializationContext; -import com.evolveum.midpoint.prism.SerializationOptions; -import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.prism.xnode.XNode; -import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.EntryType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ParamsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UnknownJavaObjectType; import com.evolveum.prism.xml.ns._public.types_3.RawType; public class ParamsTypeUtil { - public static ParamsType toParamsType(Map paramsMap){ - Set> params = paramsMap.entrySet(); - if (!params.isEmpty()) { - ParamsType paramsType = new ParamsType(); - - for (Entry entry : params) { - paramsType.getEntry().add(createEntryElement(entry.getKey(),entry.getValue())); - } - return paramsType; - } - return null; - } - - public static ParamsType toParamsType(Map paramsMap, PrismContext prismContext) throws SchemaException{ - Set> params = paramsMap.entrySet(); + public static ParamsType toParamsType(Map> paramsMap){ + Set>> params = paramsMap.entrySet(); if (!params.isEmpty()) { ParamsType paramsType = new ParamsType(); - for (Entry entry : params) { - paramsType.getEntry().add(createEntryElement(entry, prismContext)); + for (Entry> entry : params) { + if (entry.getValue() == null) { + paramsType.getEntry().add(createEntryElement(entry.getKey(), null)); + } else { + for (String value: entry.getValue()) { + paramsType.getEntry().add(createEntryElement(entry.getKey(), value)); + } + } } return paramsType; } return null; } - private static EntryType createEntryElement(Entry entry, PrismContext prismContext) throws SchemaException { - EntryType result = new EntryType(); - result.setKey(entry.getKey()); - if (XmlTypeConverter.canConvert(entry.getValue().getClass())){ - return createEntryElement(entry.getKey(), entry.getValue()); - } else { - RootXNode xnode = prismContext.xnodeSerializer() - .options(SerializationOptions.createSerializeReferenceNames()) - .serializeAnyData(entry.getValue(), SchemaConstants.C_PARAM_VALUE); - return createEntryElement(entry.getKey(), new RawType(xnode, prismContext)); + private static EntryType createEntryElement(String key, String value) { + EntryType entryType = new EntryType(); + entryType.setKey(key); + if (value != null) { + entryType.setEntryValue(new JAXBElement(SchemaConstants.C_PARAM_VALUE, Serializable.class, value)); } + return entryType; } public static Map fromParamsType(ParamsType paramsType, PrismContext prismContext) throws SchemaException{ @@ -97,96 +89,35 @@ public static Map fromParamsType(ParamsType paramsType, Pr return null; } - public static Map fromParamsType(ParamsType paramsType) { + public static Map> fromParamsType(ParamsType paramsType) throws SchemaException { if (paramsType != null) { - Map params = new HashMap(); + Map> params = new HashMap<>(); Serializable realValue = null; for (EntryType entry : paramsType.getEntry()) { - if (entry.getEntryValue() != null){ - -// Serializable value = (Serializable) entry.getEntryValue().getValue(); -// if (value instanceof RawType){ -// XNode xnode = ((RawType) value).getXnode(); -// if (xnode instanceof PrimitiveXNode){ -// realValue = ((PrimitiveXNode) xnode).getGuessedFormattedValue(); -// } -// } else { -// realValue = value; -// } -// } - params.put(entry.getKey(), (Serializable) entry.getEntryValue()); + if (entry.getEntryValue() != null) { + String newValue = extractString(entry.getEntryValue()); + Collection values = params.get(entry.getKey()); + if (values == null) { + values = new ArrayList<>(); + params.put(entry.getKey(), values); + } + values.add(newValue); } } - return params; } return null; } - - /** - * Temporary workaround, brutally hacked -- so that the conversion - * of OperationResult into OperationResultType 'somehow' works, at least to the point - * where when we: - * - have OR1 - * - serialize it into ORT1 - * - then deserialize into OR2 - * - serialize again into ORT2 - * so we get ORT1.equals(ORT2) - at least in our simple test case :) - * - * FIXME: this should be definitely reworked - * - * @param entry - * @return - */ - private static EntryType createEntryElement(String key, Serializable value) { - EntryType entryType = new EntryType(); - entryType.setKey(key); - if (value != null) { - Document doc = DOMUtil.getDocument(); - if (value instanceof ObjectType && ((ObjectType)value).getOid() != null) { - // Store only reference on the OID. This is faster and getObject can be used to retrieve - // the object if needed. Although is does not provide 100% accuracy, it is a good tradeoff. - setObjectReferenceEntry(entryType, ((ObjectType)value)); - // these values should be put 'as they are', in order to be deserialized into themselves - } else if (value instanceof String || value instanceof Integer || value instanceof Long) { - entryType.setEntryValue(new JAXBElement(SchemaConstants.C_PARAM_VALUE, Serializable.class, value)); - } else if (XmlTypeConverter.canConvert(value.getClass())) { -// try { -// entryType.setEntryValue(new JXmlTypeConverter.toXsdElement(value, SchemaConstants.C_PARAM_VALUE, doc, true)); -// } catch (SchemaException e) { -// LOGGER.error("Cannot convert value {} to XML: {}",value,e.getMessage()); -// setUnknownJavaObjectEntry(entryType, value); -// } - } else if (value instanceof Element || value instanceof JAXBElement) { - entryType.setEntryValue((JAXBElement) value); - // FIXME: this is really bad code ... it means that 'our' JAXB object should be put as is - } else if ("com.evolveum.midpoint.xml.ns._public.common.common_3".equals(value.getClass().getPackage().getName())) { - JAXBElement o = new JAXBElement(SchemaConstants.C_PARAM_VALUE, Object.class, value); - entryType.setEntryValue(o); - } else { - setUnknownJavaObjectEntry(entryType, value); - } - } - return entryType; - } - private static void setObjectReferenceEntry(EntryType entryType, ObjectType objectType) { - ObjectReferenceType objRefType = new ObjectReferenceType(); - objRefType.setOid(objectType.getOid()); - ObjectTypes type = ObjectTypes.getObjectType(objectType.getClass()); - if (type != null) { - objRefType.setType(type.getTypeQName()); + private static String extractString(JAXBElement jaxbElement) throws SchemaException { + Object value = jaxbElement.getValue(); + if (value instanceof RawType){ + XNode xnode = ((RawType) value).getXnode(); + if (xnode instanceof PrimitiveXNode) { + value = ((PrimitiveXNode) xnode).getStringValue(); + } } - JAXBElement element = new JAXBElement( - SchemaConstants.C_OBJECT_REF, ObjectReferenceType.class, objRefType); -// entryType.setAny(element); + return value.toString(); } - - private static void setUnknownJavaObjectEntry(EntryType entryType, Serializable value) { - UnknownJavaObjectType ujo = new UnknownJavaObjectType(); - ujo.setClazz(value.getClass().getName()); - ujo.setToString(value.toString()); - entryType.setEntryValue(new ObjectFactory().createUnknownJavaObject(ujo)); - } - + } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java index f7af75c0c23..f06d8b1401f 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java @@ -35,7 +35,7 @@ import org.w3c.dom.NodeList; import org.w3c.dom.Text; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -459,7 +459,7 @@ public static String prettyPrint(ItemDeltaType change) throws SchemaException { sb.append(","); if (change.getPath() != null) { //FIXME : xpath vs itemPath - XPathHolder xpath = new XPathHolder(change.getPath().getItemPath()); + ItemPathHolder xpath = new ItemPathHolder(change.getPath().getItemPath()); sb.append(xpath.toString()); } else { sb.append("xpath=null"); 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 c68126dd1ed..f580d3cbfe3 100644 --- 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 @@ -2626,15 +2626,22 @@

Indicates user's preferred language, usually for the purpose of localizing - user interfaces. The format is ISO 639-1 two letter language code and the - ISO 3166-1 two letter country code separated by underscore. If not specified - then system default locale is assumed. + user interfaces. The format is IETF language tag defined in BCP 47, where + underscore is used as a subtag separator. This is usually a ISO 639-1 two-letter + language code optionally followed by ISO 3166-1 two letter country code + separated by underscore. The languages that do not have coutry-specific + variants are usually specified by using a two-letter coutry code ("sk", + "cs", "tr"). Languages with coutry-specific variants have country-specific + subtags ("pt_BR", "zn_CN"). + If no value is specified in this property then system default locale is assumed.

Examples:

  • en_US
  • -
  • sk_SK
  • +
  • sk
  • +
  • cs
  • +
  • pt_BR

@@ -2651,15 +2658,22 @@

Defines user's preference in displaying currency, dates and other items - related to location and culture. The format ISO 639-1 two letter language code and the - ISO 3166-1 two letter country code separated by underscore. If not specified - then system default locale is assumed. + related to location and culture. The format is IETF language tag defined in BCP 47, where + underscore is used as a subtag separator. This is usually a ISO 639-1 two-letter + language code optionally followed by ISO 3166-1 two letter country code + separated by underscore. The languages that do not have coutry-specific + variants are usually specified by using a two-letter coutry code ("sk", + "cs", "tr"). Languages with coutry-specific variants have country-specific + subtags ("pt_BR", "zn_CN"). + If not specified then system default locale is assumed.

Examples:

  • en_US
  • -
  • sk_SK
  • +
  • sk
  • +
  • cs
  • +
  • pt_BR

@@ -10593,6 +10607,7 @@ + @@ -10889,7 +10904,7 @@ Definition of default object policy for a individual object type. The definition of this policy contains object template and other similar settings. The policy will be used - "universally" during all operations with specified object types - unless it is overriden + "universally" during all operations with specified object types - unless it is overridden in other definitions (e.g. in resource or org). @@ -11529,7 +11544,7 @@ - + Specification of the type (class) of the object to apply this definition to. @@ -11541,35 +11556,138 @@ Specification of the subtype of the object to apply this template to. If no subtype is specified then this definition will be applied to all subtypes. - The subtype is compared agains the subType property but it is also compared to the + The subtype is compared against the subType property but it is also compared to the deprecated employeeType, roleType, orgType and serviceType properties. - - - Reference to the template. - - - tns:ObjectTemplateType - - - - - - - - A mode in which OID and name of the specified object are the same. - - - true - - - + + + Reference to the template. + + + tns:ObjectTemplateType + + + + + + + + A mode in which OID and name of the specified object are the same. + + + true + + + + + + + How to resolve write-write conflicts on focal objects, i.e. if two threads modify given objects at once. + + + 3.6.1 + + + - + + + + + How to resolve write-write conflicts on focal objects, i.e. if two threads modify given objects at once. + + + + 3.6.1 + + + + + + + What action to take. + + + + + + + How many attempts to undertake at most. + + + + + + + What delay (in milliseconds) to introduce between attempts. Actual delay is taken as + a random number between 0 and delayUnit*(2^(n-1)), where n is the number of conflict resolution attempt, + starting at 1. (In other words, the potential delay is multiplied by two after each unsuccessful + resolution attempt.) + + + + + + + + + + What to do in the case of modify-modify conflict during model (clockwork) operation. + + + + 3.6.1 + + + + + + + Nothing should be done. This is the default behavior. + + + + + + + + + + Warning should be issued into the log file. + + + + + + + + + + The focus object should be recomputed. + + + + + + + + + + The whole operation should fail. This is to be used mainly for testing purposes, + to check if conflict detection algorithm does not yield false positive results. + + + + + + + + + @@ -12113,6 +12231,13 @@ + + + + Prudent mode allows remote and shared file destinations (see https://logback.qos.ch/manual/appenders.html#prudentWithRolling ) + + + diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestConstants.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestConstants.java index 379cabbf3df..558b81a36ea 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestConstants.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestConstants.java @@ -62,4 +62,5 @@ public class TestConstants { public static final String METAROLE_FILE_BASENAME = "metarole"; public static final String OBJECTS_FILE_BASENAME = "objects"; + public static final String OBJECTS_WRONG_FILE_BASENAME = "objects-wrong"; } diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestOperationResult.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestOperationResult.java index 52acde388c1..35abc60e6c8 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestOperationResult.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestOperationResult.java @@ -15,8 +15,10 @@ */ package com.evolveum.midpoint.schema; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.constants.MidPointConstants; +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.util.PrettyPrinter; @@ -43,7 +45,6 @@ public void setup() throws SchemaException, SAXException, IOException { PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); } - @Test public void testCleanup() throws Exception { System.out.println("===[ testCleanup ]==="); @@ -51,10 +52,10 @@ public void testCleanup() throws Exception { // GIVEN (checks also conversions during result construction) OperationResult root = new OperationResult("dummy"); - checkResultConversion(root); + checkResultConversion(root, true); OperationResult sub1 = root.createSubresult("sub1"); - checkResultConversion(root); + checkResultConversion(root, true); OperationResult sub11 = sub1.createMinorSubresult("sub11"); OperationResult sub12 = sub1.createMinorSubresult("sub12"); @@ -62,12 +63,12 @@ public void testCleanup() throws Exception { OperationResult sub2 = root.createSubresult("sub2"); sub2.recordFatalError("Fatal"); - checkResultConversion(root); + checkResultConversion(root, true); sub11.recordSuccess(); sub12.recordWarning("Warning"); sub13.recordSuccess(); - checkResultConversion(root); + checkResultConversion(root, true); // WHEN sub1.computeStatus(); @@ -81,7 +82,7 @@ public void testCleanup() throws Exception { assertEquals("Wrong status of sub1", OperationResultStatus.WARNING, sub1.getStatus()); // because of sub12 assertEquals("Wrong # of sub1 subresults", 2, sub1.getSubresults().size()); - checkResultConversion(root); + checkResultConversion(root, true); } @Test @@ -114,7 +115,7 @@ public void testSummarizeByHiding() throws Exception { assertEquals("Wrong status in summary", OperationResultStatus.SUCCESS, summary.getStatus()); assertEquals("Wrong hidden records count in summary", 20, summary.getHiddenRecordsCount()); - checkResultConversion(root); + checkResultConversion(root, true); } @Test @@ -149,7 +150,7 @@ public void testExplicitSummarization() throws Exception { assertEquals("Wrong message in summary", "message", summary.getMessage()); assertEquals("Wrong count in summary", 30, summary.getCount()); - checkResultConversion(root); + checkResultConversion(root, false); // summarization settings are not serialized } @Test @@ -202,17 +203,22 @@ public void testIncrementalSummarization() throws Exception { } } - checkResultConversion(root); + checkResultConversion(root, true); } - private void checkResultConversion(OperationResult result) { + private void checkResultConversion(OperationResult result, boolean assertEquals) throws SchemaException { // WHEN OperationResultType resultType = result.createOperationResultType(); - OperationResult result1 = OperationResult.createOperationResult(resultType); - OperationResultType resultType1 = result1.createOperationResultType(); + String serialized = PrismTestUtil.getPrismContext().serializerFor(PrismContext.LANG_XML).serializeAnyData(resultType, SchemaConstants.C_RESULT); + System.out.println("Converted OperationResultType\n" + serialized); + OperationResult resultRoundTrip = OperationResult.createOperationResult(resultType); + OperationResultType resultTypeRoundTrip = resultRoundTrip.createOperationResultType(); // THEN - assertEquals("Operation result conversion changes the result", resultType, resultType1); + assertEquals("Operation result conversion changes the result (OperationResultType)", resultType, resultTypeRoundTrip); + if (assertEquals) { + assertEquals("Operation result conversion changes the result (OperationResult)", result, resultRoundTrip); + } } } diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestSerialization.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestSerialization.java index daaea9b1526..2ff5386390d 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestSerialization.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestSerialization.java @@ -96,7 +96,7 @@ private void serializationRoundTrip(File file) throws Exc PrismObject parsedObject = prismContext.parseObject(file); - System.out.println("Parsed object:"); + System.out.println("\nParsed object:"); System.out.println(parsedObject.debugDump()); serializationRoundTripPrismObject(parsedObject); @@ -109,9 +109,11 @@ private void serializationRoundTripPrismObject(PrismObjec String serializedObject = SerializationUtil.toString(parsedObject); // THEN + System.out.println("\nSerialized object:"); + System.out.println(serializedObject); PrismObject deserializedObject = SerializationUtil.fromString(serializedObject); - System.out.println("Deserialized object (PrismObject):"); + System.out.println("\nDeserialized object (PrismObject):"); System.out.println(deserializedObject.debugDump()); ObjectDelta diff = parsedObject.diff(deserializedObject); diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjects.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjects.java index b48e3bf6e83..6dd7813a7f3 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjects.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjects.java @@ -58,15 +58,25 @@ public void testRoundTrip() throws Exception { assertEquals("Wrong class of object 2", RoleType.class, objects.get(2).asObjectable().getClass()); PrismSerializer serializer = prismContext.serializerFor(language); - String serialized = serializer.serializeObjects(objects, SchemaConstants.C_OBJECTS); - System.out.println("Objects as re-serialized:\n" + serialized); + String serializedAsObjects = serializer.serializeObjects(objects, SchemaConstants.C_OBJECTS); + System.out.println("Objects as re-serialized (c:objects):\n" + serializedAsObjects); System.out.println("Re-serialized to XML:\n" + prismContext.xmlSerializer().serializeObjects(objects, SchemaConstants.C_OBJECTS)); System.out.println("Re-serialized to JSON:\n" + prismContext.jsonSerializer().serializeObjects(objects, SchemaConstants.C_OBJECTS)); System.out.println("Re-serialized to YAML:\n" + prismContext.yamlSerializer().serializeObjects(objects, SchemaConstants.C_OBJECTS)); - List> objectsReparsed = prismContext.parserFor(serialized).parseObjects(); + List> objectsReparsed = prismContext.parserFor(serializedAsObjects).parseObjects(); assertEquals("Reparsed objects are different from original ones", objects, objectsReparsed); + + String serializedByDefault = serializer.serializeObjects(objects, null); + System.out.println("Objects as re-serialized (default method):\n" + serializedByDefault); + + System.out.println("Re-serialized to XML (default):\n" + prismContext.xmlSerializer().serializeObjects(objects, null)); + System.out.println("Re-serialized to JSON (default):\n" + prismContext.jsonSerializer().serializeObjects(objects, null)); + System.out.println("Re-serialized to YAML (default):\n" + prismContext.yamlSerializer().serializeObjects(objects, null)); + + List> objectsReparsedDefault = prismContext.parserFor(serializedAsObjects).parseObjects(); + assertEquals("Reparsed objects are different from original ones", objects, objectsReparsedDefault); } } diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIteratively.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIteratively.java new file mode 100644 index 00000000000..5d5d0d85e65 --- /dev/null +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIteratively.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.schema.parser; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismParser; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static com.evolveum.midpoint.schema.TestConstants.OBJECTS_FILE_BASENAME; +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author mederly + */ +public class TestParseObjectsIteratively extends AbstractParserTest { + + @Override + protected File getFile() { + return getFile(OBJECTS_FILE_BASENAME); + } + + @Test + public void testRoundTrip() throws Exception { + displayTestTitle("testRoundTrip"); + PrismContext prismContext = getPrismContext(); + + PrismParser parser = prismContext.parserFor(getFile()); + List> objects = new ArrayList<>(); + parser.parseObjectsIteratively(new PrismParser.ObjectHandler() { + @Override + public boolean handleData(PrismObject object) { + objects.add(object); + return true; + } + + @Override + public boolean handleError(Throwable t) { + throw new AssertionError("unexpected handleError call"); + } + }); + + System.out.println("Objects as parsed: " + DebugUtil.debugDump(objects)); + + assertEquals("Wrong # of objects", 3, objects.size()); + assertEquals("Wrong class of object 1", UserType.class, objects.get(0).asObjectable().getClass()); + assertEquals("Wrong class of object 2", UserType.class, objects.get(1).asObjectable().getClass()); + assertEquals("Wrong class of object 2", RoleType.class, objects.get(2).asObjectable().getClass()); + + List> objectsStandard = prismContext.parserFor(getFile()).parseObjects(); + assertEquals("Objects are different if read in a standard way", objectsStandard, objects); + } + +} diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyFirstTwo.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyFirstTwo.java new file mode 100644 index 00000000000..2c490492848 --- /dev/null +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyFirstTwo.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.schema.parser; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismParser; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static com.evolveum.midpoint.schema.TestConstants.OBJECTS_FILE_BASENAME; +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author mederly + */ +public class TestParseObjectsIterativelyFirstTwo extends AbstractParserTest { + + @Override + protected File getFile() { + return getFile(OBJECTS_FILE_BASENAME); + } + + @Test + public void testRoundTrip() throws Exception { + displayTestTitle("testRoundTrip"); + PrismContext prismContext = getPrismContext(); + + PrismParser parser = prismContext.parserFor(getFile()); + List> objects = new ArrayList<>(); + parser.parseObjectsIteratively(new PrismParser.ObjectHandler() { + @Override + public boolean handleData(PrismObject object) { + objects.add(object); + return objects.size() != 2; + } + + @Override + public boolean handleError(Throwable t) { + throw new AssertionError("unexpected handleError call"); + } + }); + + System.out.println("Objects as parsed: " + DebugUtil.debugDump(objects)); + + assertEquals("Wrong # of objects", 2, objects.size()); + assertEquals("Wrong class of object 1", UserType.class, objects.get(0).asObjectable().getClass()); + assertEquals("Wrong class of object 2", UserType.class, objects.get(1).asObjectable().getClass()); + + List> objectsStandard = prismContext.parserFor(getFile()).parseObjects(); + objectsStandard.remove(2); + assertEquals("Objects are different if read in a standard way", objectsStandard, objects); + } + +} diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyWrong.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyWrong.java new file mode 100644 index 00000000000..466384e8113 --- /dev/null +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseObjectsIterativelyWrong.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.schema.parser; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismParser; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.evolveum.midpoint.schema.TestConstants.OBJECTS_WRONG_FILE_BASENAME; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.fail; + +/** + * @author mederly + */ +public class TestParseObjectsIterativelyWrong extends AbstractParserTest { + + @Override + protected File getFile() { + return getFile(OBJECTS_WRONG_FILE_BASENAME); + } + + @Test + public void testParse() throws Exception { + displayTestTitle("testParse"); + PrismContext prismContext = getPrismContext(); + + PrismParser parser = prismContext.parserFor(getFile()); + List> objects = new ArrayList<>(); + AtomicInteger errors = new AtomicInteger(0); + parser.parseObjectsIteratively(new PrismParser.ObjectHandler() { + @Override + public boolean handleData(PrismObject object) { + objects.add(object); + return true; + } + + @Override + public boolean handleError(Throwable t) { + System.out.println("Got (probably expected) exception:"); + t.printStackTrace(System.out); + assert t instanceof SchemaException; + errors.incrementAndGet(); + return true; + } + }); + + System.out.println("Objects as parsed: " + DebugUtil.debugDump(objects)); + + assertEquals("Wrong # of objects", 2, objects.size()); + assertEquals("Wrong class of object 1", UserType.class, objects.get(0).asObjectable().getClass()); + assertEquals("Wrong class of object 2", RoleType.class, objects.get(1).asObjectable().getClass()); + + assertEquals("Wrong # of errors", 1, errors.get()); + + try { + prismContext.parserFor(getFile()).parseObjects(); + fail("unexpected success"); + } catch (SchemaException e) { + System.out.println("Got expected exception: " + e); + } + } + +} diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseResource.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseResource.java index 8ecbe402d01..af0454c9673 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseResource.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/parser/TestParseResource.java @@ -101,10 +101,25 @@ public void testParseResourceFileSimple() throws Exception { assertResource(resource, true, true, true); } + @Test + public void testParseResourceRoundtripXml() throws Exception { + displayTestTitle("testParseResourceRoundtripXml"); + doTestParseResourceRoundtrip(PrismContext.LANG_XML); + } + + @Test + public void testParseResourceRoundtripJson() throws Exception { + displayTestTitle("testParseResourceRoundtripJson"); + doTestParseResourceRoundtrip(PrismContext.LANG_JSON); + } @Test - public void testParseResourceRoundtrip() throws Exception { - displayTestTitle("testParseResourceRoundtrip"); + public void testParseResourceRoundtripYaml() throws Exception { + displayTestTitle("testParseResourceRoundtripYaml"); + doTestParseResourceRoundtrip(PrismContext.LANG_YAML); + } + + private void doTestParseResourceRoundtrip(String serializeInto) throws Exception { // GIVEN PrismContext prismContext = getPrismContext(); @@ -118,7 +133,7 @@ public void testParseResourceRoundtrip() throws Exception { // SERIALIZE - String serializedResource = prismContext.serializerFor(language).serialize(resource); + String serializedResource = prismContext.serializerFor(serializeInto).serialize(resource); System.out.println("serialized resource:"); System.out.println(serializedResource); @@ -272,8 +287,24 @@ private void assertResourceExpression(PrismObject resource, PrismC } @Test - public void testParseResourceExpressionRoundtrip() throws Exception { - displayTestTitle("testParseResourceExpressionRoundtrip"); + public void testParseResourceExpressionRoundtripXml() throws Exception { + displayTestTitle("testParseResourceExpressionRoundtripXml"); + doTestParseResourceExpressionRoundtrip(PrismContext.LANG_XML); + } + + @Test + public void testParseResourceExpressionRoundtripJson() throws Exception { + displayTestTitle("testParseResourceExpressionRoundtripJson"); + doTestParseResourceExpressionRoundtrip(PrismContext.LANG_JSON); + } + + @Test + public void testParseResourceExpressionRoundtripYaml() throws Exception { + displayTestTitle("testParseResourceExpressionRoundtripYaml"); + doTestParseResourceExpressionRoundtrip(PrismContext.LANG_YAML); + } + + private void doTestParseResourceExpressionRoundtrip(String serializeInto) throws Exception { // GIVEN PrismContext prismContext = getPrismContext(); @@ -287,7 +318,7 @@ public void testParseResourceExpressionRoundtrip() throws Exception { // SERIALIZE (1) - String serializedResource = prismContext.serializerFor(language).serialize(resource); + String serializedResource = prismContext.serializerFor(serializeInto).serialize(resource); System.out.println("\nserialized resource (1):"); System.out.println(serializedResource); @@ -319,7 +350,7 @@ public void testParseResourceExpressionRoundtrip() throws Exception { System.out.println("\nResource (2):"); System.out.println(resource.debugDump()); - serializedResource = prismContext.serializerFor(language).serialize(resource); + serializedResource = prismContext.serializerFor(serializeInto).serialize(resource); System.out.println("\nserialized resource (2):"); System.out.println(serializedResource); diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java index bbdda313034..c64e17c8012 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java @@ -32,9 +32,9 @@ import org.testng.annotations.Test; import org.testng.AssertJUnit; -import com.evolveum.midpoint.prism.marshaller.TrivialXPathParser; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; -import com.evolveum.midpoint.prism.marshaller.XPathSegment; +import com.evolveum.midpoint.prism.marshaller.TrivialItemPathParser; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; +import com.evolveum.midpoint.prism.marshaller.PathHolderSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; @@ -54,6 +54,7 @@ import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -119,7 +120,7 @@ public void xpathTest() throws JAXBException, FileNotFoundException, IOException // } // } ItemPath path = pathType.getItemPath(); - XPathHolder xpath = new XPathHolder(path); + ItemPathHolder xpath = new ItemPathHolder(path); AssertJUnit.assertEquals("c:extension/piracy:ship[2]/c:name", xpath.getXPathWithoutDeclarations()); @@ -143,7 +144,7 @@ public void xpathTest() throws JAXBException, FileNotFoundException, IOException System.out.println("XPATH Element: " + xpathElement); - XPathHolder xpathFromElement = new XPathHolder(xpathElement); + ItemPathHolder xpathFromElement = new ItemPathHolder(xpathElement); AssertJUnit.assertEquals(xpath, xpathFromElement); // attributes = xpathElement.getAttributes(); @@ -152,11 +153,11 @@ public void xpathTest() throws JAXBException, FileNotFoundException, IOException // System.out.println(" A: " + n.getNodeName() + "(" + n.getPrefix() + " : " + n.getLocalName() + ") = " + n.getNodeValue()); // } - List segments = xpath.toSegments(); + List segments = xpath.toSegments(); System.out.println("XPATH segments: " + segments); - XPathHolder xpathFromSegments = new XPathHolder(segments); + ItemPathHolder xpathFromSegments = new ItemPathHolder(segments); System.out.println("XPath from segments: " + xpathFromSegments); @@ -176,7 +177,7 @@ public void xPathFromDomNode1() throws ParserConfigurationException, SAXExceptio // When - XPathHolder xpath = new XPathHolder(el1); + ItemPathHolder xpath = new ItemPathHolder(el1); // Then @@ -184,7 +185,7 @@ public void xPathFromDomNode1() throws ParserConfigurationException, SAXExceptio //AssertJUnit.assertEquals("http://default.com/", namespaceMap.get("c")); - List segments = xpath.toSegments(); + List segments = xpath.toSegments(); AssertJUnit.assertNotNull(segments); AssertJUnit.assertEquals(3, segments.size()); @@ -230,7 +231,7 @@ public void xPathFromDomNode2() throws ParserConfigurationException, SAXExceptio // When - XPathHolder xpath = new XPathHolder(xpathString, el1); + ItemPathHolder xpath = new ItemPathHolder(xpathString, el1); // Then @@ -247,7 +248,7 @@ public void variableTest() { "declare namespace x='http://www.xxx.com';" + "$v:var/x:xyz[10]"; - XPathHolder xpath = new XPathHolder(xpathStr); + ItemPathHolder xpath = new ItemPathHolder(xpathStr); AssertJUnit.assertEquals("$v:var/x:xyz[10]", xpath.getXPathWithoutDeclarations()); AssertJUnit.assertEquals("http://vvv.com", xpath.getNamespaceMap().get("v")); @@ -257,7 +258,7 @@ public void variableTest() { @Test public void dotTest() { - XPathHolder dotPath = new XPathHolder("."); + ItemPathHolder dotPath = new ItemPathHolder("."); AssertJUnit.assertTrue(dotPath.toSegments().isEmpty()); AssertJUnit.assertEquals(".", dotPath.getXPathWithoutDeclarations()); @@ -269,14 +270,14 @@ public void explicitNsParseTest() { String xpathStr = "declare namespace foo='http://ff.com/';\ndeclare default namespace 'http://default.com/';\n declare namespace bar = 'http://www.b.com' ;declare namespace x= \"http://xxx.com/\";\nfoo:foofoo[1]/x:bar"; - TrivialXPathParser parser = TrivialXPathParser.parse(xpathStr); + TrivialItemPathParser parser = TrivialItemPathParser.parse(xpathStr); AssertJUnit.assertEquals("http://ff.com/", parser.getNamespaceMap().get("foo")); AssertJUnit.assertEquals("http://www.b.com", parser.getNamespaceMap().get("bar")); AssertJUnit.assertEquals("http://xxx.com/", parser.getNamespaceMap().get("x")); AssertJUnit.assertEquals("http://default.com/", parser.getNamespaceMap().get("")); - AssertJUnit.assertEquals("foo:foofoo[1]/x:bar", parser.getPureXPathString()); + AssertJUnit.assertEquals("foo:foofoo[1]/x:bar", parser.getPureItemPathString()); } @Test @@ -284,8 +285,8 @@ public void simpleXPathParseTest() { String xpathStr = "foo/bar"; - TrivialXPathParser parser = TrivialXPathParser.parse(xpathStr); - AssertJUnit.assertEquals("foo/bar", parser.getPureXPathString()); + TrivialItemPathParser parser = TrivialItemPathParser.parse(xpathStr); + AssertJUnit.assertEquals("foo/bar", parser.getPureItemPathString()); } @Test @@ -294,16 +295,19 @@ public void explicitNsRoundTripTest() { String xpathStr = "declare namespace foo='http://ff.com/';\ndeclare default namespace 'http://default.com/';\n declare namespace bar = 'http://www.b.com' ;declare namespace x= \"http://xxx.com/\";\nfoo:foofoo/x:bar"; - XPathHolder xpath = new XPathHolder(xpathStr); + ItemPathHolder xpath = new ItemPathHolder(xpathStr); System.out.println("Pure XPath: "+xpath.getXPathWithoutDeclarations()); AssertJUnit.assertEquals("foo:foofoo/x:bar", xpath.getXPathWithoutDeclarations()); System.out.println("ROUND TRIP: "+xpath.getXPathWithDeclarations()); - AssertJUnit.assertTrue("Unexpected path with declarations: "+xpath.getXPathWithDeclarations(), - "declare default namespace 'http://default.com/'; declare namespace foo='http://ff.com/'; declare namespace bar='http://www.b.com'; declare namespace x='http://xxx.com/'; foo:foofoo/x:bar".equals(xpath.getXPathWithDeclarations()) // java7 - || "declare default namespace 'http://default.com/'; declare namespace bar='http://www.b.com'; declare namespace foo='http://ff.com/'; declare namespace x='http://xxx.com/'; foo:foofoo/x:bar".equals(xpath.getXPathWithDeclarations())); // java8 - + + List expected = Arrays.asList( + "declare default namespace 'http://default.com/'; declare namespace foo='http://ff.com/'; declare namespace bar='http://www.b.com'; declare namespace x='http://xxx.com/'; foo:foofoo/x:bar", // java7 + "declare default namespace 'http://default.com/'; declare namespace bar='http://www.b.com'; declare namespace foo='http://ff.com/'; declare namespace x='http://xxx.com/'; foo:foofoo/x:bar", // java8 + "declare default namespace 'http://default.com/'; declare namespace x='http://xxx.com/'; declare namespace bar='http://www.b.com'; declare namespace foo='http://ff.com/'; foo:foofoo/x:bar" // after JSON/YAML serialization fix (java8) + ); + AssertJUnit.assertTrue("Unexpected path with declarations: "+xpath.getXPathWithDeclarations(), expected.contains(xpath.getXPathWithDeclarations())); } @Test @@ -315,7 +319,7 @@ public void pureXPathRoundTripTest() { String xpathStr = "foo:foo/bar:bar"; - XPathHolder xpath = new XPathHolder(xpathStr, namespaceMap); + ItemPathHolder xpath = new ItemPathHolder(xpathStr, namespaceMap); System.out.println("Pure XPath: "+xpath.getXPathWithoutDeclarations()); AssertJUnit.assertEquals("foo:foo/bar:bar", xpath.getXPathWithoutDeclarations()); @@ -327,7 +331,7 @@ public void pureXPathRoundTripTest() { @Test - public void strangeCharsTest() throws FileNotFoundException, UnsupportedEncodingException, IOException { + public void strangeCharsTest() throws IOException { String xpathStr; @@ -345,7 +349,7 @@ public void strangeCharsTest() throws FileNotFoundException, UnsupportedEncoding stream.close(); } - XPathHolder xpath = new XPathHolder(xpathStr); + ItemPathHolder xpath = new ItemPathHolder(xpathStr); System.out.println("Stragechars Pure XPath: "+xpath.getXPathWithoutDeclarations()); AssertJUnit.assertEquals("$i:user/i:extension/ri:foobar", xpath.getXPathWithoutDeclarations()); @@ -358,7 +362,7 @@ public void strangeCharsTest() throws FileNotFoundException, UnsupportedEncoding public void xpathFromQNameTest() { // GIVEN QName qname = new QName(NS_FOO, "foo"); - XPathHolder xpath = new XPathHolder(qname); + ItemPathHolder xpath = new ItemPathHolder(qname); QName elementQName = new QName(NS_BAR, "bar"); // WHEN @@ -381,37 +385,37 @@ public void testXPathSerializationToDom() { // GIVEN QName qname1 = new QName(NS_C, "extension"); QName qname2 = new QName(NS_FOO, "foo"); - XPathHolder xPathHolder1 = new XPathHolder(qname1, qname2); + ItemPathHolder itemPathHolder1 = new ItemPathHolder(qname1, qname2); QName elementQName = new QName(NS_BAR, "bar"); // WHEN - Element element = xPathHolder1.toElement(elementQName, DOMUtil.getDocument()); - XPathHolder xPathHolder2 = new XPathHolder(element); + Element element = itemPathHolder1.toElement(elementQName, DOMUtil.getDocument()); + ItemPathHolder itemPathHolder2 = new ItemPathHolder(element); // THEN System.out.println("XPath from QNames:"); System.out.println(DOMUtil.serializeDOMToString(element)); - ItemPath xpath1 = xPathHolder1.toItemPath(); - ItemPath xpath2 = xPathHolder2.toItemPath(); + ItemPath xpath1 = itemPathHolder1.toItemPath(); + ItemPath xpath2 = itemPathHolder2.toItemPath(); assertTrue("Paths are not equivalent", xpath1.equivalent(xpath2)); } @Test public void parseSpecial() { final String D = "declare namespace x='http://xyz.com/'; "; - AssertJUnit.assertEquals("..", TrivialXPathParser.parse("..").getPureXPathString()); - AssertJUnit.assertEquals("..", TrivialXPathParser.parse(D+"..").getPureXPathString()); - AssertJUnit.assertEquals("a/../b", TrivialXPathParser.parse("a/../b").getPureXPathString()); - AssertJUnit.assertEquals("a/../b", TrivialXPathParser.parse(D+"a/../b").getPureXPathString()); - AssertJUnit.assertEquals("@", TrivialXPathParser.parse("@").getPureXPathString()); - AssertJUnit.assertEquals("@", TrivialXPathParser.parse(D+"@").getPureXPathString()); - AssertJUnit.assertEquals("a/@/b", TrivialXPathParser.parse("a/@/b").getPureXPathString()); - AssertJUnit.assertEquals("a/@/b", TrivialXPathParser.parse(D+"a/@/b").getPureXPathString()); - AssertJUnit.assertEquals("#", TrivialXPathParser.parse("#").getPureXPathString()); - AssertJUnit.assertEquals("#", TrivialXPathParser.parse(D+"#").getPureXPathString()); - AssertJUnit.assertEquals("a/#/b", TrivialXPathParser.parse("a/#/b").getPureXPathString()); - AssertJUnit.assertEquals("a/#/b", TrivialXPathParser.parse(D+"a/#/b").getPureXPathString()); + AssertJUnit.assertEquals("..", TrivialItemPathParser.parse("..").getPureItemPathString()); + AssertJUnit.assertEquals("..", TrivialItemPathParser.parse(D+"..").getPureItemPathString()); + AssertJUnit.assertEquals("a/../b", TrivialItemPathParser.parse("a/../b").getPureItemPathString()); + AssertJUnit.assertEquals("a/../b", TrivialItemPathParser.parse(D+"a/../b").getPureItemPathString()); + AssertJUnit.assertEquals("@", TrivialItemPathParser.parse("@").getPureItemPathString()); + AssertJUnit.assertEquals("@", TrivialItemPathParser.parse(D+"@").getPureItemPathString()); + AssertJUnit.assertEquals("a/@/b", TrivialItemPathParser.parse("a/@/b").getPureItemPathString()); + AssertJUnit.assertEquals("a/@/b", TrivialItemPathParser.parse(D+"a/@/b").getPureItemPathString()); + AssertJUnit.assertEquals("#", TrivialItemPathParser.parse("#").getPureItemPathString()); + AssertJUnit.assertEquals("#", TrivialItemPathParser.parse(D+"#").getPureItemPathString()); + AssertJUnit.assertEquals("a/#/b", TrivialItemPathParser.parse("a/#/b").getPureItemPathString()); + AssertJUnit.assertEquals("a/#/b", TrivialItemPathParser.parse(D+"a/#/b").getPureItemPathString()); } //not actual anymore..we have something like "wildcard" in xpath..there don't need to be prefix specified.we will try to match the local names @@ -425,7 +429,7 @@ public void testUndefinedPrefix() throws ParserConfigurationException, SAXExcept try { // WHEN - XPathHolder xpath = new XPathHolder(el1); + ItemPathHolder xpath = new ItemPathHolder(el1); AssertJUnit.fail("Unexpected success"); } catch (IllegalArgumentException e) { diff --git a/infra/schema/src/test/resources/common/json/no-ns/objects-wrong.json b/infra/schema/src/test/resources/common/json/no-ns/objects-wrong.json new file mode 100644 index 00000000000..ec204e22a55 --- /dev/null +++ b/infra/schema/src/test/resources/common/json/no-ns/objects-wrong.json @@ -0,0 +1,15 @@ +{ + "objects" : [ { + "user" : { + "name" : "u1" + } + }, { + "user" : { + "name-error" : "u2" + } + }, { + "role" : { + "name" : "r1" + } + } ] +} diff --git a/infra/schema/src/test/resources/common/json/ns/objects-wrong.json b/infra/schema/src/test/resources/common/json/ns/objects-wrong.json new file mode 100644 index 00000000000..d4d790f2c5e --- /dev/null +++ b/infra/schema/src/test/resources/common/json/ns/objects-wrong.json @@ -0,0 +1,16 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "user" : { + "name" : "u1" + } + }, { + "user" : { + "name-error" : "u2" + } + }, { + "role" : { + "name" : "r1" + } + } ] +} diff --git a/infra/schema/src/test/resources/common/xml/no-ns/objects-wrong.xml b/infra/schema/src/test/resources/common/xml/no-ns/objects-wrong.xml new file mode 100644 index 00000000000..81a179fe744 --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/no-ns/objects-wrong.xml @@ -0,0 +1,28 @@ + + + + + + u1 + + + u2 + + + r1 + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/xml/ns/objects-wrong.xml b/infra/schema/src/test/resources/common/xml/ns/objects-wrong.xml new file mode 100644 index 00000000000..9cb4575ee63 --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/objects-wrong.xml @@ -0,0 +1,28 @@ + + + + + + u1 + + + u2 + + + r1 + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml b/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml index c2164aa0836..278cb35dffd 100644 --- a/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml +++ b/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml @@ -626,8 +626,10 @@ This is now the only account type that midPoint can work with. --> c:name - + + declare namespace my='http://myself.me/schemas/whatever'; + declare namespace c='http://midpoint.evolveum.com/xml/ns/public/common/common-3'; $account/c:attributes/my:yyy diff --git a/infra/schema/src/test/resources/common/yaml/no-ns/objects-wrong.yaml b/infra/schema/src/test/resources/common/yaml/no-ns/objects-wrong.yaml new file mode 100644 index 00000000000..18736379ba1 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/no-ns/objects-wrong.yaml @@ -0,0 +1,8 @@ +--- +objects: +- user: + name: "u1" +- user: + name-error: "u2" +- role: + name: "r1" diff --git a/infra/schema/src/test/resources/common/yaml/ns/objects-wrong.yaml b/infra/schema/src/test/resources/common/yaml/ns/objects-wrong.yaml new file mode 100644 index 00000000000..7d5c967a656 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/ns/objects-wrong.yaml @@ -0,0 +1,9 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- user: + name: "u1" +- user: + name-error: "u2" +- role: + name: "r1" diff --git a/infra/schema/testng-unit.xml b/infra/schema/testng-unit.xml index 5875123f926..a601d8a8d68 100644 --- a/infra/schema/testng-unit.xml +++ b/infra/schema/testng-unit.xml @@ -33,6 +33,9 @@ + + + @@ -44,6 +47,9 @@ + + + @@ -55,6 +61,9 @@ + + + @@ -66,6 +75,9 @@ + + + @@ -77,6 +89,9 @@ + + + @@ -88,6 +103,9 @@ + + + diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/CertificationManagerImpl.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/CertificationManagerImpl.java index c0b96f2ea47..2a608977234 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/CertificationManagerImpl.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/CertificationManagerImpl.java @@ -175,7 +175,7 @@ void startAdHocCertifications(PrismObject focus, if (!definitionOids.isEmpty()) { OperationResult result = parentResult.createSubresult(OPERATION_CREATE_AD_HOC_CAMPAIGNS); result.addParam("focus", focus); - result.addCollectionOfSerializablesAsParam("definitionOids", definitionOids); + result.addArbitraryObjectCollectionAsParam("definitionOids", definitionOids); try { PrismObject administrator = repositoryService .getObject(UserType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), null, result); @@ -430,8 +430,8 @@ public void delegateWorkItems(@NotNull String campaignOid, @NotNull List> eval PrismContainer output = outputDefinition.instantiate(); QName assocName = context.getMappingQName(); - String resourceOid = rAssocTargetDef.getResourceType().getOid(); + String resourceOid = rAssocTargetDef.getResourceOid(); Collection> options = null; // Always process the first role (myself) regardless of recursion setting diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java index 5beb28c2a1a..dfdfd02a2ac 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java @@ -78,7 +78,7 @@ protected ObjectQuery extendQuery(ObjectQuery query, ExpressionEvaluationContext throw new ExpressionEvaluationException("No association target object class definition variable in "+ params.getContextDescription()+"; the expression may be used in a wrong place. It is only supposed to create an association."); } - ObjectFilter resourceFilter = ObjectQueryUtil.createResourceFilter(rAssocTargetDef.getResourceType().getOid(), getPrismContext()); + ObjectFilter resourceFilter = ObjectQueryUtil.createResourceFilter(rAssocTargetDef.getResourceOid(), getPrismContext()); ObjectFilter objectClassFilter = ObjectQueryUtil.createObjectClassFilter(rAssocTargetDef.getObjectClassDefinition().getTypeName(), getPrismContext()); ObjectFilter extendedFilter = AndFilter.createAnd(resourceFilter, objectClassFilter, query.getFilter()); diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java index a4e55f1f3e7..7316c976463 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java @@ -17,7 +17,7 @@ import java.util.Map; -import com.evolveum.midpoint.prism.marshaller.TrivialXPathParser; +import com.evolveum.midpoint.prism.marshaller.TrivialItemPathParser; /** * @author Radovan Semancik @@ -61,8 +61,8 @@ public String getExpressionAsString() { String stringExpression = getFullExpressionAsString(); // try to strip namespace declarations - TrivialXPathParser parser = TrivialXPathParser.parse(stringExpression); - stringExpression = parser.getPureXPathString(); + TrivialItemPathParser parser = TrivialItemPathParser.parse(stringExpression); + stringExpression = parser.getPureItemPathString(); return stringExpression; } @@ -86,7 +86,7 @@ public Map getNamespaceMap() { String stringExpression = getFullExpressionAsString(); // try to strip namespace declarations - TrivialXPathParser parser = TrivialXPathParser.parse(stringExpression); + TrivialItemPathParser parser = TrivialItemPathParser.parse(stringExpression); namespaceMap = parser.getNamespaceMap(); // this isn't available any more [pm] diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java index fcc5e016018..007f9f50b19 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java @@ -160,7 +160,7 @@ public boolean validateValue(String newValue, ValuePolicy Validate.notNull(pp, "Value policy must not be null."); OperationResult result = parentResult.createSubresult(OPERATION_STRING_POLICY_VALIDATION); - result.addParam("policyName", pp.getName()); + result.addArbitraryObjectAsParam("policyName", pp.getName()); normalize(pp); if (newValue == null && diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java index 8a632dda4a1..cf9208482b8 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java @@ -39,7 +39,7 @@ import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -240,7 +240,7 @@ private ItemPath toItemPath(String stringPath) { stringPath + ""; Document doc = DOMUtil.parseDocument(xml); Element element = DOMUtil.getFirstChildElement(doc); - return new XPathHolder(element).toItemPath(); + return new ItemPathHolder(element).toItemPath(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelCrudService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelCrudService.java index 46626f22af1..efe89fc6918 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelCrudService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelCrudService.java @@ -260,7 +260,7 @@ public String addObject(PrismObject object, ModelExecu prismContext.adopt(objectType); OperationResult result = parentResult.createSubresult(ADD_OBJECT); - result.addParams(new String[] { "object" }, object); + result.addParam(OperationResult.PARAM_OBJECT, object); Utils.resolveReferences(object, repository, false, false, EvaluationTimeType.IMPORT, true, prismContext, result); @@ -334,7 +334,7 @@ public void deleteObject(Class clazz, String oid, Mode Validate.notNull(parentResult, "Result type must not be null."); OperationResult result = parentResult.createSubresult(DELETE_OBJECT); - result.addParams(new String[] { "oid" }, oid); + result.addParam(OperationResult.PARAM_OID, oid); RepositoryCache.enter(); @@ -435,7 +435,7 @@ public void modifyObject(Class type, String oid, // TODO: check definitions, but tolerate missing definitions in OperationResult result = parentResult.createSubresult(MODIFY_OBJECT); - result.addCollectionOfSerializablesAsParam("modifications", modifications); + result.addArbitraryObjectCollectionAsParam("modifications", modifications); RepositoryCache.enter(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java index 4b2d232a210..6daca2981b2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java @@ -215,7 +215,12 @@ private void serializeFaultMessage(Detail detail, FaultMessage faultMessage) { private void throwFault(Exception ex, OperationResultType resultType) throws FaultMessage { if (resultType != null) { - ws.throwFault(ex, OperationResult.createOperationResult(resultType)); + try { + ws.throwFault(ex, OperationResult.createOperationResult(resultType)); + } catch (SchemaException e) { + LOGGER.error("Error serializing operation result: {}", e.getMessage(), e); + ws.throwFault(ex, null); + } } else { ws.throwFault(ex, null); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index 4688cd42c6e..2a0be97b67c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -227,7 +227,7 @@ public PrismObject getObject(Class clazz, String oi PrismObject object; OperationResult result = parentResult.createMinorSubresult(GET_OBJECT); result.addParam("oid", oid); - result.addCollectionOfSerializablesAsParam("options", rawOptions); + result.addArbitraryObjectCollectionAsParam("options", rawOptions); result.addParam("class", clazz); Collection> options = preProcessOptionsSecurity(rawOptions); @@ -379,7 +379,7 @@ public Collection> executeChanges(fin Collection> executedDeltas = new ArrayList<>(); OperationResult result = parentResult.createSubresult(EXECUTE_CHANGES); - result.addParam(OperationResult.PARAM_OPTIONS, options); + result.addArbitraryObjectAsParam(OperationResult.PARAM_OPTIONS, options); // Search filters treatment: if reevaluation is requested, we have to deal with three cases: // 1) for ADD operation: filters contained in object-to-be-added -> these are treated here @@ -681,7 +681,8 @@ public void recompute(Class type, String oid, Task tas public void recompute(Class type, String oid, ModelExecuteOptions options, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { OperationResult result = parentResult.createMinorSubresult(RECOMPUTE); - result.addParams(new String[] { "oid", "type" }, oid, type); + result.addParam(OperationResult.PARAM_OID, oid); + result.addParam(OperationResult.PARAM_TYPE, type); RepositoryCache.enter(); @@ -785,8 +786,9 @@ public SearchResultList> searchObjects(Cla } OperationResult result = parentResult.createSubresult(SEARCH_OBJECTS); - result.addParams(new String[] { "query", "paging", "searchProvider" }, - query, (query != null ? query.getPaging() : "undefined"), searchProvider); + result.addParam(OperationResult.PARAM_TYPE, type); + result.addParam(OperationResult.PARAM_QUERY, query); + result.addArbitraryObjectAsParam("searchProvider", searchProvider); query = preProcessQuerySecurity(type, query); if (isFilterNone(query, result)) { @@ -901,8 +903,8 @@ public SearchResultList searchContainers( final GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); final OperationResult result = parentResult.createSubresult(SEARCH_CONTAINERS); - result.addParams(new String[] { "type", "query", "paging" }, - type, query, (query != null ? query.getPaging() : "undefined")); + result.addParam(OperationResult.PARAM_TYPE, type); + result.addParam(OperationResult.PARAM_QUERY, query); query = ctx.refinedQuery; @@ -975,7 +977,8 @@ public Integer countContainers( final GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); final OperationResult result = parentResult.createSubresult(SEARCH_CONTAINERS); - result.addParams(new String[] { "type", "query"}, type, query); + result.addParam(OperationResult.PARAM_TYPE, type); + result.addParam(OperationResult.PARAM_QUERY, query); query = ctx.refinedQuery; @@ -1084,8 +1087,8 @@ public SearchResultMetadata searchObjectsIterative(Class< } final OperationResult result = parentResult.createSubresult(SEARCH_OBJECTS); - result.addParams(new String[] { "query", "paging", "searchProvider" }, - query, (query != null ? query.getPaging() : "undefined"), searchProvider); + result.addParam(OperationResult.PARAM_QUERY, query); + result.addArbitraryObjectAsParam("searchProvider", searchProvider); query = preProcessQuerySecurity(type, query); if (isFilterNone(query, result)) { @@ -1164,8 +1167,7 @@ public Integer countObjects(Class type, ObjectQuery qu throws SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, CommunicationException, ExpressionEvaluationException { OperationResult result = parentResult.createMinorSubresult(COUNT_OBJECTS); - result.addParams(new String[] { "query", "paging"}, - query, (query != null ? query.getPaging() : "undefined")); + result.addParam(OperationResult.PARAM_QUERY, query); query = preProcessQuerySecurity(type, query); if (isFilterNone(query, result)) { @@ -1216,7 +1218,7 @@ public PrismObject findShadowOwner(String accountOid, Task task, Opera LOGGER.trace("Listing account shadow owner for account with oid {}.", new Object[]{accountOid}); OperationResult result = parentResult.createSubresult(LIST_ACCOUNT_SHADOW_OWNER); - result.addParams(new String[] { "accountOid" }, accountOid); + result.addParam("accountOid", accountOid); try { @@ -1270,7 +1272,7 @@ public PrismObject searchShadowOwner(String shadowOid, Coll LOGGER.trace("Listing account shadow owner for account with oid {}.", new Object[]{shadowOid}); OperationResult result = parentResult.createSubresult(LIST_ACCOUNT_SHADOW_OWNER); - result.addParams(new String[] { "accountOid" }, shadowOid); + result.addParam("shadowOid", shadowOid); try { Collection> options = preProcessOptionsSecurity(rawOptions); @@ -1329,8 +1331,8 @@ public List> listResourceObjects(String resour paging.getOrderBy(), paging.getDirection()); OperationResult result = parentResult.createSubresult(LIST_RESOURCE_OBJECTS); - result.addParams(new String[] { "resourceOid", "objectType", "paging" }, resourceOid, - objectClass, paging); + result.addParam("resourceOid", resourceOid); + result.addParam("objectType", objectClass); try { @@ -1408,7 +1410,7 @@ public void importFromResource(String resourceOid, QName objectClass, Task task, OperationResult result = parentResult.createSubresult(IMPORT_ACCOUNTS_FROM_RESOURCE); result.addParam("resourceOid", resourceOid); result.addParam("objectClass", objectClass); - result.addArbitraryObjectAsParam("task", task); + result.addArbitraryObjectAsParam(OperationResult.PARAM_TASK, task); // TODO: add context to the result // Fetch resource definition from the repo/provisioning @@ -1462,7 +1464,7 @@ public void importFromResource(String shadowOid, Task task, OperationResult pare OperationResult result = parentResult.createSubresult(IMPORT_ACCOUNTS_FROM_RESOURCE); result.addParam(OperationResult.PARAM_OID, shadowOid); - result.addArbitraryObjectAsParam("task", task); + result.addArbitraryObjectAsParam(OperationResult.PARAM_TASK, task); // TODO: add context to the result try { @@ -1524,8 +1526,8 @@ public void importObjectsFromStream(InputStream input, ImportOptionsType options public void importObjectsFromStream(InputStream input, String language, ImportOptionsType options, Task task, OperationResult parentResult) { RepositoryCache.enter(); OperationResult result = parentResult.createSubresult(IMPORT_OBJECTS_FROM_STREAM); - result.addParam("options", options); - result.addParam("language", language); + result.addArbitraryObjectAsParam(OperationResult.PARAM_OPTIONS, options); + result.addParam(OperationResult.PARAM_LANGUAGE, language); try { objectImporter.importObjects(input, language, options, task, result); if (LOGGER.isTraceEnabled()) { @@ -1620,11 +1622,11 @@ public CompareResultType compareObject(PrismObject pro Validate.notNull(parentResult, "Operation result must not be null."); OperationResult result = parentResult.createMinorSubresult(COMPARE_OBJECT); - result.addParam("oid", provided.getOid()); - result.addParam("name", provided.getName()); - result.addCollectionOfSerializablesAsParam("readOptions", rawReadOptions); - result.addParam("compareOptions", compareOptions); - result.addCollectionOfSerializablesAsParam("ignoreItems", ignoreItems); + result.addParam(OperationResult.PARAM_OID, provided.getOid()); + result.addParam(OperationResult.PARAM_NAME, provided.getName()); + result.addArbitraryObjectCollectionAsParam("readOptions", rawReadOptions); + result.addArbitraryObjectAsParam("compareOptions", compareOptions); + result.addArbitraryObjectCollectionAsParam("ignoreItems", ignoreItems); Collection> readOptions = preProcessOptionsSecurity(rawReadOptions); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java index de814be19a5..70e360f0c07 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java @@ -421,7 +421,7 @@ private void repositorySelfTestLookupTable(Task task, OperationResult testResult GetOperationOptions.createRetrieve(subquery)); PrismObject lookupTableRetrieved = repositoryService.getObject(LookupTableType.class, oid, options, result); - subresult.addParam("subquery", subquery); + subresult.addArbitraryObjectAsParam("subquery", subquery); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Self-test:lookupTable getObject by row key:\n{}", DebugUtil.debugDump(lookupTableRetrieved)); } @@ -467,7 +467,7 @@ private void checkObjectProperty(PrismObject object, OperationResult result = parentResult.createSubresult(parentResult.getOperation() + ".checkObjectProperty." + propName); PrismProperty prop = object.findProperty(propQName); Collection actualValues = prop.getRealValues(); - result.addArbitraryCollectionAsParam("actualValues", actualValues); + result.addArbitraryObjectCollectionAsParam("actualValues", actualValues); assertMultivalue("User, property '"+propName+"'", expectedValues, actualValues, result); result.recordSuccessIfUnknown(); } @@ -497,7 +497,7 @@ private void checkObjectPropertyPolyString(PrismObject OperationResult result = parentResult.createSubresult(parentResult.getOperation() + "." + propName); PrismProperty prop = object.findProperty(propQName); Collection actualValues = prop.getRealValues(); - result.addArbitraryCollectionAsParam("actualValues", actualValues); + result.addArbitraryObjectCollectionAsParam("actualValues", actualValues); assertMultivaluePolyString("User, property '"+propName+"'", expectedValues, actualValues, result); result.recordSuccessIfUnknown(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index c541280bf2d..e2a477e26c0 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -855,7 +855,7 @@ public void generateValue(PrismObject object, PolicyIt continue; } - result.addParam("policyItemPath", path); + result.addArbitraryObjectAsParam("policyItemPath", path); PrismPropertyDefinition propertyDef = getItemDefinition(object, path); if (propertyDef == null) { @@ -1121,7 +1121,7 @@ private boolean validateValue(PrismObject object, V for (String newValue : valuesToValidate) { OperationResult result = parentResult.createSubresult(OPERATION_VALIDATE_VALUE + ".value"); - if (path != null ) result.addParam("path", path); + if (path != null ) result.addArbitraryObjectAsParam("path", path); result.addParam("valueToValidate", newValue); if (!policyProcessor.validateValue(newValue, stringPolicy, object, "validate value " + (path!= null ? "for " + path : "") + " for " + object + " value " + valueToValidate, task, result)) { result.recordFatalError("Validation for value " + newValue + " against policy " + stringPolicy + " failed"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelUtils.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelUtils.java index 6efafe72f59..29ce88e2587 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelUtils.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelUtils.java @@ -15,12 +15,8 @@ */ package com.evolveum.midpoint.model.impl.controller; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - import com.evolveum.midpoint.model.api.ModelAuthorizationAction; +import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.query.ObjectPaging; @@ -28,17 +24,17 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.FocusTypeUtil; import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectPolicyConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * @@ -118,6 +114,9 @@ public static ObjectPolicyConfigurationType determineObje ObjectPolicyConfigurationType applicablePolicyConfigurationType = null; for (ObjectPolicyConfigurationType aPolicyConfigurationType: systemConfigurationType.getDefaultObjectPolicyConfiguration()) { QName typeQName = aPolicyConfigurationType.getType(); + if (typeQName == null) { + continue; // TODO implement correctly (using 'applicable policies' perhaps) + } ObjectTypes objectType = ObjectTypes.getObjectTypeFromTypeQName(typeQName); if (objectType == null) { throw new ConfigurationException("Unknown type "+typeQName+" in default object policy definition in system configuration"); @@ -140,6 +139,9 @@ public static ObjectPolicyConfigurationType determineObje // Deprecated for (ObjectPolicyConfigurationType aPolicyConfigurationType: systemConfigurationType.getObjectTemplate()) { QName typeQName = aPolicyConfigurationType.getType(); + if (typeQName == null) { + continue; + } ObjectTypes objectType = ObjectTypes.getObjectTypeFromTypeQName(typeQName); if (objectType == null) { throw new ConfigurationException("Unknown type "+typeQName+" in object template definition in system configuration"); @@ -163,4 +165,86 @@ public static ObjectPolicyConfigurationType determineObje return null; } + // from the most to least appropriate + @NotNull + public static List getApplicablePolicies( + Class objectClass, List objectSubtypes, SystemConfigurationType systemConfigurationType) + throws ConfigurationException { + List rv = new ArrayList<>(); + List typeNoSubtype = new ArrayList<>(); + List typeWithSubtype = new ArrayList<>(); + List noTypeNoSubtype = new ArrayList<>(); + List noTypeWithSubtype = new ArrayList<>(); + List all = new ArrayList<>(); + + all.addAll(systemConfigurationType.getDefaultObjectPolicyConfiguration()); + all.addAll(systemConfigurationType.getObjectTemplate()); // deprecated + if (objectClass == UserType.class) { + // Deprecated method to specify user template. For compatibility only + ObjectReferenceType templateRef = systemConfigurationType.getDefaultUserTemplateRef(); + if (templateRef != null) { + all.add(new ObjectPolicyConfigurationType().objectTemplateRef(templateRef.clone())); + } + } + + for (ObjectPolicyConfigurationType aPolicyConfigurationType: all) { + QName typeQName = aPolicyConfigurationType.getType(); + if (typeQName != null) { + ObjectTypes objectType = ObjectTypes.getObjectTypeFromTypeQName(typeQName); + if (objectType == null) { + throw new ConfigurationException( + "Unknown type " + typeQName + " in default object policy definition or object template definition in system configuration"); + } + if (objectType.getClassDefinition() == objectClass) { + String aSubType = aPolicyConfigurationType.getSubtype(); + if (aSubType == null) { + typeNoSubtype.add(aPolicyConfigurationType); + } else if (objectSubtypes != null && objectSubtypes.contains(aSubType)) { + typeWithSubtype.add(aPolicyConfigurationType); + } + } + } else { + String aSubType = aPolicyConfigurationType.getSubtype(); + if (aSubType == null) { + noTypeNoSubtype.add(aPolicyConfigurationType); + } else if (objectSubtypes != null && objectSubtypes.contains(aSubType)) { + noTypeWithSubtype.add(aPolicyConfigurationType); + } + } + } + rv.addAll(typeWithSubtype); + rv.addAll(typeNoSubtype); + rv.addAll(noTypeWithSubtype); + rv.addAll(noTypeNoSubtype); + return rv; + } + + @NotNull + public static List getApplicablePolicies(LensContext context) { + PrismObject config = context.getSystemConfiguration(); + if (config == null) { + return Collections.emptyList(); + } + PrismObject object = context.getFocusContext() != null ? context.getFocusContext().getObjectAny() : null; + List subTypes = FocusTypeUtil.determineSubTypes(object); + List relevantPolicies; + try { + relevantPolicies = ModelUtils.getApplicablePolicies(context.getFocusContext().getObjectTypeClass(), subTypes, + config.asObjectable()); + } catch (ConfigurationException e) { + throw new SystemException("Couldn't get relevant object policies", e); + } + LOGGER.trace("Relevant policies: {}", relevantPolicies); + return relevantPolicies; + } + + public static ConflictResolutionType getConflictResolution(LensContext context) { + for (ObjectPolicyConfigurationType p : ModelUtils.getApplicablePolicies(context)) { + if (p.getConflictResolution() != null) { + return p.getConflictResolution(); + } + } + return null; + } + } 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 7644c8a3b21..ae0327133d7 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 @@ -34,14 +34,13 @@ import com.evolveum.midpoint.model.impl.lens.LensFocusContext; import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; import com.evolveum.midpoint.model.impl.lens.SynchronizationIntent; -import com.evolveum.midpoint.notifications.api.events.ModelEvent; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.ItemPathHolder; import com.evolveum.midpoint.prism.match.DefaultMatchingRule; import com.evolveum.midpoint.prism.match.PolyStringOrigMatchingRule; import com.evolveum.midpoint.prism.path.ItemPath; @@ -545,7 +544,7 @@ private Integer countAccounts(ResourceType resourceType, QName attributeName public boolean isUniquePropertyValue(ObjectType objectType, String propertyPathString, T propertyValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { Validate.notEmpty(propertyPathString, "Empty property path"); OperationResult result = getCurrentResult(MidpointFunctions.class.getName()+".isUniquePropertyValue"); - ItemPath propertyPath = new XPathHolder(propertyPathString).toItemPath(); + ItemPath propertyPath = new ItemPathHolder(propertyPathString).toItemPath(); return isUniquePropertyValue(objectType, propertyPath, propertyValue, getCurrentTask(), result); } @@ -563,7 +562,7 @@ public List getObjectsInConflictOnPropertyValue(O o public List getObjectsInConflictOnPropertyValue(O objectType, String propertyPathString, T propertyValue, String matchingRuleName, boolean getAllConflicting) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { Validate.notEmpty(propertyPathString, "Empty property path"); OperationResult result = getCurrentResult(MidpointFunctions.class.getName()+".getObjectsInConflictOnPropertyValue"); - ItemPath propertyPath = new XPathHolder(propertyPathString).toItemPath(); + ItemPath propertyPath = new ItemPathHolder(propertyPathString).toItemPath(); QName matchingRuleQName = new QName(matchingRuleName); // no namespace for now return getObjectsInConflictOnPropertyValue(objectType, propertyPath, propertyValue, matchingRuleQName, getAllConflicting, getCurrentTask(), result); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java index 8ce22676573..78f008e5ae0 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,7 +99,7 @@ public void launch(File input, Task task, OperationResult parentResult) { LOGGER.debug("Launching import accounts from file {}", input); OperationResult result = parentResult.createSubresult(ImportObjectsFromFileTaskHandler.class.getName() + ".launch"); - result.addParam("input", input); + result.addParam("input", input.getPath()); // TODO // Set handler URI so we will be called back diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java index 494bf5bac79..3a4bb2b3c05 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java @@ -61,6 +61,7 @@ import java.io.InputStream; import java.util.Collection; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; /** * Extension of validator used to import objects to the repository. @@ -120,23 +121,50 @@ private void importObjectsInternal(InputStream input, String language, final Imp } } + int stopAfterErrors = options != null && options.getStopAfterErrors() != null ? + options.getStopAfterErrors() : 0; + if (!PrismContext.LANG_XML.equals(language)) { - List> prismObjects; + AtomicInteger index = new AtomicInteger(0); + AtomicInteger errors = new AtomicInteger(0); + AtomicInteger successes = new AtomicInteger(0); + PrismParser.ObjectHandler handler = new PrismParser.ObjectHandler() { + @Override + public boolean handleData(PrismObject object) { + OperationResult objectResult = parentResult.createSubresult(OperationConstants.IMPORT_OBJECT); + objectResult.addContext("objectNumber", index.incrementAndGet()); + importParsedObject(object, null, objectResult, options, task, raw); + objectResult.computeStatusIfUnknown(); + objectResult.cleanupResult(); + parentResult.summarize(); + + if (objectResult.isAcceptable()) { + successes.incrementAndGet(); + } else { + errors.incrementAndGet(); + } + return stopAfterErrors == 0 || errors.get() < stopAfterErrors; + } + + @Override + public boolean handleError(Throwable t) { + OperationResult objectResult = parentResult.createSubresult(OperationConstants.IMPORT_OBJECT); + objectResult.addContext("objectNumber", index.incrementAndGet()); + objectResult.recordFatalError("Couldn't parse object", t); + parentResult.summarize(); + + errors.incrementAndGet(); + return stopAfterErrors == 0 || errors.get() < stopAfterErrors; + } + }; try { - prismObjects = prismContext.parserFor(input).language(language).parseObjects(); + prismContext.parserFor(input).language(language).parseObjectsIteratively(handler); } catch (SchemaException|IOException e) { parentResult.recordFatalError("Couldn't parse objects to be imported: " + e.getMessage(), e); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse objects to be imported", e); return; } - int i = 0; - for (PrismObject prismObject : prismObjects) { - OperationResult objectResult = parentResult.createSubresult(OperationConstants.IMPORT_OBJECT); - objectResult.addContext("objectNumber", ++i); - importParsedObject(prismObject, null, objectResult, options, task, raw); - objectResult.computeStatusIfUnknown(); - } - parentResult.computeStatusIfUnknown(); // TODO some statistics here + parentResult.computeStatus(errors.get() + " errors, " + successes.get() + " passed"); } else { EventHandler handler = new EventHandler() { @@ -161,10 +189,8 @@ public void handleGlobalError(OperationResult currentResult) { validator.setVerbose(true); if (options != null) { validator.setValidateSchema(BooleanUtils.isTrue(options.isValidateStaticSchema())); - if (options.getStopAfterErrors() != null) { - validator.setStopAfterErrors(options.getStopAfterErrors().longValue()); - } } + validator.setStopAfterErrors(stopAfterErrors); validator.validate(input, parentResult, OperationConstants.IMPORT_OBJECT); } } @@ -206,8 +232,8 @@ private EventResult importParsedObject(PrismObject pri return EventResult.skipObject(objectResult.getMessage()); } - if (objectElement != null && options != null && BooleanUtils.isTrue(options.isValidateDynamicSchema())) { - validateWithDynamicSchemas(object, objectElement, repository, objectResult); + if (options != null && BooleanUtils.isTrue(options.isValidateDynamicSchema())) { + validateWithDynamicSchemas(object, repository, objectResult); } objectResult.computeStatus(); @@ -388,8 +414,8 @@ private String deleteObject(PrismObject object, Reposi return object.getOid(); } - protected void validateWithDynamicSchemas(PrismObject object, Element objectElement, - RepositoryService repository, OperationResult objectResult) { + private void validateWithDynamicSchemas(PrismObject object, RepositoryService repository, + OperationResult objectResult) { // TODO: check extension schema (later) OperationResult result = objectResult.createSubresult(OPERATION_VALIDATE_DYN_SCHEMA); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java index d592e091a5a..f3200d0a688 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java @@ -684,9 +684,11 @@ private void evaluateSegmentTarget(AssignmentPathSegmentImpl segment, PlusMinusZ LOGGER.debug("Evaluating RBAC [{}]", ctx.assignmentPath.shortDumpLazily()); InternalMonitor.recordRoleEvaluation(targetType, true); - // Cache it immediately, even before evaluation. So if there is a cycle in the role path - // then we can detect it and skip re-evaluation of aggressively idempotent roles. - evaluatedAssignmentTargetCache.recordProcessing(segment, ctx.primaryAssignmentMode); + if (isValid) { + // Cache it immediately, even before evaluation. So if there is a cycle in the role path + // then we can detect it and skip re-evaluation of aggressively idempotent roles. + evaluatedAssignmentTargetCache.recordProcessing(segment, ctx.primaryAssignmentMode); + } if (isTargetValid && targetType instanceof AbstractRoleType) { MappingType roleCondition = ((AbstractRoleType)targetType).getCondition(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java index a4dcff00bce..b403515a6cf 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.SynchronizationUtils; +import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.repo.common.expression.Expression; import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; @@ -193,6 +194,10 @@ public boolean executeChanges(LensContext context, Tas try { context.reportProgress(new ProgressInformation(FOCUS_OPERATION, ENTERING)); executeDelta(focusDelta, focusContext, context, null, null, task, subResult); + if (focusDelta.isAdd() && focusDelta.getOid() != null) { + ConflictWatcher watcher = context.createAndRegisterConflictWatcher(focusDelta.getOid(), cacheRepositoryService); + watcher.setExpectedVersion(focusDelta.getObjectToAdd().getVersion()); + } subResult.computeStatus(); } catch (SchemaException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException | ExpressionEvaluationException | RuntimeException e) { @@ -236,9 +241,9 @@ public boolean executeChanges(LensContext context, Tas OperationResult subResult = result.createSubresult( OPERATION_EXECUTE_PROJECTION + "." + projCtx.getObjectTypeClass().getSimpleName()); - subResult.addContext("discriminator", projCtx.getResourceShadowDiscriminator()); + subResult.addArbitraryObjectAsContext("discriminator", projCtx.getResourceShadowDiscriminator()); if (projCtx.getResource() != null) { - subResult.addParam("resource", projCtx.getResource().getName()); + subResult.addParam("resource", projCtx.getResource()); } try { @@ -711,7 +716,7 @@ private void updateSituationInShadow(Task task, String projectionOid = projectionCtx.getOid(); OperationResult result = new OperationResult(OPERATION_UPDATE_SITUATION_ACCOUNT); - result.addParam("situation", situation); + result.addArbitraryObjectAsParam("situation", situation); result.addParam("accountRef", projectionOid); PrismObject account = null; @@ -942,17 +947,8 @@ private ObjectDelta computeDiffDelta( return objectDelta; } - ObjectDeltaOperation lastRelated = findLastRelatedDelta(executedDeltas, objectDelta); // any - // delta - // related - // to - // our - // OID, - // not - // ending - // with - // fatal - // error + // any delta related to our OID, not ending with fatal error + ObjectDeltaOperation lastRelated = findLastRelatedDelta(executedDeltas, objectDelta); if (LOGGER.isTraceEnabled()) { LOGGER.trace("findLastRelatedDelta returned:\n{}", lastRelated != null ? lastRelated.debugDump() : "(null)"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index 5c55155e547..caa46f2c585 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -20,6 +20,8 @@ import com.evolveum.midpoint.audit.api.AuditEventType; import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.common.Clock; +import com.evolveum.midpoint.model.api.ProgressInformation; +import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.api.ModelAuthorizationAction; import com.evolveum.midpoint.model.api.ModelExecuteOptions; @@ -101,6 +103,13 @@ import java.util.*; import java.util.Map.Entry; +import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.CLOCKWORK; +import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.WAITING; +import static com.evolveum.midpoint.model.api.ProgressInformation.StateType.ENTERING; +import static com.evolveum.midpoint.model.api.ProgressInformation.StateType.EXITING; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + /** * @author semancik * @@ -110,62 +119,37 @@ public class Clockwork { private static final int DEFAULT_NUMBER_OF_RESULTS_TO_KEEP = 5; + private static final int DEFAULT_MAX_CONFLICT_RESOLUTION_ATTEMPTS = 1; // synchronize with common-core-3.xsd + private static final int DEFAULT_CONFLICT_RESOLUTION_DELAY_UNIT = 5000; // synchronize with common-core-3.xsd + private static final Trace LOGGER = TraceManager.getTrace(Clockwork.class); - @Autowired(required=true) - private Projector projector; - // This is ugly // TODO: cleanup - @Autowired - private ContextLoader contextLoader; - - @Autowired(required=true) - private ChangeExecutor changeExecutor; + @Autowired private Projector projector; + @Autowired private ContextLoader contextLoader; + @Autowired private ChangeExecutor changeExecutor; + @Autowired private AuditService auditService; + @Autowired private SecurityEnforcer securityEnforcer; + @Autowired private Clock clock; + @Autowired private ModelObjectResolver objectResolver; + @Autowired private SystemObjectCache systemObjectCache; + @Autowired private transient ProvisioningService provisioningService; + @Autowired private transient ChangeNotificationDispatcher changeNotificationDispatcher; + @Autowired private ScriptExpressionFactory scriptExpressionFactory; + @Autowired private PersonaProcessor personaProcessor; + @Autowired private PrismContext prismContext; + @Autowired private TaskManager taskManager; + @Autowired private OperationalDataManager metadataManager; + @Autowired private ContextFactory contextFactory; - @Autowired(required = false) - private HookRegistry hookRegistry; - - @Autowired - private AuditService auditService; - - @Autowired - private SecurityEnforcer securityEnforcer; - - @Autowired - private Clock clock; - - @Autowired - @Qualifier("cacheRepositoryService") - private transient RepositoryService repositoryService; - - @Autowired - private ModelObjectResolver objectResolver; - - @Autowired - private SystemObjectCache systemObjectCache; + @Autowired(required = false) + private HookRegistry hookRegistry; @Autowired - private transient ProvisioningService provisioningService; - - @Autowired - private transient ChangeNotificationDispatcher changeNotificationDispatcher; - - @Autowired - private ScriptExpressionFactory scriptExpressionFactory; - - @Autowired(required=true) - private PersonaProcessor personaProcessor; - - @Autowired - private PrismContext prismContext; - - @Autowired - private TaskManager taskManager; + @Qualifier("cacheRepositoryService") + private transient RepositoryService repositoryService; - @Autowired - private OperationalDataManager metadataManager; - private LensDebugListener debugListener; public LensDebugListener getDebugListener() { @@ -185,8 +169,14 @@ public HookOperationMode run(LensContext context, Task } int clicked = 0; + boolean focusConflictPresent = false; + HookOperationMode finalMode; try { + context.reportProgress(new ProgressInformation(CLOCKWORK, ENTERING)); + if (context.getFocusContext() != null && context.getFocusContext().getOid() != null) { + context.createAndRegisterConflictWatcher(context.getFocusContext().getOid(), repositoryService); + } FocusConstraintsChecker.enterCache(); enterAssociationSearchExpressionEvaluatorCache(); provisioningService.enterConstraintsCheckerCache(); @@ -210,12 +200,120 @@ public HookOperationMode run(LensContext context, Task } } // One last click in FINAL state - return click(context, task, result); + finalMode = click(context, task, result); + if (finalMode == HookOperationMode.FOREGROUND) { + focusConflictPresent = checkFocusConflicts(context, task, result); + } } finally { + context.unregisterConflictWatchers(repositoryService); FocusConstraintsChecker.exitCache(); exitAssociationSearchExpressionEvaluatorCache(); provisioningService.exitConstraintsCheckerCache(); + context.reportProgress(new ProgressInformation(CLOCKWORK, EXITING)); + } + + // intentionally outside the "try-finally" block to start with clean caches + if (focusConflictPresent) { + assert finalMode == HookOperationMode.FOREGROUND; + finalMode = resolveFocusConflict(context, task, result); + } else if (context.getConflictResolutionAttemptNumber() > 0) { + LOGGER.info("Resolved update conflict on attempt number {}", context.getConflictResolutionAttemptNumber()); + } + return finalMode; + } + + private boolean checkFocusConflicts(LensContext context, Task task, OperationResult result) { + for (ConflictWatcher watcher : context.getConflictWatchers()) { + if (repositoryService.hasConflict(watcher, result)) { + LOGGER.debug("Found modify-modify conflict on {}", watcher); + return true; + } + } + return false; + } + + private HookOperationMode resolveFocusConflict(LensContext context, Task task, OperationResult result) + throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, ConfigurationException, + CommunicationException, SecurityViolationException, PolicyViolationException, ObjectAlreadyExistsException { + ConflictResolutionType resolutionPolicy = ModelUtils.getConflictResolution(context); + if (resolutionPolicy == null || resolutionPolicy.getAction() == ConflictResolutionActionType.NONE) { + return HookOperationMode.FOREGROUND; + } + PrismObject focusObject = context.getFocusContext() != null ? context.getFocusContext().getObjectAny() : null; + switch (resolutionPolicy.getAction()) { + case FAIL: throw new SystemException("Conflict detected while updating " + focusObject); + case LOG: + LOGGER.warn("Conflict detected while updating {}", focusObject); + return HookOperationMode.FOREGROUND; + case RECOMPUTE: + break; + default: + throw new IllegalStateException("Unsupported conflict resolution action: " + resolutionPolicy.getAction()); + } + + // so, recompute is the action + + if (context.getFocusContext() == null) { + LOGGER.warn("No focus context, not possible to resolve conflict by focus recomputation"); // should really never occur + return HookOperationMode.FOREGROUND; + } + String oid = context.getFocusContext().getOid(); + if (oid == null) { + LOGGER.warn("No focus OID, not possible to resolve conflict by focus recomputation"); // should really never occur + return HookOperationMode.FOREGROUND; + } + Class focusClass = context.getFocusContext().getObjectTypeClass(); + if (focusClass == null) { + LOGGER.warn("Focus class not known, not possible to resolve conflict by focus recomputation"); // should really never occur + return HookOperationMode.FOREGROUND; + } + if (TaskType.class.isAssignableFrom(focusClass)) { + return HookOperationMode.FOREGROUND; // this is actually quite expected, so don't bother anyone with that + } + if (!FocusType.class.isAssignableFrom(focusClass)) { + LOGGER.warn("Focus is not of FocusType (it is {}); not possible to resolve conflict by focus recomputation", focusClass.getName()); + return HookOperationMode.FOREGROUND; + } + + PrismObject focus = repositoryService.getObject(focusClass, oid, null, result); + LensContext contextNew = contextFactory.createRecomputeContext(focus, null, task, result); + contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners()))); + int attemptOld = context.getConflictResolutionAttemptNumber(); + int attemptNew = attemptOld + 1; + boolean shouldExecuteAttempt = shouldExecuteAttempt(resolutionPolicy, attemptNew, context); + if (shouldExecuteAttempt) { + contextNew.setConflictResolutionAttemptNumber(attemptNew); + // this is a recursion; but limited to max attempts which should not be a large number + return run(contextNew, task, result); + } else { + LOGGER.warn("Couldn't resolve conflict even after {} resolution attempt(s), giving up.", attemptOld); + return HookOperationMode.FOREGROUND; + } + } + + private boolean shouldExecuteAttempt(@NotNull ConflictResolutionType resolutionPolicy, int attemptNew, + LensContext context) { + int maxAttempts = defaultIfNull(resolutionPolicy.getMaxAttempts(), DEFAULT_MAX_CONFLICT_RESOLUTION_ATTEMPTS); + if (attemptNew > maxAttempts) { + return false; + } + long delayUnit = defaultIfNull(resolutionPolicy.getDelayUnit(), DEFAULT_CONFLICT_RESOLUTION_DELAY_UNIT); + for (int i = 0; i < attemptNew; i++) { + delayUnit *= 2; + } + long delay = (long) (Math.random() * delayUnit); + String message = "Waiting "+delay+" milliseconds before starting conflict resolution attempt "+attemptNew+" of "+maxAttempts; + // TODO convey information about waiting time after some GUI mechanism for displaying it is available + // (showing text messages is currently really ugly) + context.reportProgress(new ProgressInformation(WAITING, EXITING)); + LOGGER.debug(message); + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + // ignore } + context.reportProgress(new ProgressInformation(WAITING, EXITING)); + return true; } private void enterAssociationSearchExpressionEvaluatorCache() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java index 5c0d0168b0e..1f313358973 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java @@ -23,6 +23,8 @@ import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.provisioning.api.ProvisioningService; +import com.evolveum.midpoint.repo.api.ConflictWatcher; +import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.result.OperationResult; @@ -60,6 +62,10 @@ public class LensContext implements ModelContext { private ModelState state = ModelState.INITIAL; + @NotNull private final transient List conflictWatchers = new ArrayList<>(); + + private int conflictResolutionAttemptNumber; + /** * Channel that is the source of primary change (GUI, live sync, import, * ...) @@ -1297,4 +1303,28 @@ public T getHookPreviewResult(@NotNull Class clazz) { return null; } } + + public int getConflictResolutionAttemptNumber() { + return conflictResolutionAttemptNumber; + } + + public void setConflictResolutionAttemptNumber(int conflictResolutionAttemptNumber) { + this.conflictResolutionAttemptNumber = conflictResolutionAttemptNumber; + } + + @NotNull + public List getConflictWatchers() { + return conflictWatchers; + } + + public ConflictWatcher createAndRegisterConflictWatcher(String oid, RepositoryService repositoryService) { + ConflictWatcher watcher = repositoryService.createAndRegisterConflictWatcher(oid); + conflictWatchers.add(watcher); + return watcher; + } + + public void unregisterConflictWatchers(RepositoryService repositoryService) { + conflictWatchers.forEach(w -> repositoryService.unregisterConflictWatcher(w)); + conflictWatchers.clear(); + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java index 7f4c7088179..6850fa2b761 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java @@ -139,11 +139,9 @@ public void applyMetadataModify(Obj if (objectContext != null && objectContext.getObjectOld() != null) { // a null value of objectOld means that we execute MODIFY delta - // that is a part of primary ADD operation (in a wave greater - // than 0) + // that is a part of primary ADD operation (in a wave greater than 0) // i.e. there are NO modifyApprovers set (theoretically they - // could be set in previous waves, but because in these waves - // the data + // could be set in previous waves, but because in these waves the data // are taken from the same source as in this step - so there are // none modify approvers). @@ -232,6 +230,9 @@ private void applyAssignmentValueMetadataAdd(LensContext EvaluatedAssignmentImpl evaluateAssignment(Item EvaluatedAssignmentImpl evaluatedAssignment = assignmentEvaluator.evaluate(assignmentIdi, mode, evaluateOld, source, assignmentPlacementDesc, task, result); context.rememberResources(evaluatedAssignment.getResources(task, result)); result.recordSuccess(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Evaluated assignment:\n{}", evaluatedAssignment == null ? null : evaluatedAssignment.debugDump(1)); + } return evaluatedAssignment; } catch (ObjectNotFoundException ex) { if (LOGGER.isTraceEnabled()) { @@ -532,6 +535,10 @@ private EvaluatedAssignmentImpl evaluateAssignment(Item } return null; } catch (ExpressionEvaluationException | PolicyViolationException e) { + AssignmentType assignmentType = LensUtil.getAssignmentType(assignmentIdi, evaluateOld); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Processing of assignment resulted in error {}: {}", e, SchemaDebugUtil.prettyPrint(assignmentType)); + } result.recordFatalError(e); throw e; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConstructionProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConstructionProcessor.java index 66462aa3642..b3d580e65fb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConstructionProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConstructionProcessor.java @@ -215,7 +215,7 @@ private void collectToC OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { for (EvaluatedAssignmentImpl evaluatedAssignment: evaluatedAssignments) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Collecting constructions from evaluated assignment:\n{}", evaluatedAssignment.debugDump()); + LOGGER.trace("Collecting constructions from evaluated assignment:\n{}", evaluatedAssignment.debugDump(1)); } DeltaSetTriple constructionTriple = constructionTripleExtractor.apply(evaluatedAssignment); collectToConstructionMapFromEvaluatedConstructions(context, evaluatedAssignment, constructionTriple.getZeroSet(), constructionMapTriple, keyGenerator, mode, PlusMinusZero.ZERO, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java index 799727aedaf..90bb3645e1c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java @@ -45,7 +45,9 @@ import com.evolveum.midpoint.model.impl.lens.projector.credentials.CredentialsProcessor; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.OriginType; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; @@ -53,10 +55,13 @@ import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.NameItemPathSegment; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -76,6 +81,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractCredentialType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.GlobalPolicyRuleType; @@ -247,7 +253,7 @@ private void processFocusFocus(LensContext context, Str // ACTIVATION LensUtil.partialExecute("focusActivation", - () -> processActivation(context, now, result), + () -> processActivationBeforeAssignments(context, now, result), partialProcessingOptions::getFocusActivation); @@ -262,7 +268,7 @@ private void processFocusFocus(LensContext context, Str // process activation again. Object template might have changed it. context.recomputeFocus(); LensUtil.partialExecute("focusActivation", - () -> processActivation(context, now, result), + () -> processActivationBeforeAssignments(context, now, result), partialProcessingOptions::getFocusActivation); // ASSIGNMENTS @@ -296,9 +302,10 @@ private void processFocusFocus(LensContext context, Str context.recompute(); // process activation again. Second pass through object template might have changed it. + // We also need to apply assignment activation if needed context.recomputeFocus(); LensUtil.partialExecute("focusActivation", - () -> processActivation(context, now, result), + () -> processActivationAfterAssignments(context, now, result), partialProcessingOptions::getFocusActivation); // CREDENTIALS (including PASSWORD POLICY) @@ -589,7 +596,20 @@ private void cleanupContext(LensFocusContext focusConte focusContext.recompute(); } - private void processActivation(LensContext context, XMLGregorianCalendar now, + private void processActivationBeforeAssignments(LensContext context, XMLGregorianCalendar now, + OperationResult result) + throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException { + processActivationBasic(context, now, result); + } + + private void processActivationAfterAssignments(LensContext context, XMLGregorianCalendar now, + OperationResult result) + throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException { + processActivationBasic(context, now, result); + processAssignmentActivation(context, now, result); + } + + private void processActivationBasic(LensContext context, XMLGregorianCalendar now, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException { LensFocusContext focusContext = context.getFocusContext(); @@ -878,5 +898,53 @@ private void addIterationTokenDeltas(LensFocusContext f focusContext.swallowToSecondaryDelta(iterationTokenDelta); } + + private void processAssignmentActivation(LensContext context, XMLGregorianCalendar now, + OperationResult result) throws SchemaException { + DeltaSetTriple> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple(); + if (evaluatedAssignmentTriple == null) { + // Code path that should not normally happen. But is used in some tests and may + // happen during partial processing. + return; + } + // We care only about existing assignments here. New assignments will be taken care of in the executor + // (OperationalDataProcessor). And why care about deleted assignments? + Collection> zeroSet = evaluatedAssignmentTriple.getZeroSet(); + if (zeroSet == null) { + return; + } + LensFocusContext focusContext = context.getFocusContext(); + for (EvaluatedAssignmentImpl evaluatedAssignment: zeroSet) { + AssignmentType assignmentType = evaluatedAssignment.getAssignmentType(); + ActivationType currentActivationType = assignmentType.getActivation(); + ActivationStatusType expectedEffectiveStatus = activationComputer.getEffectiveStatus(assignmentType.getLifecycleState(), currentActivationType); + if (currentActivationType == null) { + PrismContainerDefinition activationDef = focusContext.getObjectDefinition().findContainerDefinition(SchemaConstants.PATH_ASSIGNMENT_ACTIVATION); + ContainerDelta activationDelta = activationDef.createEmptyDelta( + new ItemPath( + new NameItemPathSegment(FocusType.F_ASSIGNMENT), new IdItemPathSegment(assignmentType.getId()), + new NameItemPathSegment(AssignmentType.F_ACTIVATION) + )); + ActivationType newActivationType = new ActivationType(); + activationDelta.setValuesToReplace(newActivationType.asPrismContainerValue()); + newActivationType.setEffectiveStatus(expectedEffectiveStatus); + focusContext.swallowToSecondaryDelta(activationDelta); + } else { + ActivationStatusType currentEffectiveStatus = currentActivationType.getEffectiveStatus(); + if (!expectedEffectiveStatus.equals(currentEffectiveStatus)) { + PrismPropertyDefinition effectiveStatusPropertyDef = focusContext.getObjectDefinition().findPropertyDefinition(SchemaConstants.PATH_ASSIGNMENT_ACTIVATION_EFFECTIVE_STATUS); + PropertyDelta effectiveStatusDelta = effectiveStatusPropertyDef.createEmptyDelta( + new ItemPath( + new NameItemPathSegment(FocusType.F_ASSIGNMENT), new IdItemPathSegment(assignmentType.getId()), + new NameItemPathSegment(AssignmentType.F_ACTIVATION), + new NameItemPathSegment(ActivationType.F_EFFECTIVE_STATUS) + )); + effectiveStatusDelta.setValueToReplace(new PrismPropertyValue(expectedEffectiveStatus)); + focusContext.swallowToSecondaryDelta(effectiveStatusDelta); + } + } + } + } + } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java index f1e8b1c783c..3743ced0af3 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java @@ -139,8 +139,8 @@ public void processOutbound(LensContext context, LensPr Mapping.Builder,RefinedAttributeDefinition> builder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(refinedAttributeDefinition.getName()) - + " in " + rOcDef.getResourceType()); - builder = builder.originObject(rOcDef.getResourceType()) + + " in " + projCtx.getResource()); + builder = builder.originObject(projCtx.getResource()) .originType(OriginType.OUTBOUND); Mapping,RefinedAttributeDefinition> evaluatedMapping = evaluateMapping(builder, attributeName, refinedAttributeDefinition, focusOdo, projectionOdo, operation, rOcDef, null, context, projCtx, task, result); @@ -165,7 +165,7 @@ public void processOutbound(LensContext context, LensPr Mapping.Builder,PrismContainerDefinition> mappingBuilder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(associationDefinition.getName()) - + " in " + rOcDef.getResourceType()); + + " in " + projCtx.getResource()); PrismContainerDefinition outputDefinition = getAssociationContainerDefinition(); Mapping,PrismContainerDefinition> evaluatedMapping = (Mapping) evaluateMapping(mappingBuilder, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java index 08672f1d78b..029e6979fed 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java @@ -277,7 +277,7 @@ public void run(Task workerTask) { // temporary hack: how to see thread name for this task workerTask.setName(workerTask.getName().getOrig() + " (" + Thread.currentThread().getName() + ")"); - workerSpecificResult.addContext("subtaskName", workerTask.getName()); + workerSpecificResult.addArbitraryObjectAsContext("subtaskName", workerTask.getName()); while (workerTask.canRun()) { ProcessingRequest request; diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 1e6a3e6a970..a94ff490290 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -266,6 +266,9 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final File ROLE_CYAN_SAILOR_FILE = new File(COMMON_DIR, "role-cyan-sailor.xml"); protected static final String ROLE_CYAN_SAILOR_OID = "d3abd794-9c30-11e6-bb5a-af14bf2cc29b"; + protected static final File ROLE_STRONG_SAILOR_FILE = new File(COMMON_DIR, "role-strong-sailor.xml"); + protected static final String ROLE_STRONG_SAILOR_OID = "0bf7532e-7d15-11e7-8594-7bff6e0adc6e"; + protected static final File ROLE_DRINKER_FILE = new File(COMMON_DIR, "role-drinker.xml"); protected static final String ROLE_DRINKER_OID = "0abbde4c-ab3f-11e6-910d-d7dabf5f09f0"; @@ -529,6 +532,10 @@ public void initSystem(Task initTask, OperationResult initResult) throws Except repoAddObjectFromFile(ROLE_SUPERUSER_FILE, initResult); login(userAdministrator); } + + protected int getNumberOfRoles() { + return 1; // Superuser role + } protected File getSystemConfigurationFile() { return SYSTEM_CONFIGURATION_FILE; diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractInitializedModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractInitializedModelIntegrationTest.java index f88e9eba071..54b2fd39f0e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractInitializedModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractInitializedModelIntegrationTest.java @@ -15,7 +15,6 @@ */ package com.evolveum.midpoint.model.intest; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNull; @@ -26,7 +25,7 @@ import com.evolveum.midpoint.prism.query.OrgFilter; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.beans.factory.annotation.Autowired; @@ -54,11 +53,6 @@ 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.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import javax.xml.datatype.XMLGregorianCalendar; @@ -73,6 +67,8 @@ public class AbstractInitializedModelIntegrationTest extends AbstractConfiguredM protected static final Trace LOGGER = TraceManager.getTrace(AbstractInitializedModelIntegrationTest.class); + private static final int NUMBER_OF_IMPORTED_ROLES = 15; + @Autowired(required = true) protected MappingFactory mappingFactory; @@ -125,7 +121,9 @@ public AbstractInitializedModelIntegrationTest() { public void initSystem(Task initTask, OperationResult initResult) throws Exception { LOGGER.trace("initSystem"); super.initSystem(initTask, initResult); - + + assumeConflictResolutionAction(getDefaultConflictResolutionAction()); + mappingFactory.setProfiling(true); lensDebugListener = new ProfilingLensDebugListener(); clockwork.setDebugListener(lensDebugListener); @@ -255,6 +253,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti repoAddObjectFromFile(ROLE_SAILOR_FILE, initResult); repoAddObjectFromFile(ROLE_RED_SAILOR_FILE, initResult); repoAddObjectFromFile(ROLE_CYAN_SAILOR_FILE, initResult); + repoAddObjectFromFile(ROLE_STRONG_SAILOR_FILE, initResult); // Orgstruct if (doAddOrgstruct()) { @@ -265,7 +264,14 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti repoAddObjectFromFile(SERVICE_SHIP_SEA_MONKEY_FILE, initResult); repoAddObjectFromFile(PASSWORD_POLICY_BENEVOLENT_FILE, initResult); + } + + protected ConflictResolutionActionType getDefaultConflictResolutionAction() { + return ConflictResolutionActionType.FAIL; + } + protected int getNumberOfRoles() { + return super.getNumberOfRoles() + NUMBER_OF_IMPORTED_ROLES; } protected boolean doAddOrgstruct() { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/DelayingProgressListener.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/DelayingProgressListener.java new file mode 100644 index 00000000000..0e4179014e8 --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/DelayingProgressListener.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.intest; + +import com.evolveum.midpoint.model.api.ProgressInformation; +import com.evolveum.midpoint.model.api.ProgressListener; +import com.evolveum.midpoint.model.api.context.ModelContext; + +/** + * @author mederly + */ +public class DelayingProgressListener implements ProgressListener { + + private final long delayMin, delayMax; + + public DelayingProgressListener(long delayMin, long delayMax) { + this.delayMin = delayMin; + this.delayMax = delayMax; + } + + @Override + public void onProgressAchieved(ModelContext modelContext, ProgressInformation progressInformation) { + try { + long delay = (long) (delayMin + Math.random() * (delayMax - delayMin)); + System.out.println("[" + Thread.currentThread().getName() + "] Delaying execution by " + delay + " ms for " + progressInformation); + Thread.sleep(delay); + } catch (InterruptedException e) { + // ignore + } + } + + @Override + public boolean isAbortRequested() { + return false; + } +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java index f638dbdc943..53ed0dee9f4 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java @@ -93,6 +93,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; @@ -1678,8 +1679,8 @@ public void test151ModifyUserJackAssignAccountRelativeEnforcement() throws Excep modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); + assertResultSerialization(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); @@ -1728,7 +1729,7 @@ public void test151ModifyUserJackAssignAccountRelativeEnforcement() throws Excep assertCounterIncrement(InternalCounters.SCRIPT_COMPILE_COUNT, 0); assertSteadyResources(); } - + /** * Assignment enforcement is set to RELATIVE for this test. The account should be gone. */ @@ -3294,5 +3295,11 @@ private void preTestCleanup(AssignmentPolicyEnforcementType enforcementPolicy) t purgeProvisioningScriptHistory(); rememberCounter(InternalCounters.SHADOW_FETCH_OPERATION_COUNT); } + + private void assertResultSerialization(OperationResult result) throws SchemaException { + OperationResultType resultType = result.createOperationResultType(); + String serialized = prismContext.serializerFor(PrismContext.LANG_XML).serializeAnyData(resultType, SchemaConstants.C_RESULT); + display("OperationResultType serialized", serialized); + } } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java new file mode 100644 index 00000000000..378ed847cc0 --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.intest; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.*; + +import static org.testng.AssertJUnit.*; + +/** + * @author mederly + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestRaceConditions extends AbstractInitializedModelIntegrationTest { + + public static final File TEST_DIR = new File("src/test/resources/contract"); + + @Override + public void initSystem(Task initTask, OperationResult initResult) + throws Exception { + super.initSystem(initTask, initResult); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + } + + @Override + protected ConflictResolutionActionType getDefaultConflictResolutionAction() { + return ConflictResolutionActionType.RECOMPUTE; + } + + @Test + public void test100AssignRoles() throws Exception { + final String TEST_NAME="test100AssignRoles"; + displayTestTile(TEST_NAME); + + // GIVEN + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + @SuppressWarnings({"unchecked", "raw"}) + ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT).add( + ObjectTypeUtil.createAssignmentTo(ROLE_PIRATE_OID, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(ROLE_SAILOR_OID, ObjectTypes.ROLE, prismContext)) + .asObjectDelta(USER_JACK_OID); + executeChangesAssertSuccess(objectDelta, null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack); + + String accountJackOid = getSingleLinkOid(userJack); + + // Check shadow + PrismObject accountShadow = repositoryService.getObject(ShadowType.class, accountJackOid, null, result); + assertDummyAccountShadowRepo(accountShadow, accountJackOid, "jack"); + + // Check account + PrismObject accountModel = modelService.getObject(ShadowType.class, accountJackOid, null, task, result); + assertDummyAccountShadowModel(accountModel, accountJackOid, "jack", "Jack Sparrow"); + + // Check account in dummy resource + assertDefaultDummyAccount("jack", "Jack Sparrow", true); + } + + /** + * Remove both roles at once, in different threads. + */ + @Test + public void test110UnassignRoles() throws Exception { + final String TEST_NAME = "test110UnassignRoles"; + displayTestTile(TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestRaceConditions.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userJack = getUser(USER_JACK_OID); + List assignments = userJack.asObjectable().getAssignment(); + assertEquals("Wrong # of assignments", 2, assignments.size()); + + // WHEN + Thread t1 = new Thread(() -> deleteAssignment(userJack, 0, task, result)); + Thread t2 = new Thread(() -> deleteAssignment(userJack, 1, task, result)); + t1.start(); + t2.start(); + t1.join(30000L); + t2.join(30000L); + + // THEN + PrismObject userJackAfter = getUser(USER_JACK_OID); + display("User after change execution", userJackAfter); + assertEquals("Unexpected # of projections of jack", 0, userJackAfter.asObjectable().getLinkRef().size()); + } + + private void deleteAssignment(PrismObject user, int index, Task task, OperationResult result) { + try { + login(userAdministrator); + @SuppressWarnings({ "unchecked", "raw" }) + ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(FocusType.F_ASSIGNMENT).delete(user.asObjectable().getAssignment().get(index).clone()) + .asObjectDelta(USER_JACK_OID); + modelService.executeChanges(Collections.singletonList(objectDelta), null, task, + Collections.singletonList(new DelayingProgressListener(0, 1000)), result); + } catch (Throwable t) { + throw new SystemException(t); + } + } + +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java index 6e27a38441f..2e6e4ebbe08 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java @@ -15,7 +15,6 @@ */ package com.evolveum.midpoint.model.intest; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; @@ -38,7 +37,6 @@ import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.common.expression.evaluator.GenerateExpressionEvaluator; import com.evolveum.midpoint.model.impl.trigger.RecomputeTriggerHandler; -import com.evolveum.midpoint.model.intest.sync.TestImportRecon; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismValue; @@ -109,7 +107,7 @@ public class TestUserTemplate extends AbstractInitializedModelIntegrationTest { private static final String EMPLOYEE_TYPE_MAROONED = "marooned"; - private static final int NUMBER_OF_ROLES = 20; + private static final int NUMBER_OF_IMPORTED_ROLES = 5; private static String jackEmployeeNumber; @@ -129,6 +127,10 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti setDefaultObjectTemplate(UserType.COMPLEX_TYPE, EMPLOYEE_TYPE_MAROONED, USER_TEMPLATE_MAROONED_OID, initResult); } + protected int getNumberOfRoles() { + return super.getNumberOfRoles() + NUMBER_OF_IMPORTED_ROLES; + } + @Test public void test000Sanity() throws Exception { final String TEST_NAME = "test000Sanity"; @@ -150,11 +152,11 @@ public void test000Sanity() throws Exception { assertNotNull("no system config", systemConfiguration); List defaultObjectPolicyConfiguration = systemConfiguration.asObjectable().getDefaultObjectPolicyConfiguration(); assertNotNull("No object policy", defaultObjectPolicyConfiguration); - assertEquals("Wrong object policy size", 2, defaultObjectPolicyConfiguration.size()); + assertEquals("Wrong object policy size", 3, defaultObjectPolicyConfiguration.size()); // third is the conflict resolution rule assertObjectTemplate(defaultObjectPolicyConfiguration, UserType.COMPLEX_TYPE, null, USER_TEMPLATE_COMPLEX_OID); assertObjectTemplate(defaultObjectPolicyConfiguration, UserType.COMPLEX_TYPE, EMPLOYEE_TYPE_MAROONED, USER_TEMPLATE_MAROONED_OID); - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } private void assertObjectTemplate(List defaultObjectPolicyConfigurations, @@ -1341,7 +1343,7 @@ public void test191ModifyUserGuybrushOrganizationAutomatic() throws Exception { assertAssignedRole(userAfter, ROLE_AUTOMATIC_OID); assertAssignments(userAfter, 2); - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1392,7 +1394,7 @@ public void test192ModifyUserGuybrushOrganizationAddMixed() throws Exception { assertAssignments(userAfter, 4); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1443,7 +1445,7 @@ public void test193ModifyUserGuybrushOrganizationAddOutOfDomain() throws Excepti assertAssignments(userAfter, 4); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1490,7 +1492,7 @@ public void test194ModifyUserGuybrushOrganizationDeleteMixed() throws Exception assertAssignments(userAfter, 2); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1533,7 +1535,7 @@ public void test195ModifyUserGuybrushOrganizationDeleteOutOfDomain() throws Exce assertAssignments(userAfter, 2); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1575,7 +1577,7 @@ public void test196GuybrushAssignCaptain() throws Exception { assertAssignments(userAfter, 3); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1614,7 +1616,7 @@ public void test197ModifyGuybrushEmployeeTypePirate() throws Exception { assertAssignments(userAfter, 4); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1664,7 +1666,7 @@ public void test198AModifyUserGuybrushOrganizationAddInDomain() throws Exception assertAssignments(userAfter, 6); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1711,7 +1713,7 @@ public void test198BModifyUserGuybrushOrganizationDeleteMixed() throws Exception assertAssignments(userAfter, 5); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1753,7 +1755,7 @@ public void test199AGuyBrushModifyEmployeeTypeWannabe() throws Exception { assertAssignments(userAfter, 4); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1794,7 +1796,7 @@ public void test199BGuyBrushUnassignCaptain() throws Exception { assertAssignments(userAfter, 3); // Make sure nothing was created on demand - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } /** @@ -1828,7 +1830,7 @@ public void test199CModifyUserGuybrushOrganizationCleanup() throws Exception { assertAssignedNoRole(userAfter); - assertRoles(NUMBER_OF_ROLES); + assertRoles(getNumberOfRoles()); } @Test diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/AbstractImportTest.java similarity index 78% rename from model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportTest.java rename to model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/AbstractImportTest.java index 91df43e405f..36d1c7d2213 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/AbstractImportTest.java @@ -72,31 +72,38 @@ */ @ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) @DirtiesContext(classMode=ClassMode.AFTER_CLASS) -public class ImportTest extends AbstractConfiguredModelIntegrationTest { +public abstract class AbstractImportTest extends AbstractConfiguredModelIntegrationTest { private static final String TEST_FILE_DIRECTORY = "src/test/resources/importer/"; - private static final File TEST_FOLDER_COMMON = new File("./src/test/resources/common"); - private static final File IMPORT_USERS_FILE = new File(TEST_FILE_DIRECTORY, "import-users.xml"); - private static final File IMPORT_USERS_OVERWRITE_FILE = new File(TEST_FILE_DIRECTORY, "import-users-overwrite.xml"); + private static final String TEST_FOLDER_COMMON = "src/test/resources/common/"; + + private static final String IMPORT_USERS_FILE_NAME = "import-users"; + private static final String IMPORT_USERS_OVERWRITE_FILE_NAME = "import-users-overwrite"; + private static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; private static final String USER_WILL_OID = "c0c010c0-d34d-b33f-f00d-111111111112"; - private static final File CONNECTOR_DBTABLE_FILE = new File(TEST_FOLDER_COMMON, "connector-dbtable.xml"); + private static final String CONNECTOR_DBTABLE_FILE_NAME = "connector-dbtable"; private static final String CONNECOTR_DBTABLE_OID = "7d3ebd6f-6113-4833-8a6a-596b73a5e434"; private static final String CONNECTOR_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.db.databasetable/org.identityconnectors.databasetable.DatabaseTableConnector"; - private static final File RESOURCE_DERBY_FILE = new File(TEST_FILE_DIRECTORY, "resource-derby.xml"); + private static final String RESOURCE_DERBY_FILE_NAME = "resource-derby"; private static final String RESOURCE_DERBY_OID = "ef2bc95b-76e0-59e2-86d6-9119011311ab"; private static final String RESOURCE_DERBY_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-9119011311ab"; - - private static final File RESOURCE_DUMMY_RUNTIME_FILE = new File(TEST_FILE_DIRECTORY, "resource-dummy-runtime-resolution.xml"); + + private static final String RESOURCE_DUMMY_FILE_NAME = "resource-dummy"; + private static final String RESOURCE_DUMMY_RUNTIME_FILE_NAME = "resource-dummy-runtime-resolution"; private static final String RESOURCE_DUMMY_RUNTIME_OID = "78fc521e-69f0-11e6-9ec5-130eb0c6fb6d"; - private static final File IMPORT_TASK_FILE = new File(TEST_FILE_DIRECTORY, "import-task.xml"); + private static final String IMPORT_TASK_FILE_NAME = "import-task"; private static final String TASK1_OID = "00000000-0000-0000-0000-123450000001"; private static final String TASK1_OWNER_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; - private static final File RESOURCE_DUMMY_CHANGED_FILE = new File(TEST_FILE_DIRECTORY, "resource-dummy-changed.xml");; - + private static final String RESOURCE_DUMMY_CHANGED_FILE_NAME = "resource-dummy-changed"; + + protected static final String USER_HERMAN_FILE_NAME = "user-herman"; + private static final String IMPORT_REF_FILE_NAME = "import-ref"; + private static final String BAD_IMPORT_FILE_NAME = "import-bad"; + private DummyResource dummyResource; private DummyResourceContoller dummyResourceCtl; @@ -106,6 +113,14 @@ public class ImportTest extends AbstractConfiguredModelIntegrationTest { private static String guybrushOid; private static String hermanOid; + + abstract String getSuffix(); + + abstract String getLanguage(); + + File getFile(String name, boolean common) { + return new File(common ? TEST_FOLDER_COMMON : TEST_FILE_DIRECTORY, name + "." + getSuffix()); + } @Autowired private Clock clock; @@ -145,14 +160,14 @@ public void test001ImportConnector() throws FileNotFoundException, ObjectNotFoun TestUtil.displayTestTile(this,"test001ImportConnector"); // GIVEN Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test001ImportConnector"); - FileInputStream stream = new FileInputStream(CONNECTOR_DBTABLE_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test001ImportConnector"); + FileInputStream stream = new FileInputStream(getFile(CONNECTOR_DBTABLE_FILE_NAME, true)); dummyAuditService.clear(); XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); @@ -185,14 +200,14 @@ public void test003ImportUsers() throws Exception { TestUtil.displayTestTile(this,"test003ImportUsers"); // GIVEN Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test003ImportUsers"); - FileInputStream stream = new FileInputStream(IMPORT_USERS_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test003ImportUsers"); + FileInputStream stream = new FileInputStream(getFile(IMPORT_USERS_FILE_NAME, false)); dummyAuditService.clear(); XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); @@ -242,18 +257,17 @@ public void test003ImportUsers() throws Exception { // Import the same thing again. Watch how it burns :-) @Test - public void test004DuplicateImportUsers() throws Exception, - SchemaException { + public void test004DuplicateImportUsers() throws Exception { TestUtil.displayTestTile(this,"test004DuplicateImportUsers"); // GIVEN Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test004DuplicateImportUsers"); - FileInputStream stream = new FileInputStream(IMPORT_USERS_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test004DuplicateImportUsers"); + FileInputStream stream = new FileInputStream(getFile(IMPORT_USERS_FILE_NAME, false)); dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN result.computeStatus(); @@ -280,15 +294,15 @@ public void test005ImportUsersWithOverwrite() throws Exception { TestUtil.displayTestTile(this,"test005ImportUsersWithOverwrite"); // GIVEN Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test005ImportUsersWithOverwrite"); - FileInputStream stream = new FileInputStream(IMPORT_USERS_OVERWRITE_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test005ImportUsersWithOverwrite"); + FileInputStream stream = new FileInputStream(getFile(IMPORT_USERS_OVERWRITE_FILE_NAME, false)); ImportOptionsType options = getDefaultImportOptions(); options.setOverwrite(true); dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, options, task, result); + modelService.importObjectsFromStream(stream, getLanguage(), options, task, result); // THEN result.computeStatus(); @@ -302,25 +316,25 @@ public void test005ImportUsersWithOverwrite() throws Exception { for (PrismObject user : users) { UserType userType = user.asObjectable(); - if (userType.getName().equals("jack")) { + if (userType.getName().toString().equals("jack")) { // OID and all the attributes should be the same assertEquals(USER_JACK_OID,userType.getOid()); PrismAsserts.assertEqualsPolyString("wrong givenName", "Jack", userType.getGivenName()); PrismAsserts.assertEqualsPolyString("wrong familyName", "Sparrow", userType.getFamilyName()); PrismAsserts.assertEqualsPolyString("wrong fullName", "Cpt. Jack Sparrow", userType.getFullName()); } - if (userType.getName().equals("will")) { + if (userType.getName().toString().equals("will")) { // OID should be the same, and there should be an employee type assertEquals(USER_WILL_OID,userType.getOid()); assertTrue("Wrong Will's employee type", userType.getEmployeeType().contains("legendary")); } - if (userType.getName().equals("guybrush")) { + if (userType.getName().toString().equals("guybrush")) { // OID may be different, there should be a locality attribute guybrushOid = userType.getOid(); assertNotNull(guybrushOid); PrismAsserts.assertEqualsPolyString("Guybrush is not in the Caribbean", "Deep in the Caribbean", userType.getLocality()); } - if (userType.getName().equals("ht")) { + if (userType.getName().toString().equals("ht")) { // Herman should be here now hermanOid = userType.getOid(); assertNotNull(hermanOid); @@ -344,8 +358,8 @@ public void test006ImportUsersWithOverwriteKeepOid() throws Exception { TestUtil.displayTestTile(this,"test006ImportUsersWithOverwriteKeepOid"); // GIVEN Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test005ImportUsersWithOverwrite"); - FileInputStream stream = new FileInputStream(IMPORT_USERS_OVERWRITE_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test005ImportUsersWithOverwrite"); + FileInputStream stream = new FileInputStream(getFile(IMPORT_USERS_OVERWRITE_FILE_NAME, false)); ImportOptionsType options = getDefaultImportOptions(); options.setOverwrite(true); options.setKeepOid(true); @@ -353,7 +367,7 @@ public void test006ImportUsersWithOverwriteKeepOid() throws Exception { dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, options, task, result); + modelService.importObjectsFromStream(stream, getLanguage(), options, task, result); // THEN result.computeStatus(); @@ -367,24 +381,24 @@ public void test006ImportUsersWithOverwriteKeepOid() throws Exception { for (PrismObject user : users) { UserType userType = user.asObjectable(); - if (userType.getName().equals("jack")) { + if (userType.getName().toString().equals("jack")) { // OID and all the attributes should be the same assertEquals(USER_JACK_OID,userType.getOid()); PrismAsserts.assertEqualsPolyString("wrong givenName", "Jack", userType.getGivenName()); PrismAsserts.assertEqualsPolyString("wrong familyName", "Sparrow", userType.getFamilyName()); PrismAsserts.assertEqualsPolyString("wrong fullName", "Cpt. Jack Sparrow", userType.getFullName()); } - if (userType.getName().equals("will")) { + if (userType.getName().toString().equals("will")) { // OID should be the same, and there should be an employee type assertEquals(USER_WILL_OID,userType.getOid()); assertTrue("Wrong Will's employee type", userType.getEmployeeType().contains("legendary")); } - if (userType.getName().equals("guybrush")) { + if (userType.getName().toString().equals("guybrush")) { // OID should be the same, there should be a locality attribute assertEquals("Guybrush's OID went leeway", guybrushOid, userType.getOid()); PrismAsserts.assertEqualsPolyString("Guybrush is not in the Caribbean", "Deep in the Caribbean", userType.getLocality()); } - if (userType.getName().equals("ht")) { + if (userType.getName().toString().equals("ht")) { // Herman should still be here assertEquals("Herman's OID went leeway", hermanOid, userType.getOid()); PrismAsserts.assertEqualsPolyString("Herman is confused", "Herman Toothrot", userType.getFullName()); @@ -405,9 +419,9 @@ public void test020ImportTask() throws Exception { final String TEST_NAME = "test020ImportTask"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(ImportTest.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(AbstractImportTest.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - FileInputStream stream = new FileInputStream(IMPORT_TASK_FILE); + FileInputStream stream = new FileInputStream(getFile(IMPORT_TASK_FILE_NAME, false)); // well, let's check whether task owner really exists PrismObject ownerPrism = repositoryService.getObject(UserType.class, TASK1_OWNER_OID, null, result); @@ -416,7 +430,7 @@ public void test020ImportTask() throws Exception { dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN result.computeStatus(); @@ -450,20 +464,20 @@ public void test030ImportResource() throws Exception { final String TEST_NAME = "test030ImportResource"; TestUtil.displayTestTile(this,TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(ImportTest.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(AbstractImportTest.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - FileInputStream stream = new FileInputStream(RESOURCE_DUMMY_FILE); + FileInputStream stream = new FileInputStream(getFile(RESOURCE_DUMMY_FILE_NAME, true)); IntegrationTestTools.assertNoRepoCache(); dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN result.computeStatus(); display("Result after import", result); - TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_FILE+" has failed (result)", result, 2); + TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_FILE_NAME+" has failed (result)", result, 2); IntegrationTestTools.assertNoRepoCache(); @@ -501,9 +515,9 @@ public void test031ReimportResource() throws Exception { final String TEST_NAME = "test031ReimportResource"; TestUtil.displayTestTile(this,TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(ImportTest.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(AbstractImportTest.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - FileInputStream stream = new FileInputStream(RESOURCE_DUMMY_CHANGED_FILE); + FileInputStream stream = new FileInputStream(getFile(RESOURCE_DUMMY_CHANGED_FILE_NAME, false)); ImportOptionsType options = getDefaultImportOptions(); options.setOverwrite(true); @@ -512,12 +526,12 @@ public void test031ReimportResource() throws Exception { dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, options, task, result); + modelService.importObjectsFromStream(stream, getLanguage(), options, task, result); // THEN result.computeStatus(); display("Result after import", result); - TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_CHANGED_FILE+" has failed (result)", result, 2); + TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_CHANGED_FILE_NAME+" has failed (result)", result, 2); IntegrationTestTools.assertNoRepoCache(); @@ -556,20 +570,20 @@ public void test032ImportResourceOidAndFilter() throws Exception { final String TEST_NAME = "test032ImportResourceOidAndFilter"; TestUtil.displayTestTile(this,TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(ImportTest.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(AbstractImportTest.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - FileInputStream stream = new FileInputStream(RESOURCE_DERBY_FILE); + FileInputStream stream = new FileInputStream(getFile(RESOURCE_DERBY_FILE_NAME, false)); IntegrationTestTools.assertNoRepoCache(); dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN result.computeStatus(); display("Result after import", result); - TestUtil.assertSuccess("Import of "+RESOURCE_DERBY_FILE+" has failed (result)", result, 2); + TestUtil.assertSuccess("Import of "+RESOURCE_DERBY_FILE_NAME+" has failed (result)", result, 2); IntegrationTestTools.assertNoRepoCache(); @@ -610,20 +624,20 @@ public void test033ImportResourceDummyRuntime() throws Exception { final String TEST_NAME = "test033ImportResourceDummyRuntime"; TestUtil.displayTestTile(this,TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(ImportTest.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(AbstractImportTest.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - FileInputStream stream = new FileInputStream(RESOURCE_DUMMY_RUNTIME_FILE); + FileInputStream stream = new FileInputStream(getFile(RESOURCE_DUMMY_RUNTIME_FILE_NAME, false)); IntegrationTestTools.assertNoRepoCache(); dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); // THEN result.computeStatus(); display("Result after import", result); - TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_RUNTIME_FILE+" has failed (result)", result, 2); + TestUtil.assertSuccess("Import of "+RESOURCE_DUMMY_RUNTIME_FILE_NAME+" has failed (result)", result, 2); IntegrationTestTools.assertNoRepoCache(); @@ -653,8 +667,8 @@ public void test040ImportUserHermanNoEncryption() throws Exception { InternalsConfig.readEncryptionChecks = false; Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "." + TEST_NAME); - FileInputStream stream = new FileInputStream(USER_HERMAN_FILE); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "." + TEST_NAME); + FileInputStream stream = new FileInputStream(getFile(USER_HERMAN_FILE_NAME, true)); ImportOptionsType importOptions = getDefaultImportOptions(); importOptions.setEncryptProtectedValues(false); @@ -662,7 +676,7 @@ public void test040ImportUserHermanNoEncryption() throws Exception { dummyAuditService.clear(); // WHEN - modelService.importObjectsFromStream(stream, importOptions, task, result); + modelService.importObjectsFromStream(stream, getLanguage(), importOptions, task, result); // THEN result.computeStatus(); @@ -690,7 +704,73 @@ public void test040ImportUserHermanNoEncryption() throws Exception { dummyAuditService.assertHasDelta(ChangeType.ADD, UserType.class); dummyAuditService.assertExecutionSuccess(); } - + + @Test + public void test100GoodRefImport() throws Exception { + final String TEST_NAME = "test100GoodRefImport"; + TestUtil.displayTestTile(this,TEST_NAME); + // GIVEN + Task task = taskManager.createTaskInstance(); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "." +TEST_NAME); + FileInputStream stream = new FileInputStream(getFile(IMPORT_REF_FILE_NAME, false)); + + // WHEN + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); + + // THEN + result.computeStatus("Failed import."); + display("Result after good import", result); + TestUtil.assertSuccessOrWarning("Import has failed (result)", result, 2); + + // EqualsFilter equal = EqualsFilter.createEqual(UserType.F_NAME, UserType.class, PrismTestUtil.getPrismContext(), null, "jack"); + // ObjectQuery query = ObjectQuery.createObjectQuery(equal); + ObjectQuery query = ObjectQueryUtil.createNameQuery("jack", PrismTestUtil.getPrismContext()); + + List> users = repositoryService.searchObjects(UserType.class, query, null, result); + + assertNotNull(users); + assertEquals("Search returned unexpected results", 1, users.size()); + UserType jack = users.get(0).asObjectable(); + assertNotNull(jack); + PrismAsserts.assertEqualsPolyString("wrong givenName", "Jack", jack.getGivenName()); + PrismAsserts.assertEqualsPolyString("wrong familyName", "Sparrow", jack.getFamilyName()); + PrismAsserts.assertEqualsPolyString("wrong fullName", "Cpt. Jack Sparrow", jack.getFullName()); + + } + + @Test + public void test200BadImport() throws FileNotFoundException, SchemaException, ObjectNotFoundException { + TestUtil.displayTestTile(this,"test200BadImport"); + // GIVEN + Task task = taskManager.createTaskInstance(); + OperationResult result = new OperationResult(AbstractImportTest.class.getName() + "test001GoodImport"); + FileInputStream stream = new FileInputStream(getFile(BAD_IMPORT_FILE_NAME, false)); + + repositoryService.deleteObject(UserType.class, USER_JACK_OID, result); + + // WHEN + modelService.importObjectsFromStream(stream, getLanguage(), getDefaultImportOptions(), task, result); + + // THEN + result.computeStatus("Failed import."); + display("Result after bad import", result); + + // Jack is OK in the import file, he should be imported + try { + UserType jack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result).asObjectable(); + AssertJUnit.assertNotNull("Jack is null", jack); + } catch (ObjectNotFoundException e) { + AssertJUnit.fail("Jack was not imported"); + } + + List> users = repositoryService.searchObjects(UserType.class, null, null, result); + + AssertJUnit.assertNotNull(users); + AssertJUnit.assertEquals("Search returned unexpected results: "+users, 7, users.size()); + + } + + private void assertDummyResource(PrismObject resource, boolean fromRepo) { PrismContainer configurationPropertiesContainer = assertResource(resource, "Dummy Resource", RESOURCE_DUMMY_NAMESPACE, dummyConnector.getOid(), fromRepo); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/BadImportTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/BadImportTest.java deleted file mode 100644 index 6818b2ddd96..00000000000 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/BadImportTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010-2015 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.model.intest.importer; - -import static com.evolveum.midpoint.schema.util.MiscSchemaUtil.getDefaultImportOptions; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.List; - -import com.evolveum.midpoint.model.intest.AbstractConfiguredModelIntegrationTest; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; - -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; -import org.testng.annotations.AfterClass; -import org.testng.annotations.Test; - -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.util.TestUtil; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; - -/** - * Test import with wrong data. Check if the import produces usable error messages. - * - * @author Radovan Semancik - * - */ -@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) -@DirtiesContext(classMode=ClassMode.AFTER_CLASS) -public class BadImportTest extends AbstractConfiguredModelIntegrationTest { - - private static final Trace LOGGER = TraceManager.getTrace(BadImportTest.class); - private static final File BAD_IMPORT_FILE_NAME = new File("src/test/resources/importer/import-bad.xml"); - private static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; - - @AfterClass - @Override - protected void springTestContextAfterTestClass() throws Exception { - long time = System.currentTimeMillis(); - LOGGER.info("###>>> springTestContextAfterTestClass start"); - super.springTestContextAfterTestClass(); - - AbstractConfiguredModelIntegrationTest.nullAllFields(this, getClass()); - - LOGGER.info("###>>> springTestContextAfterTestClass end ({}ms)", new Object[]{(System.currentTimeMillis() - time)}); - } - - /** - * Test integrity of the test setup. - * - */ - @Test - public void test000Integrity() { - TestUtil.displayTestTile(this,"test000Integrity"); - AssertJUnit.assertNotNull(modelService); - AssertJUnit.assertNotNull(repositoryService); - - } - - @Test - public void test001BadImport() throws FileNotFoundException, SchemaException { - TestUtil.displayTestTile(this,"test001BadImport"); - // GIVEN - Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportTest.class.getName() + "test001GoodImport"); - FileInputStream stream = new FileInputStream(BAD_IMPORT_FILE_NAME); - - // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); - - // THEN - result.computeStatus("Failed import."); - display("Result after bad import", result); - - // Jack is OK in the import file, he should be imported - try { - UserType jack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result).asObjectable(); - AssertJUnit.assertNotNull("Jack is null", jack); - } catch (ObjectNotFoundException e) { - AssertJUnit.fail("Jack was not imported"); - } - - List> users = repositoryService.searchObjects(UserType.class, null, null, result); - - AssertJUnit.assertNotNull(users); - AssertJUnit.assertEquals("Search retuned unexpected results: "+users, 3, users.size()); - - } - -} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportRefTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportRefTest.java deleted file mode 100644 index d18491ae855..00000000000 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/ImportRefTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2010-2015 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.model.intest.importer; - -import com.evolveum.midpoint.model.intest.AbstractConfiguredModelIntegrationTest; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.util.PrismAsserts; -import com.evolveum.midpoint.prism.util.PrismTestUtil; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ObjectQueryUtil; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.util.TestUtil; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; - -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.ContextConfiguration; -import org.testng.annotations.AfterClass; -import org.testng.annotations.Test; - -import java.io.File; -import java.io.FileInputStream; -import java.util.List; - -import static com.evolveum.midpoint.schema.util.MiscSchemaUtil.getDefaultImportOptions; -import static com.evolveum.midpoint.test.IntegrationTestTools.*; -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertNotNull; - -/** - * @author Radovan Semancik - * - */ -@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) -@DirtiesContext(classMode=ClassMode.AFTER_CLASS) -public class ImportRefTest extends AbstractConfiguredModelIntegrationTest { - - private static final Trace LOGGER = TraceManager.getTrace(ImportRefTest.class); - private static final File IMPORT_FILE_NAME = new File("src/test/resources/importer/import-ref.xml"); - - @AfterClass - @Override - protected void springTestContextAfterTestClass() throws Exception { - long time = System.currentTimeMillis(); - LOGGER.info("###>>> springTestContextAfterTestClass start"); - super.springTestContextAfterTestClass(); - - AbstractConfiguredModelIntegrationTest.nullAllFields(this, getClass()); - - LOGGER.info("###>>> springTestContextAfterTestClass end ({}ms)", new Object[]{(System.currentTimeMillis() - time)}); - } - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - } - - /** - * Test integrity of the test setup. - * - */ - @Test - public void test000Integrity() { - TestUtil.displayTestTile(this,"test000Integrity"); - assertNotNull(modelService); - assertNotNull(repositoryService); - - } - - @Test - public void test010GoodRefImport() throws Exception { - final String TEST_NAME = "test010GoodRefImport"; - TestUtil.displayTestTile(this,TEST_NAME); - // GIVEN - Task task = taskManager.createTaskInstance(); - OperationResult result = new OperationResult(ImportRefTest.class.getName() + "." +TEST_NAME); - FileInputStream stream = new FileInputStream(IMPORT_FILE_NAME); - - // WHEN - modelService.importObjectsFromStream(stream, getDefaultImportOptions(), task, result); - - // THEN - result.computeStatus("Failed import."); - display("Result after good import", result); - TestUtil.assertSuccessOrWarning("Import has failed (result)", result, 2); - -// EqualsFilter equal = EqualsFilter.createEqual(UserType.F_NAME, UserType.class, PrismTestUtil.getPrismContext(), null, "jack"); -// ObjectQuery query = ObjectQuery.createObjectQuery(equal); - ObjectQuery query = ObjectQueryUtil.createNameQuery("jack", PrismTestUtil.getPrismContext()); - - List> users = repositoryService.searchObjects(UserType.class, query, null, result); - - assertNotNull(users); - assertEquals("Search retuned unexpected results", 1, users.size()); - UserType jack = users.get(0).asObjectable(); - assertNotNull(jack); - PrismAsserts.assertEqualsPolyString("wrong givenName", "Jack", jack.getGivenName()); - PrismAsserts.assertEqualsPolyString("wrong familyName", "Sparrow", jack.getFamilyName()); - PrismAsserts.assertEqualsPolyString("wrong fullName", "Cpt. Jack Sparrow", jack.getFullName()); - - } - -} diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/VariousValues.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/JsonImportTest.java similarity index 50% rename from infra/schema/src/main/java/com/evolveum/midpoint/schema/result/VariousValues.java rename to model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/JsonImportTest.java index 98002681148..92399e2b097 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/VariousValues.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/JsonImportTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,24 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.schema.result; -import java.io.Serializable; +package com.evolveum.midpoint.model.intest.importer; + +import com.evolveum.midpoint.prism.PrismContext; /** - * A class that marks presence of various values in a specific OperationResult map. E.g. if an instance of this class is present - * as a "foo" parameter in OperationResult parameter map then such parameter contains many different values. - * - * It only makes sense for OperationResult entries that are summarized (has count > 1) - * - * @author Radovan Semancik - * + * @author mederly */ -public class VariousValues implements Serializable { +public class JsonImportTest extends AbstractImportTest { @Override - public String toString() { - return "[various values]"; + String getSuffix() { + return "json"; } + @Override + String getLanguage() { + return PrismContext.LANG_JSON; + } } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/XmlImportTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/XmlImportTest.java new file mode 100644 index 00000000000..39623a7e293 --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/XmlImportTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.intest.importer; + +import com.evolveum.midpoint.prism.PrismContext; + +/** + * @author mederly + */ +public class XmlImportTest extends AbstractImportTest { + + @Override + String getSuffix() { + return "xml"; + } + + @Override + String getLanguage() { + return PrismContext.LANG_XML; + } +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/YamlImportTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/YamlImportTest.java new file mode 100644 index 00000000000..4dc45ddb21b --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/importer/YamlImportTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.intest.importer; + +import com.evolveum.midpoint.prism.PrismContext; + +/** + * @author mederly + */ +public class YamlImportTest extends AbstractImportTest { + + @Override + String getSuffix() { + return "yaml"; + } + + @Override + String getLanguage() { + return PrismContext.LANG_YAML; + } +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java index 9628c7b94f1..8668ff7d451 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java @@ -86,6 +86,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.CapabilitiesType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CapabilityCollectionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; @@ -2626,18 +2627,13 @@ public void test526UnassignWillBothRoles() throws Exception { OperationResult result = task.getResult(); PrismObject userBefore = getUser(userWillOid); - - Collection> modifications = new ArrayList<>(); - modifications.add((createAssignmentModification(userBefore.asObjectable().getAssignment().get(0).getId(), false))); - modifications.add((createAssignmentModification(userBefore.asObjectable().getAssignment().get(1).getId(), false))); - ObjectDelta focusDelta = ObjectDelta.createModifyDelta(userWillOid, modifications, UserType.class, prismContext); - + accountWillSecondReqestTimestampStart = clock.currentTimeXMLGregorianCalendar(); // WHEN displayWhen(TEST_NAME); - modelService.executeChanges(MiscSchemaUtil.createCollection(focusDelta), null, task, result); + unassignAll(userBefore, task, result); // THEN displayThen(TEST_NAME); @@ -2655,7 +2651,7 @@ public void test526UnassignWillBothRoles() throws Exception { assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN); } - + protected void assertTest526Deltas(PrismObject shadowRepo, OperationResult result) { assertPendingOperationDeltas(shadowRepo, 3); @@ -2773,7 +2769,7 @@ public void test800ImportShadowRefreshTask() throws Exception { // WHEN displayWhen(TEST_NAME); - addObject(TASK_SHADOW_REFRESH_FILE); + addTask(TASK_SHADOW_REFRESH_FILE); // THEN displayThen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/orgstruct/TestOrgStruct.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/orgstruct/TestOrgStruct.java index 6a5f173c24f..26d499aa5df 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/orgstruct/TestOrgStruct.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/orgstruct/TestOrgStruct.java @@ -291,7 +291,7 @@ public void test208JackUnassignAll() throws Exception { // WHEN displayWhen(TEST_NAME); - unassignAll(USER_JACK_OID, task, result); + unassignAllReplace(USER_JACK_OID, task, result); // THEN displayThen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/AbstractRbacTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/AbstractRbacTest.java new file mode 100644 index 00000000000..f57c7714dda --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/AbstractRbacTest.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.intest.rbac; + +import static com.evolveum.midpoint.test.IntegrationTestTools.display; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.notifications.api.transports.Message; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +import com.evolveum.icf.dummy.resource.DummyAccount; +import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.model.api.context.EvaluatedAssignment; +import com.evolveum.midpoint.model.api.context.EvaluatedAssignmentTarget; +import com.evolveum.midpoint.model.api.context.ModelContext; +import com.evolveum.midpoint.model.intest.AbstractInitializedModelIntegrationTest; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.delta.DeltaSetTriple; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.NameItemPathSegment; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.schema.PrismSchema; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.exception.PolicyViolationException; +import com.evolveum.prism.xml.ns._public.types_3.EvaluationTimeType; + +/** + * @author semancik + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public abstract class AbstractRbacTest extends AbstractInitializedModelIntegrationTest { + + protected static final File TEST_DIR = new File("src/test/resources", "rbac"); + + protected static final File ROLE_ADRIATIC_PIRATE_FILE = new File(TEST_DIR, "role-adriatic-pirate.xml"); + protected static final String ROLE_ADRIATIC_PIRATE_OID = "12345678-d34d-b33f-f00d-5555555566aa"; + + protected static final File ROLE_BLACK_SEA_PIRATE_FILE = new File(TEST_DIR, "role-black-sea-pirate.xml"); + protected static final String ROLE_BLACK_SEA_PIRATE_OID = "12345678-d34d-b33f-f00d-5555555566bb"; + + protected static final File ROLE_INDIAN_OCEAN_PIRATE_FILE = new File(TEST_DIR, "role-indian-ocean-pirate.xml"); + protected static final String ROLE_INDIAN_OCEAN_PIRATE_OID = "12345678-d34d-b33f-f00d-555555556610"; + + protected static final File ROLE_HONORABILITY_FILE = new File(TEST_DIR, "role-honorability.xml"); + protected static final String ROLE_HONORABILITY_OID = "12345678-d34d-b33f-f00d-555555557701"; + + protected static final File ROLE_CLERIC_FILE = new File(TEST_DIR, "role-cleric.xml"); + protected static final String ROLE_CLERIC_OID = "12345678-d34d-b33f-f00d-555555557702"; + + protected static final File ROLE_WANNABE_FILE = new File(TEST_DIR, "role-wannabe.xml"); + protected static final String ROLE_WANNABE_OID = "12345678-d34d-b33f-f00d-555555557703"; + + protected static final File ROLE_HONORABLE_WANNABE_FILE = new File(TEST_DIR, "role-honorable-wannabe.xml"); + protected static final String ROLE_HONORABLE_WANNABE_OID = "12345678-d34d-b33f-f00d-555555557704"; + + protected static final File ROLE_GOVERNOR_FILE = new File(TEST_DIR, "role-governor.xml"); + protected static final String ROLE_GOVERNOR_OID = "12345678-d34d-b33f-f00d-555555557705"; + + protected static final File ROLE_CANNIBAL_FILE = new File(TEST_DIR, "role-cannibal.xml"); + protected static final String ROLE_CANNIBAL_OID = "12345678-d34d-b33f-f00d-555555557706"; + + protected static final File ROLE_PROJECT_OMNINAMAGER_FILE = new File(TEST_DIR, "role-project-omnimanager.xml"); + protected static final String ROLE_PROJECT_OMNINAMAGER_OID = "f23ab26c-69df-11e6-8330-979c643ea51c"; + + protected static final File ROLE_WEAK_GOSSIPER_FILE = new File(TEST_DIR, "role-weak-gossiper.xml"); + protected static final String ROLE_WEAK_GOSSIPER_OID = "e8fb2226-7f48-11e6-8cf1-630ce5c3f80b"; + + protected static final File ROLE_WEAK_SINGER_FILE = new File(TEST_DIR, "role-weak-singer.xml"); + protected static final String ROLE_WEAK_SINGER_OID = "caa7daf2-dd68-11e6-a780-ef610c7c3a06"; + protected static final String ROLE_WEAK_SINGER_TITLE = "Singer"; + + protected static final File ROLE_IMMUTABLE_FILE = new File(TEST_DIR, "role-immutable.xml"); + protected static final String ROLE_IMMUTABLE_OID = "e53baf94-aa99-11e6-962a-5362ec2dd7df"; + protected static final String ROLE_IMMUTABLE_DESCRIPTION = "Role that cannot be modified because there is a modification rule with enforcement action."; + + protected static final File ROLE_IMMUTABLE_GLOBAL_FILE = new File(TEST_DIR, "role-immutable-global.xml"); + protected static final String ROLE_IMMUTABLE_GLOBAL_OID = "e7ba8884-b2f6-11e6-a0b9-d3540dd687d6"; + protected static final String ROLE_IMMUTABLE_GLOBAL_DESCRIPTION = "Thou shalt not modify this role!"; + protected static final String ROLE_IMMUTABLE_GLOBAL_IDENTIFIER = "GIG001"; + + protected static final File ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_FILE = new File(TEST_DIR, "role-immutable-description-global.xml"); + protected static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_OID = "b7ea1c0c-31d6-445e-8949-9f8f4a665b3b"; + protected static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_DESCRIPTION = "Thou shalt not modify description of this role!"; + protected static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_IDENTIFIER = "GIG001D"; + + protected static final File ROLE_NON_ASSIGNABLE_FILE = new File(TEST_DIR, "role-non-assignable.xml"); + protected static final String ROLE_NON_ASSIGNABLE_OID = "db67d2f0-abd8-11e6-9c30-b35abe3e4e3a"; + + protected static final File ROLE_SCREAMING_FILE = new File(TEST_DIR, "role-screaming.xml"); + protected static final String ROLE_SCREAMING_OID = "024e204d-ce40-4fe9-ae5a-0da3cbce989a"; + + protected static final File ROLE_NON_CREATEABLE_FILE = new File(TEST_DIR, "role-non-createable.xml"); + protected static final String ROLE_NON_CREATEABLE_OID = "c45a25ce-b2e8-11e6-923e-938d2c54d334"; + + protected static final File ROLE_IMMUTABLE_ASSIGN_FILE = new File(TEST_DIR, "role-immutable-assign.xml"); + protected static final String ROLE_IMMUTABLE_ASSIGN_OID = "a6b10a7c-b57e-11e6-bcb3-1ba47cb07e2e"; + + protected static final File ROLE_META_UNTOUCHABLE_FILE = new File(TEST_DIR, "role-meta-untouchable.xml"); + protected static final String ROLE_META_UNTOUCHABLE_OID = "a80c9572-b57d-11e6-80a9-6fdae1dc39bc"; + + protected static final File ROLE_META_FOOL_FILE = new File(TEST_DIR, "role-meta-fool.xml"); + protected static final String ROLE_META_FOOL_OID = "2edc5fe4-af3c-11e6-a81e-eb332578ec4f"; + + protected static final File ROLE_BLOODY_FOOL_FILE = new File(TEST_DIR, "role-bloody-fool.xml"); + protected static final String ROLE_BLOODY_FOOL_OID = "0a0ac150-af3d-11e6-9901-67fbcbd5bb25"; + + protected static final File ROLE_TREASURE_GOLD_FILE = new File(TEST_DIR, "role-treasure-gold.xml"); + protected static final String ROLE_TREASURE_GOLD_OID = "00a1db70-5817-11e7-93eb-9305bec579fe"; + + protected static final File ROLE_TREASURE_SILVER_FILE = new File(TEST_DIR, "role-treasure-silver.xml"); + protected static final String ROLE_TREASURE_SILVER_OID = "4e237ee4-5817-11e7-8345-8731a29a1fcb"; + + protected static final File ROLE_TREASURE_BRONZE_FILE = new File(TEST_DIR, "role-treasure-bronze.xml"); + protected static final String ROLE_TREASURE_BRONZE_OID = "60f9352c-5817-11e7-bc1e-f7e208714c43"; + + protected static final File ROLE_ALL_TREASURE_FILE = new File(TEST_DIR, "role-all-treasure.xml"); + protected static final String ROLE_ALL_TREASURE_OID = "7fda5d86-5817-11e7-ac85-3b1cba81d3ef"; + + protected static final File ROLE_LOOT_DIAMONDS_FILE = new File(TEST_DIR, "role-loot-diamonds.xml"); + protected static final String ROLE_LOOT_DIAMONDS_OID = "974d7156-581c-11e7-916d-03ed3d47d102"; + + protected static final File ROLE_ALL_LOOT_FILE = new File(TEST_DIR, "role-all-loot.xml"); + protected static final String ROLE_ALL_LOOT_OID = "aaede614-581c-11e7-91bf-db837eb406b7"; + + protected static final File ROLE_ALL_YOU_CAN_GET_FILE = new File(TEST_DIR, "role-all-you-can-get.xml"); + protected static final String ROLE_ALL_YOU_CAN_GET_OID = "4671874e-5822-11e7-a571-8b43dc7d2876"; + + protected static final File ORG_PROJECT_RECLAIM_BLACK_PEARL_FILE = new File(TEST_DIR, "org-project-reclaim-black-pearl.xml"); + protected static final String ORG_PROJECT_RECLAIM_BLACK_PEARL_OID = "00000000-8888-6666-0000-200000005000"; + + protected static final String USER_LEMONHEAD_NAME = "lemonhead"; + protected static final String USER_LEMONHEAD_FULLNAME = "Cannibal Lemonhead"; + + protected static final String USER_SHARPTOOTH_NAME = "sharptooth"; + protected static final String USER_SHARPTOOTH_FULLNAME = "Cannibal Sharptooth"; + + protected static final String USER_REDSKULL_NAME = "redskull"; + protected static final String USER_REDSKULL_FULLNAME = "Cannibal Redskull"; + + protected static final String USER_BIGNOSE_NAME = "bignose"; + protected static final String USER_BIGNOSE_FULLNAME = "Bignose the Noncannibal"; + + protected static final String GROUP_FOOLS_NAME = "fools"; + protected static final String GROUP_SIMPLETONS_NAME = "simpletons"; + + /** + * Undefined relation. It is not standard relation not a relation that is in any way configured. + */ + protected static final QName RELATION_COMPLICATED_QNAME = new QName("http://exmple.com/relation", "complicated"); + + protected File getRoleGovernorFile() { + return ROLE_GOVERNOR_FILE; + } + + protected File getRoleCannibalFile() { + return ROLE_CANNIBAL_FILE; + } + + @Override + public void initSystem(Task initTask, OperationResult initResult) + throws Exception { + super.initSystem(initTask, initResult); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + repoAddObjectFromFile(ROLE_ADRIATIC_PIRATE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_BLACK_SEA_PIRATE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_INDIAN_OCEAN_PIRATE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_HONORABILITY_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_CLERIC_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_WANNABE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_HONORABLE_WANNABE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(getRoleGovernorFile(), RoleType.class, initResult); + repoAddObjectFromFile(getRoleCannibalFile(), RoleType.class, initResult); + repoAddObjectFromFile(ROLE_PROJECT_OMNINAMAGER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_WEAK_GOSSIPER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_WEAK_SINGER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_IMMUTABLE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_NON_ASSIGNABLE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_SCREAMING_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_META_UNTOUCHABLE_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_META_FOOL_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_BLOODY_FOOL_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_TREASURE_SILVER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_TREASURE_BRONZE_FILE, RoleType.class, initResult); + // ROLE_TREASURE_GOLD is NOT loaded by purpose. It will come in later. + repoAddObjectFromFile(ROLE_LOOT_DIAMONDS_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_ALL_LOOT_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_ALL_YOU_CAN_GET_FILE, RoleType.class, initResult); + + repoAddObjectFromFile(USER_RAPP_FILE, initResult); + + dummyResourceCtl.addGroup(GROUP_FOOLS_NAME); + dummyResourceCtl.addGroup(GROUP_SIMPLETONS_NAME); + + } + +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java new file mode 100644 index 00000000000..0ce5482e656 --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java @@ -0,0 +1,1428 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.intest.rbac; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.internals.InternalsConfig; +import com.evolveum.midpoint.schema.internals.TestingPaths; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +/** + * @author semancik + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestAssignmentValidity extends AbstractRbacTest { + + private XMLGregorianCalendar jackPirateValidTo; + + @Override + public void initSystem(Task initTask, OperationResult initResult) + throws Exception { + super.initSystem(initTask, initResult); +// InternalsConfig.setTestingPaths(TestingPaths.REVERSED); + } + + /** + * MID-4110 + */ + @Test + public void test100JackAssignRolePirateValidTo() throws Exception { + final String TEST_NAME = "test100JackAssignRolePirateValidTo"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, activationType, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.ENABLED); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test102Forward15min() throws Exception { + final String TEST_NAME = "test102Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test104JackAssignRolePirateAgain() throws Exception { + final String TEST_NAME = "test104JackAssignRolePirateAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * Unassign valid assignment. Only invalid assignment remains. + * MID-4110 + */ + @Test + public void test106JackUnassignRolePirateValid() throws Exception { + final String TEST_NAME = "test106JackUnassignRolePirateValid"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + unassignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * MID-4110 + */ + @Test + public void test109JackUnassignAll() throws Exception { + unassignAll("test109JackUnassignAll"); + } + + /** + * Raw modification of assignment. The assignment is not effective immediately, + * as this is raw operation. So, nothing much happens. Yet. + * MID-4110 + */ + @Test + public void test110JackAssignRolePirateValidToRaw() throws Exception { + final String TEST_NAME = "test110JackAssignRolePirateValidToRaw"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + ModelExecuteOptions options = ModelExecuteOptions.createRaw(); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_PIRATE_OID, RoleType.COMPLEX_TYPE, null, + task, null, activationType, true, options, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, null); + assertRoleMembershipRef(userAfter); + assertDelegatedRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * MID-4110, MID-4114 + */ + @Test + public void test111RecomputeJack() throws Exception { + final String TEST_NAME = "test111RecomputeJack"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.ENABLED); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test112Forward15min() throws Exception { + final String TEST_NAME = "test102Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test114JackAssignRolePirateAgain() throws Exception { + final String TEST_NAME = "test114JackAssignRolePirateAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test119JackUnassignAll() throws Exception { + unassignAll("test119JackUnassignAll"); + } + + /** + * Sailor is an idempotent(conservative) role. + * MID-4110 + */ + @Test + public void test120JackAssignRoleSailorValidTo() throws Exception { + final String TEST_NAME = "test120JackAssignRoleSailorValidTo"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, activationType, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.ENABLED); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test122Forward15min() throws Exception { + final String TEST_NAME = "test122Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test124JackAssignRoleSailorAgain() throws Exception { + final String TEST_NAME = "test124JackAssignRoleSailorAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test129JackUnassignAll() throws Exception { + unassignAll("test129JackUnassignAll"); + } + + /** + * Raw modification of assignment. The assignment is not effective immediately, + * as this is raw operation. So, nothing much happens. Yet. + * MID-4110 + */ + @Test + public void test130JackAssignRoleSailorValidToRaw() throws Exception { + final String TEST_NAME = "test130JackAssignRoleSailorValidToRaw"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + ModelExecuteOptions options = ModelExecuteOptions.createRaw(); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, + task, null, activationType, true, options, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, null); + assertRoleMembershipRef(userAfter); + assertDelegatedRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * MID-4110, MID-4114 + */ + @Test + public void test131RecomputeJack() throws Exception { + final String TEST_NAME = "test131RecomputeJack"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.ENABLED); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test132Forward15min() throws Exception { + final String TEST_NAME = "test132Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test134JackAssignRoleSailorAgain() throws Exception { + final String TEST_NAME = "test134JackAssignRoleSailorAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test139JackUnassignAll() throws Exception { + unassignAll("test139JackUnassignAll"); + } + + /** + * This time do not recompute. Just set everything up, let the assignment expire + * and assign the role again. + * MID-4110 + */ + @Test + public void test140JackAssignRoleSailorValidToRaw() throws Exception { + final String TEST_NAME = "test140JackAssignRoleSailorValidToRaw"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + ModelExecuteOptions options = ModelExecuteOptions.createRaw(); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, + task, null, activationType, true, options, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, null); + assertRoleMembershipRef(userAfter); + assertDelegatedRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * Assignment expires. BUt do NOT recompute. + * MID-4110 + */ + @Test + public void test142Forward15min() throws Exception { + final String TEST_NAME = "test142Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + + // WHEN + displayWhen(TEST_NAME); + clockForward("PT15M"); + // do NOT recompute + + // THEN + displayThen(TEST_NAME); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, null); // Not recomputed + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test144JackAssignRoleSailorAgain() throws Exception { + final String TEST_NAME = "test144JackAssignRoleSailorAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertModifyMetadata(userAfter, startTs, endTs); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test149JackUnassignAll() throws Exception { + unassignAll("test149JackUnassignAll"); + } + + /** + * MID-4110 + */ + @Test + public void test150JackAssignRolePirate() throws Exception { + final String TEST_NAME = "test150JackAssignRolePirate"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 1); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * Sailor is an idempotent(conservative) role. + * MID-4110 + */ + @Test + public void test151JackAssignRoleSailorValidTo() throws Exception { + final String TEST_NAME = "test151JackAssignRoleSailorValidTo"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, activationType, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 2); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSailorAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test153Forward15min() throws Exception { + final String TEST_NAME = "test153Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 2); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + + assertJackDummyPirateAccount(); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test154JackAssignRoleSailorAgain() throws Exception { + final String TEST_NAME = "test154JackAssignRoleSailorAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 3); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test159JackUnassignAll() throws Exception { + unassignAll("test159JackUnassignAll"); + } + + /** + * MID-4110 + */ + @Test + public void test160JackAssignRolePirate() throws Exception { + final String TEST_NAME = "test160JackAssignRolePirate"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 1); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test161JackAssignRoleSailorValidToRaw() throws Exception { + final String TEST_NAME = "test161JackAssignRoleSailorValidToRaw"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + ModelExecuteOptions options = ModelExecuteOptions.createRaw(); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, + task, null, activationType, true, options, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 2); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, null); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); // SAILOR is not here, we are raw + assertDelegatedRef(userAfter); + + + assertJackDummyPirateAccount(); + } + + /** + * Recompute should fix it all. + * MID-4110 + */ + @Test + public void test162RecomputeJack() throws Exception { + final String TEST_NAME = "test162RecomputeJack"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + // WHEN + displayWhen(TEST_NAME); + reconcileUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 2); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSailorAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test163Forward15min() throws Exception { + final String TEST_NAME = "test163Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 2); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + + assertJackDummyPirateAccount(); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test164JackAssignRoleSailorAgain() throws Exception { + final String TEST_NAME = "test164JackAssignRoleSailorAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 3); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test169JackUnassignAll() throws Exception { + unassignAll("test169JackUnassignAll"); + } + + /** + * MID-4110 + */ + @Test + public void test170JackAssignRolePirate() throws Exception { + final String TEST_NAME = "test170JackAssignRolePirate"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 1); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test171JackAssignRoleWeakSingerValidTo() throws Exception { + final String TEST_NAME = "test171JackAssignRoleWeakSingerValidTo"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_WEAK_SINGER_OID, activationType, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + + assertAssignments(userAfter, 2); + AssignmentType assignmentSingerTypeAfter = assertAssignedRole(userAfter, ROLE_WEAK_SINGER_OID); + assertEffectiveActivation(assignmentSingerTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_WEAK_SINGER_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSingerAccount(); + } + + /** + * Assignment expires. + * MID-4110, MID-4114 + */ + @Test + public void test173Forward15min() throws Exception { + final String TEST_NAME = "test173Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 2); + AssignmentType assignmentPirateTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID); + assertEffectiveActivation(assignmentPirateTypeAfter, ActivationStatusType.ENABLED); + AssignmentType assignmentSailorTypeAfter = assertAssignedRole(userAfter, ROLE_WEAK_SINGER_OID); + assertEffectiveActivation(assignmentSailorTypeAfter, ActivationStatusType.DISABLED); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); + + // Dummy attribute "title" is tolerant, so the singer value remains + assertJackDummyPirateSingerAccount(); + } + + /** + * New assignment. No time validity. + * MID-4110 + */ + @Test + public void test174JackAssignRoleSingerAgain() throws Exception { + final String TEST_NAME = "test174JackAssignRoleSingerAgain"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_WEAK_SINGER_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 3); + assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID, ROLE_WEAK_SINGER_OID); + assertDelegatedRef(userAfter); + + assertJackDummyPirateSingerAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test179JackUnassignAll() throws Exception { + unassignAll("test179JackUnassignAll"); + } + + /** + * This time do both assigns as raw. And do NOT recompute until everything is set up. + * MID-4110 + */ + @Test + public void test180JackAssignRoleSailorValidToRaw() throws Exception { + final String TEST_NAME = "test180JackAssignRoleSailorValidToRaw"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + ActivationType activationType = new ActivationType(); + jackPirateValidTo = getTimestamp("PT10M"); + activationType.setValidTo(jackPirateValidTo); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, + task, null, activationType, true, ModelExecuteOptions.createRaw(), result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 1); + AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID); + assertEffectiveActivation(assignmentTypeAfter, null); + assertRoleMembershipRef(userAfter); + assertDelegatedRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * MID-4110 + */ + @Test + public void test182Forward15minAndAssignRaw() throws Exception { + final String TEST_NAME = "test142Forward15min"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + clockForward("PT15M"); + + // WHEN + displayWhen(TEST_NAME); + modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, + task, null, null, true, ModelExecuteOptions.createRaw(), result); + + // THEN + displayThen(TEST_NAME); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + /** + * MID-4110, MID-4114 + */ + @Test + public void test184RecomputeJack() throws Exception { + final String TEST_NAME = "test184RecomputeJack"; + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 2); + assertRoleMembershipRef(userAfter, ROLE_STRONG_SAILOR_OID); + assertDelegatedRef(userAfter); + + assertJackDummySailorAccount(); + } + + /** + * MID-4110 + */ + @Test + public void test189JackUnassignAll() throws Exception { + unassignAll("test189JackUnassignAll"); + } + + + private void assertJackDummyPirateAccount() throws Exception { + assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, USER_JACK_LOCALITY); + // Outbound mapping for weapon is weak, therefore the mapping in role should override it + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, ROLE_PIRATE_WEAPON); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, + "Jack Sparrow is the best pirate Caribbean has ever seen"); + } + + private void assertJackDummySailorAccount() throws Exception { + assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME, RESOURCE_DUMMY_DRINK, ROLE_SAILOR_DRINK); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, USER_JACK_LOCALITY); + } + + private void assertJackDummyPirateSailorAccount() throws Exception { + assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME, RESOURCE_DUMMY_DRINK, ROLE_SAILOR_DRINK); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, USER_JACK_LOCALITY); + // Outbound mapping for weapon is weak, therefore the mapping in role should override it + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, ROLE_PIRATE_WEAPON); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, + "Jack Sparrow is the best pirate Caribbean has ever seen"); + } + + private void assertJackDummyPirateSingerAccount() throws Exception { + assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_PIRATE_TITLE, ROLE_WEAK_SINGER_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME, RESOURCE_DUMMY_DRINK); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, USER_JACK_LOCALITY); + // Outbound mapping for weapon is weak, therefore the mapping in role should override it + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, ROLE_PIRATE_WEAPON); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, + "Jack Sparrow is the best pirate Caribbean has ever seen"); + } + + private void unassignAll(final String TEST_NAME) throws Exception { + displayTestTile(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = getUser(USER_JACK_OID); + display("User jack before", userBefore); + + // WHEN + displayWhen(TEST_NAME); + unassignAll(userBefore, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + PrismObject userAfter = getUser(USER_JACK_OID); + display("User jack after", userAfter); + assertAssignments(userAfter, 0); + assertRoleMembershipRef(userAfter); + + assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + } + + +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbac.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbac.java index 781ec22c78d..e9dcb7d7538 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbac.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbac.java @@ -76,176 +76,21 @@ */ @ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestRbac extends AbstractInitializedModelIntegrationTest { +public class TestRbac extends AbstractRbacTest { - protected static final File TEST_DIR = new File("src/test/resources", "rbac"); + private static final String LOCALITY_TORTUGA = "Tortuga"; - protected static final File ROLE_ADRIATIC_PIRATE_FILE = new File(TEST_DIR, "role-adriatic-pirate.xml"); - protected static final String ROLE_ADRIATIC_PIRATE_OID = "12345678-d34d-b33f-f00d-5555555566aa"; - - protected static final File ROLE_BLACK_SEA_PIRATE_FILE = new File(TEST_DIR, "role-black-sea-pirate.xml"); - protected static final String ROLE_BLACK_SEA_PIRATE_OID = "12345678-d34d-b33f-f00d-5555555566bb"; - - protected static final File ROLE_INDIAN_OCEAN_PIRATE_FILE = new File(TEST_DIR, "role-indian-ocean-pirate.xml"); - protected static final String ROLE_INDIAN_OCEAN_PIRATE_OID = "12345678-d34d-b33f-f00d-555555556610"; - - protected static final File ROLE_HONORABILITY_FILE = new File(TEST_DIR, "role-honorability.xml"); - protected static final String ROLE_HONORABILITY_OID = "12345678-d34d-b33f-f00d-555555557701"; - - protected static final File ROLE_CLERIC_FILE = new File(TEST_DIR, "role-cleric.xml"); - protected static final String ROLE_CLERIC_OID = "12345678-d34d-b33f-f00d-555555557702"; - - protected static final File ROLE_WANNABE_FILE = new File(TEST_DIR, "role-wannabe.xml"); - protected static final String ROLE_WANNABE_OID = "12345678-d34d-b33f-f00d-555555557703"; - - protected static final File ROLE_HONORABLE_WANNABE_FILE = new File(TEST_DIR, "role-honorable-wannabe.xml"); - protected static final String ROLE_HONORABLE_WANNABE_OID = "12345678-d34d-b33f-f00d-555555557704"; - - protected static final File ROLE_GOVERNOR_FILE = new File(TEST_DIR, "role-governor.xml"); - protected static final String ROLE_GOVERNOR_OID = "12345678-d34d-b33f-f00d-555555557705"; - - protected static final File ROLE_CANNIBAL_FILE = new File(TEST_DIR, "role-cannibal.xml"); - protected static final String ROLE_CANNIBAL_OID = "12345678-d34d-b33f-f00d-555555557706"; - - protected static final File ROLE_PROJECT_OMNINAMAGER_FILE = new File(TEST_DIR, "role-project-omnimanager.xml"); - protected static final String ROLE_PROJECT_OMNINAMAGER_OID = "f23ab26c-69df-11e6-8330-979c643ea51c"; - - protected static final File ROLE_WEAK_GOSSIPER_FILE = new File(TEST_DIR, "role-weak-gossiper.xml"); - protected static final String ROLE_WEAK_GOSSIPER_OID = "e8fb2226-7f48-11e6-8cf1-630ce5c3f80b"; - - protected static final File ROLE_WEAK_SINGER_FILE = new File(TEST_DIR, "role-weak-singer.xml"); - protected static final String ROLE_WEAK_SINGER_OID = "caa7daf2-dd68-11e6-a780-ef610c7c3a06"; - - protected static final File ROLE_IMMUTABLE_FILE = new File(TEST_DIR, "role-immutable.xml"); - protected static final String ROLE_IMMUTABLE_OID = "e53baf94-aa99-11e6-962a-5362ec2dd7df"; - private static final String ROLE_IMMUTABLE_DESCRIPTION = "Role that cannot be modified because there is a modification rule with enforcement action."; - - protected static final File ROLE_IMMUTABLE_GLOBAL_FILE = new File(TEST_DIR, "role-immutable-global.xml"); - protected static final String ROLE_IMMUTABLE_GLOBAL_OID = "e7ba8884-b2f6-11e6-a0b9-d3540dd687d6"; - private static final String ROLE_IMMUTABLE_GLOBAL_DESCRIPTION = "Thou shalt not modify this role!"; - private static final String ROLE_IMMUTABLE_GLOBAL_IDENTIFIER = "GIG001"; - - protected static final File ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_FILE = new File(TEST_DIR, "role-immutable-description-global.xml"); - protected static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_OID = "b7ea1c0c-31d6-445e-8949-9f8f4a665b3b"; - private static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_DESCRIPTION = "Thou shalt not modify description of this role!"; - private static final String ROLE_IMMUTABLE_DESCRIPTION_GLOBAL_IDENTIFIER = "GIG001D"; - - protected static final File ROLE_NON_ASSIGNABLE_FILE = new File(TEST_DIR, "role-non-assignable.xml"); - protected static final String ROLE_NON_ASSIGNABLE_OID = "db67d2f0-abd8-11e6-9c30-b35abe3e4e3a"; - - protected static final File ROLE_SCREAMING_FILE = new File(TEST_DIR, "role-screaming.xml"); - protected static final String ROLE_SCREAMING_OID = "024e204d-ce40-4fe9-ae5a-0da3cbce989a"; - - protected static final File ROLE_NON_CREATEABLE_FILE = new File(TEST_DIR, "role-non-createable.xml"); - protected static final String ROLE_NON_CREATEABLE_OID = "c45a25ce-b2e8-11e6-923e-938d2c54d334"; - - protected static final File ROLE_IMMUTABLE_ASSIGN_FILE = new File(TEST_DIR, "role-immutable-assign.xml"); - protected static final String ROLE_IMMUTABLE_ASSIGN_OID = "a6b10a7c-b57e-11e6-bcb3-1ba47cb07e2e"; - - protected static final File ROLE_META_UNTOUCHABLE_FILE = new File(TEST_DIR, "role-meta-untouchable.xml"); - protected static final String ROLE_META_UNTOUCHABLE_OID = "a80c9572-b57d-11e6-80a9-6fdae1dc39bc"; - - protected static final File ROLE_META_FOOL_FILE = new File(TEST_DIR, "role-meta-fool.xml"); - protected static final String ROLE_META_FOOL_OID = "2edc5fe4-af3c-11e6-a81e-eb332578ec4f"; - - protected static final File ROLE_BLOODY_FOOL_FILE = new File(TEST_DIR, "role-bloody-fool.xml"); - protected static final String ROLE_BLOODY_FOOL_OID = "0a0ac150-af3d-11e6-9901-67fbcbd5bb25"; - - protected static final File ROLE_TREASURE_GOLD_FILE = new File(TEST_DIR, "role-treasure-gold.xml"); - protected static final String ROLE_TREASURE_GOLD_OID = "00a1db70-5817-11e7-93eb-9305bec579fe"; - - protected static final File ROLE_TREASURE_SILVER_FILE = new File(TEST_DIR, "role-treasure-silver.xml"); - protected static final String ROLE_TREASURE_SILVER_OID = "4e237ee4-5817-11e7-8345-8731a29a1fcb"; - - protected static final File ROLE_TREASURE_BRONZE_FILE = new File(TEST_DIR, "role-treasure-bronze.xml"); - protected static final String ROLE_TREASURE_BRONZE_OID = "60f9352c-5817-11e7-bc1e-f7e208714c43"; - - protected static final File ROLE_ALL_TREASURE_FILE = new File(TEST_DIR, "role-all-treasure.xml"); - protected static final String ROLE_ALL_TREASURE_OID = "7fda5d86-5817-11e7-ac85-3b1cba81d3ef"; - - protected static final File ROLE_LOOT_DIAMONDS_FILE = new File(TEST_DIR, "role-loot-diamonds.xml"); - protected static final String ROLE_LOOT_DIAMONDS_OID = "974d7156-581c-11e7-916d-03ed3d47d102"; - - protected static final File ROLE_ALL_LOOT_FILE = new File(TEST_DIR, "role-all-loot.xml"); - protected static final String ROLE_ALL_LOOT_OID = "aaede614-581c-11e7-91bf-db837eb406b7"; - - protected static final File ROLE_ALL_YOU_CAN_GET_FILE = new File(TEST_DIR, "role-all-you-can-get.xml"); - protected static final String ROLE_ALL_YOU_CAN_GET_OID = "4671874e-5822-11e7-a571-8b43dc7d2876"; - - protected static final File ORG_PROJECT_RECLAIM_BLACK_PEARL_FILE = new File(TEST_DIR, "org-project-reclaim-black-pearl.xml"); - protected static final String ORG_PROJECT_RECLAIM_BLACK_PEARL_OID = "00000000-8888-6666-0000-200000005000"; - - private static final String USER_LEMONHEAD_NAME = "lemonhead"; - private static final String USER_LEMONHEAD_FULLNAME = "Cannibal Lemonhead"; - - private static final String USER_SHARPTOOTH_NAME = "sharptooth"; - private static final String USER_SHARPTOOTH_FULLNAME = "Cannibal Sharptooth"; - - private static final String USER_REDSKULL_NAME = "redskull"; - private static final String USER_REDSKULL_FULLNAME = "Cannibal Redskull"; - - private static final String USER_BIGNOSE_NAME = "bignose"; - private static final String USER_BIGNOSE_FULLNAME = "Bignose the Noncannibal"; - - private static final String GROUP_FOOLS_NAME = "fools"; - private static final String GROUP_SIMPLETONS_NAME = "simpletons"; - - /** - * Undefined relation. It is not standard relation not a relation that is in any way configured. - */ - private static final QName RELATION_COMPLICATED_QNAME = new QName("http://exmple.com/relation", "complicated"); - private String userLemonheadOid; private String userSharptoothOid; private String userRedskullOid; private String userBignoseOid; private final String EXISTING_GOSSIP = "Black spot!"; - - protected File getRoleGovernorFile() { - return ROLE_GOVERNOR_FILE; - } - - protected File getRoleCannibalFile() { - return ROLE_CANNIBAL_FILE; - } - + @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); - - repoAddObjectFromFile(ROLE_ADRIATIC_PIRATE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_BLACK_SEA_PIRATE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_INDIAN_OCEAN_PIRATE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_HONORABILITY_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_CLERIC_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_WANNABE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_HONORABLE_WANNABE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(getRoleGovernorFile(), RoleType.class, initResult); - repoAddObjectFromFile(getRoleCannibalFile(), RoleType.class, initResult); - repoAddObjectFromFile(ROLE_PROJECT_OMNINAMAGER_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_WEAK_GOSSIPER_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_WEAK_SINGER_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_IMMUTABLE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_NON_ASSIGNABLE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_SCREAMING_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_META_UNTOUCHABLE_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_META_FOOL_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_BLOODY_FOOL_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_TREASURE_SILVER_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_TREASURE_BRONZE_FILE, RoleType.class, initResult); - // ROLE_TREASURE_GOLD is NOT loaded by purpose. It will come in later. - repoAddObjectFromFile(ROLE_LOOT_DIAMONDS_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_ALL_LOOT_FILE, RoleType.class, initResult); - repoAddObjectFromFile(ROLE_ALL_YOU_CAN_GET_FILE, RoleType.class, initResult); - - repoAddObjectFromFile(USER_RAPP_FILE, initResult); - - dummyResourceCtl.addGroup(GROUP_FOOLS_NAME); - dummyResourceCtl.addGroup(GROUP_SIMPLETONS_NAME); - } @Test @@ -327,8 +172,7 @@ public void test101JackAssignRolePirate() throws Exception { // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); PrismObject userAfter = getUser(USER_JACK_OID); @@ -341,11 +185,15 @@ public void test101JackAssignRolePirate() throws Exception { assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Caribbean"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, USER_JACK_LOCALITY); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, ROLE_PIRATE_WEAPON); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Caribbean has ever seen"); } @@ -373,12 +221,12 @@ public void test102JackModifyUserLocality() throws Exception { XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - modifyUserReplace(USER_JACK_OID, UserType.F_LOCALITY, getDefaultOptions(), task, result, PrismTestUtil.createPolyString("Tortuga")); + modifyUserReplace(USER_JACK_OID, UserType.F_LOCALITY, getDefaultOptions(), task, result, + createPolyString(LOCALITY_TORTUGA)); // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); @@ -388,9 +236,13 @@ public void test102JackModifyUserLocality() throws Exception { assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, LOCALITY_TORTUGA); + // Outbound mapping for weapon is weak, therefore the mapping in role should override it + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen", EXISTING_GOSSIP); } @@ -408,8 +260,7 @@ public void test110UnAssignRolePirate() throws Exception { // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); PrismObject userAfter = getUser(USER_JACK_OID); display("User jack after", userAfter); @@ -438,7 +289,7 @@ public void test120JackAssignRolePirateWhileAlreadyHasAccount() throws Exception // should work around that. TestUtil.setAttribute(account, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME), - DOMUtil.XSD_STRING, prismContext, "Bloody Pirate"); + DOMUtil.XSD_STRING, prismContext, ROLE_PIRATE_TITLE); ObjectDelta delta = ObjectDelta.createModificationAddReference(UserType.class, USER_JACK_OID, UserType.F_LINK_REF, prismContext, account); @@ -475,8 +326,8 @@ public void test120JackAssignRolePirateWhileAlreadyHasAccount() throws Exception assertRoleMembershipRef(userJack, ROLE_PIRATE_OID); assertDelegatedRef(userJack); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // The account already has a value for 'weapon', it should be unchanged. assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "rum"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, @@ -513,8 +364,8 @@ public void test121JackAssignAccountImplicitIntent() throws Exception { assertRoleMembershipRef(userJack, ROLE_PIRATE_OID); assertDelegatedRef(userJack); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen", EXISTING_GOSSIP); @@ -547,8 +398,8 @@ public void test122JackAssignAccountExplicitIntent() throws Exception { assertRoleMembershipRef(userJack, ROLE_PIRATE_OID); assertDelegatedRef(userJack); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen", EXISTING_GOSSIP); @@ -577,8 +428,8 @@ public void test127UnAssignAccountImplicitIntent() throws Exception { assertRoleMembershipRef(userJack, ROLE_PIRATE_OID); assertDelegatedRef(userJack); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen", EXISTING_GOSSIP); } @@ -606,8 +457,8 @@ public void test128UnAssignAccountExplicitIntent() throws Exception { assertRoleMembershipRef(userJack, ROLE_PIRATE_OID); assertDelegatedRef(userJack); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen", EXISTING_GOSSIP); } @@ -663,10 +514,10 @@ public void test130JackAssignRolePirateWithSeaInAssignment() throws Exception { assertRoleMembershipRef(userAfter, ROLE_PIRATE_OID); assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -727,10 +578,10 @@ public void test134JackAssignRoleAdriaticPirate() throws Exception { assertRoleMembershipRef(userAfter, ROLE_ADRIATIC_PIRATE_OID, ROLE_PIRATE_OID); assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -828,10 +679,10 @@ public void test137JackAssignRoleAdriaticPirateWithSeaInAssignment() throws Exce assertRoleMembershipRef(userAfter, ROLE_ADRIATIC_PIRATE_OID, ROLE_PIRATE_OID); assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -889,10 +740,10 @@ public void test144JackAssignRoleBlackSeaPirate() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -951,10 +802,10 @@ public void test147JackAssignRoleBlackSeaPirateWithSeaInAssignment() throws Exce assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -1016,10 +867,10 @@ public void test154JackAssignRoleIndianOceanPirate() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, @@ -1420,10 +1271,10 @@ public void test501JackAssignRolePirate() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Tortuga"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", LOCALITY_TORTUGA); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Tortuga has ever seen"); } @@ -1460,9 +1311,9 @@ public void test502JackModifyUserLocality() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Isla de Muerta"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Isla de Muerta has ever seen", "Jack Sparrow is the best pirate Tortuga has ever seen", // Positive enforcement. This vales are not removed. @@ -1555,10 +1406,10 @@ public void test520JackAssignRolePirate() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Isla de Muerta"); // Outbound mapping for weapon is weak, therefore the mapping in role should override it - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Jack Sparrow is the best pirate Isla de Muerta has ever seen"); } @@ -1996,7 +1847,7 @@ public void test605JackUnAssignRoleJudgeAssignRolePirate() throws Exception { assertDelegatedRef(userAfter); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "location", "Isla de Muerta"); // Even though Jack is a pirate now the mapping from the role is not applied. // the mapping is weak and the account already has a value for weapon from the times @@ -2701,8 +2552,8 @@ public void test712JackModifyEmptyRoleAddInducementPirateRecompute() throws Exce waitForTaskFinish(task.getOid(), true); assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", "Bloody Pirate"); - assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", "cutlass"); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "title", ROLE_PIRATE_TITLE); + assertDefaultDummyAccountAttribute(ACCOUNT_JACK_DUMMY_USERNAME, "weapon", ROLE_PIRATE_WEAPON); } @Test @@ -3619,7 +3470,7 @@ public void test782JackAssignRoleSailor() throws Exception { assertDummyAccountAttribute(null, ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "Pssst! hear this: dead men tell no tales"); assertDummyAccountAttribute(null, ACCOUNT_JACK_DUMMY_USERNAME, - DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Singer"); + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_WEAK_SINGER_TITLE); } @@ -3987,7 +3838,7 @@ public void test793JackSwitchRolesSingerAndGossiper() throws Exception { assertNoDummyAccountAttribute(null, ACCOUNT_JACK_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME); assertDummyAccountAttribute(null, ACCOUNT_JACK_DUMMY_USERNAME, - DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Singer"); + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, ROLE_WEAK_SINGER_TITLE); } /** diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacLightInitialProjection.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacLightInitialProjection.java index c061f3cdcee..ff2d3760ecd 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacLightInitialProjection.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacLightInitialProjection.java @@ -24,7 +24,7 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP; /** - * @author semancik + * @author mederly * */ @ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacNoInbounds.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacNoInbounds.java index 3d9af69de4a..120381f7c2e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacNoInbounds.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestRbacNoInbounds.java @@ -25,7 +25,7 @@ import java.io.File; /** - * @author semancik + * @author mederly * */ @ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java index 19d156c249f..d5e590f660c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java @@ -341,7 +341,7 @@ public abstract class AbstractSecurityTest extends AbstractInitializedModelInteg protected static final XMLGregorianCalendar JACK_VALID_FROM_LONG_AGO = XmlTypeConverter.createXMLGregorianCalendar(10000L); protected static final int NUMBER_OF_ALL_USERS = 11; - protected static final int NUMBER_OF_ALL_ROLES = 76; + protected static final int NUMBER_OF_IMPORTED_ROLES = 61; protected static final int NUMBER_OF_ALL_ORGS = 11; protected String userRumRogersOid; @@ -446,6 +446,10 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti assignRole(userCobbOid, ROLE_ORDINARY_OID, initTask, initResult); assignRole(userCobbOid, ROLE_UNINTERESTING_OID, initTask, initResult); } + + protected int getNumberOfRoles() { + return super.getNumberOfRoles() + NUMBER_OF_IMPORTED_ROLES; + } @Test public void test000Sanity() throws Exception { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityAdvanced.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityAdvanced.java index aed867d527f..019f4d42d63 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityAdvanced.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityAdvanced.java @@ -367,7 +367,7 @@ public void test151AutzJackApproverUnassignRolesAndRead() throws Exception { assertSearch(OrgType.class, null, NUMBER_OF_ALL_ORGS); // The appr-read-roles authorization is maySkipOnSearch and the readonly role allows read. - assertSearch(RoleType.class, null, NUMBER_OF_ALL_ROLES); + assertSearch(RoleType.class, null, getNumberOfRoles()); // The appr-read-users authorization is maySkipOnSearch and the readonly role allows read. assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); @@ -408,7 +408,7 @@ public void test154AutzJackApproverRead() throws Exception { assertGetAllow(UserType.class, USER_LECHUCK_OID); assertSearch(OrgType.class, null, NUMBER_OF_ALL_ORGS); - assertSearch(RoleType.class, null, NUMBER_OF_ALL_ROLES); + assertSearch(RoleType.class, null, getNumberOfRoles()); assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); assertSearch(UserType.class, createMembersQuery(UserType.class, ROLE_ORDINARY_OID), 0); @@ -530,7 +530,7 @@ public void test157AutzJackReadRoleMembers() throws Exception { assertGetAllow(UserType.class, USER_GUYBRUSH_OID); assertGetAllow(UserType.class, USER_LECHUCK_OID); - assertSearch(RoleType.class, null, NUMBER_OF_ALL_ROLES); + assertSearch(RoleType.class, null, getNumberOfRoles()); assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); assertSearch(OrgType.class, null, 0); @@ -583,7 +583,7 @@ public void test158AutzJackReadRoleMembersWrong() throws Exception { assertGetAllow(UserType.class, USER_GUYBRUSH_OID); assertGetAllow(UserType.class, USER_LECHUCK_OID); - assertSearch(RoleType.class, null, NUMBER_OF_ALL_ROLES); + assertSearch(RoleType.class, null, getNumberOfRoles()); assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); assertSearch(OrgType.class, null, 0); @@ -636,7 +636,7 @@ public void test159AutzJackReadRoleMembersNone() throws Exception { assertGetAllow(UserType.class, USER_GUYBRUSH_OID); assertGetAllow(UserType.class, USER_LECHUCK_OID); - assertSearch(RoleType.class, null, NUMBER_OF_ALL_ROLES); + assertSearch(RoleType.class, null, getNumberOfRoles()); assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); assertSearch(OrgType.class, null, 0); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java index 8970c8d1d72..92da83b698e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/AbstractSynchronizationStoryTest.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.model.intest.sync; import static org.testng.AssertJUnit.assertTrue; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; @@ -29,6 +28,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -64,15 +64,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.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author semancik @@ -99,7 +90,12 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); // DebugUtil.setDetailedDebugDump(true); } - + + @Override + protected ConflictResolutionActionType getDefaultConflictResolutionAction() { + return ConflictResolutionActionType.NONE; // too many conflicts in these scenarios + } + protected abstract void importSyncTask(PrismObject resource) throws FileNotFoundException; protected abstract String getSyncTaskOid(PrismObject resource); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java index 21166e6096f..4978f12729a 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestRecomputeTask.java @@ -179,7 +179,7 @@ public void test100RecomputeAll() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - addObject(TASK_USER_RECOMPUTE_FILE); + addTask(TASK_USER_RECOMPUTE_FILE); dummyAuditService.clear(); @@ -280,7 +280,7 @@ public void test110RecomputeSome() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - addObject(TASK_USER_RECOMPUTE_CAPTAIN_FILE); + addTask(TASK_USER_RECOMPUTE_CAPTAIN_FILE); dummyAuditService.clear(); @@ -334,7 +334,7 @@ public void test120RecomputeByExpression() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - addObject(TASK_USER_RECOMPUTE_HERMAN_BY_EXPRESSION_FILE); + addTask(TASK_USER_RECOMPUTE_HERMAN_BY_EXPRESSION_FILE); dummyAuditService.clear(); @@ -407,7 +407,7 @@ public void test130RecomputeLight() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - addObject(TASK_USER_RECOMPUTE_LIGHT_FILE); + addTask(TASK_USER_RECOMPUTE_LIGHT_FILE); dummyAuditService.clear(); diff --git a/model/model-intest/src/test/resources/common/connector-dbtable.json b/model/model-intest/src/test/resources/common/connector-dbtable.json new file mode 100644 index 00000000000..3c8cc05ef83 --- /dev/null +++ b/model/model-intest/src/test/resources/common/connector-dbtable.json @@ -0,0 +1,18 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "connector" : { + "oid" : "7d3ebd6f-6113-4833-8a6a-596b73a5e434", + "name" : "ICF org.identityconnectors.databasetable.DatabaseTableConnector", + "framework" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1", + "connectorType" : "org.identityconnectors.databasetable.DatabaseTableConnector", + "connectorVersion" : "1.1.0.e6296", + "connectorBundle" : "org.forgerock.openicf.connectors.db.databasetable", + "namespace" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.db.databasetable/org.identityconnectors.databasetable.DatabaseTableConnector", + "schema" : { + "definition" : { + "@ns" : "http://www.w3.org/2001/XMLSchema", + "schema" : "\n\n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t qn342:ConnectorPoolConfigurationType\n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t qn342:TimeoutsType\n\t \n\t \n\t \n\t \n\t \n\t \n\t tns:ConfigurationPropertiesType\n\t \n\t \n\t \n\t \n\t \n\t\t\t\t\n\t \n\t \n\t \n\t \n\t \n\t Name Quoting\n\t Name Quoting\n\t \n\t \n\t \n\t \n\t \n\t \n\t Host\n\t Host\n\t \n\t \n\t \n\t \n\t \n\t \n\t Port\n\t Port\n\t \n\t \n\t \n\t \n\t \n\t \n\t User\n\t User\n\t \n\t \n\t \n\t\t\t\t\n\t \n\t \n\t User Password\n\t User Password\n\t \n\t \n\t \n\t \n\t \n\t \n\t Database\n\t Database\n\t \n\t \n\t \n\t \n\t \n\t \n\t Table\n\t Table\n\t \n\t \n\t \n\t \n\t \n\t \n\t Key Column\n\t Key Column\n\t \n\t \n\t \n\t\t\t\t\n\t \n\t \n\t Password Column\n\t Password Column\n\t \n\t \n\t \n\t \n\t \n\t \n\t JDBC Driver\n\t JDBC Driver\n\t \n\t \n\t \n\t \n\t \n\t \n\t JDBC Connection URL\n\t JDBC Connection URL\n\t \n\t \n\t \n\t \n\t \n\t \n\t Enable writing empty string\n\t Enable writing empty string\n\t \n\t \n\t \n\t \n\t \n\t \n\t Rethrow all SQLExceptions\n\t Rethrow all SQLExceptions\n\t \n\t \n\t \n\t \n\t \n\t \n\t Native Timestamps \n\t Native Timestamps \n\t \n\t \n\t \n\t \n\t \n\t \n\t All native\n\t All native\n\t \n\t \n\t \n\t \n\t \n\t \n\t Validate Connection Query\n\t Validate Connection Query\n\t \n\t \n\t \n\t \n\t \n\t \n\t Change Log Column (Sync)\n\t Change Log Column (Sync)\n\t \n\t \n\t \n\t \n\t \n\t \n\t Datasource Path\n\t Datasource Path\n\t \n\t \n\t \n\t \n\t \n\t \n\t Initial JNDI Properties\n\t Initial JNDI Properties\n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t \n\t " + } + } + } +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/common/connector-dbtable.yaml b/model/model-intest/src/test/resources/common/connector-dbtable.yaml new file mode 100644 index 00000000000..ea06e5b6cd8 --- /dev/null +++ b/model/model-intest/src/test/resources/common/connector-dbtable.yaml @@ -0,0 +1,141 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +connector: + oid: "7d3ebd6f-6113-4833-8a6a-596b73a5e434" + name: "ICF org.identityconnectors.databasetable.DatabaseTableConnector" + framework: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1" + connectorType: "org.identityconnectors.databasetable.DatabaseTableConnector" + connectorVersion: "1.1.0.e6296" + connectorBundle: "org.forgerock.openicf.connectors.db.databasetable" + namespace: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.db.databasetable/org.identityconnectors.databasetable.DatabaseTableConnector" + schema: + definition: + '@ns': "http://www.w3.org/2001/XMLSchema" + schema: "\n\n\t \n\t \n\t \n\t \n\t \ + \ \n\t \n\t \n\t \n\t\ + \ qn342:ConnectorPoolConfigurationType\n\ + \t \n\t \n\t\ + \ \n\t \n\t \n\t \n\t \ + \ \n\t qn342:TimeoutsType\n\ + \t \n\t \n\t\ + \ \n\t \n\t \n\t \n\t\ + \ tns:ConfigurationPropertiesType\n\t\ + \ \n\t \n\t\ + \ \n\t \n\t \ + \ \n\t\t\t\t\n\t \n\t \n\t\ + \ \n\t \n\t \n\t\ + \ Name Quoting\n\t \ + \ Name Quoting\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ Host\n\t \ + \ Host\n\t \n\t \ + \ \n\t \n\t \ + \ \n\t \ + \ \n\t \n\t \ + \ Port\n\t Port\n\ + \t \n\t \n\t\ + \ \n\t \n\t \n\ + \t \n\t User\n\ + \t User\n\t \n\ + \t \n\t \n\t\t\t\t\ + \n\t \n\t \n\t\ + \ User Password\n\t \ + \ User Password\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ Database\n\t \ + \ Database\n\t \n\t\ + \ \n\t \n\t \ + \ \n\t \ + \ \n\t \n\t \ + \ Table\n\t Table\n\ + \t \n\t \n\t\ + \ \n\t \n\t \n\t \ + \ \n\t Key Column\n\ + \t Key Column\n\t \n\ + \t \n\t \n\t\t\t\t\ + \n\t \n\t \n\t\ + \ Password Column\n\t \ + \ Password Column\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ JDBC Driver\n\t \ + \ JDBC Driver\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ JDBC Connection URL\n\t\ + \ JDBC Connection URL\n\t \ + \ \n\t \n\t \n\ + \t \n\t \n\t \n\ + \t Enable writing empty string\n\ + \t Enable writing empty string\n\t \ + \ \n\t \n\t \ + \ \n\t \n\t \n\ + \t \n\t Rethrow\ + \ all SQLExceptions\n\t Rethrow\ + \ all SQLExceptions\n\t \n\t \ + \ \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ Native Timestamps \n\t\ + \ Native Timestamps \n\t \ + \ \n\t \n\t \n\ + \t \n\t \n\t \n\t\ + \ All native\n\t \ + \ All native\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \n\ + \t Validate Connection Query\n\ + \t Validate Connection Query\n\t \ + \ \n\t \n\t \ + \ \n\t \n\t \n\ + \t \n\t Change\ + \ Log Column (Sync)\n\t Change\ + \ Log Column (Sync)\n\t \n\t \ + \ \n\t \n\t \ + \ \n\t \n\t \n\t\ + \ Datasource Path\n\t \ + \ Datasource Path\n\t \n\ + \t \n\t \n\t \ + \ \n\t \n\t \ + \ \n\t Initial JNDI Properties\n\ + \t Initial JNDI Properties\n\t \ + \ \n\t \n\t \ + \ \n\t \n\t \n\ + \t \n\t \n\t \n\t \ + \ \n\t \n\t \n\ + \t \n\t " diff --git a/model/model-intest/src/test/resources/common/resource-dummy.json b/model/model-intest/src/test/resources/common/resource-dummy.json new file mode 100644 index 00000000000..caf8d549e62 --- /dev/null +++ b/model/model-intest/src/test/resources/common/resource-dummy.json @@ -0,0 +1,644 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "resource" : { + "oid" : "10000000-0000-0000-0000-000000000004", + "name" : "Dummy Resource", + "connectorRef" : { + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType", + "filter" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "and" : { + "equal" : [ { + "path" : "connectorType", + "value" : "com.evolveum.icf.dummy.connector.DummyConnector" + }, { + "path" : "connectorVersion", + "value" : "2.0" + } ] + } + } + }, + "connectorConfiguration" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorConfigurationType", + "configurationProperties" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3#ConfigurationPropertiesType", + "instanceId" : "", + "requireExplicitEnable" : "true", + "uselessGuardedString" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "clearValue" : "whatever" + }, + "uselessString" : "USEless", + "varyLetterCase" : "true" + }, + "resultsHandlerConfiguration" : { + "enableNormalizingResultsHandler" : false, + "enableFilteredResultsHandler" : false, + "enableAttributesToGetSearchResultsHandler" : false + } + }, + "namespace" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004", + "schemaHandling" : { + "objectType" : [ { + "kind" : "account", + "intent" : "default", + "displayName" : "Default Account", + "default" : true, + "objectClass" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass", + "attribute" : [ { + "ref" : "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:name", + "displayName" : "Username", + "outbound" : { + "strength" : "strong", + "source" : [ { + "path" : "$user/name" + } ], + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t\t\t\tname + iterationToken\n\t\t\t\t\t\t\t" + } ] + } + }, + "inbound" : [ { + "strength" : "weak", + "target" : { + "path" : "$user/name" + } + } ] + }, { + "ref" : "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:uid", + "displayName" : "UID" + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:fullname", + "displayName" : "Full Name", + "outbound" : { + "source" : [ { + "path" : "$user/fullName" + } ] + }, + "inbound" : [ { + "strength" : "weak", + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "allowEmptyValues" : true, + "code" : "\n\t\t\t\t\t\t\t\tif (input?.contains('#')) {\n \t\treturn null\n \t\t} else {\n \t\treturn input\n \t\t}\n\t\t\t\t\t\t\t" + } ] + }, + "target" : { + "path" : "$user/fullName" + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:title", + "tolerant" : true + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:location", + "displayName" : "Location", + "outbound" : { + "strength" : "strong", + "source" : [ { + "path" : "$user/locality" + } ] + }, + "inbound" : [ { + "channel" : [ "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#import" ], + "expression" : { + "allowEmptyValues" : false, + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "'Came from ' + input" + } ] + }, + "target" : { + "path" : "description" + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:ship", + "displayName" : "Ship", + "inbound" : [ { + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "allowEmptyValues" : false, + "code" : "'The crew of ' + input" + } ] + }, + "target" : { + "path" : "organizationalUnit" + }, + "condition" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "input != null" + } ] + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:loot", + "displayName" : "Loot", + "fetchStrategy" : "explicit", + "outbound" : { + "channel" : [ "http://pirates.net/avast" ], + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "9999 + 1" + } ] + } + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:weapon", + "displayName" : "Weapon", + "outbound" : { + "strength" : "weak", + "source" : [ { + "path" : "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'; $user/extension/piracy:weapon" + } ] + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:drink", + "displayName" : "Drink", + "tolerant" : false, + "outbound" : { + "strength" : "strong", + "expression" : { + "value" : [ "rum" ] + } + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:quote", + "displayName" : "Quote", + "tolerant" : true, + "outbound" : { + "strength" : "strong", + "expression" : { + "value" : [ "Arr!" ] + } + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:gossip", + "displayName" : "Gossip", + "tolerant" : true + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:water", + "limitations" : [ { + "ignore" : true + } ], + "outbound" : { + "expression" : { + "value" : [ "fishy" ] + } + }, + "inbound" : [ { + "expression" : { + "value" : [ "very FISHY" ] + }, + "target" : { + "path" : "$user/fullName" + } + } ] + } ], + "association" : [ { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:group", + "tolerant" : false, + "tolerantValuePattern" : [ "LaNdLuBeRs", "mapmakers" ], + "kind" : "entitlement", + "intent" : [ "group" ], + "direction" : "objectToSubject", + "associationAttribute" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#members", + "valueAttribute" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:priv", + "kind" : "entitlement", + "intent" : [ "privilege" ], + "direction" : "subjectToObject", + "associationAttribute" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#privileges", + "valueAttribute" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + } ], + "iteration" : { + "maxIterations" : 5 + }, + "protected" : [ { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3", + "name" : "daviejones" + }, { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3", + "name" : "calypso" + } ], + "activation" : { + "existence" : { + "outbound" : [ { + "expression" : { + "asIs" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#AsIsExpressionEvaluatorType" + } ] + } + } ] + }, + "administrativeStatus" : { + "outbound" : [ { } ], + "inbound" : [ { + "strength" : "weak", + "condition" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "focus?.getActivation()?.getValidFrom() == null && focus?.getActivation()?.getValidTo() == null" + } ] + } + } ] + }, + "lockoutStatus" : { + "outbound" : [ { } ] + } + }, + "credentials" : { + "password" : { + "outbound" : [ { + "expression" : { + "asIs" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#AsIsExpressionEvaluatorType" + } ] + } + } ], + "inbound" : [ { + "strength" : "weak", + "expression" : { + "generate" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#GenerateExpressionEvaluatorType" + } ] + } + } ] + } + } + }, { + "kind" : "account", + "intent" : "test", + "displayName" : "Testing Account", + "default" : false, + "objectClass" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass", + "attribute" : [ { + "ref" : "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:name", + "outbound" : { + "strength" : "strong", + "source" : [ { + "path" : "$user/name" + } ], + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t\t\t\t'T' + name + iterationToken\n\t\t\t\t\t\t\t" + } ] + } + }, + "inbound" : [ { + "strength" : "weak", + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t\t\t\tinput?.substring(1)\n\t\t\t\t\t\t\t" + } ] + }, + "target" : { + "path" : "$user/name" + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:fullname", + "outbound" : { + "source" : [ { + "path" : "$user/fullName" + } ], + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "fullName + ' (test)'" + } ] + } + }, + "inbound" : [ { + "strength" : "weak", + "target" : { + "path" : "$user/fullName" + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:location", + "outbound" : { + "strength" : "strong", + "source" : [ { + "path" : "$user/locality" + } ] + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:ship", + "displayName" : "Ship", + "inbound" : [ { + "expression" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "'The crew of Titanicum ' + input + 'icum'" + } ] + }, + "target" : { + "path" : "organizationalUnit" + }, + "condition" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "input != null" + } ] + } + } ] + } ], + "association" : [ { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:group", + "outbound" : { + "expression" : { + "value" : [ { + "name" : "ri:group", + "shadowRef" : { + "oid" : "20000000-0000-0000-3333-000000000002", + "type" : "ShadowType" + } + } ] + } + }, + "kind" : "entitlement", + "intent" : [ "group" ], + "direction" : "objectToSubject", + "associationAttribute" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#members", + "valueAttribute" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:priv", + "kind" : "entitlement", + "intent" : [ "privilege" ], + "direction" : "subjectToObject", + "associationAttribute" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#privileges", + "valueAttribute" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + } ], + "iteration" : { + "maxIterations" : 5 + }, + "activation" : { + "administrativeStatus" : { + "outbound" : [ { } ], + "inbound" : [ { + "strength" : "weak" + } ] + } + }, + "credentials" : { + "password" : { + "outbound" : [ { } ] + } + } + }, { + "kind" : "entitlement", + "intent" : "group", + "default" : true, + "objectClass" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#GroupObjectClass", + "attribute" : [ { + "ref" : "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:name", + "displayName" : "Groupname", + "matchingRule" : "http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase", + "exclusiveStrong" : true, + "outbound" : { + "source" : [ { + "path" : "$focus/name" + } ], + "expression" : { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "declare namespace t='http://prism.evolveum.com/xml/ns/public/types-3'; t:norm" + } ] + } + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:description", + "outbound" : { + "source" : [ { + "path" : "$focus/description" + } ] + } + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:cc", + "outbound" : { + "strength" : "weak", + "source" : [ { + "path" : "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'; $focus/extension/piracy:costCenter" + } ] + }, + "inbound" : [ { + "target" : { + "path" : "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'; $focus/extension/piracy:costCenter" + } + } ] + }, { + "ref" : "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004'; ri:members", + "fetchStrategy" : "minimal" + } ] + }, { + "kind" : "entitlement", + "intent" : "privilege", + "default" : false, + "objectClass" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#CustomprivilegeObjectClass" + } ] + }, + "scripts" : { + "script" : [ { + "host" : "resource", + "language" : "Logo", + "argument" : [ { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t'user: ' + user?.getName()\n\t\t\t\t\t" + } ], + "name" : "usr" + }, { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t'account: ' + account?.getActivation()?.getAdministrativeStatus()\n\t\t\t\t\t" + } ], + "name" : "acc" + }, { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "\n\t\t\t\t\t'resource: ' + resource?.getName()\n\t\t\t\t\t" + } ], + "name" : "res" + }, { + "value" : [ "3" ], + "name" : "size" + } ], + "code" : "\nto spiral :size\n if :size > 30 [stop]\n fd :size rt 15\n spiral :size *1.02\nend\n\t\t\t", + "operation" : [ "add" ], + "kind" : [ "account" ], + "order" : "after" + }, { + "host" : "resource", + "language" : "Gibberish", + "argument" : [ { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "$user/costCenter" + } ], + "name" : "howMuch" + }, { + "value" : [ "from here to there" ], + "name" : "howLong" + }, { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "$user/name" + } ], + "name" : "who" + }, { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "$user/fullName" + } ], + "name" : "whatchacallit" + } ], + "code" : "Beware the Jabberwock, my son!", + "operation" : [ "modify" ], + "kind" : [ "account" ], + "order" : "before" + }, { + "host" : "resource", + "language" : "Gibberish", + "code" : "The Jabberwock, with eyes of flame", + "operation" : [ "delete" ], + "kind" : [ "account" ], + "order" : "after" + }, { + "host" : "resource", + "language" : "Gibberish", + "argument" : [ { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "$focus/name" + } ], + "name" : "who" + } ], + "code" : "The vorpal blade went snicker-snack!", + "operation" : [ "reconcile" ], + "kind" : [ "account" ], + "order" : "before" + }, { + "host" : "resource", + "language" : "Gibberish", + "argument" : [ { + "path" : [ { + "@type" : "http://prism.evolveum.com/xml/ns/public/types-3#ItemPathType", + "@value" : "$shadow/activation/administrativeStatus" + } ], + "name" : "how" + } ], + "code" : "He left it dead, and with its head", + "operation" : [ "reconcile" ], + "kind" : [ "account" ], + "order" : "after" + } ] + }, + "consistency" : { + "avoidDuplicateValues" : true, + "caseIgnoreAttributeNames" : true + }, + "synchronization" : { + "objectSynchronization" : [ { + "objectClass" : [ "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" ], + "kind" : "account", + "intent" : "default", + "enabled" : true, + "condition" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "!basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3', 'name').startsWith(\"T\")" + } ] + }, + "correlation" : [ { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "equal" : { + "path" : "name", + "http://midpoint.evolveum.com/xml/ns/public/common/common-3#expression" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "path" : "declare namespace icfs=\"http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3\";\n $account/attributes/icfs:name" + } + } + } ], + "reaction" : [ { + "situation" : "linked", + "synchronize" : true + }, { + "situation" : "deleted", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink" + } ] + }, { + "situation" : "unlinked", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#link" + } ] + }, { + "situation" : "unmatched", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus" + } ] + } ] + }, { + "objectClass" : [ "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" ], + "kind" : "account", + "intent" : "test", + "enabled" : true, + "condition" : { + "script" : [ { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ScriptExpressionEvaluatorType", + "code" : "basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3', 'name').startsWith(\"T\")" + } ] + }, + "correlation" : [ { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "equal" : { + "path" : "name", + "http://midpoint.evolveum.com/xml/ns/public/common/common-3#expression" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "script" : { + "code" : "basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3', 'name').substring(1)" + } + } + } + } ], + "reaction" : [ { + "situation" : "linked", + "synchronize" : true + }, { + "situation" : "deleted", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink" + } ] + }, { + "situation" : "unlinked", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#link" + } ] + }, { + "situation" : "unmatched", + "synchronize" : true, + "action" : [ { + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus" + } ] + } ] + } ] + } + } +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/common/resource-dummy.yaml b/model/model-intest/src/test/resources/common/resource-dummy.yaml new file mode 100644 index 00000000000..5696deba307 --- /dev/null +++ b/model/model-intest/src/test/resources/common/resource-dummy.yaml @@ -0,0 +1,510 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +resource: + oid: "10000000-0000-0000-0000-000000000004" + name: "Dummy Resource" + connectorRef: + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + and: + equal: + - path: "connectorType" + value: "com.evolveum.icf.dummy.connector.DummyConnector" + - path: "connectorVersion" + value: "2.0" + connectorConfiguration: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector" + instanceId: "" + requireExplicitEnable: "true" + uselessGuardedString: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + clearValue: "whatever" + uselessString: "USEless" + varyLetterCase: "true" + resultsHandlerConfiguration: + enableNormalizingResultsHandler: false + enableFilteredResultsHandler: false + enableAttributesToGetSearchResultsHandler: false + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004" + schemaHandling: + objectType: + - kind: "account" + intent: "default" + displayName: "Default Account" + default: true + objectClass: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" + attribute: + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3';\ + \ icfs:name" + displayName: "Username" + outbound: + strength: "strong" + source: + - path: "$user/name" + expression: + script: + - ! + code: "\n\t\t\t\t\t\t\t\tname + iterationToken\n\t\t\t\t\t\t\t" + inbound: + - strength: "weak" + target: + path: "$user/name" + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3';\ + \ icfs:uid" + displayName: "UID" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:fullname" + displayName: "Full Name" + outbound: + source: + - path: "$user/fullName" + inbound: + - strength: "weak" + expression: + script: + - ! + allowEmptyValues: true + code: "\n\t\t\t\t\t\t\t\tif (input?.contains('#')) {\n \ + \ \t\treturn null\n \t\t} else\ + \ {\n \t\treturn input\n \ + \ \t\t}\n\t\t\t\t\t\t\t" + target: + path: "$user/fullName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:title" + tolerant: true + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:location" + displayName: "Location" + outbound: + strength: "strong" + source: + - path: "$user/locality" + inbound: + - channel: + - "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#import" + expression: + allowEmptyValues: false + script: + - ! + code: "'Came from ' + input" + target: + path: "description" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:ship" + displayName: "Ship" + inbound: + - expression: + script: + - ! + allowEmptyValues: false + code: "'The crew of ' + input" + target: + path: "organizationalUnit" + condition: + script: + - ! + code: "input != null" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:loot" + displayName: "Loot" + fetchStrategy: "explicit" + outbound: + channel: + - "http://pirates.net/avast" + expression: + script: + - ! + code: "9999 + 1" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:weapon" + displayName: "Weapon" + outbound: + strength: "weak" + source: + - path: "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy';\ + \ $user/extension/piracy:weapon" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:drink" + displayName: "Drink" + tolerant: false + outbound: + strength: "strong" + expression: + value: + - "rum" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:quote" + displayName: "Quote" + tolerant: true + outbound: + strength: "strong" + expression: + value: + - "Arr!" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:gossip" + displayName: "Gossip" + tolerant: true + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:water" + limitations: + - ignore: true + outbound: + expression: + value: + - "fishy" + inbound: + - expression: + value: + - "very FISHY" + target: + path: "$user/fullName" + association: + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:group" + tolerant: false + tolerantValuePattern: + - "LaNdLuBeRs" + - "mapmakers" + kind: "entitlement" + intent: + - "group" + direction: "objectToSubject" + associationAttribute: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#members" + valueAttribute: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:priv" + kind: "entitlement" + intent: + - "privilege" + direction: "subjectToObject" + associationAttribute: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#privileges" + valueAttribute: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + iteration: + maxIterations: 5 + protected: + - '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" + name: "daviejones" + - '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" + name: "calypso" + activation: + existence: + outbound: + - expression: + asIs: + - ! {} + administrativeStatus: + outbound: + - {} + inbound: + - strength: "weak" + condition: + script: + - ! + code: "focus?.getActivation()?.getValidFrom() == null && focus?.getActivation()?.getValidTo()\ + \ == null" + lockoutStatus: + outbound: + - {} + credentials: + password: + outbound: + - expression: + asIs: + - ! {} + inbound: + - strength: "weak" + expression: + generate: + - ! {} + - kind: "account" + intent: "test" + displayName: "Testing Account" + default: false + objectClass: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" + attribute: + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3';\ + \ icfs:name" + outbound: + strength: "strong" + source: + - path: "$user/name" + expression: + script: + - ! + code: "\n\t\t\t\t\t\t\t\t'T' + name + iterationToken\n\t\t\t\t\t\t\t" + inbound: + - strength: "weak" + expression: + script: + - ! + code: "\n\t\t\t\t\t\t\t\tinput?.substring(1)\n\t\t\t\t\t\t\t" + target: + path: "$user/name" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:fullname" + outbound: + source: + - path: "$user/fullName" + expression: + script: + - ! + code: "fullName + ' (test)'" + inbound: + - strength: "weak" + target: + path: "$user/fullName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:location" + outbound: + strength: "strong" + source: + - path: "$user/locality" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:ship" + displayName: "Ship" + inbound: + - expression: + script: + - ! + code: "'The crew of Titanicum ' + input + 'icum'" + target: + path: "organizationalUnit" + condition: + script: + - ! + code: "input != null" + association: + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:group" + outbound: + expression: + value: + - name: "ri:group" + shadowRef: + oid: "20000000-0000-0000-3333-000000000002" + type: "ShadowType" + kind: "entitlement" + intent: + - "group" + direction: "objectToSubject" + associationAttribute: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#members" + valueAttribute: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:priv" + kind: "entitlement" + intent: + - "privilege" + direction: "subjectToObject" + associationAttribute: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#privileges" + valueAttribute: "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3#name" + iteration: + maxIterations: 5 + activation: + administrativeStatus: + outbound: + - {} + inbound: + - strength: "weak" + credentials: + password: + outbound: + - {} + - kind: "entitlement" + intent: "group" + default: true + objectClass: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#GroupObjectClass" + attribute: + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3';\ + \ icfs:name" + displayName: "Groupname" + matchingRule: "http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase" + exclusiveStrong: true + outbound: + source: + - path: "$focus/name" + expression: + path: + - ! "declare\ + \ namespace t='http://prism.evolveum.com/xml/ns/public/types-3'; t:norm" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:description" + outbound: + source: + - path: "$focus/description" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:cc" + outbound: + strength: "weak" + source: + - path: "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy';\ + \ $focus/extension/piracy:costCenter" + inbound: + - target: + path: "declare namespace piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy';\ + \ $focus/extension/piracy:costCenter" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004';\ + \ ri:members" + fetchStrategy: "minimal" + - kind: "entitlement" + intent: "privilege" + default: false + objectClass: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#CustomprivilegeObjectClass" + scripts: + script: + - host: "resource" + language: "Logo" + argument: + - script: + - ! + code: "\n\t\t\t\t\t'user: ' + user?.getName()\n\t\t\t\t\t" + name: "usr" + - script: + - ! + code: "\n\t\t\t\t\t'account: ' + account?.getActivation()?.getAdministrativeStatus()\n\ + \t\t\t\t\t" + name: "acc" + - script: + - ! + code: "\n\t\t\t\t\t'resource: ' + resource?.getName()\n\t\t\t\t\t" + name: "res" + - value: + - "3" + name: "size" + code: "\nto spiral :size\n if :size > 30 [stop]\n fd :size rt 15\n spiral\ + \ :size *1.02\nend\n\t\t\t" + operation: + - "add" + kind: + - "account" + order: "after" + - host: "resource" + language: "Gibberish" + argument: + - path: + - ! "$user/costCenter" + name: "howMuch" + - value: + - "from here to there" + name: "howLong" + - path: + - ! "$user/name" + name: "who" + - path: + - ! "$user/fullName" + name: "whatchacallit" + code: "Beware the Jabberwock, my son!" + operation: + - "modify" + kind: + - "account" + order: "before" + - host: "resource" + language: "Gibberish" + code: "The Jabberwock, with eyes of flame" + operation: + - "delete" + kind: + - "account" + order: "after" + - host: "resource" + language: "Gibberish" + argument: + - path: + - ! "$focus/name" + name: "who" + code: "The vorpal blade went snicker-snack!" + operation: + - "reconcile" + kind: + - "account" + order: "before" + - host: "resource" + language: "Gibberish" + argument: + - path: + - ! "$shadow/activation/administrativeStatus" + name: "how" + code: "He left it dead, and with its head" + operation: + - "reconcile" + kind: + - "account" + order: "after" + consistency: + avoidDuplicateValues: true + caseIgnoreAttributeNames: true + synchronization: + objectSynchronization: + - objectClass: + - "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" + kind: "account" + intent: "default" + enabled: true + condition: + script: + - ! + code: "!basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3',\ + \ 'name').startsWith(\"T\")" + correlation: + - '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + equal: + path: "name" + http://midpoint.evolveum.com/xml/ns/public/common/common-3#expression: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + path: |- + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + $account/attributes/icfs:name + reaction: + - situation: "linked" + synchronize: true + - situation: "deleted" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink" + - situation: "unlinked" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#link" + - situation: "unmatched" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus" + - objectClass: + - "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004#AccountObjectClass" + kind: "account" + intent: "test" + enabled: true + condition: + script: + - ! + code: "basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3',\ + \ 'name').startsWith(\"T\")" + correlation: + - '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + equal: + path: "name" + http://midpoint.evolveum.com/xml/ns/public/common/common-3#expression: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + script: + code: "basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3',\ + \ 'name').substring(1)" + reaction: + - situation: "linked" + synchronize: true + - situation: "deleted" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink" + - situation: "unlinked" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#link" + - situation: "unmatched" + synchronize: true + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus" diff --git a/model/model-intest/src/test/resources/common/role-strong-sailor.xml b/model/model-intest/src/test/resources/common/role-strong-sailor.xml new file mode 100644 index 00000000000..4209d23bf2a --- /dev/null +++ b/model/model-intest/src/test/resources/common/role-strong-sailor.xml @@ -0,0 +1,53 @@ + + + Strong Sailor + + + + account + + ri:drink + + strong + + grog + + + + + + + + + + + CC-TITANIC + + + costCenter + + + + + conservative + + http://midpoint.evolveum.com/xml/ns/test/authorization#sail + + diff --git a/model/model-intest/src/test/resources/common/user-herman.json b/model/model-intest/src/test/resources/common/user-herman.json new file mode 100644 index 00000000000..c3f1e9a97c6 --- /dev/null +++ b/model/model-intest/src/test/resources/common/user-herman.json @@ -0,0 +1,23 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "user" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111122", + "name" : "herman", + "activation" : { + "validFrom" : "1700-05-30T11:00:00Z", + "validTo" : "2233-03-23T18:30:00Z" + }, + "fullName" : "Herman Toothrot", + "givenName" : "Herman", + "familyName" : "Toothrot", + "locality" : "Monkey Island", + "credentials" : { + "password" : { + "value" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/types-3", + "clearValue" : "m0nk3y" + } + } + } + } +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/common/user-herman.yaml b/model/model-intest/src/test/resources/common/user-herman.yaml new file mode 100644 index 00000000000..6f22e417668 --- /dev/null +++ b/model/model-intest/src/test/resources/common/user-herman.yaml @@ -0,0 +1,17 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + oid: "c0c010c0-d34d-b33f-f00d-111111111122" + name: "herman" + activation: + validFrom: "1700-05-30T11:00:00.000Z" + validTo: "2233-03-23T18:30:00.000Z" + fullName: "Herman Toothrot" + givenName: "Herman" + familyName: "Toothrot" + locality: "Monkey Island" + credentials: + password: + value: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + clearValue: "m0nk3y" diff --git a/model/model-intest/src/test/resources/importer/import-bad.json b/model/model-intest/src/test/resources/importer/import-bad.json new file mode 100644 index 00000000000..c77d2024ba8 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-bad.json @@ -0,0 +1,44 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "user" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111111", + "name" : "jack", + "extension" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/samples/piracy", + "ship" : "Black Pearl" + }, + "fullName" : "Cpt. Jack Sparrow", + "givenName" : "Jack", + "familyName" : "Sparrow", + "honorificPrefix" : "Cpt." + } + }, { + "user" : { + "fullName" : "Will Turner", + "givenName" : "William", + "familyName" : "Turner" + } + }, { + "user" : { + "name" : "guybrush", + "fullName" : "Guybrush Threepwood", + "givenName" : "Guybrush", + "familyName" : "Threepwood" + } + }, { + "account" : { + "name" : "Wrong Ref Account", + "resourceRef" : { + "oid" : "d0e5707e-8157-3333-4444-555511111111", + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ResourceType" + }, + "objectClass" : "AccountObjectClass", + "attributes" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/samples/piracy", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ShadowAttributesType", + "bar" : "foobar" + } + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/import-bad.yaml b/model/model-intest/src/test/resources/importer/import-bad.yaml new file mode 100644 index 00000000000..ccf66602a80 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-bad.yaml @@ -0,0 +1,36 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + oid: "c0c010c0-d34d-b33f-f00d-111111111111" + name: "jack" + extension: + '@ns': "http://midpoint.evolveum.com/xml/ns/samples/piracy" + ship: "Black Pearl" + fullName: "Cpt. Jack Sparrow" + givenName: "Jack" + familyName: "Sparrow" + honorificPrefix: "Cpt." +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + fullName: "Will Turner" + givenName: "William" + familyName: "Turner" +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +user: + name: "guybrush" + fullName: "Guybrush Threepwood" + givenName: "Guybrush" + familyName: "Threepwood" +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +account: + name: "Wrong Ref Account" + resourceRef: + oid: "d0e5707e-8157-3333-4444-555511111111" + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ResourceType" + objectClass: "AccountObjectClass" + attributes: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/samples/piracy" + bar: "foobar" diff --git a/model/model-intest/src/test/resources/importer/import-ref.json b/model/model-intest/src/test/resources/importer/import-ref.json new file mode 100644 index 00000000000..c6e82a85795 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-ref.json @@ -0,0 +1,35 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "resource" : { + "name" : "Sample Resource", + "connectorRef" : { + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType", + "filter" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "equal" : { + "path" : "connectorType", + "value" : "com.evolveum.polygon.connector.ldap.LdapConnector" + } + } + }, + "connectorConfiguration" : { + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorConfigurationType" + }, + "namespace" : "http://foo.bar.com/", + "schema" : { } + } + }, { + "user" : { + "name" : "jack2", + "extension" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/samples/piracy", + "ship" : "Black Pearl" + }, + "fullName" : "Cpt. Jack Sparrow", + "givenName" : "Jack", + "familyName" : "Sparrow", + "honorificPrefix" : "Cpt." + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/import-ref.xml b/model/model-intest/src/test/resources/importer/import-ref.xml index edd2c68ad28..f0efd5d1909 100644 --- a/model/model-intest/src/test/resources/importer/import-ref.xml +++ b/model/model-intest/src/test/resources/importer/import-ref.xml @@ -42,7 +42,7 @@ - jack + jack2 Black Pearl diff --git a/model/model-intest/src/test/resources/importer/import-ref.yaml b/model/model-intest/src/test/resources/importer/import-ref.yaml new file mode 100644 index 00000000000..d7a4604760a --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-ref.yaml @@ -0,0 +1,24 @@ +--- +- '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + resource: + name: "Sample Resource" + connectorRef: + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + equal: + path: "connectorType" + value: "com.evolveum.polygon.connector.ldap.LdapConnector" + connectorConfiguration: ! {} + namespace: "http://foo.bar.com/" + schema: {} +- '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + user: + name: "jack2" + extension: + '@ns': "http://midpoint.evolveum.com/xml/ns/samples/piracy" + ship: "Black Pearl" + fullName: "Cpt. Jack Sparrow" + givenName: "Jack" + familyName: "Sparrow" + honorificPrefix: "Cpt." diff --git a/model/model-intest/src/test/resources/importer/import-task.json b/model/model-intest/src/test/resources/importer/import-task.json new file mode 100644 index 00000000000..54237ce0d7e --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-task.json @@ -0,0 +1,24 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "task" : { + "oid" : "00000000-0000-0000-0000-123450000001", + "name" : "Task1: basic single-run task (takes 180x1 sec)", + "extension" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/task/noop/handler-3", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ExtensionType", + "delay" : 1000, + "steps" : 10 + }, + "taskIdentifier" : "10000000-0000-0000-0000-123450000001", + "ownerRef" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111111", + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#UserType" + }, + "executionStatus" : "runnable", + "handlerUri" : "http://midpoint.evolveum.com/xml/ns/public/task/noop/handler-3", + "recurrence" : "single", + "binding" : "tight" + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/import-task.yaml b/model/model-intest/src/test/resources/importer/import-task.yaml new file mode 100644 index 00000000000..0311cc7d3ec --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-task.yaml @@ -0,0 +1,18 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- task: + oid: "00000000-0000-0000-0000-123450000001" + name: "Task1: basic single-run task (takes 180x1 sec)" + extension: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/task/noop/handler-3" + delay: 1000 + steps: 10 + taskIdentifier: "10000000-0000-0000-0000-123450000001" + ownerRef: + oid: "c0c010c0-d34d-b33f-f00d-111111111111" + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#UserType" + executionStatus: "runnable" + handlerUri: "http://midpoint.evolveum.com/xml/ns/public/task/noop/handler-3" + recurrence: "single" + binding: "tight" diff --git a/model/model-intest/src/test/resources/importer/import-users-overwrite.json b/model/model-intest/src/test/resources/importer/import-users-overwrite.json new file mode 100644 index 00000000000..549702c75fb --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-users-overwrite.json @@ -0,0 +1,28 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "user" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111112", + "name" : "will", + "fullName" : "Will Turner", + "givenName" : "William", + "familyName" : "Turner", + "employeeType" : "legendary" + } + }, { + "user" : { + "name" : "guybrush", + "fullName" : "Guybrush Threepwood", + "givenName" : "Guybrush", + "familyName" : "Threepwood", + "locality" : "Deep in the Caribbean" + } + }, { + "user" : { + "name" : "ht", + "fullName" : "Herman Toothrot", + "givenName" : "Herman", + "familyName" : "Toothrot" + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/import-users-overwrite.yaml b/model/model-intest/src/test/resources/importer/import-users-overwrite.yaml new file mode 100644 index 00000000000..225c65429d0 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-users-overwrite.yaml @@ -0,0 +1,21 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- user: + oid: "c0c010c0-d34d-b33f-f00d-111111111112" + name: "will" + fullName: "Will Turner" + givenName: "William" + familyName: "Turner" + employeeType: "legendary" +- user: + name: "guybrush" + fullName: "Guybrush Threepwood" + givenName: "Guybrush" + familyName: "Threepwood" + locality: "Deep in the Caribbean" +- user: + name: "ht" + fullName: "Herman Toothrot" + givenName: "Herman" + familyName: "Toothrot" diff --git a/model/model-intest/src/test/resources/importer/import-users.json b/model/model-intest/src/test/resources/importer/import-users.json new file mode 100644 index 00000000000..dfd983b3a2b --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-users.json @@ -0,0 +1,41 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "user" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111111", + "name" : "jack", + "extension" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/samples/piracy", + "ship" : "Black Pearl" + }, + "fullName" : "Cpt. Jack Sparrow", + "givenName" : "Jack", + "familyName" : "Sparrow", + "honorificPrefix" : "Cpt.", + "costCenter" : "", + "credentials" : { + "password" : { + "value" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/types-3", + "clearValue" : "dead men tell no tales" + } + } + } + } + }, { + "user" : { + "oid" : "c0c010c0-d34d-b33f-f00d-111111111112", + "name" : "will", + "fullName" : "Will Turner", + "givenName" : "William", + "familyName" : "Turner" + } + }, { + "user" : { + "name" : "guybrush", + "fullName" : "Guybrush Threepwood", + "givenName" : "Guybrush", + "familyName" : "Threepwood" + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/import-users.yaml b/model/model-intest/src/test/resources/importer/import-users.yaml new file mode 100644 index 00000000000..f32f940cf2c --- /dev/null +++ b/model/model-intest/src/test/resources/importer/import-users.yaml @@ -0,0 +1,30 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- user: + oid: "c0c010c0-d34d-b33f-f00d-111111111111" + name: "jack" + extension: + '@ns': "http://midpoint.evolveum.com/xml/ns/samples/piracy" + ship: "Black Pearl" + fullName: "Cpt. Jack Sparrow" + givenName: "Jack" + familyName: "Sparrow" + honorificPrefix: "Cpt." + costCenter: "" + credentials: + password: + value: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + clearValue: "dead men tell no tales" +- user: + oid: "c0c010c0-d34d-b33f-f00d-111111111112" + name: "will" + fullName: "Will Turner" + givenName: "William" + familyName: "Turner" +- user: + name: "guybrush" + fullName: "Guybrush Threepwood" + givenName: "Guybrush" + familyName: "Threepwood" diff --git a/model/model-intest/src/test/resources/importer/resource-derby.json b/model/model-intest/src/test/resources/importer/resource-derby.json new file mode 100644 index 00000000000..b2594b338a0 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-derby.json @@ -0,0 +1,44 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "resource" : { + "oid" : "ef2bc95b-76e0-59e2-86d6-9119011311ab", + "name" : "Embedded Test Derby: Import test", + "connectorRef" : { + "oid" : "7d3ebd6f-6113-4833-8a6a-596b73a5e434", + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType", + "filter" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "equal" : { + "path" : "connectorType", + "value" : "com.evolveum.icf.dummy.connector.DummyConnector" + } + } + }, + "connectorConfiguration" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorConfigurationType", + "configurationProperties" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.db.databasetable/org.identityconnectors.databasetable.DatabaseTableConnector", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3#ConfigurationPropertiesType", + "jdbcDriver" : "org.apache.derby.jdbc.ClientDriver", + "jdbcUrlTemplate" : "jdbc:derby://%h:%p/%d", + "keyColumn" : "login", + "passwordColumn" : "password", + "password" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "clearValue" : "secret" + }, + "table" : "users", + "user" : "midpoint", + "database" : "target/derbyMidPointTest", + "host" : "localhost", + "port" : "11527" + } + }, + "namespace" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-9119011311ab", + "schema" : { }, + "schemaHandling" : { } + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/resource-derby.yaml b/model/model-intest/src/test/resources/importer/resource-derby.yaml new file mode 100644 index 00000000000..440ee8f5154 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-derby.yaml @@ -0,0 +1,33 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- resource: + oid: "ef2bc95b-76e0-59e2-86d6-9119011311ab" + name: "Embedded Test Derby: Import test" + connectorRef: + oid: "7d3ebd6f-6113-4833-8a6a-596b73a5e434" + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + equal: + path: "connectorType" + value: "com.evolveum.icf.dummy.connector.DummyConnector" + connectorConfiguration: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.db.databasetable/org.identityconnectors.databasetable.DatabaseTableConnector" + jdbcDriver: "org.apache.derby.jdbc.ClientDriver" + jdbcUrlTemplate: "jdbc:derby://%h:%p/%d" + keyColumn: "login" + passwordColumn: "password" + password: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + clearValue: "secret" + table: "users" + user: "midpoint" + database: "target/derbyMidPointTest" + host: "localhost" + port: "11527" + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-9119011311ab" + schema: {} + schemaHandling: {} diff --git a/model/model-intest/src/test/resources/importer/resource-dummy-changed.json b/model/model-intest/src/test/resources/importer/resource-dummy-changed.json new file mode 100644 index 00000000000..81985a84f65 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-dummy-changed.json @@ -0,0 +1,39 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "resource" : { + "oid" : "10000000-0000-0000-0000-000000000004", + "name" : "Dummy Resource", + "connectorRef" : { + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType", + "filter" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "and" : { + "equal" : [ { + "path" : "connectorType", + "value" : "com.evolveum.icf.dummy.connector.DummyConnector" + }, { + "path" : "connectorVersion", + "value" : "2.0" + } ] + } + } + }, + "connectorConfiguration" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorConfigurationType", + "configurationProperties" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3#ConfigurationPropertiesType", + "instanceId" : "", + "requireExplicitEnable" : "true", + "uselessGuardedString" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "clearValue" : "whatever" + } + } + }, + "namespace" : "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004" + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/resource-dummy-changed.yaml b/model/model-intest/src/test/resources/importer/resource-dummy-changed.yaml new file mode 100644 index 00000000000..c777459c6e3 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-dummy-changed.yaml @@ -0,0 +1,26 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- resource: + oid: "10000000-0000-0000-0000-000000000004" + name: "Dummy Resource" + connectorRef: + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + and: + equal: + - path: "connectorType" + value: "com.evolveum.icf.dummy.connector.DummyConnector" + - path: "connectorVersion" + value: "2.0" + connectorConfiguration: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector" + instanceId: "" + requireExplicitEnable: "true" + uselessGuardedString: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + clearValue: "whatever" + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004" diff --git a/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.json b/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.json new file mode 100644 index 00000000000..2b5b077be08 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.json @@ -0,0 +1,39 @@ +{ + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "objects" : [ { + "resource" : { + "oid" : "78fc521e-69f0-11e6-9ec5-130eb0c6fb6d", + "name" : "Dummy Resource (runtime)", + "connectorRef" : { + "type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType", + "filter" : { + "@ns" : "http://prism.evolveum.com/xml/ns/public/query-3", + "and" : { + "equal" : [ { + "path" : "connectorType", + "value" : "com.evolveum.icf.dummy.connector.DummyConnector" + }, { + "path" : "connectorVersion", + "value" : "2.0" + } ] + } + }, + "resolutionTime" : "run" + }, + "connectorConfiguration" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorConfigurationType", + "configurationProperties" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector", + "@type" : "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3#ConfigurationPropertiesType", + "instanceId" : "runtime", + "requireExplicitEnable" : "true", + "uselessGuardedString" : { + "@ns" : "http://midpoint.evolveum.com/xml/ns/public/common/common-3", + "clearValue" : "whatever" + } + } + } + } + } ] +} \ No newline at end of file diff --git a/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.yaml b/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.yaml new file mode 100644 index 00000000000..f085dd99255 --- /dev/null +++ b/model/model-intest/src/test/resources/importer/resource-dummy-runtime-resolution.yaml @@ -0,0 +1,26 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +objects: +- resource: + oid: "78fc521e-69f0-11e6-9ec5-130eb0c6fb6d" + name: "Dummy Resource (runtime)" + connectorRef: + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + and: + equal: + - path: "connectorType" + value: "com.evolveum.icf.dummy.connector.DummyConnector" + - path: "connectorVersion" + value: "2.0" + resolutionTime: "run" + connectorConfiguration: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: ! + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector" + instanceId: "runtime" + requireExplicitEnable: "true" + uselessGuardedString: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" + clearValue: "whatever" diff --git a/model/model-intest/src/test/resources/logback-test.xml b/model/model-intest/src/test/resources/logback-test.xml index 9e6c9d0b663..3fc62368c66 100644 --- a/model/model-intest/src/test/resources/logback-test.xml +++ b/model/model-intest/src/test/resources/logback-test.xml @@ -62,7 +62,7 @@ - + diff --git a/model/model-intest/src/test/resources/rbac/role-weak-singer.xml b/model/model-intest/src/test/resources/rbac/role-weak-singer.xml index 21993bf9730..710f1b5af95 100644 --- a/model/model-intest/src/test/resources/rbac/role-weak-singer.xml +++ b/model/model-intest/src/test/resources/rbac/role-weak-singer.xml @@ -26,6 +26,7 @@ ri:title + strong Singer diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index 2c3e7883df2..cdfd75f677b 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -59,6 +59,10 @@ + + + + @@ -81,9 +85,9 @@ - - - + + + diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 1ff745513e3..98a5f1c2d21 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -15,7 +15,6 @@ */ package com.evolveum.midpoint.model.test; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; @@ -389,7 +388,7 @@ protected void importObjectFromFile(String filename, OperationResult result) thr protected void importObjectFromFile(File file, OperationResult result) throws FileNotFoundException { OperationResult subResult = result.createSubresult(AbstractModelIntegrationTest.class+".importObjectFromFile"); - subResult.addParam("filename", file); + subResult.addParam("filename", file.getPath()); LOGGER.trace("importObjectFromFile: {}", file); Task task = taskManager.createTaskInstance(); importObjectFromFile(file, task, result); @@ -677,7 +676,7 @@ protected void modifyUserReplace(String userOid, ItemPath propertyPath, ModelExe ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = createModifyUserReplaceDelta(userOid, propertyPath, newRealValue); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, options, task, result); + modelService.executeChanges(deltas, options, task, result); } protected void modifyObjectReplaceProperty(Class type, String oid, QName propertyName, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { @@ -707,7 +706,7 @@ protected void modifyObjectDeleteProperty(Class type, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = ObjectDelta.createModificationDeleteProperty(type, oid, propertyPath, prismContext, newRealValue); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected void modifyObjectAddProperty(Class type, String oid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) @@ -715,7 +714,7 @@ protected void modifyObjectAddProperty(Class type, Str ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = ObjectDelta.createModificationAddProperty(type, oid, propertyPath, prismContext, newRealValue); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected void modifyObjectReplaceContainer(Class type, String oid, ItemPath propertyPath, Task task, OperationResult result, C... newRealValue) @@ -751,7 +750,7 @@ protected void modifyObjectReplaceReference(Class type ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = ObjectDelta.createModificationReplaceReference(type, oid, refPath, prismContext, refVals); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected void modifyUserAdd(String userOid, QName propertyName, Task task, OperationResult result, Object... newRealValue) @@ -765,7 +764,7 @@ protected void modifyUserAdd(String userOid, ItemPath propertyPath, Task task, O ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = createModifyUserAddDelta(userOid, propertyPath, newRealValue); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected void modifyUserDelete(String userOid, QName propertyName, Task task, OperationResult result, Object... newRealValue) @@ -779,7 +778,7 @@ protected void modifyUserDelete(String userOid, ItemPath propertyPath, Task task ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta objectDelta = createModifyUserDeleteDelta(userOid, propertyPath, newRealValue); Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected void modifyAccountShadowReplace(String accountOid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) @@ -1147,18 +1146,37 @@ protected void modifyFocusAssignment(Class focusClass, Collection> deltas = MiscSchemaUtil.createCollection(focusDelta); modelService.executeChanges(deltas, options, task, result); } + + /** + * Executes unassign delta by removing each assignment individually by id. + */ + protected void unassignAll(PrismObject focusBefore, Task task, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { + ObjectDelta focusDelta = createUnassignAllDelta(focusBefore); + modelService.executeChanges(MiscSchemaUtil.createCollection(focusDelta), null, task, result); + } + /** + * Creates unassign delta by removing each assignment individually by id. + */ + protected ObjectDelta createUnassignAllDelta(PrismObject focusBefore) throws SchemaException { + Collection> modifications = new ArrayList<>(); + for (AssignmentType assignmentType: focusBefore.asObjectable().getAssignment()) { + modifications.add((createAssignmentModification(assignmentType.getId(), false))); + } + return ObjectDelta.createModifyDelta(focusBefore.getOid(), modifications, focusBefore.getCompileTimeClass(), prismContext); + } + /** * Executes assignment replace delta with empty values. */ - protected void unassignAll(String userOid, Task task, OperationResult result) + protected void unassignAllReplace(String userOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta userDelta = ObjectDelta.createModificationReplaceContainer(UserType.class, userOid, UserType.F_ASSIGNMENT, prismContext, new PrismContainerValue[0]); Collection> deltas = MiscSchemaUtil.createCollection(userDelta); - modelService.executeChanges(deltas, null, task, result); + modelService.executeChanges(deltas, null, task, result); } protected ContainerDelta createAssignmentModification(String roleOid, QName refType, QName relation, @@ -2869,9 +2887,10 @@ protected void assertSideEffectiveDeltasOnly(String desc, } int expectedModifications = 0; // There may be metadata modification, we tolerate that - Collection> metadataDelta = focusDelta.findItemDeltasSubPath(new ItemPath(UserType.F_METADATA)); - if (metadataDelta != null && !metadataDelta.isEmpty()) { - expectedModifications+=metadataDelta.size(); + for (ItemDelta modification: focusDelta.getModifications()) { + if (isSideEffectDelta(modification)) { + expectedModifications++; + } } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ENABLE_TIMESTAMP)) != null) { expectedModifications++; @@ -2912,7 +2931,7 @@ protected void assertEffectualDeltas(ObjectDelta focusD int expectedModifications = expectedEffectualModifications; // There may be metadata modification, we tolerate that for (ItemDelta modification: focusDelta.getModifications()) { - if (modification.getPath().containsName(ObjectType.F_METADATA)) { + if (isSideEffectDelta(modification)) { expectedModifications++; } } @@ -2945,6 +2964,25 @@ protected void assertEffectualDeltas(ObjectDelta focusD assertEquals("Unexpected modifications in "+desc+": "+focusDelta, expectedModifications, focusDelta.getModifications().size()); } + private boolean isSideEffectDelta(ItemDelta modification) { + if (modification.getPath().containsName(ObjectType.F_METADATA) || + (modification.getPath().containsName(FocusType.F_ASSIGNMENT) && modification.getPath().containsName(ActivationType.F_EFFECTIVE_STATUS))) { + return true; + } else if (modification.getPath().containsName(FocusType.F_ASSIGNMENT) && modification.getPath().containsName(AssignmentType.F_ACTIVATION) && modification.isReplace() && (modification instanceof ContainerDelta)) { + Collection> valuesToReplace = ((ContainerDelta)modification).getValuesToReplace(); + if (valuesToReplace != null && valuesToReplace.size() == 1) { + PrismContainerValue cval = valuesToReplace.iterator().next(); + if (cval.getItems().size() == 1) { + Item item = cval.getItems().iterator().next(); + if (ActivationType.F_EFFECTIVE_STATUS.equals(item.getElementName())) { + return true; + } + } + } + } + return false; + } + protected void assertValidFrom(PrismObject obj, Date expectedDate) { assertEquals("Wrong validFrom in "+obj, XmlTypeConverter.createXMLGregorianCalendar(expectedDate), getActivation(obj).getValidFrom()); @@ -3025,6 +3063,11 @@ protected void addObjects(File... files) throws ObjectAlr } } + // not going through model to avoid conflicts (because the task starts execution during the clockwork operation) + protected void addTask(File file) throws SchemaException, IOException, ObjectAlreadyExistsException { + taskManager.addTask(prismContext.parseObject(file), new OperationResult("addTask")); + } + protected void addObject(File file) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, IOException { PrismObject object = PrismTestUtil.parseObject(file); addObject(object); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/CustomTransport.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/CustomTransport.java index cf8b8f26d94..24c2cdd36f6 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/CustomTransport.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/CustomTransport.java @@ -90,7 +90,7 @@ public void init() { public void send(Message message, String transportName, Event event, Task task, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_CLASS + "send"); - result.addCollectionOfSerializablesAsParam("message recipient(s)", message.getTo()); + result.addArbitraryObjectCollectionAsParam("message recipient(s)", message.getTo()); result.addParam("message subject", message.getSubject()); SystemConfigurationType systemConfiguration = NotificationFunctionsImpl diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/MailTransport.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/MailTransport.java index 71e053b7f58..1a6946026f8 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/MailTransport.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/MailTransport.java @@ -84,7 +84,7 @@ public void init() { public void send(Message mailMessage, String transportName, Event event, Task task, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_CLASS + "send"); - result.addCollectionOfSerializablesAsParam("mailMessage recipient(s)", mailMessage.getTo()); + result.addArbitraryObjectCollectionAsParam("mailMessage recipient(s)", mailMessage.getTo()); result.addParam("mailMessage subject", mailMessage.getSubject()); SystemConfigurationType systemConfiguration = NotificationFunctionsImpl.getSystemConfiguration(cacheRepositoryService, new OperationResult("dummy")); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java index bfc00494166..ba3e27cd911 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java @@ -97,7 +97,7 @@ public void init() { public void send(Message message, String transportName, Event event, Task task, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_CLASS + "send"); - result.addCollectionOfSerializablesAsParam("message recipient(s)", message.getTo()); + result.addArbitraryObjectCollectionAsParam("message recipient(s)", message.getTo()); result.addParam("message subject", message.getSubject()); SystemConfigurationType systemConfiguration = NotificationFunctionsImpl.getSystemConfiguration(cacheRepositoryService, new OperationResult("dummy")); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java index dff16084070..8a72a4f98b1 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java @@ -95,7 +95,7 @@ public HookOperationMode invoke(@NotNull ModelContext // as minor afterwards. OperationResult result = parentResult.createSubresult(OPERATION_INVOKE); result.addParam("taskFromModel", taskFromModel.toString()); - result.addContext("model state", context.getState()); + result.addArbitraryObjectAsContext("model state", context.getState()); try { WfConfigurationType wfConfigurationType = baseConfigurationHelper.getWorkflowConfiguration(context, result); // TODO consider this if it's secure enough diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WorkflowManagerImpl.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WorkflowManagerImpl.java index 53e30395a80..ed7735a68f9 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WorkflowManagerImpl.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WorkflowManagerImpl.java @@ -94,8 +94,9 @@ public void initialize() { public Integer countContainers(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException { OperationResult result = parentResult.createSubresult(DOT_INTERFACE + ".countContainers"); - result.addParams(new String[] { "type", "query" }, type, query); - result.addCollectionOfSerializablesAsParam("options", options); + result.addParam(OperationResult.PARAM_TYPE, type); + result.addParam(OperationResult.PARAM_QUERY, query); + result.addArbitraryObjectCollectionAsParam(OperationResult.PARAM_OPTIONS, options); try { if (!WorkItemType.class.equals(type)) { throw new UnsupportedOperationException("countContainers is available only for work items"); @@ -114,8 +115,9 @@ public Integer countContainers(Class type, ObjectQu public SearchResultList searchContainers(Class type, ObjectQuery query, Collection> options, OperationResult parentResult) throws SchemaException { OperationResult result = parentResult.createSubresult(DOT_INTERFACE + ".searchContainers"); - result.addParams(new String[] { "type", "query" }, type, query); - result.addCollectionOfSerializablesAsParam("options", options); + result.addParam(OperationResult.PARAM_TYPE, type); + result.addParam(OperationResult.PARAM_QUERY, query); + result.addArbitraryObjectCollectionAsParam(OperationResult.PARAM_OPTIONS, options); try { if (!WorkItemType.class.equals(type)) { throw new UnsupportedOperationException("searchContainers is available only for work items"); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceProvider.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceProvider.java index 36488c29f17..a50f47c8f7d 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceProvider.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/ProcessInstanceProvider.java @@ -60,7 +60,7 @@ public void augmentTaskObject(PrismObject object, final OperationResult result = parentResult.createSubresult(OPERATION_AUGMENT_TASK_OBJECT); result.addParam("object", ObjectTypeUtil.toShortString(object)); - result.addCollectionOfSerializablesAsParam("options", options); + result.addArbitraryObjectCollectionAsParam("options", options); if (!(object.asObjectable() instanceof TaskType)) { result.recordNotApplicableIfUnknown(); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java index 0e631bc898e..6d17b2cd695 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java @@ -93,8 +93,10 @@ public void completeWorkItem(String workItemId, String outcome, String comment, throws SecurityViolationException, SchemaException { OperationResult result = parentResult.createSubresult(OPERATION_COMPLETE_WORK_ITEM); - result.addParams(new String[] { "workItemId", "decision", "comment", "additionalDelta" }, - workItemId, outcome, comment, additionalDelta); + result.addParam("workItemId", workItemId); + result.addParam("decision", outcome); + result.addParam("comment", comment); + result.addParam("additionalDelta", additionalDelta); try { final String userDescription = toShortString(securityEnforcer.getPrincipal().getUser()); @@ -231,8 +233,8 @@ public void delegateWorkItem(String workItemId, List delega throws ObjectNotFoundException, SecurityViolationException, SchemaException { OperationResult result = parentResult.createSubresult(OPERATION_DELEGATE_WORK_ITEM); result.addParam("workItemId", workItemId); - result.addParam("escalation", escalation); - result.addCollectionOfSerializablesAsParam("delegates", delegates); + result.addArbitraryObjectAsParam("escalation", escalation); + result.addArbitraryObjectCollectionAsParam("delegates", delegates); try { MidPointPrincipal principal = securityEnforcer.getPrincipal(); result.addContext("user", toShortString(principal.getUser())); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java index 3f9d54ccf5b..fc37e663859 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemProvider.java @@ -403,8 +403,10 @@ public WorkItemType taskEventToWorkItemNew(TaskEvent taskEvent, Map T handleError(T shadow, FailedOperation op, Except OperationResult operationResult = parentResult.createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.CommunicationExceptionHandler.handleError." + op.name()); operationResult.addParam("shadow", shadow); - operationResult.addParam("currentOperation", op); + operationResult.addArbitraryObjectAsParam("currentOperation", op); operationResult.addParam("exception", ex.getMessage()); // first modify last availability status in the resource, so by others diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java index fe66a6fa0de..3b88435c807 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ConfigurationExceptionHandler.java @@ -88,7 +88,7 @@ public T handleError(T shadow, FailedOperation op, Except case GET: OperationResult operationResult = parentResult.createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.ConfigurationExceptionHandler.handleError." + op.name()); operationResult.addParam("shadow", shadow); - operationResult.addParam("currentOperation", op); + operationResult.addArbitraryObjectAsParam("currentOperation", op); operationResult.addParam("exception", ex.getMessage()); for (OperationResult subRes : parentResult.getSubresults()) { subRes.muteError(); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java index 588b612c407..8db9457f088 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/GenericErrorHandler.java @@ -91,7 +91,7 @@ public T handleError(T shadow, FailedOperation op, Except result.addContext("compensatedOperation", operation); result.addContext("operationType",op.name()); result.addParam("shadow", shadow); - result.addParam("currentOperation", op); + result.addArbitraryObjectAsParam("currentOperation", op); result.addParam("reconciled", true); switch (op) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java index 4a719b2fbd0..5df90495a03 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java @@ -86,7 +86,7 @@ public T handleError(T shadow, FailedOperation op, Except OperationResult operationResult = parentResult .createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.ObjectAlreadyExistHandler.handleError." + op.name()); operationResult.addParam("shadow", shadow); - operationResult.addParam("currentOperation", op); + operationResult.addArbitraryObjectAsParam("currentOperation", op); operationResult.addParam("exception", ex.getMessage()); ResourceObjectShadowChangeDescription change = new ResourceObjectShadowChangeDescription(); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java index 676873efa75..48d2fa45afe 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectNotFoundHandler.java @@ -113,7 +113,7 @@ public T handleError(T shadow, FailedOperation op, Except OperationResult result = parentResult .createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.ObjectNotFoundHandler.handleError." + op.name()); result.addParam("shadow", shadow); - result.addParam("currentOperation", op); + result.addArbitraryObjectAsParam("currentOperation", op); if (ex.getMessage() != null) { result.addParam("exception", ex.getMessage()); } @@ -348,7 +348,7 @@ private String findCreatedAccountOid(OperationResult handleErrorResult, String o } List subresults = handleErrorResult.getSubresults(); for (OperationResult subresult : subresults) { - String oidValue = (String) subresult.getReturn("createdAccountOid"); + String oidValue = subresult.getReturnSingle("createdAccountOid"); String oid = findCreatedAccountOid(subresult, oidValue); if (oid != null) { return oid; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java index 64c972af2ad..61450ea8ca5 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java @@ -235,7 +235,8 @@ private ConnectorInstance createConfiguredConnectorInstance(ConnectorSpec connec ConnectorInstance connector = createConnectorInstance(connectorSpec, result); - PrismContainerValue connectorConfigurationVal = connectorSpec.getConnectorConfiguration().getValue(); + PrismContainerValue connectorConfigurationVal = connectorSpec.getConnectorConfiguration() != null ? + connectorSpec.getConnectorConfiguration().getValue() : null; if (connectorConfigurationVal == null) { SchemaException e = new SchemaException("No connector configuration in "+connectorSpec); result.recordFatalError(e); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java index 259c8faf8e6..717b933273b 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java @@ -162,7 +162,7 @@ public PrismObject getObject(Class type, String oid OperationResult result = parentResult.createMinorSubresult(ProvisioningService.class.getName() + ".getObject"); result.addParam(OperationResult.PARAM_OID, oid); result.addParam(OperationResult.PARAM_TYPE, type); - result.addCollectionOfSerializablesAsParam("options", options); + result.addArbitraryObjectCollectionAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); @@ -299,7 +299,7 @@ public String addObject(PrismObject object, OperationP OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".addObject"); result.addParam("object", object); - result.addParam("scripts", scripts); + result.addArbitraryObjectAsParam("scripts", scripts); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); String oid = null; @@ -647,10 +647,10 @@ public String modifyObject(Class type, String oid, } OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".modifyObject"); - result.addCollectionOfSerializablesAsParam("modifications", modifications); + result.addArbitraryObjectCollectionAsParam("modifications", modifications); result.addParam(OperationResult.PARAM_OID, oid); - result.addParam("scripts", scripts); - result.addParam("options", options); + result.addArbitraryObjectAsParam("scripts", scripts); + result.addArbitraryObjectAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); if (LOGGER.isTraceEnabled()) { @@ -721,7 +721,7 @@ public void deleteObject(Class type, String oid, Provi OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".deleteObject"); result.addParam("oid", oid); - result.addParam("scripts", scripts); + result.addArbitraryObjectAsParam("scripts", scripts); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); //TODO: is critical when shadow does not exits anymore?? do we need to log it?? if not, change null to allowNotFound options @@ -795,7 +795,7 @@ public void executeScript(String resourceOid, Provisionin OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".executeScript"); result.addParam("oid", resourceOid); - result.addParam("script", script); + result.addArbitraryObjectAsParam("script", script); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); try { @@ -855,7 +855,7 @@ public List> listResourceObjects(String resour + ".listResourceObjects"); result.addParam("resourceOid", resourceOid); result.addParam("objectClass", objectClass); - result.addParam("paging", paging); + result.addArbitraryObjectAsParam("paging", paging); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class); if (resourceOid == null) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java index 1d03189f019..0c5022a1516 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java @@ -753,7 +753,7 @@ private Collection executeModify(ProvisioningCont boolean inProgress = false; String asyncronousOperationReference = null; for (Collection operationsWave : operationsWaves) { - Collection readReplaceAttributes = determineReadReplace(operationsWave, objectClassDefinition); + Collection readReplaceAttributes = determineReadReplace(ctx, operationsWave, objectClassDefinition); LOGGER.trace("Read+Replace attributes: {}", readReplaceAttributes); if (!readReplaceAttributes.isEmpty()) { AttributesToReturn attributesToReturn = new AttributesToReturn(); @@ -850,11 +850,11 @@ private PrismObject preReadShadow(ProvisioningContext ctx, return currentShadow; } - private Collection determineReadReplace(Collection operations, RefinedObjectClassDefinition objectClassDefinition) { + private Collection determineReadReplace(ProvisioningContext ctx, Collection operations, RefinedObjectClassDefinition objectClassDefinition) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException { Collection retval = new ArrayList<>(); for (Operation operation : operations) { RefinedAttributeDefinition rad = getRefinedAttributeDefinitionIfApplicable(operation, objectClassDefinition); - if (rad != null && isReadReplaceMode(rad, objectClassDefinition) && operation instanceof PropertyModificationOperation) { // third condition is just to be sure + if (rad != null && isReadReplaceMode(ctx, rad, objectClassDefinition) && operation instanceof PropertyModificationOperation) { // third condition is just to be sure PropertyDelta propertyDelta = ((PropertyModificationOperation) operation).getPropertyDelta(); if (propertyDelta.isAdd() || propertyDelta.isDelete()) { retval.add(rad); // REPLACE operations are not needed to be converted to READ+REPLACE @@ -864,12 +864,12 @@ private Collection determineReadReplace(Collection convertToReplace(ProvisioningContext ctx, Collecti if (isAttributeDelta(propertyDelta)) { QName attributeName = propertyDelta.getElementName(); RefinedAttributeDefinition rad = ctx.getObjectClassDefinition().findAttributeDefinition(attributeName); - if (isReadReplaceMode(rad, ctx.getObjectClassDefinition()) && (propertyDelta.isAdd() || propertyDelta.isDelete())) { + if (isReadReplaceMode(ctx, rad, ctx.getObjectClassDefinition()) && (propertyDelta.isAdd() || propertyDelta.isDelete())) { PropertyModificationOperation newOp = convertToReplace(propertyDelta, currentShadow, rad.getMatchingRuleQName()); newOp.setMatchingRuleQName(((PropertyModificationOperation) operation).getMatchingRuleQName()); retval.add(newOp); @@ -1243,7 +1243,7 @@ public SearchResultMetadata searchResourceObjects(final ProvisioningContext ctx, RepositoryCache.exit(); } }, - attributesToReturn, objectClassDef.getPagedSearches(), searchHierarchyConstraints, + attributesToReturn, objectClassDef.getPagedSearches(ctx.getResource()), searchHierarchyConstraints, ctx, parentResult); } catch (GenericFrameworkException e) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 2f2281b6489..43e107b91c6 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -1641,7 +1641,7 @@ public Integer countObjects(ObjectQuery query, Task task, final OperationResult RefinedObjectClassDefinition objectClassDef = ctx.getObjectClassDefinition(); ResourceType resourceType = ctx.getResource(); CountObjectsCapabilityType countObjectsCapabilityType = objectClassDef - .getEffectiveCapability(CountObjectsCapabilityType.class); + .getEffectiveCapability(CountObjectsCapabilityType.class, resourceType); if (countObjectsCapabilityType == null) { // Unable to count. Return null which means "I do not know" result.recordNotApplicableIfUnknown(); @@ -1657,7 +1657,7 @@ public Integer countObjects(ObjectQuery query, Task task, final OperationResult int count; try { count = connector.count(objectClassDef.getObjectClassDefinition(), attributeQuery, - objectClassDef.getPagedSearches(), ctx, result); + objectClassDef.getPagedSearches(resourceType), ctx, result); } catch (CommunicationException | GenericFrameworkException | SchemaException | UnsupportedOperationException e) { result.recordFatalError(e); @@ -1675,7 +1675,7 @@ public Integer countObjects(ObjectQuery query, Task task, final OperationResult } else if (simulate == CountObjectsSimulateType.PAGED_SEARCH_ESTIMATE) { - if (!objectClassDef.isPagedSearchEnabled()) { + if (!objectClassDef.isPagedSearchEnabled(resourceType)) { throw new ConfigurationException( "Configured count object capability to be simulated using a paged search but paged search capability is not present"); } @@ -1885,7 +1885,7 @@ boolean processSynchronization(ProvisioningContext ctx, Change change, Operation } OperationResult notifyChangeResult = new OperationResult( ShadowCache.class.getName() + "notifyChange"); - notifyChangeResult.addParam("resourceObjectShadowChangeDescription", shadowChangeDescription); + notifyChangeResult.addParam("resourceObjectShadowChangeDescription", shadowChangeDescription.toString()); try { notifyResourceObjectChangeListeners(shadowChangeDescription, ctx.getTask(), notifyChangeResult); diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManagedConnectorInstance.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManagedConnectorInstance.java index 59c10e7da71..22dad99dc20 100644 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManagedConnectorInstance.java +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManagedConnectorInstance.java @@ -120,7 +120,6 @@ public void configure(PrismContainerValue configuration, OperationResult pare ConfigurationException { OperationResult result = parentResult.createSubresult(ConnectorInstance.OPERATION_CONFIGURE); - result.addParam("configuration", configuration); boolean immutable = configuration.isImmutable(); try { @@ -148,7 +147,7 @@ public void initialize(ResourceSchema resourceSchema, Collection capabil throws CommunicationException, GenericFrameworkException, ConfigurationException { OperationResult result = parentResult.createSubresult(ConnectorInstance.OPERATION_INITIALIZE); - result.addContext("connector", getConnectorObject()); + result.addContext("connector", getConnectorObject().toString()); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, this.getClass()); setResourceSchema(resourceSchema); diff --git a/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ManualConnectorInstance.java b/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ManualConnectorInstance.java index d8ecf3efd2d..2e90c685635 100644 --- a/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ManualConnectorInstance.java +++ b/provisioning/ucf-impl-builtin/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/builtin/ManualConnectorInstance.java @@ -237,7 +237,7 @@ public void test(OperationResult parentResult) { OperationResult connectionResult = parentResult .createSubresult(ConnectorTestOperation.CONNECTOR_CONNECTION.getOperation()); connectionResult.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ManualConnectorInstance.class); - connectionResult.addContext("connector", getConnectorObject()); + connectionResult.addContext("connector", getConnectorObject().toString()); if (repositoryService == null) { connectionResult.recordFatalError("No repository service"); diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java index e2ba43e8e31..b8dcd784f01 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java @@ -247,7 +247,6 @@ public void configure(PrismContainerValue configurationOriginal, OperationRes throws CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException { OperationResult result = parentResult.createSubresult(ConnectorInstance.OPERATION_CONFIGURE); - result.addParam("configuration", configurationOriginal); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Configuring connector {}, provided configuration:\n{}", connectorType, configurationOriginal.debugDump(1)); @@ -442,8 +441,7 @@ public ResourceSchema fetchResourceSchema(List generateObjectClasses, Ope GenericFrameworkException, ConfigurationException { // Result type for this operation - OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() - + ".fetchResourceSchema"); + OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".fetchResourceSchema"); result.addContext("connector", connectorType); try { @@ -479,8 +477,7 @@ public Collection fetchCapabilities(OperationResult parentResult) throws GenericFrameworkException, ConfigurationException { // Result type for this operation - OperationResult result = parentResult.createMinorSubresult(ConnectorInstance.class.getName() - + ".fetchCapabilities"); + OperationResult result = parentResult.createMinorSubresult(ConnectorInstance.class.getName() + ".fetchCapabilities"); result.addContext("connector", connectorType); try { @@ -1030,8 +1027,8 @@ public PrismObject fetchObject(ResourceObjectIdentification resource // Result type for this operation OperationResult result = parentResult.createMinorSubresult(ConnectorInstance.class.getName() + ".fetchObject"); - result.addParam("resourceObjectDefinition", objectClassDefinition); - result.addParam("identification", resourceObjectIdentification); + result.addArbitraryObjectAsParam("resourceObjectDefinition", objectClassDefinition); + result.addArbitraryObjectAsParam("identification", resourceObjectIdentification); result.addContext("connector", connectorType); if (connIdConnectorFacade == null) { @@ -1140,7 +1137,7 @@ private ConnectorObject fetchConnectorObject(StateReporter reporter, ObjectClass // create result for it OperationResult icfResult = parentResult.createMinorSubresult(ConnectorFacade.class.getName() + ".getObject"); - icfResult.addParam("objectClass", icfObjectClass.toString()); + icfResult.addArbitraryObjectAsParam("objectClass", icfObjectClass); icfResult.addParam("uid", uid.getUidValue()); icfResult.addArbitraryObjectAsParam("options", options); icfResult.addContext("connector", connIdConnectorFacade.getClass()); @@ -1378,8 +1375,8 @@ public AsynchronousOperationReturnValue>> addObj OperationResult connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".create"); connIdResult.addArbitraryObjectAsParam("objectClass", icfObjectClass); - connIdResult.addArbitraryCollectionAsParam("auxiliaryObjectClasses", icfAuxiliaryObjectClasses); - connIdResult.addArbitraryCollectionAsParam("attributes", attributes); + connIdResult.addArbitraryObjectCollectionAsParam("auxiliaryObjectClasses", icfAuxiliaryObjectClasses); + connIdResult.addArbitraryObjectCollectionAsParam("attributes", attributes); connIdResult.addArbitraryObjectAsParam("options", options); connIdResult.addContext("connector", connIdConnectorFacade.getClass()); @@ -1476,9 +1473,9 @@ public AsynchronousOperationReturnValue PrismProperty fetchCurrentToken(ObjectClassComplexTypeDefinition o OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".fetchCurrentToken"); - result.addParam("objectClass", objectClassDef); + result.addArbitraryObjectAsParam("objectClass", objectClassDef); ObjectClass icfObjectClass; if (objectClassDef == null) { @@ -2058,8 +2055,8 @@ public List fetchChanges(ObjectClassComplexTypeDefinition objectClass, OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".fetchChanges"); - result.addContext("objectClass", objectClass); - result.addParam("lastToken", lastToken); + result.addArbitraryObjectAsContext("objectClass", objectClass); + result.addArbitraryObjectAsParam("lastToken", lastToken); // create sync token from the property last token SyncToken syncToken = null; @@ -2183,7 +2180,7 @@ public SearchResultMetadata search(final ObjectClassComplexTypeDefinition object // Result type for this operation final OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".search"); - result.addParam("objectClass", objectClassDefinition); + result.addArbitraryObjectAsParam("objectClass", objectClassDefinition); result.addContext("connector", connectorType); if (objectClassDefinition == null) { @@ -2407,7 +2404,7 @@ public int count(ObjectClassComplexTypeDefinition objectClassDefinition, final O // Result type for this operation final OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".count"); - result.addParam("objectClass", objectClassDefinition); + result.addArbitraryObjectAsParam("objectClass", objectClassDefinition); result.addContext("connector", connectorType); if (objectClassDefinition == null) { diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/ConflictWatcher.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/ConflictWatcher.java new file mode 100644 index 00000000000..91c232e2ab1 --- /dev/null +++ b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/ConflictWatcher.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.api; + +import org.jetbrains.annotations.NotNull; + +/** + * A bit experimental. + * + * @author mederly + */ +public interface ConflictWatcher { + + @NotNull + String getOid(); + + boolean hasConflict(); + + void setExpectedVersion(String version); +} diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java index ad85fb0bdd5..1fdfe74e83d 100644 --- a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java +++ b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/RepositoryService.java @@ -599,4 +599,10 @@ boolean selectorMatches(ObjectSelectorType objectSelector FullTextSearchConfigurationType getFullTextSearchConfiguration(); void postInit(OperationResult result) throws SchemaException; + + ConflictWatcher createAndRegisterConflictWatcher(String oid); + + void unregisterConflictWatcher(ConflictWatcher watcher); + + boolean hasConflict(ConflictWatcher watcher, OperationResult result); } diff --git a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java index da819ae3536..0ff3bf587ed 100644 --- a/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java +++ b/repo/repo-cache/src/main/java/com/evolveum/midpoint/repo/cache/RepositoryCache.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; @@ -460,4 +461,19 @@ public FullTextSearchConfigurationType getFullTextSearchConfiguration() { public void postInit(OperationResult result) throws SchemaException { repository.postInit(result); } + + @Override + public ConflictWatcher createAndRegisterConflictWatcher(String oid) { + return repository.createAndRegisterConflictWatcher(oid); + } + + @Override + public void unregisterConflictWatcher(ConflictWatcher watcher) { + repository.unregisterConflictWatcher(watcher); + } + + @Override + public boolean hasConflict(ConflictWatcher watcher, OperationResult result) { + return repository.hasConflict(watcher, result); + } } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java index 60d6c8f6609..6b1105ddfca 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java @@ -22,6 +22,8 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.repo.api.ConflictWatcher; +import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; @@ -50,6 +52,10 @@ import java.io.File; import java.util.*; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + /** * @author lazyman */ @@ -283,7 +289,7 @@ public void addUserWithAssignmentExtension() throws Exception { ObjectDelta delta = fileUser.diff(repoUser); AssertJUnit.assertNotNull(delta); LOGGER.info("delta\n{}", delta.debugDump(3)); - AssertJUnit.assertTrue(delta.isEmpty()); + assertTrue(delta.isEmpty()); } /** @@ -310,7 +316,7 @@ public void addGetFullAccount() throws Exception { ObjectDelta delta = fileAccount.diff(repoAccount); AssertJUnit.assertNotNull(delta); LOGGER.info("delta\n{}", new Object[]{delta.debugDump(3)}); - AssertJUnit.assertTrue(delta.isEmpty()); + assertTrue(delta.isEmpty()); ShadowType repoShadow = repoAccount.asObjectable(); AssertJUnit.assertNotNull(repoShadow.getSynchronizationSituation()); AssertJUnit.assertEquals(SynchronizationSituationType.LINKED, repoShadow.getSynchronizationSituation()); @@ -409,7 +415,7 @@ public void addGetRoleWithResourceRefFilter() throws Exception{ public void emtpyIterationToken() throws Exception { String token = testIterationToken(""); AssertJUnit.assertNotNull(token); - AssertJUnit.assertTrue(token.equals("")); + assertTrue(token.equals("")); } /** @@ -497,7 +503,7 @@ public boolean handle(PrismObject object, OperationResult parentResu }; repositoryService.searchObjectsIterative(ObjectType.class, null, handler, null, false, result); - AssertJUnit.assertTrue(!objects.isEmpty()); + assertTrue(!objects.isEmpty()); } @Test @@ -587,6 +593,144 @@ public void test110AddUserWithDuplicateAssignmentIds() throws Exception { } } + private final String OID_200 = "70016628-2c41-4a2d-9558-8340014adaab"; + + @Test + public void test200WatcherAddWithOid() throws Exception { + OperationResult result = new OperationResult("test200WatcherAddWithOid"); + + // GIVEN + UserType user = new UserType(prismContext).name("t200").oid(OID_200); + + // WHEN + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(OID_200); + repositoryService.addObject(user.asPrismObject(), null, result); + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 0, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test201WatcherOverwriteWithOidNoVersion() throws Exception { + OperationResult result = new OperationResult("test201WatcherOverwriteWithOidNoVersion"); + + // GIVEN + UserType user = new UserType(prismContext).name("t200").oid(OID_200); + + // WHEN + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(OID_200); + repositoryService.addObject(user.asPrismObject(), RepoAddOptions.createOverwrite(), result); + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 1, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test202WatcherOverwriteWithOidNoVersion2() throws Exception { + OperationResult result = new OperationResult("test202WatcherOverwriteWithOidNoVersion2"); + + // GIVEN + UserType user = new UserType(prismContext).name("t200").oid(OID_200); + + // WHEN + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(OID_200); + repositoryService.addObject(user.asPrismObject(), RepoAddOptions.createOverwrite(), result); + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 2, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test203WatcherOverwriteWithOidAndVersion() throws Exception { + OperationResult result = new OperationResult("test203WatcherOverwriteWithOidAndVersion"); + + // GIVEN + UserType user = new UserType(prismContext).name("t200").oid(OID_200).version("1000"); + + // WHEN + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(OID_200); + repositoryService.addObject(user.asPrismObject(), RepoAddOptions.createOverwrite(), result); + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 3, watcher.getExpectedVersion()); // the version is ignored when overwriting + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test210WatcherAddWithOidAndVersion() throws Exception { + OperationResult result = new OperationResult("test210WatcherAddWithOidAndVersion"); + + // GIVEN + final String OID = "f82cdad5-8748-43c1-b20b-7f679fbc1995"; + UserType user = new UserType(prismContext).name("t210").oid(OID).version("443"); + + // WHEN + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(OID); + repositoryService.addObject(user.asPrismObject(), null, result); + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 443, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test220WatcherAddWithNoOidNorVersion() throws Exception { + OperationResult result = new OperationResult("test220WatcherAddWithNoOidNorVersion"); + + // GIVEN + UserType user = new UserType(prismContext).name("t220"); + + // WHEN + String oid = repositoryService.addObject(user.asPrismObject(), null, result); + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(oid); + watcher.setExpectedVersion(user.getVersion()); // the version should be set by repo here + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 0, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + + @Test + public void test230WatcherAddWithVersion() throws Exception { + OperationResult result = new OperationResult("test230WatcherAddWithVersion"); + + // GIVEN + UserType user = new UserType(prismContext).name("t230").version("2000"); + + // WHEN + String oid = repositoryService.addObject(user.asPrismObject(), null, result); + ConflictWatcherImpl watcher = (ConflictWatcherImpl) repositoryService.createAndRegisterConflictWatcher(oid); + watcher.setExpectedVersion(user.getVersion()); // the version should be preserved here + + // THEN + assertTrue("watcher is not initialized", watcher.isInitialized()); + assertFalse("watcher is marked as deleted", watcher.isObjectDeleted()); + assertEquals("expectedVersion is wrong", 2000, watcher.getExpectedVersion()); + boolean hasConflict = repositoryService.hasConflict(watcher, result); + assertFalse("false conflict reported for " + watcher, hasConflict); + } + @Test public void test990AddResourceWithEmptyConnectorConfiguration() throws Exception { OperationResult result = new OperationResult("test990AddResourceWithEmptyConnectorConfiguration"); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java index d7eea4d4cd7..cb34250e600 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java @@ -617,7 +617,7 @@ private void checkUserProperty(PrismObject object, OperationResult result = parentResult.createSubresult(parentResult.getOperation() + "." + propName); PrismProperty prop = object.findProperty(propQName); Collection actualValues = prop.getRealValues(); - result.addArbitraryCollectionAsParam("actualValues", actualValues); + result.addArbitraryObjectCollectionAsParam("actualValues", actualValues); assertMultivalue("User, property '" + propName + "'", expectedValues, actualValues, result); result.recordSuccessIfUnknown(); } @@ -692,7 +692,7 @@ private void checkUserPropertyPolyString(PrismObject o OperationResult result = parentResult.createSubresult(parentResult.getOperation() + "." + propName); PrismProperty prop = object.findProperty(propQName); Collection actualValues = prop.getRealValues(); - result.addArbitraryCollectionAsParam("actualValues", actualValues); + result.addArbitraryObjectCollectionAsParam("actualValues", actualValues); assertMultivaluePolyString("User, property '" + propName + "'", expectedValues, actualValues, result); result.recordSuccessIfUnknown(); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ConflictWatcherImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ConflictWatcherImpl.java new file mode 100644 index 00000000000..fb3db0c022c --- /dev/null +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ConflictWatcherImpl.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.sql; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.repo.api.ConflictWatcher; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; + +/** + * @author mederly + */ +public class ConflictWatcherImpl implements ConflictWatcher { + + @NotNull private final String oid; + private boolean initialized; + private boolean hasConflict; + private int expectedVersion; + private boolean objectDeleted; // skip all future checks + + ConflictWatcherImpl(@NotNull String oid) { + this.oid = oid; + } + + void afterAddObject(@NotNull String oid, @NotNull PrismObject object) { + if (notRelevant(oid)) { + return; + } + String version = object.getVersion(); + if (version == null) { + throw new IllegalStateException("No version in object " + object); + } + expectedVersion = Integer.parseInt(version); + initialized = true; + //System.out.println(Thread.currentThread().getName() + ": afterAddObject: " + this); + } + + void afterDeleteObject(String oid) { + if (this.oid.equals(oid)) { + objectDeleted = true; + } + } + + public void beforeModifyObject(PrismObject object) { + if (notRelevant(object.getOid())) { + return; + } + checkExpectedVersion(object.getVersion()); + } + + void afterModifyObject(String oid) { + if (notRelevant(oid)) { + return; + } + expectedVersion++; + //System.out.println(Thread.currentThread().getName() + ": afterModifyObject: " + this); + } + + void afterGetVersion(String oid, String currentRepoVersion) { + if (notRelevant(oid)) { + return; + } + checkExpectedVersion(currentRepoVersion); + } + + void afterGetObject(PrismObject object) { + if (notRelevant(object.getOid())) { + return; + } + checkExpectedVersion(object.getVersion()); + } + + private boolean notRelevant(@NotNull String oid) { + return objectDeleted || hasConflict || !this.oid.equals(oid); + } + + private void checkExpectedVersion(@NotNull String currentRepoVersion) { + int current = Integer.parseInt(currentRepoVersion); + //System.out.println(Thread.currentThread().getName() + ": checkExpectedVersion: current=" + current + " in " + this); + if (initialized) { + if (current != expectedVersion) { + hasConflict = true; + } + } else { + initialized = true; + expectedVersion = current; + } + //System.out.println(Thread.currentThread().getName() + ": checkExpectedVersion finishing: current=" + current + " in " + this); + } + + @Override + @NotNull + public String getOid() { + return oid; + } + + @Override + public boolean hasConflict() { + return hasConflict; + } + + // for testing purposes + public boolean isInitialized() { + return initialized; + } + + // for testing purposes + public int getExpectedVersion() { + return expectedVersion; + } + + // for testing purposes + public boolean isObjectDeleted() { + return objectDeleted; + } + + @Override + public void setExpectedVersion(String version) { + if (initialized) { + throw new IllegalStateException("Already initialized: " + this); + } + if (StringUtils.isNotEmpty(version)) { + initialized = true; + expectedVersion = Integer.parseInt(version); + } + } + + @Override + public String toString() { + return "ConflictWatcherImpl{" + + "oid='" + oid + '\'' + + ", initialized=" + initialized + + ", expectedVersion=" + expectedVersion + + ", hasConflict=" + hasConflict + + ", objectDeleted=" + objectDeleted + + '}'; + } +} diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java index aa436738491..e7f26752fb1 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.api.RepoModifyOptions; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.repo.sql.helpers.*; import com.evolveum.midpoint.repo.sql.query2.matcher.DefaultMatcher; import com.evolveum.midpoint.repo.sql.query2.matcher.PolyStringMatcher; @@ -57,6 +58,7 @@ import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -77,10 +79,13 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.util.*; +import java.util.function.Consumer; import java.util.function.Supplier; import javax.xml.namespace.QName; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + /** * @author lazyman * @@ -94,6 +99,7 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito private static final Trace LOGGER = TraceManager.getTrace(SqlRepositoryServiceImpl.class); private static final Trace LOGGER_PERFORMANCE = TraceManager.getTrace(PERFORMANCE_LOG_NAME); + private static final int MAX_CONFLICT_WATCHERS = 10; // just a safeguard (watchers per thread should be at most 1-2) public static final int MAX_CONSTRAINT_NAME_LENGTH = 40; private static final String IMPLEMENTATION_SHORT_NAME = "SQL"; private static final String IMPLEMENTATION_DESCRIPTION = "Implementation that stores data in generic relational" + @@ -112,6 +118,8 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito @Autowired private MatchingRuleRegistry matchingRuleRegistry; @Autowired private MidpointConfiguration midpointConfiguration; + private final ThreadLocal> conflictWatchersThreadLocal = new ThreadLocal<>(); + private FullTextSearchConfigurationType fullTextSearchConfiguration; public SqlRepositoryServiceImpl(SqlRepositoryFactory repositoryFactory) { @@ -148,9 +156,11 @@ public PrismObject getObject(Class type, String oid subResult.addParam("type", type.getName()); subResult.addParam("oid", oid); - return executeAttempts(oid, "getObject", "getting", - subResult, () -> objectRetriever.getObjectAttempt(type, oid, options, subResult) - ); + PrismObject object = executeAttempts(oid, "getObject", "getting", + subResult, () -> objectRetriever.getObjectAttempt(type, oid, options, subResult) + ); + invokeConflictWatchers((w) -> w.afterGetObject(object)); + return object; } private RV executeAttempts(String oid, String operationName, String operationVerb, OperationResult subResult, @@ -387,22 +397,28 @@ public String addObject(PrismObject object, RepoAddOpt OperationResult subResult = result.createSubresult(ADD_OBJECT); subResult.addParam("object", object); - subResult.addParam("options", options); + subResult.addParam("options", options.toString()); // TODO use executeAttempts final String operation = "adding"; int attempt = 1; - String oid = object.getOid(); + String proposedOid = object.getOid(); while (true) { try { - return objectUpdater.addObjectAttempt(object, options, subResult); + String createdOid = objectUpdater.addObjectAttempt(object, options, subResult); + invokeConflictWatchers((w) -> w.afterAddObject(createdOid, object)); + return createdOid; } catch (RuntimeException ex) { - attempt = baseHelper.logOperationAttempt(oid, operation, attempt, ex, subResult); + attempt = baseHelper.logOperationAttempt(proposedOid, operation, attempt, ex, subResult); } } } + public void invokeConflictWatchers(Consumer consumer) { + emptyIfNull(conflictWatchersThreadLocal.get()).forEach(consumer); + } + private void validateName(PrismObject object) throws SchemaException { PrismProperty name = object.findProperty(ObjectType.F_NAME); if (name == null || ((PolyString) name.getRealValue()).isEmpty()) { @@ -426,6 +442,7 @@ public void deleteObject(Class type, String oid, Opera executeAttemptsNoSchemaException(oid, "deleteObject", "deleting", subResult, () -> objectUpdater.deleteObjectAttempt(type, oid, subResult) ); + invokeConflictWatchers((w) -> w.afterDeleteObject(oid)); } @Override @@ -475,7 +492,7 @@ public void modifyObject(Class type, String oid, OperationResult subResult = result.createSubresult(MODIFY_OBJECT); subResult.addParam("type", type.getName()); subResult.addParam("oid", oid); - subResult.addCollectionOfSerializablesAsParam("modifications", modifications); + subResult.addArbitraryObjectCollectionAsParam("modifications", modifications); if (modifications.isEmpty() && !RepoModifyOptions.isExecuteIfNoChanges(options)) { LOGGER.debug("Modification list is empty, nothing was modified."); @@ -518,7 +535,8 @@ public void modifyObject(Class type, String oid, try { while (true) { try { - objectUpdater.modifyObjectAttempt(type, oid, modifications, options, subResult); + objectUpdater.modifyObjectAttempt(type, oid, modifications, options, subResult, this); + invokeConflictWatchers((w) -> w.afterModifyObject(oid)); return; } catch (RuntimeException ex) { attempt = baseHelper.logOperationAttempt(oid, operation, attempt, ex, subResult); @@ -528,7 +546,6 @@ public void modifyObject(Class type, String oid, } finally { pm.registerOperationFinish(opHandle, attempt); } - } @Override @@ -719,7 +736,9 @@ public String getVersion(Class type, String oid, Opera try { while (true) { try { - return objectRetriever.getVersionAttempt(type, oid, subResult); + String rv = objectRetriever.getVersionAttempt(type, oid, subResult); + invokeConflictWatchers((w) -> w.afterGetVersion(oid, rv)); + return rv; } catch (RuntimeException ex) { attempt = baseHelper.logOperationAttempt(null, operation, attempt, ex, subResult); pm.registerOperationNewAttempt(opHandle, attempt); @@ -788,6 +807,7 @@ public SearchResultMetadata searchObjectsIterative(Class< } finally { // pm.registerOperationFinish(opHandle, attempt); } + // TODO conflict checking (if needed) } @Override @@ -904,7 +924,7 @@ public RepositoryQueryDiagResponse executeQueryDiagnostics(RepositoryQueryDiagRe int attempt = 1; OperationResult subResult = result.createMinorSubresult(EXECUTE_QUERY_DIAGNOSTICS); - subResult.addParam("query", request); + subResult.addParam("query", request.toString()); // TODO executeAttempts SqlPerformanceMonitor pm = getPerformanceMonitor(); @@ -1045,4 +1065,45 @@ public void postInit(OperationResult result) throws SchemaException { applyFullTextSearchConfiguration(systemConfiguration.getFullTextSearch()); SystemConfigurationTypeUtil.applyOperationResultHandling(systemConfiguration); } + + @Override + public ConflictWatcher createAndRegisterConflictWatcher(String oid) { + List watchers = conflictWatchersThreadLocal.get(); + if (watchers == null) { + conflictWatchersThreadLocal.set(watchers = new ArrayList<>()); + } + if (watchers.size() >= MAX_CONFLICT_WATCHERS) { + throw new IllegalStateException("Conflicts watchers leaking: reached limit of " + MAX_CONFLICT_WATCHERS + ": " + watchers); + } + ConflictWatcherImpl watcher = new ConflictWatcherImpl(oid); + watchers.add(watcher); + return watcher; + } + + @Override + public void unregisterConflictWatcher(ConflictWatcher watcher) { + ConflictWatcherImpl watcherImpl = (ConflictWatcherImpl) watcher; + List watchers = conflictWatchersThreadLocal.get(); + // change these exceptions to logged errors, eventually + if (watchers == null) { + throw new IllegalStateException("No conflict watchers registered for current thread; tried to unregister " + watcher); + } else if (!watchers.remove(watcherImpl)) { // expecting there's only one + throw new IllegalStateException("Tried to unregister conflict watcher " + watcher + " that was not registered"); + } + } + + @Override + public boolean hasConflict(ConflictWatcher watcher, OperationResult result) { + if (watcher.hasConflict()) { + return true; + } + try { + getVersion(ObjectType.class, watcher.getOid(), result); + } catch (ObjectNotFoundException e) { + // just ignore this + } catch (SchemaException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't check conflicts for {}", e, watcher.getOid()); + } + return watcher.hasConflict(); + } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java index cf1199c766d..8c3f961753f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java @@ -109,7 +109,7 @@ public PrismObject getObjectAttempt(Class type, Str } if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Get object:\n{}", new Object[]{(objectType != null ? objectType.debugDump(3) : null)}); + LOGGER.trace("Get object:\n{}", objectType != null ? objectType.debugDump(3) : null); } return objectType; @@ -219,7 +219,7 @@ public PrismObject searchShadowOwnerAttempt(String shad Session session = null; try { session = baseHelper.beginReadOnlyTransaction(); - LOGGER.trace("Selecting account shadow owner for account {}.", new Object[]{shadowOid}); + LOGGER.trace("Selecting account shadow owner for account {}.", shadowOid); Query query = session.getNamedQuery("searchShadowOwner.getOwner"); query.setString("oid", shadowOid); query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer()); @@ -270,8 +270,7 @@ public PrismObject listAccountShadowOwnerAttempt(String accountOid, Op } if (users.size() > 1) { - LOGGER.warn("Found {} users for account oid {}, returning first user. [interface change needed]", - new Object[]{users.size(), accountOid}); + LOGGER.warn("Found {} users for account oid {}, returning first user. [interface change needed]", users.size(), accountOid); } GetObjectResult user = users.get(0); @@ -358,7 +357,7 @@ public int countContainersAttempt(Class type, Objec @NotNull public SearchResultList> searchObjectsAttempt(Class type, ObjectQuery query, Collection> options, OperationResult result) throws SchemaException { - LOGGER_PERFORMANCE.debug("> search objects {}", new Object[]{type.getSimpleName()}); + LOGGER_PERFORMANCE.debug("> search objects {}", type.getSimpleName()); Session session = null; try { session = baseHelper.beginReadOnlyTransaction(); @@ -591,7 +590,7 @@ public List> listResourceObjectShadowsAtte throws ObjectNotFoundException, SchemaException { LOGGER_PERFORMANCE.debug("> list resource object shadows {}, for resource oid={}", - new Object[]{resourceObjectShadowType.getSimpleName(), resourceOid}); + resourceObjectShadowType.getSimpleName(), resourceOid); List> list = new ArrayList<>(); Session session = null; try { @@ -637,7 +636,7 @@ private void validateObjectType(PrismObject prismObjec public String getVersionAttempt(Class type, String oid, OperationResult result) throws ObjectNotFoundException, SchemaException { - LOGGER_PERFORMANCE.debug("> get version {}, oid={}", new Object[]{type.getSimpleName(), oid}); + LOGGER_PERFORMANCE.debug("> get version {}, oid={}", type.getSimpleName(), oid); String version = null; Session session = null; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index c84d2f25556..a0197e2de0a 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -78,9 +78,9 @@ public class ObjectUpdater { private static final Trace LOGGER = TraceManager.getTrace(ObjectUpdater.class); private static final Trace LOGGER_PERFORMANCE = TraceManager.getTrace(SqlRepositoryServiceImpl.PERFORMANCE_LOG_NAME); - @Autowired - @Qualifier("repositoryService") - private RepositoryService repositoryService; + @Autowired + @Qualifier("repositoryService") + private RepositoryService repositoryService; @Autowired private BaseHelper baseHelper; @@ -101,7 +101,7 @@ public class ObjectUpdater { private PrismContext prismContext; public String addObjectAttempt(PrismObject object, RepoAddOptions options, - OperationResult result) throws ObjectAlreadyExistsException, SchemaException { + OperationResult result) throws ObjectAlreadyExistsException, SchemaException { LOGGER_PERFORMANCE.debug("> add object {}, oid={}, overwrite={}", object.getCompileTimeClass().getSimpleName(), object.getOid(), options.isOverwrite()); @@ -342,7 +342,7 @@ public Object deleteObjectAttempt(Class type, String o public void modifyObjectAttempt(Class type, String oid, Collection modifications, - RepoModifyOptions modifyOptions, OperationResult result) throws ObjectNotFoundException, + RepoModifyOptions modifyOptions, OperationResult result, SqlRepositoryServiceImpl sqlRepositoryService) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, SerializationRelatedException { // clone - because some certification and lookup table related methods manipulate this collection and even their constituent deltas @@ -350,11 +350,9 @@ public void modifyObjectAttempt(Class type, String oid modifications = CloneUtil.cloneCollectionMembers(modifications); //modifications = new ArrayList<>(modifications); - LOGGER.debug("Modifying object '{}' with oid '{}'.", new Object[]{type.getSimpleName(), oid}); + LOGGER.debug("Modifying object '{}' with oid '{}'.", type.getSimpleName(), oid); LOGGER_PERFORMANCE.debug("> modify object {}, oid={}, modifications={}", type.getSimpleName(), oid, modifications); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Modifications:\n{}", DebugUtil.debugDump(modifications)); - } + LOGGER.trace("Modifications:\n{}", DebugUtil.debugDumpLazily(modifications)); Session session = null; OrgClosureManager.Context closureContext = null; @@ -391,6 +389,7 @@ public void modifyObjectAttempt(Class type, String oid // get object PrismObject prismObject = objectRetriever.getObjectInternal(session, type, oid, options, true, result); + sqlRepositoryService.invokeConflictWatchers(w -> w.beforeModifyObject(prismObject)); // apply diff LOGGER.trace("OBJECT before:\n{}", prismObject.debugDumpLazily()); PrismObject originalObject = null; diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index 21158a09843..f53a3bae8ea 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -285,7 +285,7 @@ protected PrismObject repoAddObjectFromFile(File file, OperationResult result = parentResult.createSubresult(AbstractIntegrationTest.class.getName() + ".repoAddObjectFromFile"); - result.addParam("file", file); + result.addParam("file", file.getPath()); LOGGER.debug("addObjectFromFile: {}", file); PrismObject object = prismContext.parseObject(file); @@ -304,7 +304,7 @@ protected PrismObject repoAddShadowFromFile(File file, OperationResu OperationResult result = parentResult.createSubresult(AbstractIntegrationTest.class.getName() + ".repoAddShadowFromFile"); - result.addParam("file", file); + result.addParam("file", file.getPath()); LOGGER.debug("addShadowFromFile: {}", file); PrismObject object = prismContext.parseObject(file); @@ -378,7 +378,7 @@ protected List> repoAddObjectsFromFile(Fil OperationResult parentResult) throws SchemaException, ObjectAlreadyExistsException, IOException { OperationResult result = parentResult.createSubresult(AbstractIntegrationTest.class.getName() + ".addObjectsFromFile"); - result.addParam("file", file); + result.addParam("file", file.getPath()); LOGGER.trace("addObjectsFromFile: {}", file); List> objects = (List) PrismTestUtil.parseObjects(file); for (PrismObject object: objects) { @@ -400,7 +400,7 @@ protected List> repoAddObjectsFromFile(Fil protected List repoAddObjectsFromFile(File file, OperationResult parentResult) throws SchemaException, ObjectAlreadyExistsException, IOException { OperationResult result = parentResult.createSubresult(AbstractIntegrationTest.class.getName() + ".addObjectsFromFile"); - result.addParam("file", file); + result.addParam("file", file.getPath()); LOGGER.trace("addObjectsFromFile: {}", file); List objects = (List) PrismTestUtil.parseObjects(file); for (PrismObject object: objects) { @@ -541,7 +541,34 @@ protected void assumeAssignmentPolicy(AssignmentPolicyEnforcementType policy) th syncSettings.setAssignmentPolicyEnforcement(policy); applySyncSettings(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), SchemaConstants.C_SYSTEM_CONFIGURATION_GLOBAL_ACCOUNT_SYNCHRONIZATION_SETTINGS, syncSettings); } - + + // very limited approach -- assumes that we set conflict resolution on a global level only + protected void assumeConflictResolutionAction(ConflictResolutionActionType action) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + SystemConfigurationType systemConfiguration = getSystemConfiguration(); + List current = new ArrayList<>(); + for (ObjectPolicyConfigurationType c : systemConfiguration.getDefaultObjectPolicyConfiguration()) { + if (c.getType() == null && c.getSubtype() == null && c.getConflictResolution() != null) { + current.add(c); + } + } + if (current.size() == 1 && current.get(0).getConflictResolution().getAction() == action) { + return; + } + + ObjectPolicyConfigurationType newPolicy = new ObjectPolicyConfigurationType(prismContext).beginConflictResolution().action(action).end(); + List> itemDeltas = DeltaBuilder.deltaFor(SystemConfigurationType.class, prismContext) + .item(SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION) + .add(newPolicy) + .deleteRealValues(current) + .asItemDeltas(); + OperationResult result = new OperationResult("assumeConflictResolutionAction"); + repositoryService.modifyObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), itemDeltas, result); + invalidateSystemObjectsCache(); + display("Applying conflict resolution action result", result); + result.computeStatus(); + TestUtil.assertSuccess("Applying conflict resolution action failed (result)", result); + } + protected void assumeResourceAssigmentPolicy(String resourceOid, AssignmentPolicyEnforcementType policy, boolean legalize) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException{ ProjectionPolicyType syncSettings = new ProjectionPolicyType(); syncSettings.setAssignmentPolicyEnforcement(policy); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java index 389046b767c..02b5568ea0c 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java @@ -350,7 +350,7 @@ public boolean suspendTasks(Collection taskOids, long waitForStop, Opera public boolean suspendTasksResolved(Collection tasks, long waitForStop, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "suspendTasks"); - result.addArbitraryCollectionAsParam("tasks", tasks); + result.addArbitraryObjectCollectionAsParam("tasks", tasks); result.addParam("waitForStop", waitingInfo(waitForStop)); LOGGER.info("Suspending tasks {}; {}.", tasks, waitingInfo(waitForStop)); @@ -698,7 +698,7 @@ public void modifyTask(String oid, Collection modifications public void suspendAndDeleteTasks(Collection taskOids, long suspendTimeout, boolean alsoSubtasks, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "suspendAndDeleteTasks"); - result.addCollectionOfSerializablesAsParam("taskOids", taskOids); + result.addArbitraryObjectCollectionAsParam("taskOids", taskOids); List tasksToBeDeleted = new ArrayList(); for (String oid : taskOids) { @@ -911,7 +911,7 @@ public PrismObject getObject(Class type, OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + ".getObject"); result.addParam("objectType", type); result.addParam("oid", oid); - result.addCollectionOfSerializablesAsParam("options", options); + result.addArbitraryObjectCollectionAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskManagerQuartzImpl.class); try { @@ -1057,7 +1057,7 @@ public SearchResultList> searchObjects(Cla OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + ".searchObjects"); result.addParam("objectType", type); result.addParam("query", query); - result.addCollectionOfSerializablesAsParam("options", options); + result.addArbitraryObjectCollectionAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskManagerQuartzImpl.class); if (TaskType.class.isAssignableFrom(type)) { @@ -1076,7 +1076,7 @@ public SearchResultMetadata searchObjectsIterative(Class< OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + ".searchObjects"); result.addParam("objectType", type); result.addParam("query", query); - result.addCollectionOfSerializablesAsParam("options", options); + result.addArbitraryObjectCollectionAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskManagerQuartzImpl.class); SearchResultList> objects; @@ -1629,7 +1629,7 @@ public void scheduleRunnableTaskNow(Task task, OperationResult parentResult) { @Override public void scheduleTasksNow(Collection taskOids, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "scheduleTasksNow"); - result.addCollectionOfSerializablesAsParam("taskOids", taskOids); + result.addArbitraryObjectCollectionAsParam("taskOids", taskOids); for (String oid : taskOids) { try { scheduleTaskNow(getTask(oid, result), result); 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 b825b00c70f..9c3925c881a 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 @@ -254,7 +254,11 @@ private void createOrUpdateTaskResult(String operationName) { } taskPrism.asObjectable().setResult(resultInPrism); } - taskResult = OperationResult.createOperationResult(resultInPrism); + try { + taskResult = OperationResult.createOperationResult(resultInPrism); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } } //endregion diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/ExecutionManager.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/ExecutionManager.java index bbb64acb04f..742f475f1dd 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/ExecutionManager.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/ExecutionManager.java @@ -90,7 +90,7 @@ public void stopScheduler(String nodeIdentifier, OperationResult parentResult) { public boolean stopSchedulersAndTasks(Collection nodeIdentifiers, long timeToWait, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(this.getClass().getName() + ".stopSchedulersAndTasks"); - result.addCollectionOfSerializablesAsParam("nodeList", nodeIdentifiers); + result.addArbitraryObjectCollectionAsParam("nodeList", nodeIdentifiers); result.addParam("timeToWait", timeToWait); LOGGER.info("Stopping schedulers and tasks on nodes: {}, waiting {} ms for task(s) shutdown.", nodeIdentifiers, timeToWait); @@ -239,7 +239,7 @@ public boolean stopAllTasksOnThisNodeAndWait(long timeToWait, OperationResult pa public boolean stopTasksRunAndWait(Collection tasks, ClusterStatusInformation csi, long waitTime, boolean clusterwide, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(DOT_CLASS + "stopTasksRunAndWait"); - result.addArbitraryCollectionAsParam("tasks", tasks); + result.addArbitraryObjectCollectionAsParam("tasks", tasks); result.addParam("waitTime", waitTime); result.addParam("clusterwide", clusterwide); @@ -275,7 +275,7 @@ public boolean stopTasksRunAndWait(Collection tasks, ClusterStatusInformat private boolean waitForTaskRunCompletion(Collection tasks, long maxWaitTime, boolean clusterwide, OperationResult parentResult) { OperationResult result = parentResult.createSubresult(ExecutionManager.class.getName() + ".waitForTaskRunCompletion"); - result.addArbitraryCollectionAsParam("tasks", tasks); + result.addArbitraryObjectCollectionAsParam("tasks", tasks); result.addParam("maxWaitTime", maxWaitTime); result.addParam("clusterwide", clusterwide); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/RemoteNodesManager.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/RemoteNodesManager.java index 93004da590d..6c1a50fdeb4 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/RemoteNodesManager.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/RemoteNodesManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -338,7 +338,7 @@ void stopRemoteTaskRun(String oid, NodeType node, OperationResult parentResult) OperationResult result = parentResult.createSubresult(RemoteNodesManager.class.getName() + ".stopRemoteTaskRun"); result.addParam("oid", oid); - result.addParam("node", node); + result.addParam("node", node.toString()); LOGGER.debug("Interrupting task " + oid + " running at " + getClusterManager().dumpNodeInfo(node)); diff --git a/samples/samples-test/src/test/java/com/evolveum/midpoint/samples/test/TestSampleImport.java b/samples/samples-test/src/test/java/com/evolveum/midpoint/samples/test/TestSampleImport.java index 665f317681a..74e57f44e8f 100644 --- a/samples/samples-test/src/test/java/com/evolveum/midpoint/samples/test/TestSampleImport.java +++ b/samples/samples-test/src/test/java/com/evolveum/midpoint/samples/test/TestSampleImport.java @@ -110,7 +110,7 @@ public void importSample(File sampleFile, Class type, // GIVEN Task task = taskManager.createTaskInstance(); OperationResult result = new OperationResult(TestSampleImport.class.getName() + ".importSample"); - result.addParam("file", sampleFile); + result.addParam("file", sampleFile.getPath()); FileInputStream stream = new FileInputStream(sampleFile); // WHEN