From 9ecaa09d2509cf35760d1025be28f5bef314f91c Mon Sep 17 00:00:00 2001 From: lskublik Date: Mon, 19 Apr 2021 12:21:19 +0200 Subject: [PATCH 01/15] adding support for parameters and subreports parameter, and refactoring of code --- .../web/page/admin/reports/PageReports.java | 2 +- .../component/RunReportPopupPanel.java | 75 +++---- .../reports/dto/AuditEventRecordProvider.java | 19 +- .../xml/ns/public/common/common-core-3.xsd | 60 ++++++ .../model/api/ModelInteractionService.java | 14 +- .../CompiledObjectCollectionView.java | 8 +- .../api/interaction/DashboardService.java | 9 - .../model/common/util/DefaultColumnUtils.java | 2 +- .../impl/controller/CollectionProcessor.java | 6 +- .../impl/controller/DashboardServiceImpl.java | 132 ++++-------- .../ModelInteractionServiceImpl.java | 72 +++++++ .../midpoint/report/api/ReportService.java | 16 +- .../report/impl/ReportServiceImpl.java | 34 ++- .../controller/fileformat/CsvController.java | 134 ++---------- .../fileformat/FileFormatController.java | 92 ++++++-- .../controller/fileformat/HtmlController.java | 201 ++---------------- .../midpoint/report/BasicNewReportTest.java | 60 +++++- .../midpoint/report/TestCsvReport.java | 26 +++ ...eport-object-collection-with-condition.xml | 7 +- .../report-object-collection-with-param.xml | 54 +++++ ...object-collection-with-subreport-param.xml | 68 ++++++ 21 files changed, 607 insertions(+), 484 deletions(-) create mode 100644 model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml create mode 100644 model/report-impl/src/test/resources/reports/report-object-collection-with-subreport-param.xml diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java index af84fb5b7c5..c9b300976fd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java @@ -290,7 +290,7 @@ private void runConfirmPerformed(AjaxRequestTarget target, ReportType reportType protected void runReportPerformed(AjaxRequestTarget target, ReportType report) { - if(report.getJasper() == null) { + if(report.getJasper() != null) { runConfirmPerformed(target, report, null); return; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java index fd38330a776..8ecfb92d594 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java @@ -14,6 +14,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.gui.api.prism.wrapper.PrismObjectWrapper; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.web.component.form.MidpointForm; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -101,9 +102,11 @@ public class RunReportPopupPanel extends BasePanel implements Popupab private static final String ID_PARAMETERS = "paramTable"; private IModel reportModel; + private final ReportType reportType; public RunReportPopupPanel(String id, final ReportType reportType) { super(id); + this.reportType = reportType; reportModel = new LoadableModel(false) { @@ -124,12 +127,12 @@ protected void initLayout() { add(mainForm); - ListView paramListView = new ListView(ID_PARAMETERS, new PropertyModel<>(reportModel, "jasperReportDto.parameters")) { + ListView paramListView = new ListView(ID_PARAMETERS, new PropertyModel<>(reportType, "objectCollection.parameter")) { private static final long serialVersionUID = 1L; @Override - protected void populateItem(ListItem paramItem) { + protected void populateItem(ListItem paramItem) { paramItem.add(createParameterPanel(paramItem.getModel())); } @@ -169,41 +172,41 @@ protected void onSubmit(AjaxRequestTarget target) { } - private WebMarkupContainer createParameterPanel(final IModel parameterModel) { + private WebMarkupContainer createParameterPanel(final IModel parameterModel) { WebMarkupContainer paramPanel = new WebMarkupContainer("paramPanel"); - paramPanel.setOutputMarkupId(true); - String paramValue = new PropertyModel(parameterModel, "name").getObject(); - StringResourceModel paramDisplay = PageBase.createStringResourceStatic(RunReportPopupPanel.this, "runReportPopupContent.param.name." + paramValue); - - paramPanel.add(new Label("name", paramDisplay)); // use display name rather than property name - - WebMarkupContainer required = new WebMarkupContainer("required"); - JasperReportParameterPropertiesDto properties = parameterModel.getObject().getProperties(); - boolean mandatory = (properties != null && properties.getMandatory()); - required.add(new VisibleBehaviour(() -> mandatory)); - paramPanel.add(required); - - String paramClass = new PropertyModel(parameterModel, "nestedTypeAsString").getObject(); - if (StringUtils.isBlank(paramClass)) { - paramClass = new PropertyModel(parameterModel, "typeAsString").getObject(); - } - paramClass = paramClass == null ? "" : paramClass.substring(paramClass.lastIndexOf(".") + 1); - paramPanel.add(new Label("type", paramClass)); - - ListView listView = new ListView(ID_VALUE_LIST, new PropertyModel<>(parameterModel, "value")) { - - private static final long serialVersionUID = 1L; - - @Override - protected void populateItem(ListItem item) { - item.add(createInputMarkup(item.getModel(), parameterModel.getObject(), mandatory, paramDisplay)); - - } - - }; - listView.setOutputMarkupId(true); - - paramPanel.add(listView); +// paramPanel.setOutputMarkupId(true); +// String paramValue = new PropertyModel(parameterModel, "name").getObject(); +// StringResourceModel paramDisplay = PageBase.createStringResourceStatic(RunReportPopupPanel.this, "runReportPopupContent.param.name." + paramValue); +// +// paramPanel.add(new Label("name", paramDisplay)); // use display name rather than property name +// +// WebMarkupContainer required = new WebMarkupContainer("required"); +// JasperReportParameterPropertiesDto properties = parameterModel.getObject().getProperties(); +// boolean mandatory = (properties != null && properties.getMandatory()); +// required.add(new VisibleBehaviour(() -> mandatory)); +// paramPanel.add(required); +// +// String paramClass = new PropertyModel(parameterModel, "nestedTypeAsString").getObject(); +// if (StringUtils.isBlank(paramClass)) { +// paramClass = new PropertyModel(parameterModel, "typeAsString").getObject(); +// } +// paramClass = paramClass == null ? "" : paramClass.substring(paramClass.lastIndexOf(".") + 1); +// paramPanel.add(new Label("type", paramClass)); +// +// ListView listView = new ListView(ID_VALUE_LIST, new PropertyModel<>(parameterModel, "value")) { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void populateItem(ListItem item) { +// item.add(createInputMarkup(item.getModel(), parameterModel.getObject(), mandatory, paramDisplay)); +// +// } +// +// }; +// listView.setOutputMarkupId(true); +// +// paramPanel.add(listView); return paramPanel; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java index 56360711d1a..7f9f5ba96f3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java @@ -7,11 +7,14 @@ package com.evolveum.midpoint.web.page.admin.reports.dto; import java.util.*; +import java.util.function.Predicate; import javax.xml.namespace.QName; import com.evolveum.midpoint.audit.api.AuditResultHandler; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.xml.ns._public.common.common_3.CollectionRefSpecificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; @@ -216,19 +219,9 @@ private List listRecords(long first, long count, Task task if (collection != null && (collection.getFilter() != null || collectionRef.getFilter() != null)) { try { ObjectPaging paging = getPrismContext().queryFactory().createPaging(WebComponentUtil.safeLongToInteger(first), WebComponentUtil.safeLongToInteger(count)); - AuditResultHandler handler = new AuditResultHandler() { - @Override - public boolean handle(AuditEventRecordType auditRecord) { - auditRecordList.add(auditRecord); - return true; - } - - @Override - public int getProgress() { - return 0; - } - }; - getPageBase().getDashboardService().searchObjectFromCollection(collectionRef, handler, paging, task, task.getResult(), false); + Predicate handler = (audit) -> auditRecordList.add((AuditEventRecordType) audit.getRealValue()); + getPageBase().getModelInteractionService().searchObjectFromCollection(collectionRef, AuditEventRecordType.COMPLEX_TYPE, handler, + null, paging, null, task, task.getResult(), false); } catch (Exception e) { result.recordFatalError( getPageBase().createStringResource("AuditEventRecordProvider.message.listRecords.fatalError", e.getMessage()).getString(), e); 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 489c20ce081..26953677293 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -25594,6 +25594,54 @@ + + + + Parameter used in filter expression. + + + 4.4 + ObjectCollectionReportEngineConfigurationType.parameter + + + + + + + Subreport with expression. + + + 4.4 + ObjectCollectionReportEngineConfigurationType.subreport + + + + + + + + + + + + Subreport with expression. + + + true + 4.4 + + + + + + + + + Order in which this entry is to be evaluated. (Related to other entries.) Smaller numbers + go first. Entries with no order go last. + + + @@ -26976,6 +27024,18 @@ + + + + Define targetType when used type is ObjectReferenceType. + + + 4.4 + true + SearchFilterParameterType.targetType + + + diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java index 1c77f470aed..b6c6033d413 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java @@ -15,15 +15,15 @@ import com.evolveum.midpoint.model.api.util.MergeDeltas; import com.evolveum.midpoint.model.api.validator.StringLimitationResult; import com.evolveum.midpoint.model.api.visualizer.Scene; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; @@ -49,6 +49,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Predicate; /** * A service provided by the IDM Model that allows to improve the (user) interaction with the model. @@ -496,4 +497,9 @@ CompiledObjectCollectionView compileObjectCollectionView(@NotNull CollectionRefS @Experimental List validateValue(ProtectedStringType protectedStringValue, ValuePolicyType pp, PrismObject object, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException; + + @Experimental + void searchObjectFromCollection(CollectionRefSpecificationType collection, QName typeForFilter, Predicate handler, + Collection> options, ObjectPaging paging, VariablesMap variables, Task task, OperationResult result, boolean recordProgress) throws SchemaException, + ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/authentication/CompiledObjectCollectionView.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/authentication/CompiledObjectCollectionView.java index 82cba4e16ce..d1e6e556a35 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/authentication/CompiledObjectCollectionView.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/authentication/CompiledObjectCollectionView.java @@ -13,6 +13,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -76,11 +78,11 @@ public void setContainerType(QName containerType) { this.containerType = containerType; } - public Class getTargetClass() { + public Class getTargetClass(PrismContext prismContext) { if (containerType == null) { return null; } - return ObjectTypes.getObjectTypeClass(containerType); + return prismContext.getSchemaRegistry().determineClassForType(containerType); } public String getViewIdentifier() { @@ -243,7 +245,7 @@ public void setObjectCollectionDescription(String objectCollectionDescription) { @Override public String debugDump(int indent) { StringBuilder sb = DebugUtil.createTitleStringBuilderLn(CompiledObjectCollectionView.class, indent); - DebugUtil.debugDumpWithLabelLn(sb, "objectType", containerType, indent + 1); + DebugUtil.debugDumpWithLabelLn(sb, "containerType", containerType, indent + 1); DebugUtil.debugDumpWithLabelLn(sb, "viewIdentifier", viewIdentifier, indent + 1); DebugUtil.debugDumpWithLabelLn(sb, "actions", actions, indent + 1); DebugUtil.debugDumpWithLabelLn(sb, "columns", columns, indent + 1); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/interaction/DashboardService.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/interaction/DashboardService.java index d479786b2bf..9f98c9dddec 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/interaction/DashboardService.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/interaction/DashboardService.java @@ -38,15 +38,6 @@ DashboardWidget createWidgetData(DashboardWidgetType widget, Task task, Operatio throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, ObjectNotFoundException; - void searchObjectFromCollection(CollectionRefSpecificationType collection, QName typeForFilter, ResultHandler handler, - Collection> options, Task task, OperationResult result, boolean recordProgress) throws SchemaException, - ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException; - - void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, AuditResultHandler handler, - ObjectPaging paging, Task task, OperationResult result, boolean recordProgress) - throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, - ExpressionEvaluationException; - ObjectCollectionType getObjectCollectionType(DashboardWidgetType widget, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java index b8b55b17ecd..d84d95624cb 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java @@ -290,7 +290,7 @@ public static boolean isSpecialColumn(ItemPath itemPath, PrismContainer> createOption( - Class type, SchemaService schemaService) { + Class type, SchemaService schemaService) { if (type == null) { return null; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/CollectionProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/CollectionProcessor.java index 4e9922a659c..6f5ff95918a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/CollectionProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/CollectionProcessor.java @@ -204,7 +204,7 @@ private boolean isThresholdTriggered(CollectionStats stats, PrismObject CollectionStats determineCollectionStats(CompiledObjectCollectionView collectionView, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, ConfigurationException, CommunicationException, ExpressionEvaluationException { CollectionStats stats = new CollectionStats(); - Class targetClass = collectionView.getTargetClass(); + Class targetClass = collectionView.getTargetClass(prismContext); stats.setObjectCount(countObjects(targetClass, evaluateExpressionsInFilter(collectionView.getFilter(), result, task), collectionView.getOptions(), task, result)); stats.setDomainCount(countObjects(targetClass, evaluateExpressionsInFilter(collectionView.getDomainFilter(), result, task), collectionView.getDomainOptions(), task, result)); return stats; @@ -409,7 +409,7 @@ private void compileBaseCollectionSpec(SearchFilterType filter, CompiledObjectCo return; } compileObjectCollectionView(existingView, baseCollectionRef, targetTypeClass, task, result); - targetTypeClass = existingView.getTargetClass(); + targetTypeClass = existingView.getTargetClass(prismContext); if (targetTypeClass == null) { throw new IllegalArgumentException("UndefinedTypeForCollection type: " + baseCollectionRef); } @@ -447,7 +447,7 @@ private void compileView(CompiledObjectCollectionView existingView, GuiObjectLis } @Nullable - public ObjectFilter evaluateExpressionsInFilter(ObjectFilter filterRaw, OperationResult result, Task task) + private ObjectFilter evaluateExpressionsInFilter(ObjectFilter filterRaw, OperationResult result, Task task) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { VariablesMap variables = new VariablesMap(); // do we want to put any variables here? diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java index f54d43fbc2d..de0786664de 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java @@ -490,98 +490,46 @@ private void evaluateVariation(DashboardWidgetType widget, VariablesMap variable } } - @Override - public void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, QName typeForFilter, ResultHandler handler, - Collection> defaultOptions, Task task, OperationResult result, boolean recordProgress) - throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { - Class type = null; - - if (collectionConfig.getCollectionRef() != null && collectionConfig.getFilter() != null) { - LOGGER.error("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); - throw new IllegalArgumentException("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); - } - if (typeForFilter != null) { - type = prismContext.getSchemaRegistry().determineClassForType(typeForFilter); - } - CompiledObjectCollectionView compiledCollection = modelInteractionService.compileObjectCollectionView( - collectionConfig, type, task, task.getResult()); - - VariablesMap variables = new VariablesMap(); - ObjectFilter filter = ExpressionUtil.evaluateFilterExpressions(compiledCollection.getFilter(), variables, MiscSchemaUtil.getExpressionProfile(), - expressionFactory, prismContext, "collection filter", task, result); - if (filter == null) { - LOGGER.error("Couldn't find filter"); - throw new ConfigurationException("Couldn't find filter"); - } - - filter = collectionProcessor.evaluateExpressionsInFilter(filter, result, task); - ObjectQuery query = prismContext.queryFactory().createQuery(); - query.setFilter(filter); - - if (compiledCollection.getTargetClass() == null) { - if (typeForFilter == null) { - LOGGER.error("Type of objects is null"); - throw new ConfigurationException("Type of objects is null"); - } - type = prismContext.getSchemaRegistry().determineClassForType(typeForFilter); - } else { - type = compiledCollection.getTargetClass(); - } - - Collection> options; - if (compiledCollection.getOptions() == null) { - options = defaultOptions; - } else { - options = compiledCollection.getOptions(); - } - if (recordProgress) { - long count = modelService.countObjects(type, query, options, task, result); - task.setExpectedTotal(count); - } - modelService.searchObjectsIterative(type, query, handler, options, task, result); - } - - @Override - public void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, AuditResultHandler handler, - ObjectPaging paging, Task task, OperationResult result, boolean recordProgress) - throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { - - if (collectionConfig.getCollectionRef() != null && collectionConfig.getFilter() != null) { - LOGGER.error("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); - throw new IllegalArgumentException("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); - } - CompiledObjectCollectionView compiledCollection = modelInteractionService.compileObjectCollectionView( - collectionConfig, AuditEventRecordType.class, task, task.getResult()); - - VariablesMap variables = new VariablesMap(); - ObjectFilter filter = ExpressionUtil.evaluateFilterExpressions(compiledCollection.getFilter(), variables, MiscSchemaUtil.getExpressionProfile(), - expressionFactory, prismContext, "collection filter", task, result); - if (filter == null) { - LOGGER.error("Couldn't find filter"); - throw new ConfigurationException("Couldn't find filter"); - } - - filter = collectionProcessor.evaluateExpressionsInFilter(filter, result, task); - ObjectQuery query = prismContext.queryFactory().createQuery(); - query.setFilter(filter); - query.setPaging(paging); - ObjectCollectionType collection = null; - if (collectionConfig.getCollectionRef() != null) { - ObjectReferenceType ref = collectionConfig.getCollectionRef(); - Class refType = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); - collection = (ObjectCollectionType) modelService - .getObject(refType, ref.getOid(), null, task, result).asObjectable(); - } - @NotNull Collection> options = combineAuditOption(collectionConfig, collection, task, result); - if (recordProgress) { - long count = auditService.countObjects(query, options, result); - task.setExpectedTotal(count); - } - @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); - auditRecords.forEach(audit -> { - handler.handle(audit); - }); - } +// @Override +// public void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, AuditResultHandler handler, +// ObjectPaging paging, Task task, OperationResult result, boolean recordProgress) +// throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { +// +// if (collectionConfig.getCollectionRef() != null && collectionConfig.getFilter() != null) { +// LOGGER.error("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); +// throw new IllegalArgumentException("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); +// } +// CompiledObjectCollectionView compiledCollection = modelInteractionService.compileObjectCollectionView( +// collectionConfig, AuditEventRecordType.class, task, task.getResult()); +// +// VariablesMap variables = new VariablesMap(); +// ObjectFilter filter = ExpressionUtil.evaluateFilterExpressions(compiledCollection.getFilter(), variables, MiscSchemaUtil.getExpressionProfile(), +// expressionFactory, prismContext, "collection filter", task, result); +// if (filter == null) { +// LOGGER.error("Couldn't find filter"); +// throw new ConfigurationException("Couldn't find filter"); +// } +// +// ObjectQuery query = prismContext.queryFactory().createQuery(); +// query.setFilter(filter); +// query.setPaging(paging); +// ObjectCollectionType collection = null; +// if (collectionConfig.getCollectionRef() != null) { +// ObjectReferenceType ref = collectionConfig.getCollectionRef(); +// Class refType = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); +// collection = (ObjectCollectionType) modelService +// .getObject(refType, ref.getOid(), null, task, result).asObjectable(); +// } +// @NotNull Collection> options = combineAuditOption(collectionConfig, collection, task, result); +// if (recordProgress) { +// long count = auditService.countObjects(query, options, result); +// task.setExpectedTotal(count); +// } +// @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); +// auditRecords.forEach(audit -> { +// handler.handle(audit); +// }); +// } @Override public ObjectCollectionType getObjectCollectionType(DashboardWidgetType widget, Task task, OperationResult result) 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 3cd6d5a087c..e44ff85d73b 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 @@ -16,9 +16,15 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskSchedulingStateType.READY; import java.util.*; +import java.util.function.Predicate; import java.util.stream.Collectors; import javax.xml.namespace.QName; +import com.evolveum.midpoint.audit.api.AuditService; +import com.evolveum.midpoint.prism.query.ObjectPaging; +import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; + import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang3.StringUtils; @@ -150,6 +156,7 @@ public class ModelInteractionServiceImpl implements ModelInteractionService { @Autowired private CacheConfigurationManager cacheConfigurationManager; @Autowired private ClusterwideUserSessionManager clusterwideUserSessionManager; @Autowired private ContextLoader contextLoader; + @Autowired private AuditService auditService; private static final String OPERATION_GENERATE_VALUE = ModelInteractionService.class.getName() + ".generateValue"; private static final String OPERATION_VALIDATE_VALUE = ModelInteractionService.class.getName() + ".validateValue"; @@ -1936,4 +1943,69 @@ public List validateValue(Protect return policyProcessor.validateValue(getClearValue(protectedStringValue), pp, createOriginResolver(object, parentResult), "validate string", task, parentResult); } + @Override + public void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, QName typeForFilter, Predicate handler, + Collection> defaultOptions, ObjectPaging paging, VariablesMap variables, Task task, OperationResult result, boolean recordProgress) + throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + Class type = null; + + if (collectionConfig.getCollectionRef() != null && collectionConfig.getFilter() != null) { + LOGGER.error("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); + throw new IllegalArgumentException("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); + } + if (typeForFilter != null) { + type = prismContext.getSchemaRegistry().determineClassForType(typeForFilter); + } + CompiledObjectCollectionView compiledCollection = compileObjectCollectionView(collectionConfig, type, task, task.getResult()); + + ObjectFilter filter = ExpressionUtil.evaluateFilterExpressions(compiledCollection.getFilter(), variables, MiscSchemaUtil.getExpressionProfile(), + expressionFactory, prismContext, "collection filter", task, result); + if (filter == null) { + LOGGER.error("Couldn't find filter"); + throw new ConfigurationException("Couldn't find filter"); + } + + ObjectQuery query = prismContext.queryFactory().createQuery(); + query.setPaging(paging); + query.setFilter(filter); + + if (compiledCollection.getTargetClass(prismContext) == null) { + if (typeForFilter == null) { + LOGGER.error("Type of objects is null"); + throw new ConfigurationException("Type of objects is null"); + } + type = prismContext.getSchemaRegistry().determineClassForType(typeForFilter); + } else { + type = compiledCollection.getTargetClass(prismContext); + } + + Collection> options; + if (compiledCollection.getOptions() == null) { + options = defaultOptions; + } else { + options = compiledCollection.getOptions(); + } + if (recordProgress) { + long count; + if (AuditEventRecordType.class.equals(type)) { + count = auditService.countObjects(query, options, result); + } else { + count = modelService.countObjects((Class) type, query, options, task, result); + } + task.setExpectedTotal(count); + } + if (AuditEventRecordType.class.equals(type)) { + @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); + for (AuditEventRecordType auditRecord : auditRecords){ + PrismContainerValue prismValue = auditRecord.asPrismContainerValue(); + prismValue.setPrismContext(prismContext); + PrismContainer container = prismValue.asSingleValuedContainer(AuditEventRecordType.COMPLEX_TYPE); + handler.test(container); + } + } else { + ResultHandler resultHandler = (value, operationResult) -> handler.test((PrismContainer)value); + modelService.searchObjectsIterative((Class) type, query, resultHandler, options, task, result); + } + } + } diff --git a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportService.java b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportService.java index 69d47ff6d4a..76e6656bded 100644 --- a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportService.java +++ b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportService.java @@ -7,27 +7,31 @@ package com.evolveum.midpoint.report.api; import java.util.Collection; +import java.util.function.Predicate; import com.evolveum.midpoint.audit.api.AuditEventRecord; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.annotation.Experimental; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.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.CollectionRefSpecificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; +import javax.xml.namespace.QName; + public interface ReportService { String PARAMETER_REPORT_SERVICE = "reportService"; @@ -60,4 +64,8 @@ boolean isAuthorizedToRunReport(PrismObject report, Task task, Opera boolean isAuthorizedToImportReport(PrismObject report, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException; + + @Experimental + VariablesMap getParameters(Task task); + } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java index 7688a83cbea..14086c73657 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java @@ -8,16 +8,26 @@ import java.util.*; import java.util.Map.Entry; +import java.util.function.Predicate; import javax.xml.namespace.QName; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.LocalizationService; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.ScriptingService; +import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; import com.evolveum.midpoint.model.api.interaction.DashboardService; +import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.repo.common.commandline.CommandLineScriptExecutor; +import com.evolveum.midpoint.report.api.ReportConstants; +import com.evolveum.midpoint.schema.*; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; + +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; + import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -44,9 +54,6 @@ import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.report.api.ReportService; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SchemaService; -import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.expression.*; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; @@ -469,6 +476,27 @@ public boolean isAuthorizedToImportReport(PrismObject report, Task t return securityEnforcer.isAuthorized(ModelAuthorizationAction.IMPORT_REPORT.getUrl(), null, params, null, task, result); } + public VariablesMap getParameters(Task task) { + VariablesMap variables = new VariablesMap(); + PrismContainer reportParams = (PrismContainer) task.getExtensionItemOrClone(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + if (reportParams != null) { + PrismContainerValue reportParamsValues = reportParams.getValue(); + Collection> items = reportParamsValues.getItems(); + for (Item item : items) { + PrismProperty pp = (PrismProperty) item; + String paramName = pp.getPath().lastName().getLocalPart(); + Object value; + if (item.isSingleValue()) { + value = pp.getRealValues().iterator().next(); + } else { + value = pp.getRealValues(); + } + variables.put(paramName, new TypedValue(value, ((PrismProperty) item).getValueClass())); + } + } + return variables; + } + public Clock getClock() { return clock; } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java index 9a12bc35135..6d326220885 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java @@ -44,6 +44,7 @@ import java.nio.file.Paths; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; /** * @author skublik @@ -133,16 +134,8 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin CompiledObjectCollectionView compiledCollection = createCompiledView(collectionConfig, collection); - byte[] csvFile; - if (!isAuditCollection(collectionRefSpecification, task, result)) { - csvFile = createTableBoxForObjectView(collectionRefSpecification, compiledCollection, - collectionConfig.getCondition(), task, result); - } else { - csvFile = createTableForAuditView(collectionRefSpecification, compiledCollection, collectionConfig.getCondition(), task, result); - } - - - return csvFile; + return createTableBox(collectionRefSpecification, compiledCollection, + collectionConfig.getCondition(), collectionConfig.getSubreport(), task, result); } private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEngineConfigurationType collectionConfig, boolean useDefaultView, Task task, OperationResult result) @@ -162,7 +155,7 @@ private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEn CompiledObjectCollectionView compiledCollection = createCompiledView(collectionConfig, collection); if (compiledCollection.getColumns().isEmpty()) { if (useDefaultView) { - Class type = resolveType(collectionRefSpecification, compiledCollection); + Class type = resolveType(collectionRefSpecification, compiledCollection); getReportService().getModelInteractionService().applyView(compiledCollection, DefaultColumnUtils.getDefaultView(type)); } else { return null; @@ -171,7 +164,7 @@ private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEn return compiledCollection; } - private CompiledObjectCollectionView createCompiledView (ObjectCollectionReportEngineConfigurationType collectionConfig, ObjectCollectionType collection){ + private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEngineConfigurationType collectionConfig, ObjectCollectionType collection) { CollectionRefSpecificationType collectionRefSpecification = collectionConfig.getCollection(); CompiledObjectCollectionView compiledCollection = new CompiledObjectCollectionView(); if (!Boolean.TRUE.equals(collectionConfig.isUseOnlyReportView())) { @@ -191,103 +184,13 @@ private CompiledObjectCollectionView createCompiledView (ObjectCollectionReportE return compiledCollection; } - private byte[] createTableForAuditView(CollectionRefSpecificationType collectionRef, CompiledObjectCollectionView compiledCollection, - ExpressionType condition, Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, - SecurityViolationException, ConfigurationException, ExpressionEvaluationException { - - List headers = new ArrayList<>(); - List> records = new ArrayList<>(); - - List columns; - if (compiledCollection.getColumns().isEmpty()) { - columns = MiscSchemaUtil.orderCustomColumns(DefaultColumnUtils.getDefaultAuditEventsView().getColumn()); - } else { - columns = MiscSchemaUtil.orderCustomColumns(compiledCollection.getColumns()); - } - PrismContainerDefinition def = getReportService().getPrismContext().getSchemaRegistry() - .findItemDefinitionByCompileTimeClass(AuditEventRecordType.class, PrismContainerDefinition.class); - columns.forEach(column -> { - Validate.notNull(column.getName(), "Name of column is null"); - String label = getColumnLabel(column, def); - headers.add(label); - - }); - - AuditResultHandler handler = new AuditResultHandler() { - - public int i = 1; - - @Override - public boolean handle(AuditEventRecordType auditRecord) { - recordProgress(task, i, result, LOGGER); - i++; - boolean writeRecord = true; - if (condition != null) { - try { - writeRecord = evaluateCondition(condition, auditRecord, task, result); - } catch (Exception e) { - LOGGER.error("Couldn't evaluate condition for report record."); - return false; - } - } - - if (writeRecord) { - List items = new ArrayList<>(); - columns.forEach(column -> { - ExpressionType expression = column.getExport() != null ? column.getExport().getExpression() : null; - ItemPath path = column.getPath() == null ? null : column.getPath().getItemPath(); - try { - items.add(getRealValueAsString(column, getAuditRecordAsContainer(auditRecord), path, expression, task, result) - ); - } catch (SchemaException e) { - LOGGER.error("Couldn't create singleValueContainer for audit record " + auditRecord); - } - }); - records.add(items); - } - return true; - } - - @Override - public int getProgress() { - return i; - } - }; - - getReportService().getDashboardService().searchObjectFromCollection(collectionRef, handler, null, task, result, true); - - CSVFormat csvFormat = createCsvFormat(); - if (Boolean.TRUE.equals(isHeader())) { - String[] arrayHeader = new String[headers.size()]; - arrayHeader = headers.toArray(arrayHeader); - csvFormat = csvFormat.withHeader(arrayHeader) - .withSkipHeaderRecord(false); - } else { - csvFormat = csvFormat.withSkipHeaderRecord(true); - } - try { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - CSVPrinter printer = new CSVPrinter(new OutputStreamWriter(output, getEncoding()), csvFormat); - for (List record : records) { - printer.printRecord(record.toArray()); - } - printer.flush(); - - return output.toByteArray(); - } catch (IOException e) { - LOGGER.error("Couldn't create CSVPrinter", e); - } - return null; - } - - private byte[] createTableBoxForObjectView(CollectionRefSpecificationType collection, CompiledObjectCollectionView compiledCollection, ExpressionType condition, Task task, OperationResult result) + private byte[] createTableBox(CollectionRefSpecificationType collection, CompiledObjectCollectionView compiledCollection, ExpressionType condition, + List subreports, Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { - Class type = resolveType(collection, compiledCollection); + Class type = resolveType(collection, compiledCollection); Collection> options = DefaultColumnUtils.createOption(type, getReportService().getSchemaService()); - PrismObjectDefinition def = getReportService().getPrismContext().getSchemaRegistry().findItemDefinitionByCompileTimeClass(type, PrismObjectDefinition.class); - - CompiledObjectCollectionView columnsCompiledView; + PrismContainerDefinition def = getReportService().getPrismContext().getSchemaRegistry().findItemDefinitionByCompileTimeClass(type, PrismContainerDefinition.class); List headers = new ArrayList<>(); List> records = new ArrayList<>(); @@ -306,9 +209,8 @@ private byte[] createTableBoxForObjectView(CollectionRefSpecificationType collec }); AtomicInteger index = new AtomicInteger(1); - ResultHandler handler = (value, prentResult) -> { - recordProgress(task, index.get(), result, LOGGER); - index.getAndIncrement(); + Predicate handler = (value) -> { + recordProgress(task, index.getAndIncrement(), result, LOGGER); boolean writeRecord = true; if (condition != null) { try { @@ -321,6 +223,7 @@ private byte[] createTableBoxForObjectView(CollectionRefSpecificationType collec if (writeRecord) { List items = new ArrayList<>(); + evaluateSubreportParameters(subreports, value, task); columns.forEach(column -> { ItemPath path = column.getPath() == null ? null : column.getPath().getItemPath(); ExpressionType expression = column.getExport() != null ? column.getExport().getExpression() : null; @@ -328,16 +231,18 @@ private byte[] createTableBoxForObjectView(CollectionRefSpecificationType collec }); records.add(items); } + cleanUpVariables(); return true; }; - getReportService().getDashboardService().searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, task, result, true); + getReportService().getModelInteractionService().searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, + options, null, getReportService().getParameters(task), task, result, true); CSVFormat csvFormat = createCsvFormat(); if (Boolean.TRUE.equals(isHeader())) { String[] arrayHeader = new String[headers.size()]; arrayHeader = headers.toArray(arrayHeader); csvFormat = csvFormat.withHeader(arrayHeader) - .withSkipHeaderRecord(false); + .withSkipHeaderRecord(false); } else { csvFormat = csvFormat.withSkipHeaderRecord(true); } @@ -377,7 +282,7 @@ public void importCollectionReport(ReportType report, VariablesMap variables, Ru } if (compiledCollection != null) { - Class type = compiledCollection.getTargetClass(); + Class type = compiledCollection.getTargetClass(getReportService().getPrismContext()); if (type == null) { String message = "Definition of type in view is null"; LOGGER.error(message); @@ -393,7 +298,7 @@ public void importCollectionReport(ReportType report, VariablesMap variables, Ru for (String name : variables.keySet()) { boolean isFound = false; for (GuiObjectColumnType column : columns) { - if (DisplayValueType.NUMBER.equals(column.getDisplayValue()) || isFound){ + if (DisplayValueType.NUMBER.equals(column.getDisplayValue()) || isFound) { continue; } String columnName = getColumnLabel(column, def); @@ -641,7 +546,7 @@ public List createVariablesFromFile(ReportType report, ReportDataT CSVFormat csvFormat = createCsvFormat(); if (compiledCollection != null) { List columns = MiscSchemaUtil.orderCustomColumns(compiledCollection.getColumns()); - Class type = compiledCollection.getTargetClass(); + Class type = compiledCollection.getTargetClass(getReportService().getPrismContext()); if (type == null) { throw new IllegalArgumentException("Couldn't define type of imported objects"); } @@ -779,7 +684,6 @@ public static Character toCharacter(String value) { return value.charAt(0); } - @Override public String getTypeSuffix() { return ".csv"; diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java index 214e97f446c..d812d526eb2 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java @@ -11,7 +11,10 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.report.api.ReportConstants; + import com.google.common.collect.ImmutableSet; +import org.apache.commons.lang3.ObjectUtils; import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; @@ -56,6 +59,8 @@ public abstract class FileFormatController { private final ReportServiceImpl reportService; private final FileFormatConfigurationType fileFormatConfiguration; private final ReportType report; + private VariablesMap parameters; + private VariablesMap variables; public FileFormatController(FileFormatConfigurationType fileFormatConfiguration, ReportType report, ReportServiceImpl reportService) { this.fileFormatConfiguration = fileFormatConfiguration; @@ -93,10 +98,6 @@ protected void recordProgress(Task task, long progress, OperationResult opResult public abstract String getType(); -// protected String getMessage(Enum e) { -// return getMessage(e.getDeclaringClass().getSimpleName() + '.' + e.name()); -// } - protected String getMessage(String key) { return getMessage(key, null); } @@ -242,12 +243,13 @@ private Object evaluateExportExpression(ExpressionType expression, Item valueObj } private Object evaluateExportExpression(ExpressionType expression, Object valueObject, Task task, OperationResult result) { - - VariablesMap variables = new VariablesMap(); - if (valueObject == null) { - variables.put(ExpressionConstants.VAR_OBJECT, null, Object.class); - } else { - variables.put(ExpressionConstants.VAR_OBJECT, valueObject, valueObject.getClass()); + checkVariables(task); + if (!variables.containsKey(ExpressionConstants.VAR_OBJECT)) { + if (valueObject == null) { + variables.put(ExpressionConstants.VAR_OBJECT, null, Object.class); + } else { + variables.put(ExpressionConstants.VAR_OBJECT, valueObject, valueObject.getClass()); + } } Object values = null; try { @@ -357,14 +359,16 @@ protected QName resolveTypeQname(CollectionRefSpecificationType collectionRef, C return type; } - protected Class resolveType(CollectionRefSpecificationType collectionRef, CompiledObjectCollectionView compiledCollection) { + protected Class resolveType(CollectionRefSpecificationType collectionRef, CompiledObjectCollectionView compiledCollection) { QName type = resolveTypeQname(collectionRef, compiledCollection); - return (Class) getReportService().getPrismContext().getSchemaRegistry() - .getCompileTimeClassForObjectType(type); - } - - protected boolean isAuditCollection(CollectionRefSpecificationType collection, Task task, OperationResult result) { - return DashboardUtils.isAuditCollection(collection, getReportService().getModelService(), task, result); + ComplexTypeDefinition def = getReportService().getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByType(type); + if (def != null) { + Class clazz = def.getCompileTimeClass(); + if (Containerable.class.isAssignableFrom(clazz)) { + return (Class) clazz; + } + } + throw new IllegalArgumentException("Couldn't define type for QName " + type); } protected PrismContainer getAuditRecordAsContainer(AuditEventRecordType record) throws SchemaException { @@ -379,8 +383,10 @@ protected PrismContainer getAuditRecordAsContainer(Audi protected boolean evaluateCondition(ExpressionType condition, T value, Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { - VariablesMap variables = new VariablesMap(); - variables.put(ExpressionConstants.VAR_OBJECT, value, value.getClass()); + checkVariables(task); + if (!variables.containsKey(ExpressionConstants.VAR_OBJECT)) { + variables.put(ExpressionConstants.VAR_OBJECT, value, value.getClass()); + } PrismPropertyValue conditionValue = ExpressionUtil.evaluateCondition(variables, condition, null, getReportService().getExpressionFactory(), "Evaluate condition", task, result); if (conditionValue == null || Boolean.FALSE.equals(conditionValue.getRealValue())) { @@ -388,4 +394,52 @@ protected boolean evaluateCondition(ExpressionType condition, } return true; } + + private void checkVariables(Task task) { + if (variables == null) { + if (parameters == null) { + parameters = getReportService().getParameters(task); + } + variables = new VariablesMap(); + variables.putAll(parameters); + } + } + + protected void evaluateSubreportParameters(List subreports, Object value, Task task) { + if (subreports != null && !subreports.isEmpty()){ + cleanUpVariables(); + checkVariables(task); + if (!variables.containsKey(ExpressionConstants.VAR_OBJECT)) { + variables.put(ExpressionConstants.VAR_OBJECT, value, value.getClass()); + } + List sortedSubreports = new ArrayList<>(); + sortedSubreports.addAll(subreports); + sortedSubreports.sort(Comparator.comparingInt(s -> ObjectUtils.defaultIfNull(s.getOrder(), Integer.MAX_VALUE))); + for (SubreportParameterType subreport : sortedSubreports) { + if (subreport.getExpression() == null || subreport.getName() == null) { + continue; + } + Object subreportParameter = null; + ExpressionType expression = subreport.getExpression(); + try { + subreportParameter = ExpressionUtil.evaluateExpression(null, variables, null, expression, + determineExpressionProfile(task.getResult()), getReportService().getExpressionFactory(), "subreport parameter", task, task.getResult()); + Class subreportParameterClass; + if (subreport.getType() != null) { + subreportParameterClass = getReportService().getPrismContext().getSchemaRegistry().determineClassForType(subreport.getType()); + } else { + subreportParameterClass = subreportParameter.getClass(); + } + variables.put(subreport.getName(), subreportParameter, subreportParameterClass); + } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException + | ConfigurationException | SecurityViolationException e) { + LOGGER.error("Couldn't execute expression " + expression, e); + } + } + } + } + + protected void cleanUpVariables() { + variables = null; + } } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java index 5fd61894e3d..2356d1f0ba5 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java @@ -12,16 +12,16 @@ import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Predicate; import javax.xml.namespace.QName; -import com.evolveum.midpoint.audit.api.AuditResultHandler; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.task.api.RunningTask; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; - import j2html.TagCreator; import j2html.tags.ContainerTag; import org.apache.commons.io.IOUtils; @@ -33,7 +33,6 @@ import com.evolveum.midpoint.model.api.interaction.DashboardWidget; import com.evolveum.midpoint.model.api.util.DashboardUtils; import com.evolveum.midpoint.model.common.util.DefaultColumnUtils; -import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.report.impl.ReportServiceImpl; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -130,15 +129,17 @@ public byte[] processDashboard(DashboardReportEngineConfigurationType dashboardC } switch (sourceType) { - case OBJECT_COLLECTION: - tableBox = createTableBoxForObjectView(widgetData.getLabel(), collectionRefSpecification, compiledCollection, null, task, result, false); - break; case AUDIT_SEARCH: if (collection == null) { LOGGER.error("CollectionRef is null for report of audit records"); throw new IllegalArgumentException("CollectionRef is null for report of audit records"); } - tableBox = createTableBoxForAuditView(widgetData.getLabel(), collectionRefSpecification, compiledCollection, null, task, result, false); +// tableBox = createTableBox(widgetData.getLabel(), collectionRefSpecification, compiledCollection, +// null, Collections.emptyList(), task, result, false); +// break; + case OBJECT_COLLECTION: + tableBox = createTableBox(widgetData.getLabel(), collectionRefSpecification, compiledCollection, + null, Collections.emptyList(), task, result, false); break; } if (tableBox != null) { @@ -221,14 +222,8 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin label = defaultName; } - ContainerTag tableBox; - if (!isAuditCollection(collectionRefSpecification, task, result)) { - tableBox = createTableBoxForObjectView(label, collectionRefSpecification, compiledCollection, - collectionConfig.getCondition(), task, result, true); - } else { - tableBox = createTableBoxForAuditView(label, collectionRefSpecification, compiledCollection, - collectionConfig.getCondition(), task, result, true); - } + ContainerTag tableBox = createTableBox(label, collectionRefSpecification, compiledCollection, + collectionConfig.getCondition(), collectionConfig.getSubreport(), task, result, true); body.append(tableBox.render()); @@ -241,69 +236,6 @@ private ContainerTag createTable() { return TagCreator.table().withClasses("table", "table-striped", "table-hover", "table-bordered"); } - private ContainerTag createTable(CompiledObjectCollectionView compiledCollection, List records, boolean recordProgress, - ExpressionType condition, Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { - ContainerTag table = createTable(); - ContainerTag tHead = TagCreator.thead(); - ContainerTag tBody = TagCreator.tbody(); - List columns = MiscSchemaUtil.orderCustomColumns(compiledCollection.getColumns()); - ContainerTag trForHead = TagCreator.tr().withStyle("width: 100%;"); - PrismContainerDefinition def = getReportService().getPrismContext().getSchemaRegistry() - .findItemDefinitionByCompileTimeClass(AuditEventRecordType.class, PrismContainerDefinition.class); - columns.forEach(column -> { - Validate.notNull(column.getName(), "Name of column is null"); - - DisplayType columnDisplay = column.getDisplay(); - String label = getColumnLabel(column, def); - ContainerTag th = TagCreator.th(TagCreator.div(TagCreator.span(label).withClass("sortableLabel"))); - if (columnDisplay != null) { - if (StringUtils.isNotBlank(columnDisplay.getCssClass())) { - th.withClass(columnDisplay.getCssClass()); - } - if (StringUtils.isNotBlank(columnDisplay.getCssStyle())) { - th.withStyle(columnDisplay.getCssStyle()); - } - } - trForHead.with(th); - }); - tHead.with(trForHead); - table.with(tHead); - - int i = 1; - if (recordProgress) { - task.setExpectedTotal((long) records.size()); - } - for (AuditEventRecordType record : records) { - if (recordProgress) { - recordProgress(task, i, result, LOGGER); - i++; - } - boolean writeRecord = true; - if (condition != null) { - writeRecord = evaluateCondition(condition, record, task, result); - } - - if (writeRecord) { - ContainerTag tr = TagCreator.tr(); - columns.forEach(column -> { - ExpressionType expression = column.getExport() != null ? column.getExport().getExpression() : null; - ItemPath path = column.getPath() == null ? null : column.getPath().getItemPath(); - try { - tr.with(TagCreator - .th(TagCreator.div(getRealValueAsString(column, getAuditRecordAsContainer(record), - path, expression, task, result)) - .withStyle("white-space: pre-wrap"))); - } catch (SchemaException e) { - LOGGER.error("Couldn't create singleValueContainer for audit record " + record); - } - }); - tBody.with(tr); - } - } - table.with(tBody); - return table; - } - private ContainerTag createTableBox(ContainerTag table, String nameOfTable, int countOfTableRecords, String createdTime, DisplayType display) { ContainerTag div = TagCreator.div().withClasses("box-body", "no-padding").with(TagCreator.h1(nameOfTable)) @@ -322,13 +254,13 @@ private ContainerTag createTableBox(ContainerTag table, String nameOfTable, int return TagCreator.div().withClasses("box", "boxed-table", classes).withStyle(style).with(div); } - private ContainerTag createTableBoxForObjectView(String tableLabel, CollectionRefSpecificationType collection, @NotNull CompiledObjectCollectionView compiledCollection, - ExpressionType condition, Task task, OperationResult result, boolean recordProgress) throws ObjectNotFoundException, SchemaException, CommunicationException, + private ContainerTag createTableBox(String tableLabel, CollectionRefSpecificationType collection, @NotNull CompiledObjectCollectionView compiledCollection, + ExpressionType condition, List subreports, Task task, OperationResult result, boolean recordProgress) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { long startMillis = getReportService().getClock().currentTimeMillis(); - Class type = resolveType(collection, compiledCollection); + Class type = resolveType(collection, compiledCollection); Collection> options = DefaultColumnUtils.createOption(type, getReportService().getSchemaService()); - PrismObjectDefinition def = getReportService().getPrismContext().getSchemaRegistry().findItemDefinitionByCompileTimeClass(type, PrismObjectDefinition.class); + PrismContainerDefinition def = getReportService().getPrismContext().getSchemaRegistry().findItemDefinitionByCompileTimeClass(type, PrismContainerDefinition.class); ContainerTag table = createTable(); ContainerTag tHead = TagCreator.thead(); @@ -362,22 +294,22 @@ private ContainerTag createTableBoxForObjectView(String tableLabel, CollectionRe table.with(tHead); AtomicInteger index = new AtomicInteger(1); - ResultHandler handler = (value, prentResult) -> { + Predicate handler = (value) -> { if (recordProgress) { - recordProgress(task, index.get(), result, LOGGER); - index.getAndIncrement(); + recordProgress(task, index.getAndIncrement(), result, LOGGER); } boolean writeRecord = true; if (condition != null) { try { writeRecord = evaluateCondition(condition, value, task, result); } catch (Exception e) { - LOGGER.error("Couldn't evaluate condition for report record."); + LOGGER.error("Couldn't evaluate condition for report record " + value); return false; } } if (writeRecord) { ContainerTag tr = TagCreator.tr(); + evaluateSubreportParameters(subreports, value, task); columns.forEach(column -> { ItemPath path = column.getPath() == null ? null : column.getPath().getItemPath(); ExpressionType expression = column.getExport() != null ? column.getExport().getExpression() : null; @@ -387,10 +319,11 @@ private ContainerTag createTableBoxForObjectView(String tableLabel, CollectionRe }); tBody.with(tr); } + cleanUpVariables(); return true; }; - getReportService().getDashboardService() - .searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, task, result, recordProgress); + getReportService().getModelInteractionService().searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, + null, getReportService().getParameters(task), task, result, recordProgress); if (tBody.getNumChildren() == 0 && !recordProgress) { return null; } @@ -400,94 +333,6 @@ private ContainerTag createTableBoxForObjectView(String tableLabel, CollectionRe convertMillisToString(startMillis), display); } - private ContainerTag createTableBoxForAuditView( - String tableLabel, CollectionRefSpecificationType collection, @NotNull CompiledObjectCollectionView compiledCollection, - ExpressionType condition, Task task, OperationResult result, boolean recordProgress) throws CommunicationException, ObjectNotFoundException, - SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { - long startMillis = getReportService().getClock().currentTimeMillis(); - ContainerTag table = createTable(); - ContainerTag tHead = TagCreator.thead(); - ContainerTag tBody = TagCreator.tbody(); - - List columns; - if (compiledCollection.getColumns().isEmpty()) { - columns = MiscSchemaUtil.orderCustomColumns(DefaultColumnUtils.getDefaultAuditEventsView().getColumn()); - } else { - columns = MiscSchemaUtil.orderCustomColumns(compiledCollection.getColumns()); - } - ContainerTag trForHead = TagCreator.tr().withStyle("width: 100%;"); - PrismContainerDefinition def = getReportService().getPrismContext().getSchemaRegistry() - .findItemDefinitionByCompileTimeClass(AuditEventRecordType.class, PrismContainerDefinition.class); - columns.forEach(column -> { - Validate.notNull(column.getName(), "Name of column is null"); - - DisplayType columnDisplay = column.getDisplay(); - String label = getColumnLabel(column, def); - ContainerTag th = TagCreator.th(TagCreator.div(TagCreator.span(label).withClass("sortableLabel"))); - if (columnDisplay != null) { - if (StringUtils.isNotBlank(columnDisplay.getCssClass())) { - th.withClass(columnDisplay.getCssClass()); - } - if (StringUtils.isNotBlank(columnDisplay.getCssStyle())) { - th.withStyle(columnDisplay.getCssStyle()); - } - } - trForHead.with(th); - }); - tHead.with(trForHead); - table.with(tHead); - - AuditResultHandler handler = new AuditResultHandler() { - private int i =1; - - @Override - public boolean handle(AuditEventRecordType auditRecord) { - if (recordProgress) { - recordProgress(task, i, result, LOGGER); - i++; - } - boolean writeRecord = true; - if (condition != null) { - try { - writeRecord = evaluateCondition(condition, auditRecord, task, result); - } catch (Exception e) { - LOGGER.error("Couldn't evaluate condition for report record."); - return false; - } - } - - if (writeRecord) { - ContainerTag tr = TagCreator.tr(); - columns.forEach(column -> { - ExpressionType expression = column.getExport() != null ? column.getExport().getExpression() : null; - ItemPath path = column.getPath() == null ? null : column.getPath().getItemPath(); - try { - tr.with(TagCreator - .th(TagCreator.div(getRealValueAsString(column, getAuditRecordAsContainer(auditRecord), - path, expression, task, result)) - .withStyle("white-space: pre-wrap"))); - } catch (SchemaException e) { - LOGGER.error("Couldn't create singleValueContainer for audit record " + auditRecord); - } - }); - tBody.with(tr); - } - return true; - } - - @Override - public int getProgress() { - return i; - } - }; - table.with(tBody); - - getReportService().getDashboardService().searchObjectFromCollection(collection, handler, null, task, result, recordProgress); - DisplayType display = compiledCollection.getDisplay(); - return createTableBox(table, tableLabel, (handler.getProgress() - 1), - convertMillisToString(startMillis), display); - } - private ContainerTag createTHead(String prefix, Set set) { return TagCreator.thead(TagCreator.tr(TagCreator.each(set, header -> TagCreator.th(TagCreator.div(TagCreator.span(getMessage(prefix + header)).withClass("sortableLabel"))))) diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java index 0c73ec29c6c..6efdc3e5a04 100644 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java +++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java @@ -16,10 +16,17 @@ import java.util.Arrays; import java.util.List; +import com.evolveum.midpoint.audit.api.AuditEventStage; +import com.evolveum.midpoint.audit.api.AuditEventType; +import com.evolveum.midpoint.prism.*; + +import com.evolveum.midpoint.report.api.ReportConstants; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventTypeType; + import org.testng.annotations.Test; import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.schema.result.OperationResult; @@ -29,6 +36,8 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import javax.xml.namespace.QName; + /** * @author skublik */ @@ -80,6 +89,8 @@ public abstract class BasicNewReportTest extends AbstractReportIntegrationTest { public static final File REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-filter-and-basic-collection-without-view.xml"); public static final File REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-condition.xml"); public static final File REPORT_OBJECT_COLLECTION_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-empty.xml"); + public static final File REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-param.xml"); + public static final File REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-subreport-param.xml"); public static final File REPORT_WITH_IMPORT_SCRIPT = new File(TEST_REPORTS_DIR, "report-with-import-script.xml"); public static final String REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8582"; @@ -102,6 +113,8 @@ public abstract class BasicNewReportTest extends AbstractReportIntegrationTest { public static final String REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a851a"; public static final String REPORT_OBJECT_COLLECTION_EMPTY_LIST_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85sq"; public static final String REPORT_WITH_IMPORT_SCRIPT_OID = "2b44aa2e-dd86-4842-bcf5-762c8c4a851a"; + public static final String REPORT_OBJECT_COLLECTION_WITH_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ew"; + public static final String REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85qq"; public static final String RESOURCE_DUMMY_OID = "10000000-0000-0000-0000-000000000004"; @@ -158,6 +171,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti importObjectFromFile(REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE, initResult); importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE, initResult); importObjectFromFile(REPORT_OBJECT_COLLECTION_EMPTY_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE, initResult); importObjectFromFile(REPORT_WITH_IMPORT_SCRIPT, initResult); } @@ -280,7 +295,48 @@ public void test117CreateObjectCollectionReportWithFilterAndBasicCollectionWitho basicCheckOutputFile(report); } + @Test + public void test118CreateObjectCollectionWithParamReport() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_PARAM_OID); + runReport(report, getParameters("givenName", String.class, "Will"), false); + basicCheckOutputFile(report); + } + + @Test + public void test119CreateObjectCollectionWithSubreportParamReport() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + private PrismContainer getParameters(String name, Class type, Object realValue) throws SchemaException { + PrismContainerDefinition paramContainerDef = prismContext.getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + PrismContainer paramContainer; + paramContainer = paramContainerDef.instantiate(); + ReportParameterType reportParam = new ReportParameterType(); + PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); + reportParamValue.revive(prismContext); + paramContainer.add(reportParamValue); + + QName typeName = prismContext.getSchemaRegistry().determineTypeForClass(type); + MutablePrismPropertyDefinition def = prismContext.definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, name), typeName); + def.setDynamic(true); + def.setRuntimeSchema(true); + def.toMutable().setMaxOccurs(1); + + PrismProperty prop = def.instantiate(); + prop.addRealValue(realValue); + reportParamValue.add(prop); + + return paramContainer; + } + protected PrismObject runReport(PrismObject report, boolean errorOk) throws Exception { + return runReport(report, null, errorOk); + } + + protected PrismObject runReport(PrismObject report, PrismContainer params, boolean errorOk) throws Exception { Task task = createTask(OP_CREATE_REPORT); OperationResult result = task.getResult(); PrismObject reportBefore = report.clone(); @@ -290,7 +346,7 @@ protected PrismObject runReport(PrismObject report, boolea // WHEN when(); - reportManager.runReport(report, null, task, result); + reportManager.runReport(report, params, task, result); assertInProgress(result); diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java index 2386f8ee4d3..0c959aaf518 100644 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java +++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java @@ -8,6 +8,8 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; @@ -23,6 +25,7 @@ import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.apache.commons.lang3.StringUtils; import org.testng.annotations.Test; import javax.xml.datatype.DatatypeFactory; @@ -45,6 +48,7 @@ public class TestCsvReport extends BasicNewReportTest { int expectedColumns; int expectedRow; + String lastLine; @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { @@ -168,6 +172,22 @@ public void test117CreateObjectCollectionReportWithFilterAndBasicCollectionWitho super.test117CreateObjectCollectionReportWithFilterAndBasicCollectionWithoutView(); } + @Test + public void test118CreateObjectCollectionWithParamReport() throws Exception { + expectedColumns = 2; + expectedRow = 2; + super.test118CreateObjectCollectionWithParamReport(); + } + + @Test + public void test119CreateObjectCollectionWithSubreportParamReport() throws Exception { + expectedColumns = 2; + expectedRow = 2; + lastLine = "\"will\";\"TestRole1230,TestRole123010\""; + super.test119CreateObjectCollectionWithSubreportParamReport(); + lastLine = null; + } + @Test public void test200ImportReportForUser() throws Exception { PrismObject report = getObject(ReportType.class, REPORT_IMPORT_OBJECT_COLLECTION_WITH_CONDITION_OID); @@ -304,6 +324,12 @@ protected List basicCheckOutputFile(PrismObject report) thro if (actualColumns != expectedColumns) { fail("Unexpected count of columns of csv report. Expected: " + expectedColumns + ", Actual: " + actualColumns); } + + String lastLine = lines.get(lines.size() - 1); + if (StringUtils.isNoneEmpty(this.lastLine) && !lastLine.equals(this.lastLine)) { + fail("Unexpected last line of csv report. Expected: '" + this.lastLine + "', Actual: '" + lastLine + "'"); + } + return lines; } diff --git a/model/report-impl/src/test/resources/reports/report-object-collection-with-condition.xml b/model/report-impl/src/test/resources/reports/report-object-collection-with-condition.xml index 8122b5e11a3..bdcbe775b81 100644 --- a/model/report-impl/src/test/resources/reports/report-object-collection-with-condition.xml +++ b/model/report-impl/src/test/resources/reports/report-object-collection-with-condition.xml @@ -14,9 +14,14 @@ diff --git a/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml b/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml new file mode 100644 index 00000000000..1b1955e3210 --- /dev/null +++ b/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml @@ -0,0 +1,54 @@ + + + + Object Collection report with parameters + + + + + givenName + + + + + + + + UserType + + nameColumn + name + + + + + + nameColumn2 + name + + + + nameColumn + + + + + + + + true + + diff --git a/model/report-impl/src/test/resources/reports/report-object-collection-with-subreport-param.xml b/model/report-impl/src/test/resources/reports/report-object-collection-with-subreport-param.xml new file mode 100644 index 00000000000..988216a6817 --- /dev/null +++ b/model/report-impl/src/test/resources/reports/report-object-collection-with-subreport-param.xml @@ -0,0 +1,68 @@ + + + + Object Collection report with subreport parameter + + + + + name + + + + + + + + testRole + string + + + + + + UserType + + nameColumn + name + + + + + + nameColumn2 + name + + + + nameColumn + + + + + + + + true + + From c69ec0decfc97434ef074885f406a066d8845983 Mon Sep 17 00:00:00 2001 From: lskublik Date: Wed, 21 Apr 2021 13:04:51 +0200 Subject: [PATCH 02/15] modify GUI part of run report with parameters --- .../gui/api/util/WebComponentUtil.java | 65 +++ .../panel/PrismPropertyPanelContext.java | 8 +- .../impl/factory/panel/TextPanelFactory.java | 58 ++- .../impl/prism/panel/PrismContainerPanel.java | 2 +- .../prism/panel/PrismContainerValuePanel.java | 2 +- .../impl/prism/panel/PrismPropertyPanel.java | 4 +- .../prism/panel/PrismPropertyValuePanel.java | 2 +- .../impl/prism/panel/PrismReferencePanel.java | 2 +- .../prism/panel/PrismReferenceValuePanel.java | 2 +- .../gui/impl/prism/panel/PrismValuePanel.java | 4 +- .../impl/prism/panel/ValueMetadataPanel.java | 2 +- .../search/AbstractSearchItemPanel.java | 24 - .../component/search/FilterSearchItem.java | 41 +- .../component/search/SearchFilterPanel.java | 3 +- .../component/search/SearchPropertyPanel.java | 3 +- .../web/component/search/SearchTypePanel.java | 5 +- .../web/page/admin/reports/PageReports.java | 2 +- .../component/RunReportPopupPanel.html | 37 +- .../component/RunReportPopupPanel.java | 425 +++++------------- .../midpoint/prism/DefinitionFactory.java | 2 +- .../xml/ns/public/common/common-core-3.xsd | 12 + .../report/impl/ReportServiceImpl.java | 6 +- .../controller/fileformat/CsvController.java | 6 +- .../fileformat/FileFormatController.java | 24 + .../controller/fileformat/HtmlController.java | 7 +- .../report-object-collection-with-param.xml | 4 + 26 files changed, 303 insertions(+), 449 deletions(-) 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 e02ad4690be..1307e0c5a3b 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 @@ -5085,4 +5085,69 @@ public static String countLinkFroNonDeadShadows(Collection } return Integer.toString(count); } + + public static List> getAllowedValues(SearchFilterParameterType parameter, PageBase pageBase) { + List> allowedValues = new ArrayList<>(); + + if (parameter == null || parameter.getAllowedValuesExpression() == null) { + return allowedValues; + } + Task task = pageBase.createSimpleTask("evaluate expression for allowed values"); + ExpressionType expression = parameter.getAllowedValuesExpression(); + Object value = null; + try { + + value = ExpressionUtil.evaluateExpression(new VariablesMap(), null, + expression, MiscSchemaUtil.getExpressionProfile(), + pageBase.getExpressionFactory(), "evaluate expression for allowed values", task, task.getResult()); + } catch (Exception e) { + LOGGER.error("Couldn't execute expression " + expression, e); + pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.evaluateAllowedValuesExpression", expression).getString()); + return allowedValues; + } + if (value instanceof PrismPropertyValue) { + value = ((PrismPropertyValue) value).getRealValue(); + } + + if (!(value instanceof List)) { + LOGGER.error("Exception return unexpected type, expected List, but was " + (value == null ? null : value.getClass())); + pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.wrongType", expression).getString()); + return allowedValues; + } + + if (!((List) value).isEmpty()) { + if (!(((List) value).get(0) instanceof DisplayableValue)) { + LOGGER.error("Exception return unexpected type, expected List, but was " + (value == null ? null : value.getClass())); + pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.wrongType", expression).getString()); + return allowedValues; + } + return (List>) value; + } + return allowedValues; + } + + public static DropDownChoicePanel createDropDownChoices(String id, IModel model, IModel>> choices, + boolean allowNull, PageBase pageBase) { + return new DropDownChoicePanel(id, model, choices, new IChoiceRenderer() { + private static final long serialVersionUID = 1L; + + @Override + public Object getDisplayValue(DisplayableValue val) { + if (val.getValue() instanceof Enum) { + return pageBase.createStringResource((Enum) val.getValue()).getString(); + } + return pageBase.createStringResource(val.getLabel()).getString(); + } + + @Override + public String getIdValue(DisplayableValue val, int index) { + return Integer.toString(index); + } + + @Override + public DisplayableValue getObject(String id, IModel> choices) { + return StringUtils.isNotBlank(id) ? choices.getObject().get(Integer.parseInt(id)) : null; + } + }, allowNull); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/PrismPropertyPanelContext.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/PrismPropertyPanelContext.java index 2f47d5b5cef..b88d355f427 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/PrismPropertyPanelContext.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/PrismPropertyPanelContext.java @@ -8,9 +8,11 @@ import com.evolveum.midpoint.gui.api.model.ReadOnlyModel; import com.evolveum.midpoint.gui.api.prism.wrapper.PrismPropertyWrapper; +import com.evolveum.midpoint.util.DisplayableValue; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.StringResourceModel; + +import java.util.Collection; /** * @author katka @@ -27,6 +29,10 @@ public LookupTableType getPredefinedValues() { return unwrapWrapperModel().getPredefinedValues(); } + public Collection> getAllowedValues() { + return unwrapWrapperModel().getAllowedValues(); + } + public boolean hasValueEnumerationRef() { return unwrapWrapperModel().getValueEnumerationRef() != null; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/TextPanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/TextPanelFactory.java index eee4d69107d..109bd26ddb2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/TextPanelFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/TextPanelFactory.java @@ -7,11 +7,24 @@ package com.evolveum.midpoint.gui.impl.factory.panel; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.xml.namespace.QName; +import com.evolveum.midpoint.util.DisplayableValue; + +import com.evolveum.midpoint.web.component.search.FilterSearchItem; +import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnChangeAjaxFormUpdatingBehavior; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; import org.springframework.stereotype.Component; import com.evolveum.midpoint.common.LocalizationService; @@ -43,21 +56,44 @@ public void register() { @Override protected InputPanel getPanel(PrismPropertyPanelContext panelCtx) { LookupTableType lookupTable = panelCtx.getPredefinedValues(); - if (lookupTable == null) { - return new TextPanel<>(panelCtx.getComponentId(), - panelCtx.getRealValueModel(), panelCtx.getTypeClass(), false); + if (lookupTable != null) { + return new AutoCompleteTextPanel(panelCtx.getComponentId(), + panelCtx.getRealValueModel(), panelCtx.getTypeClass(), panelCtx.hasValueEnumerationRef(), lookupTable) { + + private static final long serialVersionUID = 1L; + + @Override + public Iterator getIterator(String input) { + return (Iterator) prepareAutoCompleteList(input, lookupTable, panelCtx.getPageBase().getLocalizationService()).iterator(); + } + }; } - return new AutoCompleteTextPanel(panelCtx.getComponentId(), - panelCtx.getRealValueModel(), panelCtx.getTypeClass(), panelCtx.hasValueEnumerationRef(), lookupTable) { + Collection> allowedValues = panelCtx.getAllowedValues(); + if (CollectionUtils.isNotEmpty(allowedValues)) { + IModel>> choices = Model.ofList(allowedValues.stream().collect(Collectors.toCollection(ArrayList::new))); + IModel convertModel = new IModel>(){ + @Override + public DisplayableValue getObject() { + Object value = panelCtx.getRealValueModel().getObject(); + for (DisplayableValue dispValue : choices.getObject()) { + if (dispValue.getValue().equals(value)) { + return dispValue; + } + } + return null; + } - private static final long serialVersionUID = 1L; + @Override + public void setObject(DisplayableValue object) { + panelCtx.getRealValueModel().setObject(object.getValue()); + } + }; + return WebComponentUtil.createDropDownChoices(panelCtx.getComponentId(), convertModel, choices, true, panelCtx.getPageBase()); + } - @Override - public Iterator getIterator(String input) { - return (Iterator) prepareAutoCompleteList(input, lookupTable, panelCtx.getPageBase().getLocalizationService()).iterator(); - } - }; + return new TextPanel<>(panelCtx.getComponentId(), + panelCtx.getRealValueModel(), panelCtx.getTypeClass(), false); } protected List prepareAutoCompleteList(String input, LookupTableType lookupTable, LocalizationService localizationService) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerPanel.java index c9068926551..451275ecff2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerPanel.java @@ -78,7 +78,7 @@ protected Component createValuePanel(ListItem> ite PrismContainerValuePanel> panel = new PrismContainerValuePanel>("value", item.getModel(), settings) { @Override - protected void removeValue(PrismContainerValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { + protected void remove(PrismContainerValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { PrismContainerPanel.this.removeValue(valueToRemove, target); } }; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerValuePanel.java index 79f2226eb27..349187095b3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismContainerValuePanel.java @@ -283,7 +283,7 @@ public boolean isOn() { } @Override - protected void removeValue(CVW valueToRemove, AjaxRequestTarget target) throws SchemaException { + protected void remove(CVW valueToRemove, AjaxRequestTarget target) throws SchemaException { throw new UnsupportedOperationException("Must be implemented in calling panel"); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyPanel.java index 94b14552588..5929211a7f1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyPanel.java @@ -53,8 +53,8 @@ protected Component createValuePanel(ListItem> item PrismPropertyValuePanel panel = new PrismPropertyValuePanel("value", item.getModel(), getSettings()) { @Override - protected void removeValue(PrismPropertyValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { - PrismPropertyPanel.this.removeValue(valueToRemove, target); + protected void remove(PrismPropertyValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { + removeValue(valueToRemove, target); } }; item.add(panel); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyValuePanel.java index df83520838f..c90f502710f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismPropertyValuePanel.java @@ -51,7 +51,7 @@ protected PV createNewValue(PrismPropertyWrapper item } @Override - protected void removeValue(PrismPropertyValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { + protected void remove(PrismPropertyValueWrapper valueToRemove, AjaxRequestTarget target) throws SchemaException { throw new UnsupportedOperationException("Must be implemented in calling panel"); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferencePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferencePanel.java index 6a6578347f4..18ea1ed1697 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferencePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferencePanel.java @@ -47,7 +47,7 @@ protected void refreshPanel(AjaxRequestTarget target) { protected Component createValuePanel(ListItem> item) { PrismReferenceValuePanel valuePanel = new PrismReferenceValuePanel(ID_VALUE, item.getModel(), getSettings()) { @Override - protected void removeValue( + protected void remove( PrismReferenceValueWrapperImpl valueToRemove, AjaxRequestTarget target) throws SchemaException { PrismReferencePanel.this.removeValue(valueToRemove, target); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferenceValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferenceValuePanel.java index d048965fd10..87588775e4d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferenceValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismReferenceValuePanel.java @@ -118,7 +118,7 @@ private PrismReferenceWrapper getParentWrapper() { } @Override - protected void removeValue(PrismReferenceValueWrapperImpl valueToRemove, AjaxRequestTarget target) throws SchemaException { + protected void remove(PrismReferenceValueWrapperImpl valueToRemove, AjaxRequestTarget target) throws SchemaException { throw new UnsupportedOperationException("Must be implemented in calling panel"); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismValuePanel.java index 76f0ea2a8ea..79d2923a491 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/PrismValuePanel.java @@ -87,7 +87,7 @@ private WebMarkupContainer createHeaderPanel() { @Override public void onClick(AjaxRequestTarget target) { try { - removeValue(PrismValuePanel.this.getModelObject(), target); + PrismValuePanel.this.remove(PrismValuePanel.this.getModelObject(), target); } catch (SchemaException e) { LOGGER.error("Cannot remove value: {}", getModelObject()); getSession().error("Cannot remove value " + getModelObject()); @@ -272,7 +272,7 @@ private O getObject() { protected abstract PV createNewValue(IW itemWrapper); //TODO move to the ItemPanel, exception handling - protected abstract void removeValue(VW valueToRemove, AjaxRequestTarget target) throws SchemaException; + protected abstract void remove(VW valueToRemove, AjaxRequestTarget target) throws SchemaException; private void showMetadataPerformed(VW value, AjaxRequestTarget target) { boolean showMetadata = !value.isShowMetadata(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ValueMetadataPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ValueMetadataPanel.java index 0b5abd8f78c..ce0625cfe85 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ValueMetadataPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ValueMetadataPanel.java @@ -84,7 +84,7 @@ protected PV createNewValue(PrismContainerWrapper ite } @Override - protected void removeValue(CVW valueToRemove, AjaxRequestTarget target) { + protected void remove(CVW valueToRemove, AjaxRequestTarget target) { } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchItemPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchItemPanel.java index 535e1b69a57..cb1cd20b1d6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchItemPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchItemPanel.java @@ -157,30 +157,6 @@ protected IModel>> createBooleanChoices() { return Model.ofList(list); } - protected DropDownChoicePanel createDropDownChoices(String id, IModel model, IModel>> choices, boolean allowNull) { - return new DropDownChoicePanel(id, model, choices, new IChoiceRenderer() { - private static final long serialVersionUID = 1L; - - @Override - public Object getDisplayValue(DisplayableValue val) { - if (val.getValue() instanceof Enum) { - return getPageBase().createStringResource((Enum) val.getValue()).getString(); - } - return getPageBase().createStringResource(val.getLabel()).getString(); - } - - @Override - public String getIdValue(DisplayableValue val, int index) { - return Integer.toString(index); - } - - @Override - public DisplayableValue getObject(String id, IModel> choices) { - return StringUtils.isNotBlank(id) ? choices.getObject().get(Integer.parseInt(id)) : null; - } - }, allowNull); - } - protected AutoCompleteTextPanel createAutoCompetePanel(String id, IModel model, LookupTableType lookupTable) { AutoCompleteTextPanel autoCompletePanel = new AutoCompleteTextPanel(id, model, String.class, true, lookupTable) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/FilterSearchItem.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/FilterSearchItem.java index 779c097c487..ee9771cf7c2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/FilterSearchItem.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/FilterSearchItem.java @@ -7,6 +7,7 @@ package com.evolveum.midpoint.web.component.search; import java.io.Serializable; +import java.util.Collections; import java.util.List; import org.apache.commons.collections4.CollectionUtils; @@ -131,43 +132,11 @@ public List> getAllowedValues(PageBase pageBase) { if (allowedValues != null) { return allowedValues; } - - if (predefinedFilter == null || predefinedFilter.getParameter() == null - || predefinedFilter.getParameter().getAllowedValuesExpression() == null) { - return null; - } - Task task = pageBase.createSimpleTask("evaluate expression for allowed values"); - ExpressionType expression = predefinedFilter.getParameter().getAllowedValuesExpression(); - Object value = null; - try { - - value = ExpressionUtil.evaluateExpression(new VariablesMap(), null, - expression, MiscSchemaUtil.getExpressionProfile(), - pageBase.getExpressionFactory(), "evaluate expression for allowed values", task, task.getResult()); - } catch (Exception e) { - LOGGER.error("Couldn't execute expression " + expression, e); - pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.evaluateAllowedValuesExpression", expression).getString()); - return null; - } - if (value instanceof PrismPropertyValue) { - value = ((PrismPropertyValue) value).getRealValue(); - } - - if (!(value instanceof List)) { - LOGGER.error("Exception return unexpected type, expected List, but was " + (value == null ? null : value.getClass())); - pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.wrongType", expression).getString()); - return null; - } - - if (!((List) value).isEmpty()) { - if (!(((List) value).get(0) instanceof DisplayableValue)) { - LOGGER.error("Exception return unexpected type, expected List, but was " + (value == null ? null : value.getClass())); - pageBase.error(pageBase.createStringResource("FilterSearchItem.message.error.wrongType", expression).getString()); - return null; - } + if (predefinedFilter == null) { + return Collections.EMPTY_LIST; } - this.allowedValues = (List>) value; - return (List>) value; + List> values = WebComponentUtil.getAllowedValues(predefinedFilter.getParameter(), pageBase); + return values; } public LookupTableType getLookupTable(PageBase pageBase) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFilterPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFilterPanel.java index b03ae95109a..5d3afc03a1f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFilterPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFilterPanel.java @@ -94,7 +94,8 @@ protected void referenceValueUpdated(ObjectReferenceType ort, AjaxRequestTarget createEnumChoices((Class) inputClass) : Model.ofList(getModelObject().getAllowedValues(getPageBase())); } if (choices != null) { - inputPanel = createDropDownChoices(ID_SEARCH_ITEM_FIELD, new PropertyModel<>(getModel(), FilterSearchItem.F_INPUT), choices, false); + inputPanel = WebComponentUtil.createDropDownChoices( + ID_SEARCH_ITEM_FIELD, new PropertyModel(getModel(), FilterSearchItem.F_INPUT), (IModel)choices, false, getPageBase()); ((InputPanel) inputPanel).getBaseFormComponent().add(new EmptyOnChangeAjaxFormUpdatingBehavior() { @Override protected void onUpdate(AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertyPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertyPanel.java index 7e2d7551fae..a3dc1a35e13 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertyPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertyPanel.java @@ -92,7 +92,8 @@ protected boolean isAllowedNotFoundObjectRef() { if (choices == null) { choices = new ListModel(item.getAllowedValues(getPageBase())); } - searchItemField = createDropDownChoices(ID_SEARCH_ITEM_FIELD, new PropertyModel<>(getModel(), "value"), choices, true); + searchItemField = WebComponentUtil.createDropDownChoices( + ID_SEARCH_ITEM_FIELD, new PropertyModel(getModel(), "value"), (IModel)choices, true, getPageBase()); ((InputPanel) searchItemField).getBaseFormComponent().add(new EmptyOnChangeAjaxFormUpdatingBehavior() { @Override protected void onUpdate(AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchTypePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchTypePanel.java index 98c137e9e08..27b5d19e5a5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchTypePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchTypePanel.java @@ -8,6 +8,8 @@ import java.util.List; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; + import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; @@ -42,7 +44,8 @@ protected void initSearchItemField(WebMarkupContainer searchItemContainer) { List>> allowedValues = item.getAllowedValues(getPageBase()); if (allowedValues != null && !allowedValues.isEmpty()) { IModel>> choices = new ListModel(item.getAllowedValues(getPageBase())); - searchItemField = createDropDownChoices(ID_SEARCH_ITEM_FIELD, new PropertyModel<>(getModel(), ContainerTypeSearchItem.F_TYPE), choices, false); + searchItemField = WebComponentUtil.createDropDownChoices( + ID_SEARCH_ITEM_FIELD, new PropertyModel(getModel(), ContainerTypeSearchItem.F_TYPE), (IModel)choices, false, getPageBase()); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java index c9b300976fd..6ae03cfaf61 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java @@ -290,7 +290,7 @@ private void runConfirmPerformed(AjaxRequestTarget target, ReportType reportType protected void runReportPerformed(AjaxRequestTarget target, ReportType report) { - if(report.getJasper() != null) { + if(report.getObjectCollection() == null) { runConfirmPerformed(target, report, null); return; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html index e47d98122b3..b76fff0b1e0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html @@ -22,40 +22,9 @@

- - - - - - - - -
-
- - - - - -
- - -
-
-
-
- - - - -
-
-
-
+
+
+

diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java index 8ecfb92d594..780fba46824 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java @@ -6,42 +6,33 @@ */ package com.evolveum.midpoint.web.page.admin.reports.component; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import java.util.*; -import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import com.evolveum.midpoint.gui.api.prism.wrapper.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.factory.wrapper.WrapperContext; +import com.evolveum.midpoint.gui.api.prism.ItemStatus; +import com.evolveum.midpoint.gui.api.prism.wrapper.ItemWrapper; +import com.evolveum.midpoint.gui.impl.prism.panel.ItemPanelSettingsBuilder; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.util.DisplayableValue; import com.evolveum.midpoint.web.component.form.MidpointForm; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.wicket.Component; -import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.feedback.ComponentFeedbackMessageFilter; import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; -import com.evolveum.midpoint.audit.api.AuditEventStage; -import com.evolveum.midpoint.audit.api.AuditEventType; import com.evolveum.midpoint.gui.api.component.BasePanel; -import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; -import com.evolveum.midpoint.gui.api.model.LoadableModel; -import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; @@ -63,20 +54,11 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.dialog.Popupable; -import com.evolveum.midpoint.web.component.input.DatePanel; -import com.evolveum.midpoint.web.component.input.TextPanel; import com.evolveum.midpoint.web.component.message.FeedbackAlerts; -import com.evolveum.midpoint.web.component.prism.InputPanel; -import com.evolveum.midpoint.web.component.util.VisibleBehaviour; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour; import com.evolveum.midpoint.web.page.admin.reports.dto.JasperReportParameterDto; import com.evolveum.midpoint.web.page.admin.reports.dto.JasperReportParameterPropertiesDto; -import com.evolveum.midpoint.web.page.admin.reports.dto.JasperReportValueDto; import com.evolveum.midpoint.web.page.admin.reports.dto.ReportDto; import com.evolveum.midpoint.web.security.util.SecurityUtils; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventTypeType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; public class RunReportPopupPanel extends BasePanel implements Popupable { @@ -95,30 +77,77 @@ public class RunReportPopupPanel extends BasePanel implements Popupab private static final Integer AUTO_COMPLETE_BOX_SIZE = 10; - private static final String ID_VALUE_LIST = "valueList"; - private static final String ID_ADD_BUTTON = "add"; - private static final String ID_REMOVE_BUTTON = "remove"; + private static final String ID_PARAMETERS = "parameters"; + private static final String ID_PARAMETER = "parameter"; - private static final String ID_PARAMETERS = "paramTable"; - - private IModel reportModel; private final ReportType reportType; + private PrismContainer paramContainer; public RunReportPopupPanel(String id, final ReportType reportType) { super(id); this.reportType = reportType; + } - reportModel = new LoadableModel(false) { + @Override + protected void onInitialize() { + super.onInitialize(); + initParameters(); + initLayout(); + } - private static final long serialVersionUID = 1L; + private void initParameters() { + PrismContainerDefinition paramContainerDef = getPrismContext().getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + for (SearchFilterParameterType parameter : reportType.getObjectCollection().getParameter()) { + try { + paramContainer = paramContainerDef.instantiate(); - @Override - protected ReportDto load() { - return new ReportDto(reportType, true); - } - }; + ReportParameterType reportParam = new ReportParameterType(); + PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); + reportParamValue.revive(getPrismContext()); + paramContainer.add(reportParamValue); - initLayout(); + Class clazz = getPrismContext().getSchemaRegistry().determineClassForType(parameter.getType()); + QName type = getPrismContext().getSchemaRegistry().determineTypeForClass(clazz); + if (Containerable.class.isAssignableFrom(clazz)) { + LOGGER.error("Couldn't create container item for parameter " + parameter); + continue; + } + MutableItemDefinition def; + if (Referencable.class.isAssignableFrom(clazz)) { + def = getPrismContext().definitionFactory().createReferenceDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); + ((MutablePrismReferenceDefinition)def).setTargetTypeName(parameter.getTargetType()); + } else { + List values = WebComponentUtil.getAllowedValues(parameter, getPageBase()); + if (CollectionUtils.isNotEmpty(values)) { + def = (MutableItemDefinition) getPrismContext().definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type, values, null); + } else { + def = getPrismContext().definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); + } + } + def.setDynamic(true); + def.setRuntimeSchema(true); + def.setMaxOccurs(1); + def.setMinOccurs(0); + if (parameter.getDisplay() != null) { + String displayName = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getLabel()); + def.setDisplayName(displayName); + String help = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getHelp()); + def.setHelp(help); + } + if (parameter.getAllowedValuesLookupTable() != null) { + def.setValueEnumerationRef(parameter.getAllowedValuesLookupTable().asReferenceValue()); + } + + Item prop = def.instantiate(); + reportParamValue.add(prop); + + } catch (SchemaException e) { + LOGGER.error("Couldn't create item for parameter " + parameter); + } + } } protected void initLayout() { @@ -126,14 +155,22 @@ protected void initLayout() { Form mainForm = new MidpointForm<>(ID_MAIN_FORM); add(mainForm); - - ListView paramListView = new ListView(ID_PARAMETERS, new PropertyModel<>(reportType, "objectCollection.parameter")) { + IModel> listModel = (IModel) () -> { + List list = new ArrayList<>(); + list.addAll(paramContainer.getValue().getItems()); + return list; + }; + ListView paramListView = new ListView(ID_PARAMETERS, listModel) { private static final long serialVersionUID = 1L; @Override - protected void populateItem(ListItem paramItem) { - paramItem.add(createParameterPanel(paramItem.getModel())); + protected void populateItem(ListItem paramItem) { + try { + paramItem.add(createParameterPanel(paramItem.getModel())); + } catch (SchemaException e) { + LOGGER.error("Couldn't create panel for item " + paramItem.getModelObject()); + } } }; @@ -141,7 +178,7 @@ protected void populateItem(ListItem paramItem) { mainForm.add(paramListView); FeedbackAlerts feedback = new FeedbackAlerts(ID_POPUP_FEEDBACK); - feedback.setFilter(new ComponentFeedbackMessageFilter(paramListView){ + feedback.setFilter(new ComponentFeedbackMessageFilter(paramListView) { private static final long serialVersionUID = 1L; @@ -158,176 +195,26 @@ public boolean accept(FeedbackMessage message) { private static final long serialVersionUID = 1L; @Override - protected void onError(AjaxRequestTarget target) { - FeedbackAlerts feedback = (FeedbackAlerts) getForm().get(ID_POPUP_FEEDBACK); - target.add(feedback); - } - - @Override - protected void onSubmit(AjaxRequestTarget target) { - runConfirmPerformed(target, reportModel); - } - }; - mainForm.add(addButton); - - } - - private WebMarkupContainer createParameterPanel(final IModel parameterModel) { - WebMarkupContainer paramPanel = new WebMarkupContainer("paramPanel"); -// paramPanel.setOutputMarkupId(true); -// String paramValue = new PropertyModel(parameterModel, "name").getObject(); -// StringResourceModel paramDisplay = PageBase.createStringResourceStatic(RunReportPopupPanel.this, "runReportPopupContent.param.name." + paramValue); -// -// paramPanel.add(new Label("name", paramDisplay)); // use display name rather than property name -// -// WebMarkupContainer required = new WebMarkupContainer("required"); -// JasperReportParameterPropertiesDto properties = parameterModel.getObject().getProperties(); -// boolean mandatory = (properties != null && properties.getMandatory()); -// required.add(new VisibleBehaviour(() -> mandatory)); -// paramPanel.add(required); -// -// String paramClass = new PropertyModel(parameterModel, "nestedTypeAsString").getObject(); -// if (StringUtils.isBlank(paramClass)) { -// paramClass = new PropertyModel(parameterModel, "typeAsString").getObject(); -// } -// paramClass = paramClass == null ? "" : paramClass.substring(paramClass.lastIndexOf(".") + 1); -// paramPanel.add(new Label("type", paramClass)); -// -// ListView listView = new ListView(ID_VALUE_LIST, new PropertyModel<>(parameterModel, "value")) { -// -// private static final long serialVersionUID = 1L; -// -// @Override -// protected void populateItem(ListItem item) { -// item.add(createInputMarkup(item.getModel(), parameterModel.getObject(), mandatory, paramDisplay)); -// -// } -// -// }; -// listView.setOutputMarkupId(true); -// -// paramPanel.add(listView); - return paramPanel; - } - - private WebMarkupContainer createInputMarkup(final IModel valueModel, JasperReportParameterDto param, boolean required, IModel name) { - param.setEditing(true); - WebMarkupContainer paramValueMarkup = new WebMarkupContainer("valueMarkup"); - paramValueMarkup.setOutputMarkupId(true); - - InputPanel input = createTypedInputPanel("inputValue", valueModel, "value", param); - input.getBaseFormComponent().setRequired(required); - input.getBaseFormComponent().setLabel(name); - paramValueMarkup.add(input); - - //buttons - AjaxLink addButton = new AjaxLink(ID_ADD_BUTTON) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { - addValue(paramValueMarkup, param, target); + protected void onError(AjaxRequestTarget target) { + FeedbackAlerts feedback = (FeedbackAlerts) getForm().get(ID_POPUP_FEEDBACK); + target.add(feedback); } - }; - addButton.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return isAddButtonVisible(param); - } - }); - paramValueMarkup.add(addButton); - - AjaxLink removeButton = new AjaxLink(ID_REMOVE_BUTTON) { - private static final long serialVersionUID = 1L; @Override - public void onClick(AjaxRequestTarget target) { - removeValue(paramValueMarkup, param, valueModel.getObject(), target); + protected void onSubmit(AjaxRequestTarget target) { + runConfirmPerformed(target); } }; - removeButton.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return isRemoveButtonVisible(); - } - }); - paramValueMarkup.add(removeButton); - return paramValueMarkup; - } - - private InputPanel createTypedInputPanel(String componentId, IModel model, String expression, JasperReportParameterDto param) { - InputPanel panel; - Class type; - try { - if (param.isMultiValue()) { - type = param.getNestedType(); - } else { - type = param.getType(); - } - } catch (ClassNotFoundException e) { - getSession().error("Could not find parameter type definition. Check the configuration."); - throw new RestartResponseException(getPageBase()); - } - - if (type.isEnum()) { - panel = WebComponentUtil.createEnumPanel(type, componentId, new PropertyModel<>(model, expression), this); - } else if (XMLGregorianCalendar.class.isAssignableFrom(type)) { - panel = new DatePanel(componentId, new PropertyModel<>(model, expression)); - } else if (param.getProperties() != null && param.getProperties().getTargetType() != null) { // render autocomplete box - LookupTableType lookup = new LookupTableType(); - //TODO: displayName - panel = new AutoCompleteTextPanel(componentId, new PropertyModel<>(model, expression), String.class, true, lookup) { - - private static final long serialVersionUID = 1L; - - @Override - public Iterator getIterator(String input) { - return prepareAutoCompleteList(input, lookup, param).iterator(); - } - }; - } else { - panel = new TextPanel<>(componentId, new PropertyModel<>(model, expression), type); - } - List components = panel.getFormComponents(); - for (FormComponent component : components) { - component.add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); - } - - panel.setOutputMarkupId(true); - return panel; - } - - private void addValue(WebMarkupContainer paramValueMarkup, JasperReportParameterDto valueModel, AjaxRequestTarget target) { - valueModel.addValue(); - //reload just current parameter container panel - target.add(paramValueMarkup.findParent(ListView.class).findParent(WebMarkupContainer.class)); - } - - private ListView getParametersView(){ - return (ListView) get(createComponentPath(ID_MAIN_FORM, ID_PARAMETERS)); - } - - private boolean isAddButtonVisible(JasperReportParameterDto valueDecs) { - try { - return valueDecs.isMultiValue(); - } catch (ClassNotFoundException e) { - return false; - } - } + mainForm.add(addButton); - private void removeValue(WebMarkupContainer paramValueMarkup, JasperReportParameterDto valueModel, - JasperReportValueDto object, AjaxRequestTarget target) { - valueModel.removeValue(object); - //reload just current parameter container panel - target.add(paramValueMarkup.findParent(ListView.class).findParent(WebMarkupContainer.class)); } - private boolean isRemoveButtonVisible() { - return true; + private WebMarkupContainer createParameterPanel(final IModel item) throws SchemaException { + Task task = getPageBase().createSimpleTask("Create child containers"); + WrapperContext ctx = new WrapperContext(task, task.getResult()); + ItemWrapper wrapper = getPageBase().createItemWrapper(item.getObject(), ItemStatus.ADDED, ctx); + return getPageBase().initItemPanel(ID_PARAMETER, item.getObject().getDefinition().getTypeName(), + Model.of(wrapper), new ItemPanelSettingsBuilder().build()); } private List createLookupTableRows(JasperReportParameterDto param, String input) { @@ -368,7 +255,7 @@ private List createLookupTableRows(Ja Collection> objects; ObjectQuery query = getPrismContext().queryFor(targetType) .item(new QName(SchemaConstants.NS_C, pLabel)).startsWith(input) - .matching(new QName(SchemaConstants.NS_MATCHING_RULE, "origIgnoreCase")) + .matching(new QName(SchemaConstants.NS_MATCHING_RULE, "origIgnoreCase")) .maxSize(AUTO_COMPLETE_BOX_SIZE) .build(); try { @@ -435,34 +322,6 @@ private PolyStringType convertObjectToPolyStringType(Object o) { } } - private List prepareAutoCompleteList(String input, LookupTableType lookupTable, JasperReportParameterDto param) { - List values = new ArrayList<>(); - - if (lookupTable == null) { - return values; - } - - List rows = createLookupTableRows(param, input); - - if (rows == null) { - return values; - } - if (lookupTable.getRow() != null) { - lookupTable.getRow().addAll(rows); - } - - for (LookupTableRowType row : rows) { - values.add(WebComponentUtil.getOrigStringFromPoly(row.getLabel())); - - if (values.size() > AUTO_COMPLETE_BOX_SIZE) { - break; - } - } - - return values; - } - - public Task createSimpleTask(String operation, PrismObject owner) { Task task = getPageBase().getTaskManager().createTaskInstance(operation); @@ -486,71 +345,16 @@ public Task createSimpleTask(String operation) { return createSimpleTask(operation, user != null ? user.getFocus().asPrismObject() : null); } - private void runConfirmPerformed(AjaxRequestTarget target, IModel model) { - ReportDto reportDto = model.getObject(); - - PrismContainerDefinition paramContainerDef = getPrismContext().getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); - PrismContainer paramContainer; - try { - paramContainer = paramContainerDef.instantiate(); - ReportParameterType reportParam = new ReportParameterType(); - PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); - reportParamValue.revive(getPrismContext()); - paramContainer.add(reportParamValue); - - List params = getParametersView().getModelObject(); - for (JasperReportParameterDto paramDto : params) { - if (paramDto.getValue() == null) { - continue; - } - List values = paramDto.getValue(); - Class paramClass = paramDto.getType(); - - boolean multivalue = false; - if (List.class.isAssignableFrom(paramClass)) { - paramClass = paramDto.getNestedType(); - if (paramClass == null) { - getSession().error("Nested type for list must be defined!"); - target.add(getPageBase().getFeedbackPanel()); - return; - } - } - - QName typeName = getPrismContext().getSchemaRegistry().determineTypeForClass(paramClass); - MutablePrismPropertyDefinition def = getPrismContext().definitionFactory().createPropertyDefinition( - new QName(ReportConstants.NS_EXTENSION, paramDto.getName()), typeName); - def.setDynamic(true); - def.setRuntimeSchema(true); - def.toMutable().setMaxOccurs(multivalue ? -1 : 1); // TODO multivalue is always 'false' here ... - - PrismProperty prop = def.instantiate(); - for (JasperReportValueDto paramValue : values) { - Object realValue = paramValue.getValue(); - if (realValue == null) { - continue; - } - if (AuditEventType.class.isAssignableFrom(paramClass)) { - paramClass = AuditEventTypeType.class; - realValue = AuditEventType.toSchemaValue((AuditEventType) realValue); - } else if (AuditEventStage.class.isAssignableFrom(paramClass)) { - paramClass = AuditEventStageType.class; - realValue = AuditEventStage.toSchemaValue((AuditEventStage) realValue); - } - - prop.addRealValue(realValue); - } - if (!prop.isEmpty()) { - reportParamValue.add(prop); - } + private void runConfirmPerformed(AjaxRequestTarget target) { + PrismContainer parameterContainer = paramContainer.clone(); + List itemForRemoving = new ArrayList<>(); + parameterContainer.getValue().getItems().forEach((item) -> { + if (item.isEmpty() || item.getRealValue() == null){ + itemForRemoving.add(item); } - } catch (SchemaException | ClassNotFoundException e) { - OperationResult result = new OperationResult("Parameters serialization"); - result.recordFatalError(getString("RunReportPopupPanel.message.runConfirmPerformed.fatalError")); - getPageBase().showResult(result); - return; - } - - runConfirmPerformed(target, reportDto.getObject().asObjectable(), paramContainer); + }); + parameterContainer.getValue().getItems().removeAll(itemForRemoving); + runConfirmPerformed(target, reportType, parameterContainer); } protected void runConfirmPerformed(AjaxRequestTarget target, ReportType reportType2, @@ -568,12 +372,12 @@ public int getHeight() { } @Override - public String getWidthUnit(){ + public String getWidthUnit() { return "px"; } @Override - public String getHeightUnit(){ + public String getHeightUnit() { return "px"; } @@ -586,21 +390,4 @@ public StringResourceModel getTitle() { public Component getComponent() { return this; } - -// static class LookupReportPropertyModel extends LookupPropertyModel { -// -// private static final long serialVersionUID = 1L; -// -// -// public LookupReportPropertyModel(IModel modelObject, String expression, LookupTableType lookupTable, boolean isStrict) { -// super(modelObject, expression, lookupTable, isStrict); -// } -// -// @Override -// public boolean isSupportsDisplayName() { -// return true; -// } -// -// } - } diff --git a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/DefinitionFactory.java b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/DefinitionFactory.java index e90ae9a5f05..95b40f45fed 100644 --- a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/DefinitionFactory.java +++ b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/DefinitionFactory.java @@ -28,5 +28,5 @@ public interface DefinitionFactory { @NotNull MutablePrismContainerDefinition createContainerDefinition(QName name, ComplexTypeDefinition ctd); - PrismPropertyDefinition createPropertyDefinition(QName name, QName typeName, Collection> allowedValues, T defaultValue); + MutablePrismPropertyDefinition createPropertyDefinition(QName name, QName typeName, Collection> allowedValues, T defaultValue); } 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 26953677293..ea78952ee2a 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -27036,6 +27036,18 @@ + + + + Display properties of the parameter. + + + 4.4 + true + SearchFilterParameterType.display + + + diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java index 14086c73657..b28c9c4e011 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java @@ -485,11 +485,9 @@ public VariablesMap getParameters(Task task) { for (Item item : items) { PrismProperty pp = (PrismProperty) item; String paramName = pp.getPath().lastName().getLocalPart(); - Object value; - if (item.isSingleValue()) { + Object value = null; + if (!pp.getRealValues().isEmpty()) { value = pp.getRealValues().iterator().next(); - } else { - value = pp.getRealValues(); } variables.put(paramName, new TypedValue(value, ((PrismProperty) item).getValueClass())); } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java index 6d326220885..c7a9f180301 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java @@ -131,7 +131,7 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin .getObject(type, ref.getOid(), null, task, result) .asObjectable(); } - + initializationParameters(collectionConfig.getParameter(), task); CompiledObjectCollectionView compiledCollection = createCompiledView(collectionConfig, collection); return createTableBox(collectionRefSpecification, compiledCollection, @@ -234,8 +234,8 @@ private byte[] createTableBox(CollectionRefSpecificationType collection, Compile cleanUpVariables(); return true; }; - getReportService().getModelInteractionService().searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, - options, null, getReportService().getParameters(task), task, result, true); + searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, + options, null, task, result, true); CSVFormat csvFormat = createCsvFormat(); if (Boolean.TRUE.equals(isHeader())) { diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java index d812d526eb2..21843d4d2b7 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java @@ -8,11 +8,16 @@ import java.io.IOException; import java.util.*; +import java.util.function.Predicate; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.report.api.ReportConstants; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; + import com.google.common.collect.ImmutableSet; import org.apache.commons.lang3.ObjectUtils; import org.jetbrains.annotations.NotNull; @@ -440,6 +445,25 @@ protected void evaluateSubreportParameters(List subrepor } protected void cleanUpVariables() { + variables.clear(); variables = null; } + + protected void initializationParameters(List parametersType, Task task) { + VariablesMap variables = getReportService().getParameters(task); + for (SearchFilterParameterType parameter : parametersType) { + if (!variables.containsKey(parameter.getName())) { + variables.put(parameter.getName(), null, String.class); + } + } + parameters = variables; + } + + protected void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, QName typeForFilter, Predicate handler, + Collection> defaultOptions, ObjectPaging paging, Task task, OperationResult result, boolean recordProgress) + throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + checkVariables(task); + getReportService().getModelInteractionService().searchObjectFromCollection( + collectionConfig, typeForFilter, handler, defaultOptions, paging, variables, task, result, recordProgress); + } } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java index 2356d1f0ba5..073e6375a70 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; +import com.evolveum.midpoint.report.api.ReportConstants; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.task.api.RunningTask; @@ -183,6 +184,8 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin .asObjectable(); } + initializationParameters(collectionConfig.getParameter(), task); + ClassLoader classLoader = getClass().getClassLoader(); InputStream in = classLoader.getResourceAsStream(REPORT_CSS_STYLE_FILE_NAME); if (in == null) { @@ -322,8 +325,8 @@ private ContainerTag createTableBox(String tableLabel, CollectionRefSpecificatio cleanUpVariables(); return true; }; - getReportService().getModelInteractionService().searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, - null, getReportService().getParameters(task), task, result, recordProgress); + searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, + null, task, result, recordProgress); if (tBody.getNumChildren() == 0 && !recordProgress) { return null; } diff --git a/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml b/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml index 1b1955e3210..49b795914f8 100644 --- a/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml +++ b/model/report-impl/src/test/resources/reports/report-object-collection-with-param.xml @@ -22,6 +22,10 @@ + + givenName + string + UserType From 3667d06451b77e02a5d7bbc6ad47837c4909342b Mon Sep 17 00:00:00 2001 From: lskublik Date: Tue, 27 Apr 2021 17:38:50 +0200 Subject: [PATCH 03/15] rewrite jasper report from initial-objects to new object collection reports --- .../AutoCompleteReferencePanelFactory.java | 72 + .../search/ReferenceAutocomplete.java | 10 +- .../ReferenceValueSearchPopupPanel.java | 8 - .../web/page/admin/reports/PageReports.java | 2 +- .../component/RunReportPopupPanel.html | 19 +- .../component/RunReportPopupPanel.java | 99 +- .../initial-objects/080-report-audit.xml | 21 - .../090-report-audit-jasper.xml | 25 - .../initial-objects/090-report-audit.xml | 227 ++ .../100-report-reconciliation.xml | 197 +- .../initial-objects/110-report-user-list.xml | 165 +- .../130-report-certification-definitions.xml | 41 +- .../140-report-certification-campaigns.xml | 189 +- .../150-report-certification-cases.xml | 203 +- .../160-report-certification-decisions.xml | 183 +- ... => 251-object-collection-resource-up.xml} | 0 ... => 261-object-collection-task-active.xml} | 0 ...it.xml => 270-object-collection-audit.xml} | 0 ...ml => 271-object-collection-audit-24h.xml} | 0 ...72-object-collection-audit-errors-24h.xml} | 0 ...ct-collection-audit-modifications-24h.xml} | 0 ...-collection-certification-campaign-all.xml | 27 + ...l => 290-object-collection-shadow-all.xml} | 10 +- .../prism}/query/PagingConvertor.java | 4 +- .../public/common/common-certification-3.xsd | 2971 +++++++++-------- .../xml/ns/public/common/common-core-3.xsd | 15 + .../impl/controller/DashboardServiceImpl.java | 41 - .../ModelInteractionServiceImpl.java | 22 +- .../report/impl/ReportServiceImpl.java | 20 +- .../controller/fileformat/CsvController.java | 12 +- .../fileformat/FileFormatController.java | 45 +- .../controller/fileformat/HtmlController.java | 15 +- 32 files changed, 2876 insertions(+), 1767 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java delete mode 100644 gui/admin-gui/src/main/resources/initial-objects/080-report-audit.xml delete mode 100644 gui/admin-gui/src/main/resources/initial-objects/090-report-audit-jasper.xml create mode 100644 gui/admin-gui/src/main/resources/initial-objects/090-report-audit.xml rename gui/admin-gui/src/main/resources/initial-objects/{280-object-collection-resource-up.xml => 251-object-collection-resource-up.xml} (100%) rename gui/admin-gui/src/main/resources/initial-objects/{270-object-collection-task-active.xml => 261-object-collection-task-active.xml} (100%) rename gui/admin-gui/src/main/resources/initial-objects/{284-object-collection-audit.xml => 270-object-collection-audit.xml} (100%) rename gui/admin-gui/src/main/resources/initial-objects/{285-object-collection-audit-24h.xml => 271-object-collection-audit-24h.xml} (100%) rename gui/admin-gui/src/main/resources/initial-objects/{290-object-collection-audit-errors-24h.xml => 272-object-collection-audit-errors-24h.xml} (100%) rename gui/admin-gui/src/main/resources/initial-objects/{300-object-collection-audit-modifications-24h.xml => 273-object-collection-audit-modifications-24h.xml} (100%) create mode 100644 gui/admin-gui/src/main/resources/initial-objects/280-object-collection-certification-campaign-all.xml rename gui/admin-gui/src/main/resources/initial-objects/{255-object-collection-certification-definition-all.xml => 290-object-collection-shadow-all.xml} (66%) rename infra/{prism-impl/src/main/java/com/evolveum/midpoint/prism/impl => prism-api/src/main/java/com/evolveum/midpoint/prism}/query/PagingConvertor.java (95%) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java new file mode 100644 index 00000000000..71f5ca79373 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010-2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.gui.impl.factory.panel; + +import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteReferenceRenderer; +import com.evolveum.midpoint.gui.api.factory.GuiComponentFactory; +import com.evolveum.midpoint.gui.api.prism.wrapper.ItemWrapper; +import com.evolveum.midpoint.gui.api.prism.wrapper.PrismReferenceWrapper; +import com.evolveum.midpoint.gui.api.registry.GuiComponentRegistry; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.impl.prism.wrapper.PrismReferenceValueWrapperImpl; +import com.evolveum.midpoint.report.api.ReportConstants; +import com.evolveum.midpoint.util.QNameUtil; +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.LinkedReferencePanel; +import com.evolveum.midpoint.web.component.search.ReferenceAutocomplete; +import com.evolveum.midpoint.web.component.search.ReferenceValueSearchPopupPanel; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.model.Model; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @author lskublik + */ +@Component +public class AutoCompleteReferencePanelFactory + implements GuiComponentFactory> { + + private static final Trace LOGGER = TraceManager.getTrace(AutoCompleteReferencePanelFactory.class); + + @Autowired private GuiComponentRegistry registry; + + @PostConstruct + public void register() { + registry.addToRegistry(this); + } + + @Override + public Integer getOrder() { + return 100; + } + + @Override + public > boolean match(IW wrapper) { + return QNameUtil.match(ObjectReferenceType.COMPLEX_TYPE, wrapper.getTypeName()) && + ReportConstants.NS_EXTENSION.equals(wrapper.getNamespace()); + } + + @Override + public org.apache.wicket.Component createPanel(PrismReferencePanelContext panelCtx) { + ReferenceAutocomplete panel = new ReferenceAutocomplete(panelCtx.getComponentId(), panelCtx.getRealValueModel(), + new AutoCompleteReferenceRenderer(), + panelCtx.getPageBase()); + panel.setOutputMarkupId(true); + panel.add(AttributeAppender.append("style", "padding-top:5px")); //ugly hack to be aligned with prism-property-label + return panel; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java index 04ec0521258..a012bf3cd33 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java @@ -11,6 +11,7 @@ import java.util.Iterator; import java.util.List; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import org.apache.commons.lang3.StringUtils; @@ -36,14 +37,16 @@ /** * @author honchar */ -public abstract class ReferenceAutocomplete extends AutoCompleteTextPanel { +public class ReferenceAutocomplete extends AutoCompleteTextPanel { private static final long serialVersionUID = 1L; private final PageBase pageBase; + private final IModel model; public ReferenceAutocomplete(String id, final IModel model, IAutoCompleteRenderer renderer, PageBase pageBase) { super(id, model, ObjectReferenceType.class, renderer); this.pageBase = pageBase; + this.model = model; } @Override @@ -82,7 +85,10 @@ protected boolean isAllowedNotFoundObjectRef() { } protected Class getReferenceTargetObjectType(){ - return (Class) AbstractRoleType.class; + if (model.getObject().getType() == null) { + return (Class) ObjectType.class; + } + return (Class) WebComponentUtil.qnameToClass(pageBase.getPrismContext(), model.getObject().getType()); } protected int getMaxRowsCount() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java index e1367088571..f9ef3d8e9dd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java @@ -86,14 +86,6 @@ public void setObject(String object) { private static final long serialVersionUID = 1L; - @Override - protected Class getReferenceTargetObjectType() { - if (getModelObject().getType() == null) { - return (Class) ObjectType.class; - } - return (Class) WebComponentUtil.qnameToClass(getPageBase().getPrismContext(), getModelObject().getType()); - } - @Override protected boolean isAllowedNotFoundObjectRef() { return ReferenceValueSearchPopupPanel.this.isAllowedNotFoundObjectRef(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java index 6ae03cfaf61..8f8ff00970b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java @@ -290,7 +290,7 @@ private void runConfirmPerformed(AjaxRequestTarget target, ReportType reportType protected void runReportPerformed(AjaxRequestTarget target, ReportType report) { - if(report.getObjectCollection() == null) { + if(report.getObjectCollection() == null || report.getObjectCollection().getParameter().isEmpty()) { runConfirmPerformed(target, report, null); return; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html index b76fff0b1e0..9cfabf7b116 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.html @@ -10,25 +10,20 @@
-
-
-
+
+
+

-
-
- -
-
-
-
-
+
+
+

- +

diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java index 780fba46824..af42566baf6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java @@ -96,53 +96,63 @@ protected void onInitialize() { } private void initParameters() { - PrismContainerDefinition paramContainerDef = getPrismContext().getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + PrismContainerValue reportParamValue; + try { + PrismContainerDefinition paramContainerDef = getPrismContext().getSchemaRegistry() + .findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + paramContainer = paramContainerDef.instantiate(); + + ReportParameterType reportParam = new ReportParameterType(); + reportParamValue = reportParam.asPrismContainerValue(); + reportParamValue.revive(getPrismContext()); + paramContainer.add(reportParamValue); + } catch (SchemaException e) { + LOGGER.error("Couldn't create container for report parameters"); + return; + } for (SearchFilterParameterType parameter : reportType.getObjectCollection().getParameter()) { - try { - paramContainer = paramContainerDef.instantiate(); - - ReportParameterType reportParam = new ReportParameterType(); - PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); - reportParamValue.revive(getPrismContext()); - paramContainer.add(reportParamValue); - - Class clazz = getPrismContext().getSchemaRegistry().determineClassForType(parameter.getType()); - QName type = getPrismContext().getSchemaRegistry().determineTypeForClass(clazz); - if (Containerable.class.isAssignableFrom(clazz)) { - LOGGER.error("Couldn't create container item for parameter " + parameter); - continue; - } - MutableItemDefinition def; - if (Referencable.class.isAssignableFrom(clazz)) { - def = getPrismContext().definitionFactory().createReferenceDefinition( - new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); - ((MutablePrismReferenceDefinition)def).setTargetTypeName(parameter.getTargetType()); + Class clazz = getPrismContext().getSchemaRegistry().determineClassForType(parameter.getType()); + QName type = getPrismContext().getSchemaRegistry().determineTypeForClass(clazz); + if (Containerable.class.isAssignableFrom(clazz)) { + LOGGER.error("Couldn't create container item for parameter " + parameter); + continue; + } + MutableItemDefinition def; + if (Referencable.class.isAssignableFrom(clazz)) { + def = getPrismContext().definitionFactory().createReferenceDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); + ((MutablePrismReferenceDefinition) def).setTargetTypeName(parameter.getTargetType()); + } else { + List values = WebComponentUtil.getAllowedValues(parameter, getPageBase()); + if (CollectionUtils.isNotEmpty(values)) { + def = (MutableItemDefinition) getPrismContext().definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type, values, null); } else { - List values = WebComponentUtil.getAllowedValues(parameter, getPageBase()); - if (CollectionUtils.isNotEmpty(values)) { - def = (MutableItemDefinition) getPrismContext().definitionFactory().createPropertyDefinition( - new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type, values, null); - } else { - def = getPrismContext().definitionFactory().createPropertyDefinition( - new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); - } - } - def.setDynamic(true); - def.setRuntimeSchema(true); - def.setMaxOccurs(1); - def.setMinOccurs(0); - if (parameter.getDisplay() != null) { - String displayName = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getLabel()); - def.setDisplayName(displayName); - String help = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getHelp()); - def.setHelp(help); + def = getPrismContext().definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, parameter.getName()), type); } - if (parameter.getAllowedValuesLookupTable() != null) { - def.setValueEnumerationRef(parameter.getAllowedValuesLookupTable().asReferenceValue()); + } + def.setDynamic(true); + def.setRuntimeSchema(true); + def.setMaxOccurs(1); + def.setMinOccurs(0); + if (parameter.getDisplay() != null) { + String displayName = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getLabel()); + def.setDisplayName(displayName); + String help = WebComponentUtil.getTranslatedPolyString(parameter.getDisplay().getHelp()); + def.setHelp(help); + } + if (parameter.getAllowedValuesLookupTable() != null) { + def.setValueEnumerationRef(parameter.getAllowedValuesLookupTable().asReferenceValue()); + } + try { + Item item = def.instantiate(); + if (item instanceof PrismReference){ + ObjectReferenceType ref = new ObjectReferenceType(); + ref.setType(parameter.getTargetType()); + item.add(ref.asReferenceValue()); } - - Item prop = def.instantiate(); - reportParamValue.add(prop); + reportParamValue.add(item); } catch (SchemaException e) { LOGGER.error("Couldn't create item for parameter " + parameter); @@ -349,7 +359,8 @@ private void runConfirmPerformed(AjaxRequestTarget target) { PrismContainer parameterContainer = paramContainer.clone(); List itemForRemoving = new ArrayList<>(); parameterContainer.getValue().getItems().forEach((item) -> { - if (item.isEmpty() || item.getRealValue() == null){ + if (item.isEmpty() || item.getRealValue() == null + || (item instanceof PrismReference && ((PrismReference) item).getRealValue() != null && ((PrismReference) item).getRealValue().getOid() == null)) { itemForRemoving.add(item); } }); diff --git a/gui/admin-gui/src/main/resources/initial-objects/080-report-audit.xml b/gui/admin-gui/src/main/resources/initial-objects/080-report-audit.xml deleted file mode 100644 index 42194b59555..00000000000 --- a/gui/admin-gui/src/main/resources/initial-objects/080-report-audit.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - All audit records report - Report made from all audit records. - - - - - - - - - diff --git a/gui/admin-gui/src/main/resources/initial-objects/090-report-audit-jasper.xml b/gui/admin-gui/src/main/resources/initial-objects/090-report-audit-jasper.xml deleted file mode 100644 index 5ec1a4d1e28..00000000000 --- a/gui/admin-gui/src/main/resources/initial-objects/090-report-audit-jasper.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - Audit logs report (Jasper) - Report made from audit records. - - true - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - html - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - - prismReference - - diff --git a/gui/admin-gui/src/main/resources/initial-objects/090-report-audit.xml b/gui/admin-gui/src/main/resources/initial-objects/090-report-audit.xml new file mode 100644 index 00000000000..1704e9025ea --- /dev/null +++ b/gui/admin-gui/src/main/resources/initial-objects/090-report-audit.xml @@ -0,0 +1,227 @@ + + + + + All audit records report + Report made from all audit records. + + + + + + + + + + + + targetRef + + filterAll + + + + + initiatorRef + + filterAll + + + + + outcome + + filterAll + + + + + eventType + + filterAll + + + + + eventStage + + filterAll + + + + + timestamp + + filterAll + + + + + timestamp + + filterAll + + + + + + + + outcome + OperationResultStatusType + + + + + + eventType + AuditEventTypeType + + + + + + eventStage + AuditEventStageType + + + + + + from + dateTime + + + + + + to + dateTime + + + + + + target + c:ObjectReferenceType + + + + + + initiator + c:ObjectReferenceType + + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/100-report-reconciliation.xml b/gui/admin-gui/src/main/resources/initial-objects/100-report-reconciliation.xml index 32f521d5f4d..b8d07a40ded 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/100-report-reconciliation.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/100-report-reconciliation.xml @@ -1,22 +1,189 @@ - - Reconciliation report (Jasper) - Reconciliation report for selected resource. - - true - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - pdf - JRSwapFileVirtualizer - 300 - 10000 - 300000 - + + + Reconciliation report + Reconciliation report for selected resource. + + + + + + + + + + + + resourceRef + + filterAll + + + + + synchronizationSituation + + filterAll + + + + + objectClass + + filterAll + + + + + kind + + filterAll + + + + + intent + + filterAll + + + + + + + + intent + string + + + + + + objectClass + string + + + + + + kind + ShadowKindType + + + + + + situation + SynchronizationSituationType + + + + + + resource + c:ObjectReferenceType + c:ResourceType + + + + + + ShadowType + + nameColumn + name + + + situationColumn + synchronizationSituation + nameColumn + + + synchTimestampColumn + synchronizationTimestamp + situationColumn + + + resourceColumn + resourceRef + synchTimestampColumn + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/110-report-user-list.xml b/gui/admin-gui/src/main/resources/initial-objects/110-report-user-list.xml index e1e6395cf7a..c73e31f96ad 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/110-report-user-list.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/110-report-user-list.xml @@ -1,21 +1,160 @@ - - Users in MidPoint (Jasper) + + + Users in MidPoint Users listed in MidPoint. - - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - pdf - JRSwapFileVirtualizer - 300 - 10000 - 300000 - + + + + + + + + + activation/administrativeStatus + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/construction/resourceRef + + filterAll + + + + + + + + activation + ActivationStatusType + + + + + + organization + c:ObjectReferenceType + c:OrgType + + + + + + role + c:ObjectReferenceType + c:RoleType + + + + + + resource + c:ObjectReferenceType + c:ResourceType + + + + + + UserType + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/130-report-certification-definitions.xml b/gui/admin-gui/src/main/resources/initial-objects/130-report-certification-definitions.xml index 9795729d665..ae05a788aa2 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/130-report-certification-definitions.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/130-report-certification-definitions.xml @@ -7,6 +7,7 @@ --> Certification definitions report All certification definitions with basic information on related campaigns. @@ -15,15 +16,14 @@ - + + + nameColumn name - - - ownerColumn @@ -43,21 +43,12 @@ + number openCampaignsColumn @@ -74,7 +65,6 @@ oid = object.getOid(); numberOfCampaigns = 0; - campaigns = midpoint.searchObjects(AccessCertificationCampaignType.class, prismContext.queryFor(AccessCertificationCampaignType.class).build(), null); for (AccessCertificationCampaignType campaign : campaigns) { if (oid.equals(campaign.getDefinitionRef().getOid())) { AccessCertificationCampaignStateType state = campaign.getState(); @@ -89,6 +79,7 @@ + number lastStartedColumn @@ -126,6 +117,24 @@ AccessCertificationDefinitionType + + ascending + name + + + campaigns + AccessCertificationCampaignType + + + + true diff --git a/gui/admin-gui/src/main/resources/initial-objects/140-report-certification-campaigns.xml b/gui/admin-gui/src/main/resources/initial-objects/140-report-certification-campaigns.xml index 78b2853c93e..c34d4949e8f 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/140-report-certification-campaigns.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/140-report-certification-campaigns.xml @@ -7,19 +7,180 @@ --> - Certification campaigns report (Jasper) - All certification campaigns along with their state. - - true - - html - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - - prismReference - + Certification campaigns report + All certification campaigns along with their state. + + + + + + + + + state + + filterAll + + + + + state + inReviewStage + + + state + reviewStageDone + + + state + inRemediation + + + + + + + + + + nameColumn + name + + + + + + ownerColumn + ownerRef + + + + nameColumn + + + startTimestampColumn + startTimestamp + + + + ownerColumn + + + + + + + + endTimestampColumn + endTimestamp + + + + startTimestampColumn + + + + + + + + casesColumn + case + + + + endTimestampColumn + number + + + stateColumn + state + + + + casesColumn + + + stageNumberColumn + stageNumber + + + + stateColumn + + + stageCasesColumn + stageNumberColumn + + + + + + + + + + + percentageCompleteColumn + stageCasesColumn + + + + + + + + + + AccessCertificationCampaignType + + true + + ascending + name + + + alsoClosedCampaigns + boolean + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/150-report-certification-cases.xml b/gui/admin-gui/src/main/resources/initial-objects/150-report-certification-cases.xml index b0f6c1478a5..edd13c50f19 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/150-report-certification-cases.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/150-report-certification-cases.xml @@ -6,19 +6,194 @@ ~ and European Union Public License. See LICENSE file for details. --> - Certification cases report (Jasper) - Cases within a given certification campaign. - - true - - html - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - - prismReference - + Certification cases report + Cases within a given certification campaign. + + + + + ../name + + filterAll + + + + + + + + objectColumn + objectRef + + + + + + + + + + + targetColumn + targetRef + + + + objectColumn + + + + + + + + reviewersColumn + + + + targetColumn + + + + + + + + lastReviewedOnColumn + + + + reviewersColumn + + + + + + + + reviewedByColumn + + + + lastReviewedOnColumn + + + + + + + + iterationColumn + iteration + + + + reviewedByColumn + + + inStageNumberColumn + stageNumber + + + + iterationColumn + + + outcomeColumn + outcome + + + + inStageNumberColumn + + + commentsColumn + + + + outcomeColumn + + + + + + + + remediedTimestampColumn + remediedTimestamp + + + + commentsColumn + + AccessCertificationCaseType + + + objectRef/@/name + + + campaignName + c:ObjectReferenceType + c:AccessCertificationCampaignType + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/160-report-certification-decisions.xml b/gui/admin-gui/src/main/resources/initial-objects/160-report-certification-decisions.xml index 86cb0f2e414..0b58b51e360 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/160-report-certification-decisions.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/160-report-certification-decisions.xml @@ -6,19 +6,176 @@ ~ and European Union Public License. See LICENSE file for details. --> - Certification decisions report (Jasper) + Certification decisions report Decisions of individual reviewers for a certification campaign as a whole or for a given campaign stage. - - true - - html - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - - prismReference - + + + + + ../name + + filterAll + + + + + + + + + + + objectColumn + objectRef + + + + + + + + + + + targetColumn + targetRef + + + + objectColumn + + + + + + + + workItemColumn + workItem + + + + targetColumn + + + + + + + c:AccessCertificationCaseType + + + objectRef/@/name + + + campaignName + c:ObjectReferenceType + c:AccessCertificationCampaignType + + + + + + stageNumber + string + + + + + + iteration + string + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/280-object-collection-resource-up.xml b/gui/admin-gui/src/main/resources/initial-objects/251-object-collection-resource-up.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/280-object-collection-resource-up.xml rename to gui/admin-gui/src/main/resources/initial-objects/251-object-collection-resource-up.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/270-object-collection-task-active.xml b/gui/admin-gui/src/main/resources/initial-objects/261-object-collection-task-active.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/270-object-collection-task-active.xml rename to gui/admin-gui/src/main/resources/initial-objects/261-object-collection-task-active.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/284-object-collection-audit.xml b/gui/admin-gui/src/main/resources/initial-objects/270-object-collection-audit.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/284-object-collection-audit.xml rename to gui/admin-gui/src/main/resources/initial-objects/270-object-collection-audit.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/285-object-collection-audit-24h.xml b/gui/admin-gui/src/main/resources/initial-objects/271-object-collection-audit-24h.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/285-object-collection-audit-24h.xml rename to gui/admin-gui/src/main/resources/initial-objects/271-object-collection-audit-24h.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/290-object-collection-audit-errors-24h.xml b/gui/admin-gui/src/main/resources/initial-objects/272-object-collection-audit-errors-24h.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/290-object-collection-audit-errors-24h.xml rename to gui/admin-gui/src/main/resources/initial-objects/272-object-collection-audit-errors-24h.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/300-object-collection-audit-modifications-24h.xml b/gui/admin-gui/src/main/resources/initial-objects/273-object-collection-audit-modifications-24h.xml similarity index 100% rename from gui/admin-gui/src/main/resources/initial-objects/300-object-collection-audit-modifications-24h.xml rename to gui/admin-gui/src/main/resources/initial-objects/273-object-collection-audit-modifications-24h.xml diff --git a/gui/admin-gui/src/main/resources/initial-objects/280-object-collection-certification-campaign-all.xml b/gui/admin-gui/src/main/resources/initial-objects/280-object-collection-certification-campaign-all.xml new file mode 100644 index 00000000000..a92f8c21f25 --- /dev/null +++ b/gui/admin-gui/src/main/resources/initial-objects/280-object-collection-certification-campaign-all.xml @@ -0,0 +1,27 @@ + + + + + All certification campaigns + AccessCertificationCampaignType + + + + + + + diff --git a/gui/admin-gui/src/main/resources/initial-objects/255-object-collection-certification-definition-all.xml b/gui/admin-gui/src/main/resources/initial-objects/290-object-collection-shadow-all.xml similarity index 66% rename from gui/admin-gui/src/main/resources/initial-objects/255-object-collection-certification-definition-all.xml rename to gui/admin-gui/src/main/resources/initial-objects/290-object-collection-shadow-all.xml index 330c41f246c..5dff0c4992b 100644 --- a/gui/admin-gui/src/main/resources/initial-objects/255-object-collection-certification-definition-all.xml +++ b/gui/admin-gui/src/main/resources/initial-objects/290-object-collection-shadow-all.xml @@ -1,6 +1,6 @@ - - - - - - TODO - - - - - - - - - - - - - - - - Definition of an access certification - a template for - a set of access certification campaigns. - - - - - - - - - The certification handler that should take care of certification campaigns - created according to this definition. - - - - - - - Specifies the standard scope of certifications of this type. (In the future it can be overridden - in specific certification campaign.) - - - - - - - The user that owns certification campaigns based on this definition. - - - tns:UserType - - - - - - - How the identified cases have to be resolved? - - - - - - - Configuration of the manual or automatic reiteration. - - - 3.9 - - - - - - - Definition of individual stages (reviewers, duration, ...). - - - - - - - Strategy used to compute review outcome for a given case, based on results of individual stages, - along with instructions when a case review advances from a stage to next one. - - - - - - - Denotes "ad hoc" certification campaign, i.e. one that is started by policy rules, not explicitly by a user. - - - 3.6 - - - - - - - ID that was used to auto-generate campaign name last time (null if none so far). - - - - - - - When the last campaign of this type was started (in its first iteration)? - - - - - - - When the last campaign of this type was closed? Deletion is not recorded in this attribute. - - - - - - - - - - - - - - - - - - - - - Access certification definition augmented with report-related information - (e.g. number of campaigns). - - EXPERIMENTAL. It is to be seen if this form is OK. - - - - - - - - - - - - - - - - - Access certification definition. - - - - - - - - - - - - - Definition of an access certification campaign stage. - - - - - - - - - - Stages are numbered from 1 onwards. - - - - - - - Stage name. - - - - - - - Stage description. - - - - - - - - How long should the stage last? - - - - - - - How to round the deadline (if at all)? The default is to 23:59:59 of the computed day. - - - - - - - How long before the end of stage should notifications be sent? - (Multiple values can be put here.) - - - - - - - Send notifications only to people that have not decided yet. - - - - - - - TODO - - - - - - - How to determine outcome of the approval process (e.g. if multiple reviewers are present)? - Default is oneAcceptAccepts. - - - - - - - What is the outcome if no reviewers are available? (This is not the same situation as if some reviewers were computed but none of them responded!) - - - - - - - What decisions stop the case from advancing to the next stage? - If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined at the campaign level) is used. - - - - - - - What decisions make the case to advance to the next stage? - If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined at the campaign level) is used. - - - - - - - What actions are to be applied to work items when given timer(s) occur. - EXPERIMENTAL - - - 3.6 - - - - - - - - - - - Specifies how to select reviewers for a campaign stage. - - - - - - - - - - User-readable name of this reviewer specification. (In case it is necessary.) - - - - - - - Description of this reviewer specification. - - - - - - - - Indicates that target object (Org, Role, Resource) owner(s) should be used as reviewer(s). - - - - - - - Indicates that target object (Org, Role, Resource) approver(s) should be used as reviewer(s). - - - - - - - Indicates that object (Org, Role) owner(s) should be used as reviewer(s). - - - - - - - Indicates that object (Org, Role) approver(s) should be used as reviewer(s). - - - - - - - Indicates that the object's managers should be used. The interpretation depends on what kind - of object there is. - - For a user, the managers of all organizations to which he/she belongs, are taken. - For an org, its managers are taken. - (For the future: For a role, if it has a parentOrgRef, managers of these are taken. If it has - none, no reviewers are contributed by this option.) - - - - - - - The most general way of specifying the reviewer. Inputs for such expressions are: - - certificationCase (current certification case), - - campaign (certification campaign object), - - reviewerSpecification (current reviewer specification). - Output is a collection of parent-less reviewer references (of type ObjectReferenceType). - - - - - - - If no reviewer(s) are computed by other means, this/these should be used. - - - tns:FocusType - - - - - - - These reviewers are always used. - - - tns:FocusType - - - - - - - - - - - Definition of an access certification campaign. - - - - - - - - - Specifies the definition for this certification campaign. - (It is optional, as there are also ad-hoc certifications with no pre-existing definition.) - - - tns:AccessCertificationDefinitionType - - - - - - - Specifies the owner of this certification campaign. - - - tns:UserType - - - - - - - The certification handler that should take care of this campaign. - - - - - - - Specifies the scope of this campaign. - - - - - - - How the identified cases have to be resolved? - - - - - - - Configuration of the manual or automatic reiteration. - - - 3.9 - - - - - - - Definition of individual stages. - - - - - - - Strategy used to compute review outcome for a given case, based on results of individual stages, - along with instructions when a case review advances from a stage to next one. - - - - - - - When this campaign has to start (or has started). - - - - - - - When this campaign has finished. - - - - - - - Which iteration this campaign is in. 1 means the regular (first) run; - 2 means first repetition, etc. - - - 3.9 - - - - - - - In which state is the current campaign. - - - - - - - The stage this campaign is in. - 0 means it has not started yet. - X in 1..N (where N is the number of defined stages) means that stage X is being carried out. - Y greater than N means the campaign has been already finished. - - - - - - - Stages for this campaign (already finished, current, or planned). - - - - - - - Certification cases for this campaign. - - - - - - - - - - - - - Information about a stage of a campaign. - - - - - - - - - - Which iteration this stage is part of. 1 means the first (i.e. regular) run. - - - 3.9 - - - - - - - TODO - - - - - - - Stage name. - - - - - - - Stage description. - - - - - - - - When this stage has started. - - - - - - - When this stage has to finish. - - - - - - - When this stage has actually finished. - - - - - - - The escalation level is currently the same for open all cases and their open work items in the stage. - (This might change in the future.) - - - - - - - - - - - Specifies the scope of an access certification campaign. - - - - - - - - - - User-readable name of this scope definition. (In case it is necessary.) - - - - - - - Description of this scope definition. - - - - - - - - - - - - - - - The most common way of specifying scope - providing type+search filter to select "base" objects - and then some means of deriving certification cases from them. - - - - - - - - - Type of objects to be selected for certification. - - - - - - - Filter to find objects for certification. - By default, all objects of a given type will be selected. - - - - - - - Expression that selects items that are to be included in the certification. - Exact use of this expression depends on the certification handler. - E.g. user assignment handler could call this expression individually with each assignment - to determine which assignments should be included and which should not. - - - - - - - Expression that produces certification cases. This can be any expression, whose input is an object - that has passed the search filter specified above, and its output is a list of certification cases. - An example: a groovy expression, creating certification cases by selecting user's - "risky" assignments (e.g. assignments to a roles of a given type/types). Another example - can be the computation of all assignments (direct and indirect ones), and selecting among these. - NOT IMPLEMENTED YET - - - - - - - - - - - - - Scope for assignment-related reviews. - - - - - - - - - - - - Should assignments be included in the certification? - - - - - - - Should inducements be included in the certification? - - - - - - - Should assignments/inducements of roles be included in the certification? - - - - - - - Should assignments/inducements of orgs be included in the certification? - - - - - - - Should assignments/inducements of resources be included in the certification? - - - - - - - Should assignments/inducements of services be included in the certification? - - - - - - - Should assignments/inducements of users (e.g. deputy relations) be included in the certification? - - - - - - - Should we approve only assignments/inducements that are currently enabled? - (I.e. with administrativeStatus either null or ENABLED) - - - - - - - Relation(s) which are to be considered. Value of q:any means "any relation". - If no relation is present, org:default (i.e. null) is assumed. - - - - - - - - - - - - - An item that has to be certified, viewed in the scope of a given certification campaign. - - - - - - - - - - Object (e.g. a user) that is being touched by this case. - - - tns:ObjectType - - - - - - - Quite an abstract parameter - describing the object of the certification case (e.g. a role, a resource, ...). - Used for selecting relevant cases for approvals. - - - tns:ObjectType - - - - - - - For parameterized certification items (e.g. assignments): a tenant parameter, if applicable. - See discussion on tenantRef in AssignmentType. - - - tns:OrgType - - - - - - - For parameterized certification items (e.g. assignments): an org parameter, if applicable. - See discussion on orgRef in AssignmentType. - - - tns:OrgType - - - - - - - If the target is assigned with activation information (e.g. validFrom/validTo/administrativeStatus) - here is the information copied. Note that other activation information (e.g. effectiveStatus) are - _not_ updated here and probably should be ignored. - - - - - - - - The number of current stage in which this case is. - E.g. currentOutcome relates to the currentStage. - Case is "enabled" for a current campaign stage if and only if case.currentStage == campaign.stageNumber. - - When opening a campaign stage, case's currentStage either advances (if it is transferred to stage being opened) - or stays at the existing value (if it is not). It then indicates the last stage this case - was reviewed in. - - - - - - - Iteration this case takes part of. Case is "enabled" for a current campaign stage if and only if - case.iteration == campaign.iteration (beware of null comparison). - - - - - - - Work items for this stage. Some might be completed. Work items are not deleted. - - - 3.6 - - - - - - - When was this certification case requested to be reviewed? - (Can be found in certification.stage.start but we need to - sort according to this value.) - - - - - - - When should this certification case be reviewed? - (Can be found in certification.stage.end but we need to - sort according to this value.) - - - - - - - Currently valid outcome, relevant to the current stage. It is recomputed on each reviewer's - response based on defined algorithms. If the case is not transferred into the next stage, - the value of this item stays as it is. - - - - - - - The outcome, taking into account all closed stages plus current stage (if any). - - - - - - - When was the review process for this case finished (for the current iteration)? - This value is cleared for cases entering the next iteration. - - - 3.9 - - - - - - - When was this certification case was remedied? - If null, this means that either remediation was not required - (either because the decision was "accept" or "abstain" or - because remediation mode was set to "none"). - - - - - - - Events that occurred during lifetime of this case. - - - - - - - - - - - - - - - - - - - - - - - - - A work item for a certification case. - - - - 3.6 - - - - - - - - - When the decision was made or changed. - - - - - - - Which iteration this work item is part of. 1 means the first (i.e. regular) run. - - - 3.9 - - - - - - - - - - - - - - - - - - - - - Assignment that is being considered. - - - - - - - Indicates if the above assignment is an assignment or (in case of roles) an inducement. - - - - - - - - - - - - - An enumeration that defines possible reviewers' responses. - - - - - - - A.k.a. maintain, confirm, certify, approve, OK - the situation was approved and can be left - as it is. It is possible to enter a date when the approval will expire. Until this time - the item will be considered approved and will not be shown in the certification list - for the given certifier. (We have to decide how to implement this feature. The most simple - but not entirely correct solution is to set "validTo" date for a given assignment. But it - wouldn't work e.g. for indirect assignments.) - - - - - - - - - - A.k.a. reject, remove, "not OK" - the situation is unacceptable and has to be eliminated - or disabled. E.g. the assignment has to be removed or disabled. - - - - - - - - - - A.k.a. update - situation is not acceptable; however, simple elimination/disabling is not - necessary or not appropriate - someone has to look at this and try to find another solution. - - - - - - - - - - A.k.a. abstain - responsible person says he/she is not able to decide. - - - - - - - - - - Responsible person delegates the decision to someone else. - DEPRECATED - - - - - - - - - - No response was provided by the given reviewer. - (This state can be used e.g. to facilitate querying by state.) - - SHOULD NOT BE USED FOR INDIVIDUAL RESPONSES. (A null value should be used instead.) - But it's OK to use this for stage/case outcome. - - - - - - - - - - - - - - - Strategy used to compute review outcome for a given case, based on results of individual stages. - Default is oneDenyDenies. - - - - - - - What decisions stop the case from advancing to the next stage? - If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined by the outcomeStrategy) is used. - - - - - - - What decisions make the case to advance to the next stage? - If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined by the outcomeStrategy) is used. - - - - - - - - - - An enumeration that defines possible strategies for case outcome (approval) computation - currently both at the stage and campaign level. - (In the future, these uses might be split.) - - - - - - - If at least one reviewer approves, the result is "APPROVED" regardless of the other votes. - - - - - - - - - - If at least one reviewer denies (either via revoke or reduce), the result is "NOT APPROVED". - However, for the case to be approved, at least approval must be present. - - - - - - - - - - Approved if none of the reviewers denies (either via revoke or reduce). - So e.g. if nobody says anything, the case is approved. - - - - - - - - - - All reviewers must approve, i.e. no revoke, reduce, noResponse is acceptable. - - - - - - - - - - - - - TODO - - - - - - - - - - TODO - - - - - - - What (final) outcomes cause actual remediation (e.g. deletion of an assignment) if automated remediation is configured? - The default is "revoke". But more can be specified here, e.g. noResponse. - - - - - - - - - - - TODO - - - - 3.9 - - - - - - - How long after campaign is closed should automatic reiteration start? - The default is that reiteration starts only manually. - - - - - - - How many iterations are allowed for automatic start? After reaching the specified number of iterations - (irrespective of how they were started) automatic reiteration mechanism will be disabled for this - campaign. - - - - - - - How many iterations are allowed in total? After reaching the specified number of iterations - no new iterations can be opened. - - - - - - - - - - - An enumeration that defines possible styles for certification case remediation. - - - - - - - Resolution of revoked cases is fully automated. - - - - - - - - - - Non-conformant cases are only to be reported. - - - - - - - - - - - - - An enumeration that defines possible states of a certification campaign. - - - - - - - Campaign was created, but its first stage has not been started yet. - Current stage number is 0. - - - - - - - - - - Review is being carried out, in a given stage. - Current stage number is between 1 and N (number of stages). - - - - - - - - - - A given review stage was done. Next stage nor remediation (if any) has not started yet. - Current stage number indicates the number of stage that has been recently done. - - - - - - - - - - The last stage was closed, remediation (either automated or manual) is in progress. - - - - - - - - - - Review and possibly remediation is over. The campaign is closed. - - - - - - - - - - - - - - - Statistics give a set of access certification cases. - - - - - tns:markedAsDelegate - 4.0 - removed - - - - - - - - - - - - - - - - - - - - TODO - - - - - - - - - - - - - Configuration for access certification. - - - - - - - - - - What response types are available to reviewers? Empty list means all responses. - TODO should we configure also names of the responses? (probably no) - - - AccessCertificationConfigurationType.availableResponse - - - - - - - Instructions how to format reviewers comments before storing them into metadata. - EXPERIMENTAL - - - true - 3.7.1 - AccessCertificationConfigurationType.reviewerCommentsFormatting - - - - - - - - + + + + + + + + + TODO + + + + + + + + + + + + + + + + Definition of an access certification - a template for + a set of access certification campaigns. + + + + + + + + + The certification handler that should take care of certification campaigns + created according to this definition. + + + + + + + Specifies the standard scope of certifications of this type. (In the future it can be overridden + in specific certification campaign.) + + + + + + + The user that owns certification campaigns based on this definition. + + + tns:UserType + + + + + + + How the identified cases have to be resolved? + + + + + + + Configuration of the manual or automatic reiteration. + + + 3.9 + + + + + + + Definition of individual stages (reviewers, duration, ...). + + + + + + + Strategy used to compute review outcome for a given case, based on results of individual stages, + along with instructions when a case review advances from a stage to next one. + + + + + + + Denotes "ad hoc" certification campaign, i.e. one that is started by policy rules, not explicitly by a user. + + + 3.6 + + + + + + + ID that was used to auto-generate campaign name last time (null if none so far). + + + + + + + When the last campaign of this type was started (in its first iteration)? + + + + + + + When the last campaign of this type was closed? Deletion is not recorded in this attribute. + + + + + + + + + + + + + + + + + + + + + Access certification definition augmented with report-related information + (e.g. number of campaigns). + + EXPERIMENTAL. It is to be seen if this form is OK. + + + + + + + + + + + + + + + + + Access certification definition. + + + + + + + + + + + + + Definition of an access certification campaign stage. + + + + + + + + + + Stages are numbered from 1 onwards. + + + + + + + Stage name. + + + + + + + Stage description. + + + + + + + + How long should the stage last? + + + + + + + How to round the deadline (if at all)? The default is to 23:59:59 of the computed day. + + + + + + + How long before the end of stage should notifications be sent? + (Multiple values can be put here.) + + + + + + + Send notifications only to people that have not decided yet. + + + + + + + TODO + + + + + + + How to determine outcome of the approval process (e.g. if multiple reviewers are present)? + Default is oneAcceptAccepts. + + + + + + + What is the outcome if no reviewers are available? (This is not the same situation as if some reviewers were computed but none of them responded!) + + + + + + + What decisions stop the case from advancing to the next stage? + If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined at the campaign level) is used. + + + + + + + What decisions make the case to advance to the next stage? + If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined at the campaign level) is used. + + + + + + + What actions are to be applied to work items when given timer(s) occur. + EXPERIMENTAL + + + 3.6 + + + + + + + + + + + Specifies how to select reviewers for a campaign stage. + + + + + + + + + + User-readable name of this reviewer specification. (In case it is necessary.) + + + + + + + Description of this reviewer specification. + + + + + + + + Indicates that target object (Org, Role, Resource) owner(s) should be used as reviewer(s). + + + + + + + Indicates that target object (Org, Role, Resource) approver(s) should be used as reviewer(s). + + + + + + + Indicates that object (Org, Role) owner(s) should be used as reviewer(s). + + + + + + + Indicates that object (Org, Role) approver(s) should be used as reviewer(s). + + + + + + + Indicates that the object's managers should be used. The interpretation depends on what kind + of object there is. + + For a user, the managers of all organizations to which he/she belongs, are taken. + For an org, its managers are taken. + (For the future: For a role, if it has a parentOrgRef, managers of these are taken. If it has + none, no reviewers are contributed by this option.) + + + + + + + The most general way of specifying the reviewer. Inputs for such expressions are: + - certificationCase (current certification case), + - campaign (certification campaign object), + - reviewerSpecification (current reviewer specification). + Output is a collection of parent-less reviewer references (of type ObjectReferenceType). + + + + + + + If no reviewer(s) are computed by other means, this/these should be used. + + + tns:FocusType + + + + + + + These reviewers are always used. + + + tns:FocusType + + + + + + + + + + + Definition of an access certification campaign. + + + + + + + + + Specifies the definition for this certification campaign. + (It is optional, as there are also ad-hoc certifications with no pre-existing definition.) + + + tns:AccessCertificationDefinitionType + + + + + + + Specifies the owner of this certification campaign. + + + tns:UserType + + + + + + + The certification handler that should take care of this campaign. + + + + + + + Specifies the scope of this campaign. + + + + + + + How the identified cases have to be resolved? + + + + + + + Configuration of the manual or automatic reiteration. + + + 3.9 + + + + + + + Definition of individual stages. + + + + + + + Strategy used to compute review outcome for a given case, based on results of individual stages, + along with instructions when a case review advances from a stage to next one. + + + + + + + When this campaign has to start (or has started). + + + + + + + When this campaign has finished. + + + + + + + Which iteration this campaign is in. 1 means the regular (first) run; + 2 means first repetition, etc. + + + 3.9 + + + + + + + In which state is the current campaign. + + + + + + + The stage this campaign is in. + 0 means it has not started yet. + X in 1..N (where N is the number of defined stages) means that stage X is being carried out. + Y greater than N means the campaign has been already finished. + + + + + + + Stages for this campaign (already finished, current, or planned). + + + + + + + Certification cases for this campaign. + + + + + + + + + + + + + Information about a stage of a campaign. + + + + + + + + + + Which iteration this stage is part of. 1 means the first (i.e. regular) run. + + + 3.9 + + + + + + + TODO + + + + + + + Stage name. + + + + + + + Stage description. + + + + + + + + When this stage has started. + + + + + + + When this stage has to finish. + + + + + + + When this stage has actually finished. + + + + + + + The escalation level is currently the same for open all cases and their open work items in the stage. + (This might change in the future.) + + + + + + + + + + + Specifies the scope of an access certification campaign. + + + + + + + + + + User-readable name of this scope definition. (In case it is necessary.) + + + + + + + Description of this scope definition. + + + + + + + + + + + + + + + The most common way of specifying scope - providing type+search filter to select "base" objects + and then some means of deriving certification cases from them. + + + + + + + + + Type of objects to be selected for certification. + + + + + + + Filter to find objects for certification. + By default, all objects of a given type will be selected. + + + + + + + Expression that selects items that are to be included in the certification. + Exact use of this expression depends on the certification handler. + E.g. user assignment handler could call this expression individually with each assignment + to determine which assignments should be included and which should not. + + + + + + + Expression that produces certification cases. This can be any expression, whose input is an object + that has passed the search filter specified above, and its output is a list of certification cases. + An example: a groovy expression, creating certification cases by selecting user's + "risky" assignments (e.g. assignments to a roles of a given type/types). Another example + can be the computation of all assignments (direct and indirect ones), and selecting among these. + NOT IMPLEMENTED YET + + + + + + + + + + + + + Scope for assignment-related reviews. + + + + + + + + + + + + Should assignments be included in the certification? + + + + + + + Should inducements be included in the certification? + + + + + + + Should assignments/inducements of roles be included in the certification? + + + + + + + Should assignments/inducements of orgs be included in the certification? + + + + + + + Should assignments/inducements of resources be included in the certification? + + + + + + + Should assignments/inducements of services be included in the certification? + + + + + + + Should assignments/inducements of users (e.g. deputy relations) be included in the certification? + + + + + + + Should we approve only assignments/inducements that are currently enabled? + (I.e. with administrativeStatus either null or ENABLED) + + + + + + + Relation(s) which are to be considered. Value of q:any means "any relation". + If no relation is present, org:default (i.e. null) is assumed. + + + + + + + + + + + + + An item that has to be certified, viewed in the scope of a given certification campaign. + + + + + + + + + + Object (e.g. a user) that is being touched by this case. + + + tns:ObjectType + + + + + + + Quite an abstract parameter - describing the object of the certification case (e.g. a role, a resource, ...). + Used for selecting relevant cases for approvals. + + + tns:ObjectType + + + + + + + For parameterized certification items (e.g. assignments): a tenant parameter, if applicable. + See discussion on tenantRef in AssignmentType. + + + tns:OrgType + + + + + + + For parameterized certification items (e.g. assignments): an org parameter, if applicable. + See discussion on orgRef in AssignmentType. + + + tns:OrgType + + + + + + + If the target is assigned with activation information (e.g. validFrom/validTo/administrativeStatus) + here is the information copied. Note that other activation information (e.g. effectiveStatus) are + _not_ updated here and probably should be ignored. + + + + + + + + The number of current stage in which this case is. + E.g. currentOutcome relates to the currentStage. + Case is "enabled" for a current campaign stage if and only if case.currentStage == campaign.stageNumber. + + When opening a campaign stage, case's currentStage either advances (if it is transferred to stage being opened) + or stays at the existing value (if it is not). It then indicates the last stage this case + was reviewed in. + + + + + + + Iteration this case takes part of. Case is "enabled" for a current campaign stage if and only if + case.iteration == campaign.iteration (beware of null comparison). + + + + + + + Work items for this stage. Some might be completed. Work items are not deleted. + + + 3.6 + + + + + + + When was this certification case requested to be reviewed? + (Can be found in certification.stage.start but we need to + sort according to this value.) + + + + + + + When should this certification case be reviewed? + (Can be found in certification.stage.end but we need to + sort according to this value.) + + + + + + + Currently valid outcome, relevant to the current stage. It is recomputed on each reviewer's + response based on defined algorithms. If the case is not transferred into the next stage, + the value of this item stays as it is. + + + + + + + The outcome, taking into account all closed stages plus current stage (if any). + + + + + + + When was the review process for this case finished (for the current iteration)? + This value is cleared for cases entering the next iteration. + + + 3.9 + + + + + + + When was this certification case was remedied? + If null, this means that either remediation was not required + (either because the decision was "accept" or "abstain" or + because remediation mode was set to "none"). + + + + + + + Events that occurred during lifetime of this case. + + + + + + + + + + + + + + + + + + + + + + + + + + A work item for a certification case. + + + + 3.6 + + + + + + + + + When the decision was made or changed. + + + + + + + Which iteration this work item is part of. 1 means the first (i.e. regular) run. + + + 3.9 + + + + + + + + + + + + + + + + + + + + + Assignment that is being considered. + + + + + + + Indicates if the above assignment is an assignment or (in case of roles) an inducement. + + + + + + + + + + + + + An enumeration that defines possible reviewers' responses. + + + + + + + A.k.a. maintain, confirm, certify, approve, OK - the situation was approved and can be left + as it is. It is possible to enter a date when the approval will expire. Until this time + the item will be considered approved and will not be shown in the certification list + for the given certifier. (We have to decide how to implement this feature. The most simple + but not entirely correct solution is to set "validTo" date for a given assignment. But it + wouldn't work e.g. for indirect assignments.) + + + + + + + + + + A.k.a. reject, remove, "not OK" - the situation is unacceptable and has to be eliminated + or disabled. E.g. the assignment has to be removed or disabled. + + + + + + + + + + A.k.a. update - situation is not acceptable; however, simple elimination/disabling is not + necessary or not appropriate - someone has to look at this and try to find another solution. + + + + + + + + + + A.k.a. abstain - responsible person says he/she is not able to decide. + + + + + + + + + + Responsible person delegates the decision to someone else. + DEPRECATED + + + + + + + + + + No response was provided by the given reviewer. + (This state can be used e.g. to facilitate querying by state.) + + SHOULD NOT BE USED FOR INDIVIDUAL RESPONSES. (A null value should be used instead.) + But it's OK to use this for stage/case outcome. + + + + + + + + + + + + + + + Strategy used to compute review outcome for a given case, based on results of individual stages. + Default is oneDenyDenies. + + + + + + + What decisions stop the case from advancing to the next stage? + If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined by the outcomeStrategy) is used. + + + + + + + What decisions make the case to advance to the next stage? + If neither stopReviewOn nor advanceToNextStageOn is used, a default (defined by the outcomeStrategy) is used. + + + + + + + + + + An enumeration that defines possible strategies for case outcome (approval) computation - currently both at the stage and campaign level. + (In the future, these uses might be split.) + + + + + + + If at least one reviewer approves, the result is "APPROVED" regardless of the other votes. + + + + + + + + + + If at least one reviewer denies (either via revoke or reduce), the result is "NOT APPROVED". + However, for the case to be approved, at least approval must be present. + + + + + + + + + + Approved if none of the reviewers denies (either via revoke or reduce). + So e.g. if nobody says anything, the case is approved. + + + + + + + + + + All reviewers must approve, i.e. no revoke, reduce, noResponse is acceptable. + + + + + + + + + + + + + TODO + + + + + + + + + + TODO + + + + + + + What (final) outcomes cause actual remediation (e.g. deletion of an assignment) if automated remediation is configured? + The default is "revoke". But more can be specified here, e.g. noResponse. + + + + + + + + + + + TODO + + + + 3.9 + + + + + + + How long after campaign is closed should automatic reiteration start? + The default is that reiteration starts only manually. + + + + + + + How many iterations are allowed for automatic start? After reaching the specified number of iterations + (irrespective of how they were started) automatic reiteration mechanism will be disabled for this + campaign. + + + + + + + How many iterations are allowed in total? After reaching the specified number of iterations + no new iterations can be opened. + + + + + + + + + + + An enumeration that defines possible styles for certification case remediation. + + + + + + + Resolution of revoked cases is fully automated. + + + + + + + + + + Non-conformant cases are only to be reported. + + + + + + + + + + + + + An enumeration that defines possible states of a certification campaign. + + + + + + + Campaign was created, but its first stage has not been started yet. + Current stage number is 0. + + + + + + + + + + Review is being carried out, in a given stage. + Current stage number is between 1 and N (number of stages). + + + + + + + + + + A given review stage was done. Next stage nor remediation (if any) has not started yet. + Current stage number indicates the number of stage that has been recently done. + + + + + + + + + + The last stage was closed, remediation (either automated or manual) is in progress. + + + + + + + + + + Review and possibly remediation is over. The campaign is closed. + + + + + + + + + + + + + + + Statistics give a set of access certification cases. + + + + + tns:markedAsDelegate + 4.0 + removed + + + + + + + + + + + + + + + + + + + + TODO + + + + + + + + + + + + + Configuration for access certification. + + + + + + + + + + What response types are available to reviewers? Empty list means all responses. + TODO should we configure also names of the responses? (probably no) + + + AccessCertificationConfigurationType.availableResponse + + + + + + + Instructions how to format reviewers comments before storing them into metadata. + EXPERIMENTAL + + + true + 3.7.1 + AccessCertificationConfigurationType.reviewerCommentsFormatting + + + + + + + + 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 ea78952ee2a..34cfc42d56b 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -12867,6 +12867,9 @@ It does not provide any further details. More details can be found in the "synchronizationSituationDescription" property. + + ShadowType.synchronizationTimestamp + @@ -25616,6 +25619,18 @@ + + + + Paging for query. + + + true + 4.4 + ObjectCollectionReportEngineConfigurationType.paging + + + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java index de0786664de..270d5333a3b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java @@ -490,47 +490,6 @@ private void evaluateVariation(DashboardWidgetType widget, VariablesMap variable } } -// @Override -// public void searchObjectFromCollection(CollectionRefSpecificationType collectionConfig, AuditResultHandler handler, -// ObjectPaging paging, Task task, OperationResult result, boolean recordProgress) -// throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { -// -// if (collectionConfig.getCollectionRef() != null && collectionConfig.getFilter() != null) { -// LOGGER.error("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); -// throw new IllegalArgumentException("CollectionRefSpecificationType contains CollectionRef and Filter, please define only one"); -// } -// CompiledObjectCollectionView compiledCollection = modelInteractionService.compileObjectCollectionView( -// collectionConfig, AuditEventRecordType.class, task, task.getResult()); -// -// VariablesMap variables = new VariablesMap(); -// ObjectFilter filter = ExpressionUtil.evaluateFilterExpressions(compiledCollection.getFilter(), variables, MiscSchemaUtil.getExpressionProfile(), -// expressionFactory, prismContext, "collection filter", task, result); -// if (filter == null) { -// LOGGER.error("Couldn't find filter"); -// throw new ConfigurationException("Couldn't find filter"); -// } -// -// ObjectQuery query = prismContext.queryFactory().createQuery(); -// query.setFilter(filter); -// query.setPaging(paging); -// ObjectCollectionType collection = null; -// if (collectionConfig.getCollectionRef() != null) { -// ObjectReferenceType ref = collectionConfig.getCollectionRef(); -// Class refType = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); -// collection = (ObjectCollectionType) modelService -// .getObject(refType, ref.getOid(), null, task, result).asObjectable(); -// } -// @NotNull Collection> options = combineAuditOption(collectionConfig, collection, task, result); -// if (recordProgress) { -// long count = auditService.countObjects(query, options, result); -// task.setExpectedTotal(count); -// } -// @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); -// auditRecords.forEach(audit -> { -// handler.handle(audit); -// }); -// } - @Override public ObjectCollectionType getObjectCollectionType(DashboardWidgetType widget, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { 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 e44ff85d73b..e21555e87fe 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 @@ -1989,23 +1989,33 @@ public void searchObjectFromCollection(CollectionRefSpecificationType collection long count; if (AuditEventRecordType.class.equals(type)) { count = auditService.countObjects(query, options, result); + } else if (Containerable.class.isAssignableFrom(type)) { + count = modelService.countContainers(type, query, options, task, result); } else { count = modelService.countObjects((Class) type, query, options, task, result); } + task.setExpectedTotal(count); } if (AuditEventRecordType.class.equals(type)) { @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); - for (AuditEventRecordType auditRecord : auditRecords){ - PrismContainerValue prismValue = auditRecord.asPrismContainerValue(); - prismValue.setPrismContext(prismContext); - PrismContainer container = prismValue.asSingleValuedContainer(AuditEventRecordType.COMPLEX_TYPE); - handler.test(container); - } + processContainerByHandler(auditRecords, handler); + } else if (Containerable.class.isAssignableFrom(type)) { + SearchResultList containers = modelService.searchContainers(type, query, options, task, result); + processContainerByHandler(containers, handler); } else { ResultHandler resultHandler = (value, operationResult) -> handler.test((PrismContainer)value); modelService.searchObjectsIterative((Class) type, query, resultHandler, options, task, result); } } + private void processContainerByHandler(SearchResultList containers, Predicate handler) throws SchemaException { + for (Containerable container : containers){ + PrismContainerValue prismValue = container.asPrismContainerValue(); + prismValue.setPrismContext(prismContext); + PrismContainer prismContainer = prismValue.asSingleValuedContainer(prismValue.getTypeName()); + handler.test(prismContainer); + } + } + } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java index b28c9c4e011..9f17ea1fab2 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java @@ -26,6 +26,8 @@ import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; +import com.evolveum.prism.xml.ns._public.types_3.RawType; + import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; @@ -483,13 +485,21 @@ public VariablesMap getParameters(Task task) { PrismContainerValue reportParamsValues = reportParams.getValue(); Collection> items = reportParamsValues.getItems(); for (Item item : items) { - PrismProperty pp = (PrismProperty) item; - String paramName = pp.getPath().lastName().getLocalPart(); + String paramName = item.getPath().lastName().getLocalPart(); Object value = null; - if (!pp.getRealValues().isEmpty()) { - value = pp.getRealValues().iterator().next(); + if (!item.getRealValues().isEmpty()) { + value = item.getRealValues().iterator().next(); + } + if (item.getRealValue() instanceof RawType){ + try { + ObjectReferenceType parsedRealValue = ((RawType) item.getRealValue()).getParsedRealValue(ObjectReferenceType.class); + variables.put(paramName, new TypedValue(parsedRealValue, ObjectReferenceType.class)); + } catch (SchemaException e) { + LOGGER.error("Couldn't parse ObjectReferenceType from raw type. " + item.getRealValue()); + } + } else { + variables.put(paramName, new TypedValue(value, item.getRealValue().getClass())); } - variables.put(paramName, new TypedValue(value, ((PrismProperty) item).getValueClass())); } } return variables; diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java index c7a9f180301..a83c4846980 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/CsvController.java @@ -6,16 +6,16 @@ */ package com.evolveum.midpoint.report.impl.controller.fileformat; -import com.evolveum.midpoint.audit.api.AuditResultHandler; import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; import com.evolveum.midpoint.model.api.interaction.DashboardWidget; import com.evolveum.midpoint.model.common.util.DefaultColumnUtils; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.PagingConvertor; import com.evolveum.midpoint.report.impl.ReportServiceImpl; import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.expression.TypedValue; @@ -27,7 +27,6 @@ import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; @@ -135,7 +134,8 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin CompiledObjectCollectionView compiledCollection = createCompiledView(collectionConfig, collection); return createTableBox(collectionRefSpecification, compiledCollection, - collectionConfig.getCondition(), collectionConfig.getSubreport(), task, result); + collectionConfig.getCondition(), collectionConfig.getSubreport(), + PagingConvertor.createObjectPaging(collectionConfig.getPaging(), getReportService().getPrismContext()), result, task); } private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEngineConfigurationType collectionConfig, boolean useDefaultView, Task task, OperationResult result) @@ -185,7 +185,7 @@ private CompiledObjectCollectionView createCompiledView(ObjectCollectionReportEn } private byte[] createTableBox(CollectionRefSpecificationType collection, CompiledObjectCollectionView compiledCollection, ExpressionType condition, - List subreports, Task task, OperationResult result) + List subreports, ObjectPaging paging, OperationResult result, Task task) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { Class type = resolveType(collection, compiledCollection); @@ -235,7 +235,7 @@ private byte[] createTableBox(CollectionRefSpecificationType collection, Compile return true; }; searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, - options, null, task, result, true); + options, paging, task, result, true); CSVFormat csvFormat = createCsvFormat(); if (Boolean.TRUE.equals(isHeader())) { diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java index 21843d4d2b7..2bb9c4224ea 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/FileFormatController.java @@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableSet; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; @@ -151,8 +152,20 @@ protected String getRealValueAsString(GuiObjectColumnType column, PrismContainer } if (expression != null) { Object value = evaluateExportExpression(expression, valueObject, task, result); - if (value instanceof List) { - return processListOfRealValues((List) value); + if (value instanceof Collection) { + if (DisplayValueType.NUMBER.equals(column.getDisplayValue())) { + return String.valueOf(((Collection) value).size()); + } + return processListOfRealValues((Collection) value); + } + if (DisplayValueType.NUMBER.equals(column.getDisplayValue())) { + if (value == null) { + return "0"; + } + if (value instanceof PrismValue && ((PrismValue)value).getRealValue() instanceof Collection){ + return String.valueOf(((Collection) ((PrismValue)value).getRealValue()).size()); + } + return "1"; } return processListOfRealValues(Collections.singletonList(value)); } @@ -249,12 +262,13 @@ private Object evaluateExportExpression(ExpressionType expression, Item valueObj private Object evaluateExportExpression(ExpressionType expression, Object valueObject, Task task, OperationResult result) { checkVariables(task); - if (!variables.containsKey(ExpressionConstants.VAR_OBJECT)) { - if (valueObject == null) { - variables.put(ExpressionConstants.VAR_OBJECT, null, Object.class); - } else { - variables.put(ExpressionConstants.VAR_OBJECT, valueObject, valueObject.getClass()); - } + if (variables.containsKey(ExpressionConstants.VAR_OBJECT)) { + variables.remove(ExpressionConstants.VAR_OBJECT); + } + if (valueObject == null) { + variables.put(ExpressionConstants.VAR_OBJECT, null, Object.class); + } else { + variables.put(ExpressionConstants.VAR_OBJECT, valueObject, valueObject.getClass()); } Object values = null; try { @@ -311,12 +325,16 @@ protected String getColumnLabel(GuiObjectColumnType column, PrismContainerDefini } else { String name = column.getName(); + String displayName = null; if (path != null) { ItemDefinition def = objectDefinition.findItemDefinition(path); if (def == null) { throw new IllegalArgumentException("Could'n find item for path " + path); } - String displayName = def.getDisplayName(); + displayName = def.getDisplayName(); + + } + if (StringUtils.isNotEmpty(displayName)) { label = getMessage(displayName); } else { label = name; @@ -445,15 +463,18 @@ protected void evaluateSubreportParameters(List subrepor } protected void cleanUpVariables() { - variables.clear(); - variables = null; + if (variables != null) { + variables.clear(); + variables = null; + } } protected void initializationParameters(List parametersType, Task task) { VariablesMap variables = getReportService().getParameters(task); for (SearchFilterParameterType parameter : parametersType) { if (!variables.containsKey(parameter.getName())) { - variables.put(parameter.getName(), null, String.class); + Class clazz = getReportService().getPrismContext().getSchemaRegistry().determineClassForType(parameter.getType()); + variables.put(parameter.getName(), null, clazz); } } parameters = variables; diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java index 073e6375a70..e412547e27a 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/controller/fileformat/HtmlController.java @@ -12,17 +12,19 @@ import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; import java.util.function.Predicate; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.report.api.ReportConstants; +import com.evolveum.midpoint.prism.query.ObjectPaging; +import com.evolveum.midpoint.prism.query.PagingConvertor; import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.task.api.RunningTask; +import com.evolveum.prism.xml.ns._public.query_3.PagingType; + import j2html.TagCreator; import j2html.tags.ContainerTag; import org.apache.commons.io.IOUtils; @@ -140,7 +142,7 @@ public byte[] processDashboard(DashboardReportEngineConfigurationType dashboardC // break; case OBJECT_COLLECTION: tableBox = createTableBox(widgetData.getLabel(), collectionRefSpecification, compiledCollection, - null, Collections.emptyList(), task, result, false); + null, Collections.emptyList(), null, result, false, task); break; } if (tableBox != null) { @@ -226,7 +228,8 @@ public byte[] processCollection(String nameOfReport, ObjectCollectionReportEngin } ContainerTag tableBox = createTableBox(label, collectionRefSpecification, compiledCollection, - collectionConfig.getCondition(), collectionConfig.getSubreport(), task, result, true); + collectionConfig.getCondition(), collectionConfig.getSubreport(), + PagingConvertor.createObjectPaging(collectionConfig.getPaging(), getReportService().getPrismContext()), result, true, task); body.append(tableBox.render()); @@ -258,7 +261,7 @@ private ContainerTag createTableBox(ContainerTag table, String nameOfTable, int } private ContainerTag createTableBox(String tableLabel, CollectionRefSpecificationType collection, @NotNull CompiledObjectCollectionView compiledCollection, - ExpressionType condition, List subreports, Task task, OperationResult result, boolean recordProgress) throws ObjectNotFoundException, SchemaException, CommunicationException, + ExpressionType condition, List subreports, ObjectPaging paging, OperationResult result, boolean recordProgress, Task task) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { long startMillis = getReportService().getClock().currentTimeMillis(); Class type = resolveType(collection, compiledCollection); @@ -326,7 +329,7 @@ private ContainerTag createTableBox(String tableLabel, CollectionRefSpecificatio return true; }; searchObjectFromCollection(collection, compiledCollection.getContainerType(), handler, options, - null, task, result, recordProgress); + paging, task, result, recordProgress); if (tBody.getNumChildren() == 0 && !recordProgress) { return null; } From 2f6afd2c3cc8d0d0eb3e201ca64045e959d3c6ab Mon Sep 17 00:00:00 2001 From: lskublik Date: Tue, 27 Apr 2021 19:43:38 +0200 Subject: [PATCH 04/15] cleanup of report tests --- .../ModelInteractionServiceImpl.java | 14 +- .../report/AbstractReportIntegrationTest.java | 490 ++++++++++++++++-- .../midpoint/report/BasicNewReportTest.java | 426 --------------- .../midpoint/report/TestCsvReport.java | 27 +- .../midpoint/report/TestHtmlReport.java | 2 +- .../evolveum/midpoint/report/TestReport.java | 283 ---------- .../midpoint/report/TestReportJasper.java | 111 ---- .../midpoint/report/TestReportSafe.java | 65 --- .../resources/reports/report-audit-ds.jrxml | 226 -------- .../report-user-list-expressions-csv.xml | 26 - ...r-list-expressions-poisonous-field-csv.xml | 26 - ...r-list-expressions-poisonous-query-csv.xml | 27 - .../reports/report-user-list-script.xml | 164 +++++- .../resources/reports/report-user-list.xml | 178 +++++-- .../resources/reports/report-users-ds.jrxml | 207 -------- model/report-impl/testng-integration.xml | 2 - 16 files changed, 758 insertions(+), 1516 deletions(-) delete mode 100644 model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java delete mode 100644 model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReport.java delete mode 100644 model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportJasper.java delete mode 100644 model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportSafe.java delete mode 100644 model/report-impl/src/test/resources/reports/report-audit-ds.jrxml delete mode 100644 model/report-impl/src/test/resources/reports/report-user-list-expressions-csv.xml delete mode 100644 model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-field-csv.xml delete mode 100644 model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-query-csv.xml delete mode 100644 model/report-impl/src/test/resources/reports/report-users-ds.jrxml 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 e21555e87fe..76319647d50 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 @@ -1989,10 +1989,10 @@ public void searchObjectFromCollection(CollectionRefSpecificationType collection long count; if (AuditEventRecordType.class.equals(type)) { count = auditService.countObjects(query, options, result); - } else if (Containerable.class.isAssignableFrom(type)) { - count = modelService.countContainers(type, query, options, task, result); - } else { + } else if (ObjectType.class.isAssignableFrom(type)) { count = modelService.countObjects((Class) type, query, options, task, result); + } else { + count = modelService.countContainers(type, query, options, task, result); } task.setExpectedTotal(count); @@ -2000,12 +2000,12 @@ public void searchObjectFromCollection(CollectionRefSpecificationType collection if (AuditEventRecordType.class.equals(type)) { @NotNull SearchResultList auditRecords = auditService.searchObjects(query, options, result); processContainerByHandler(auditRecords, handler); - } else if (Containerable.class.isAssignableFrom(type)) { - SearchResultList containers = modelService.searchContainers(type, query, options, task, result); - processContainerByHandler(containers, handler); - } else { + } else if (ObjectType.class.isAssignableFrom(type)) { ResultHandler resultHandler = (value, operationResult) -> handler.test((PrismContainer)value); modelService.searchObjectsIterative((Class) type, query, resultHandler, options, task, result); + } else { + SearchResultList containers = modelService.searchContainers(type, query, options, task, result); + processContainerByHandler(containers, handler); } } diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/AbstractReportIntegrationTest.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/AbstractReportIntegrationTest.java index ddb85c5f0bf..468ed721f61 100644 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/AbstractReportIntegrationTest.java +++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/AbstractReportIntegrationTest.java @@ -1,95 +1,157 @@ /* - * Copyright (c) 2010-2019 Evolveum and contributors + * Copyright (c) 2010-2020 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. */ package com.evolveum.midpoint.report; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; +import com.evolveum.midpoint.prism.*; + +import com.evolveum.midpoint.report.api.ReportConstants; + +import com.evolveum.midpoint.report.api.ReportManager; +import com.evolveum.midpoint.report.impl.ReportJasperCreateTaskHandler; + +import com.evolveum.midpoint.report.impl.ReportTaskHandler; + +import com.evolveum.midpoint.test.util.MidPointTestConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; 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.test.AbstractModelIntegrationTest; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.report.api.ReportManager; -import com.evolveum.midpoint.report.impl.ReportJasperCreateTaskHandler; -import com.evolveum.midpoint.report.impl.ReportTaskHandler; +import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.util.exception.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; + +import javax.xml.namespace.QName; + +/** + * @author skublik + */ @ContextConfiguration(locations = { "classpath:ctx-report-test-main.xml" }) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class AbstractReportIntegrationTest extends AbstractModelIntegrationTest { +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public abstract class AbstractReportIntegrationTest extends AbstractModelIntegrationTest { protected static final File TEST_DIR_COMMON = new File("src/test/resources/common"); protected static final File EXPORT_DIR = new File("target/midpoint-home/export"); protected static final File TEST_REPORTS_DIR = new File("src/test/resources/reports"); - protected static final File REPORT_USER_LIST_FILE = new File(TEST_REPORTS_DIR, "report-user-list.xml"); - protected static final String REPORT_USER_LIST_OID = "00000000-0000-0000-0000-000000000110"; - - protected static final File REPORT_USER_LIST_EXPRESSIONS_CSV_FILE = new File(TEST_REPORTS_DIR, "report-user-list-expressions-csv.xml"); - protected static final String REPORT_USER_LIST_EXPRESSIONS_CSV_OID = "8fa48180-4f17-11e9-9eed-3fb4721a135e"; + protected static final File USER_WILL_FILE = new File(TEST_DIR_COMMON, "user-will.xml"); + protected static final File USER_JACK_FILE = new File(TEST_DIR_COMMON, "user-jack.xml"); + protected static final File ROLE_SUPERUSER_FILE = new File(TEST_DIR_COMMON, "role-superuser.xml"); + protected static final File USER_ADMINISTRATOR_FILE = new File(TEST_DIR_COMMON, "user-administrator.xml"); + protected static final File ARCHETYPE_TASK_FILE = new File(COMMON_DIR, "archetype-task-report.xml"); + protected static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR_COMMON, "system-configuration.xml"); + protected static final File SYSTEM_CONFIGURATION_SAFE_FILE = new File(TEST_DIR_COMMON, "system-configuration-safe.xml"); - protected static final File REPORT_USER_LIST_EXPRESSIONS_POISONOUS_QUERY_CSV_FILE = new File(TEST_REPORTS_DIR, "report-user-list-expressions-poisonous-query-csv.xml"); - protected static final String REPORT_USER_LIST_EXPRESSIONS_POISONOUS_QUERY_CSV_OID = "5c5af02a-4fe9-11e9-bb07-7b4e52fe05cd"; + protected static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; - protected static final File REPORT_USER_LIST_EXPRESSIONS_POISONOUS_FIELD_CSV_FILE = new File(TEST_REPORTS_DIR, "report-user-list-expressions-poisonous-field-csv.xml"); - protected static final String REPORT_USER_LIST_EXPRESSIONS_POISONOUS_FIELD_CSV_OID = "76c58132-4fe9-11e9-86fe-ff36d221f673"; + protected static final File RESOURCE_DUMMY_FILE = new File(COMMON_DIR, "resource-dummy.xml"); + protected static final File COLLECTION_ROLE_FILE = new File(COMMON_DIR, "object-collection-all-role.xml"); + protected static final File COLLECTION_RESOURCE_FILE = new File(COMMON_DIR, "object-collection-all-resource.xml"); + protected static final File COLLECTION_TASK_FILE = new File(COMMON_DIR, "object-collection-all-task.xml"); + protected static final File COLLECTION_USER_FILE = new File(COMMON_DIR, "object-collection-all-user.xml"); + protected static final File COLLECTION_AUDIT_FILE = new File(COMMON_DIR, "object-collection-all-audit-records.xml"); + protected static final File COLLECTION_ASSIGNMENT_HOLDER_FILE = new File(COMMON_DIR, "object-collection-all-assignment-holder.xml"); + protected static final File COLLECTION_SHADOW_FILE = new File(COMMON_DIR, "object-collection-shadow-of-resource.xml"); + protected static final File DASHBOARD_DEFAULT_COLUMNS_FILE = new File(COMMON_DIR, "dashboard-default-columns.xml"); + protected static final File DASHBOARD_VIEW_FILE = new File(COMMON_DIR, "dashboard-with-view.xml"); + protected static final File COLLECTION_ROLE_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-role-with-view.xml"); + protected static final File COLLECTION_RESOURCE_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-resource-with-view.xml"); + protected static final File COLLECTION_TASK_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-task-with-view.xml"); + protected static final File COLLECTION_USER_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-user-with-view.xml"); + protected static final File COLLECTION_AUDIT_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-audit-records-with-view.xml"); + protected static final File COLLECTION_AUDIT_EMPTY_FILE = new File(COMMON_DIR, "object-collection-audit-empty.xml"); + protected static final File COLLECTION_EMPTY_FILE = new File(COMMON_DIR, "object-collection-empty.xml"); + protected static final File COLLECTION_ASSIGNMENT_HOLDER_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-assignment-holder-with-view.xml"); + protected static final File COLLECTION_SHADOW_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-shadow-of-resource-with-view.xml"); + protected static final File DASHBOARD_TRIPLE_VIEW_FILE = new File(COMMON_DIR, "dashboard-with-triple-view.xml"); + protected static final File DASHBOARD_EMPTY_FILE = new File(COMMON_DIR, "dashboard-empty.xml"); + protected static final File COLLECTION_BASIC = new File(COMMON_DIR, "object-collection-basic-filter.xml"); - protected static final File REPORT_USER_LIST_SCRIPT_FILE = new File(TEST_REPORTS_DIR, "report-user-list-script.xml"); - protected static final String REPORT_USER_LIST_SCRIPT_OID = "222bf2b8-c89b-11e7-bf36-ebd4e4d45a80"; + protected static final File REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-default-column.xml"); + protected static final File REPORT_DASHBOARD_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-view.xml"); + protected static final File REPORT_DASHBOARD_WITH_TRIPLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-triple-view.xml"); + protected static final File REPORT_DASHBOARD_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-empty.xml"); - protected static final File REPORT_AUDIT_CSV_FILE = new File(TEST_REPORTS_DIR, "report-audit-csv.xml"); - protected static final String REPORT_AUDIT_CSV_OID = "66dbbecc-a9fc-11e9-b75c-03927bebc9f7"; + protected static final File REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-default-column.xml"); + protected static final File REPORT_AUDIT_COLLECTION_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-view.xml"); + protected static final File REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-double-view.xml"); + protected static final File REPORT_AUDIT_COLLECTION_WITH_CONDITION_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-condition.xml"); + protected static final File REPORT_AUDIT_COLLECTION_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-empty.xml"); - protected static final File REPORT_AUDIT_CSV_LEGACY_FILE = new File(TEST_REPORTS_DIR, "report-audit-csv-legacy.xml"); - protected static final String REPORT_AUDIT_CSV_LEGACY_OID = "78faa28c-a9ff-11e9-8c60-e7843d75831e"; + protected static final File REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-default-column.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-view.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-double-view.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_FILTER_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-filter.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-filter-and-basic-collection.xml"); + protected static final File REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-filter-and-basic-collection-without-view.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-condition.xml"); + protected static final File REPORT_OBJECT_COLLECTION_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-empty.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-param.xml"); + protected static final File REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-subreport-param.xml"); + protected static final File REPORT_WITH_IMPORT_SCRIPT_FILE = new File(TEST_REPORTS_DIR, "report-with-import-script.xml"); - protected static final File USER_JACK_FILE = new File(TEST_DIR_COMMON, "user-jack.xml"); - protected static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; - - protected static final File USERS_MONKEY_ISLAND_FILE = new File(TEST_DIR_COMMON, "users-monkey-island.xml"); - - protected static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR_COMMON, "system-configuration.xml"); - protected static final File SYSTEM_CONFIGURATION_SAFE_FILE = new File(TEST_DIR_COMMON, "system-configuration-safe.xml"); + protected static final File REPORT_USER_LIST_FILE = new File(TEST_REPORTS_DIR, "report-user-list.xml"); + protected static final File REPORT_USER_LIST_SCRIPT_FILE = new File(TEST_REPORTS_DIR, "report-user-list-script.xml"); - protected static final File RESOURCE_OPENDJ_FILE = new File(TEST_DIR_COMMON, "resource-opendj.xml"); - protected static final String RESOURCE_OPENDJ_OID = "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff"; + protected static final String REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8582"; + protected static final String REPORT_DASHBOARD_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8533"; + protected static final String REPORT_DASHBOARD_WITH_TRIPLE_VIEW_OID = "2b87aa2e-dd86-4842-bcf5-76200a9a8533"; + protected static final String REPORT_DASHBOARD_EMPTY_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8eq2"; - protected static final File CONNECTOR_DUMMY_FILE = new File(TEST_DIR_COMMON, "connector-ldap.xml"); - protected static final String CONNECTOR_DUMMY_OID = "ef2bc95b-76e0-59e2-86d6-3d4f02d3eedd"; + protected static final String REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85bc"; + protected static final String REPORT_AUDIT_COLLECTION_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85cd"; + protected static final String REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85fg"; + protected static final String REPORT_AUDIT_COLLECTION_WITH_CONDITION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85rr"; + protected static final String REPORT_AUDIT_COLLECTION_EMPTY_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85qf"; - protected static final File ROLE_SUPERUSER_FILE = new File(TEST_DIR_COMMON, "role-superuser.xml"); + protected static final String REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ab"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85de"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ef"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_FILTER_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85gh"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85hi"; + protected static final String REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85r7"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a851a"; + protected static final String REPORT_OBJECT_COLLECTION_EMPTY_LIST_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85sq"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ew"; + protected static final String REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85qq"; + protected static final String REPORT_WITH_IMPORT_SCRIPT_OID = "2b44aa2e-dd86-4842-bcf5-762c8c4a851a"; - protected static final File USER_ADMINISTRATOR_FILE = new File(TEST_DIR_COMMON, "user-administrator.xml"); + protected static final String REPORT_USER_LIST_OID = "00000000-0000-0000-0000-000000000110"; + protected static final String REPORT_USER_LIST_SCRIPT_OID = "222bf2b8-c89b-11e7-bf36-ebd4e4d45a80"; - protected static final File USER_READER_FILE = new File(TEST_DIR_COMMON, "user-reader.xml"); - protected static final String USER_READER_USERNAME = "reader"; - protected static final File USER_RUNNER_FILE = new File(TEST_DIR_COMMON, "user-runner.xml"); - protected static final String USER_RUNNER_USERNAME = "runner"; - protected static final File USER_READER_RUNNER_FILE = new File(TEST_DIR_COMMON, "user-reader-runner.xml"); - protected static final String USER_READER_RUNNER_USERNAME = "reader-runner"; - protected static final File ROLE_READER_FILE = new File(TEST_DIR_COMMON, "role-reader.xml"); - protected static final File ROLE_RUNNER_FILE = new File(TEST_DIR_COMMON, "role-runner.xml"); - public static final File ARCHETYPE_TASK_FILE = new File(COMMON_DIR, "archetype-task-report.xml"); + protected static final String RESOURCE_DUMMY_OID = "10000000-0000-0000-0000-000000000004"; protected static final String OP_CREATE_REPORT = ReportTaskHandler.class.getName() + "createReport"; protected static final String OP_IMPORT_REPORT = ReportTaskHandler.class.getName() + "importReport"; - @Autowired protected ReportManager reportManager; @Autowired - @Qualifier("reportJasperCreateTaskHandler") - protected ReportJasperCreateTaskHandler reportTaskHandler; + protected ReportManager reportManager; protected PrismObject userAdministrator; @@ -115,6 +177,330 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); importObjectFromFile(ARCHETYPE_TASK_FILE, initResult); + + CleanupPolicyType policy = new CleanupPolicyType(); + policy.setMaxRecords(0); + modelAuditService.cleanupAudit(policy, initTask, initResult); + + DummyResourceContoller dummyResourceCtl = DummyResourceContoller.create(null); + dummyResourceCtl.extendSchemaPirate(); + PrismObject resourceDummy = importAndGetObjectFromFile(ResourceType.class, RESOURCE_DUMMY_FILE, RESOURCE_DUMMY_OID, initTask, initResult); + dummyResourceCtl.setResource(resourceDummy); + assignAccountToUser(USER_JACK_OID, RESOURCE_DUMMY_OID, null, initTask, initResult); + importObjectFromFile(COLLECTION_BASIC, initResult); + importObjectFromFile(USER_WILL_FILE, initResult); + importObjectFromFile(COLLECTION_ROLE_FILE, initResult); + importObjectFromFile(COLLECTION_USER_FILE, initResult); + importObjectFromFile(COLLECTION_RESOURCE_FILE, initResult); + importObjectFromFile(COLLECTION_TASK_FILE, initResult); + importObjectFromFile(COLLECTION_AUDIT_FILE, initResult); + importObjectFromFile(COLLECTION_ASSIGNMENT_HOLDER_FILE, initResult); + importObjectFromFile(COLLECTION_SHADOW_FILE, initResult); + importObjectFromFile(DASHBOARD_DEFAULT_COLUMNS_FILE, initResult); + importObjectFromFile(DASHBOARD_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_ROLE_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_USER_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_RESOURCE_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_TASK_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_AUDIT_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_AUDIT_EMPTY_FILE, initResult); + importObjectFromFile(COLLECTION_ASSIGNMENT_HOLDER_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_SHADOW_WITH_VIEW_FILE, initResult); + importObjectFromFile(COLLECTION_EMPTY_FILE, initResult); + importObjectFromFile(DASHBOARD_TRIPLE_VIEW_FILE, initResult); + importObjectFromFile(DASHBOARD_EMPTY_FILE, initResult); + + importObjectFromFile(REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_FILE, initResult); + importObjectFromFile(REPORT_DASHBOARD_WITH_VIEW_FILE, initResult); + importObjectFromFile(REPORT_DASHBOARD_WITH_TRIPLE_VIEW_FILE, initResult); + importObjectFromFile(REPORT_DASHBOARD_EMPTY_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_VIEW_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_FILE, initResult); + importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_FILE, initResult); + importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_VIEW_FILE, initResult); + importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_FILE, initResult); + importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_CONDITION_FILE, initResult); + importObjectFromFile(REPORT_AUDIT_COLLECTION_EMPTY_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_FILTER_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_EMPTY_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE, initResult); + importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE, initResult); + importObjectFromFile(REPORT_WITH_IMPORT_SCRIPT_FILE, initResult); + + importObjectFromFile(REPORT_USER_LIST_FILE, initResult); + importObjectFromFile(REPORT_USER_LIST_SCRIPT_FILE, initResult); + } + + @Test + public void test001CreateDashboardReportWithDefaultColumn() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test002CreateDashboardReportWithView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test003CreateDashboardReportWithTripleView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_TRIPLE_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test004CreateDashboardReportEmpty() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_EMPTY_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test101CreateAuditCollectionReportWithDefaultColumn() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test102CreateAuditCollectionReportWithView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test103CreateAuditCollectionReportWithDoubleView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test104CreateAuditCollectionReportWithCondition() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_CONDITION_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test105CreateAuditCollectionReportEmpty() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_EMPTY_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test110CreateObjectCollectionReportWithDefaultColumn() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test111CreateObjectCollectionReportWithView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test112CreateObjectCollectionReportWithDoubleView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test113CreateObjectCollectionReportWithFilter() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_FILTER_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test114CreateObjectCollectionReportWithFilterAndBasicCollection() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test115CreateObjectCollectionReportWithCondition() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test116CreateObjectCollectionEmptyReport() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_EMPTY_LIST_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test117CreateObjectCollectionReportWithFilterAndBasicCollectionWithoutView() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test118CreateObjectCollectionWithParamReport() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_PARAM_OID); + runReport(report, getParameters("givenName", String.class, "Will"), false); + basicCheckOutputFile(report); + } + + @Test + public void test119CreateObjectCollectionWithSubreportParamReport() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test120RunMidpointUsers() throws Exception { + PrismObject report = getObject(ReportType.class, REPORT_USER_LIST_OID); + runReport(report, false); + basicCheckOutputFile(report); + } + + @Test + public void test121RunMidpointUsersScript() throws Exception { + if (!isOsUnix()) { + displaySkip(); + return; + } + PrismObject report = getObject(ReportType.class, REPORT_USER_LIST_SCRIPT_OID); + runReport(report, false); + basicCheckOutputFile(report); + File targetFile = new File(MidPointTestConstants.TARGET_DIR_PATH, "report-users"); + assertTrue("Target file is not there", targetFile.exists()); + } + + private PrismContainer getParameters(String name, Class type, Object realValue) throws SchemaException { + PrismContainerDefinition paramContainerDef = prismContext.getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); + PrismContainer paramContainer; + paramContainer = paramContainerDef.instantiate(); + ReportParameterType reportParam = new ReportParameterType(); + PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); + reportParamValue.revive(prismContext); + paramContainer.add(reportParamValue); + + QName typeName = prismContext.getSchemaRegistry().determineTypeForClass(type); + MutablePrismPropertyDefinition def = prismContext.definitionFactory().createPropertyDefinition( + new QName(ReportConstants.NS_EXTENSION, name), typeName); + def.setDynamic(true); + def.setRuntimeSchema(true); + def.toMutable().setMaxOccurs(1); + + PrismProperty prop = def.instantiate(); + prop.addRealValue(realValue); + reportParamValue.add(prop); + + return paramContainer; + } + + protected PrismObject runReport(PrismObject report, boolean errorOk) throws Exception { + return runReport(report, null, errorOk); + } + + protected PrismObject runReport(PrismObject report, PrismContainer params, boolean errorOk) throws Exception { + Task task = createTask(OP_CREATE_REPORT); + OperationResult result = task.getResult(); + PrismObject reportBefore = report.clone(); + report.asObjectable().setFileFormat(getFileFormatConfiguration()); + ObjectDelta diffDelta = reportBefore.diff(report, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS); + executeChanges(diffDelta, ModelExecuteOptions.createRaw(), task, result); + + // WHEN + when(); + reportManager.runReport(report, params, task, result); + + assertInProgress(result); + + display("Background task (running)", task); + + waitForTaskFinish(task.getOid(), false, DEFAULT_TASK_WAIT_TIMEOUT, errorOk); + + // THEN + then(); + PrismObject finishedTask = getTask(task.getOid()); + display("Background task (finished)", finishedTask); + + return finishedTask; + } + + protected PrismObject importReport(PrismObject report, String pathToImportFile, boolean errorOk) throws Exception { + Task task = createTask(OP_IMPORT_REPORT); + OperationResult result = task.getResult(); + PrismObject reportBefore = report.clone(); + report.asObjectable().setFileFormat(getFileFormatConfiguration()); + ObjectDelta diffDelta = reportBefore.diff(report, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS); + executeChanges(diffDelta, ModelExecuteOptions.createRaw(), task, result); + + PrismObject reportData = prismContext.getSchemaRegistry() + .findObjectDefinitionByCompileTimeClass(ReportDataType.class).instantiate(); + reportData.asObjectable().setFileFormat(getFileFormatConfiguration().getType()); + reportData.asObjectable().setFilePath(new File(pathToImportFile).getAbsolutePath()); + reportData.asObjectable().setName(new PolyStringType(report.getName())); + String reportDataOid = addObject(reportData, task, result); + reportData.setOid(reportDataOid); + + // WHEN + when(); + reportManager.importReport(report, reportData, task, result); + + assertInProgress(result); + + display("Background task (running)", task); + + waitForTaskFinish(task.getOid(), false, DEFAULT_TASK_WAIT_TIMEOUT, errorOk); + + // THEN + then(); + PrismObject finishedTask = getTask(task.getOid()); + display("Background task (finished)", finishedTask); + + return finishedTask; + } + + protected abstract FileFormatConfigurationType getFileFormatConfiguration(); + + protected List basicCheckOutputFile(PrismObject report) throws IOException, SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + File outputFile = findOutputFile(report); + displayValue("Found report file", outputFile); + assertNotNull("No output file for " + report, outputFile); + List lines = Files.readAllLines(Paths.get(outputFile.getPath())); + displayValue("Report content (" + lines.size() + " lines)", String.join("\n", lines)); + outputFile.renameTo(new File(outputFile.getParentFile(), "processed-" + outputFile.getName())); + return lines; + } + + protected File findOutputFile(PrismObject report) { + String filePrefix = report.getName().getOrig(); + File[] matchingFiles = EXPORT_DIR.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.startsWith(filePrefix); + } + }); + if (matchingFiles.length == 0) { + return null; + } + if (matchingFiles.length > 1) { + throw new IllegalStateException("Found more than one output files for " + report + ": " + Arrays.toString(matchingFiles)); + } + return matchingFiles[0]; } protected File getSystemConfigurationFile() { diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java deleted file mode 100644 index 6efdc3e5a04..00000000000 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/BasicNewReportTest.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2010-2020 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.report; - -import static org.testng.AssertJUnit.assertNotNull; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; - -import com.evolveum.midpoint.audit.api.AuditEventStage; -import com.evolveum.midpoint.audit.api.AuditEventType; -import com.evolveum.midpoint.prism.*; - -import com.evolveum.midpoint.report.api.ReportConstants; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventTypeType; - -import org.testng.annotations.Test; - -import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.DummyResourceContoller; -import com.evolveum.midpoint.util.exception.*; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - -import javax.xml.namespace.QName; - -/** - * @author skublik - */ - -public abstract class BasicNewReportTest extends AbstractReportIntegrationTest { - - protected static final File USER_WILL_FILE = new File(TEST_DIR_COMMON, "user-will.xml"); - protected static final String USER_WILL_OID = "c0c010c0-d34d-b33f-f00d-111111111122"; - - public static final File RESOURCE_DUMMY_FILE = new File(COMMON_DIR, "resource-dummy.xml"); - public static final File COLLECTION_ROLE_FILE = new File(COMMON_DIR, "object-collection-all-role.xml"); - public static final File COLLECTION_RESOURCE_FILE = new File(COMMON_DIR, "object-collection-all-resource.xml"); - public static final File COLLECTION_TASK_FILE = new File(COMMON_DIR, "object-collection-all-task.xml"); - public static final File COLLECTION_USER_FILE = new File(COMMON_DIR, "object-collection-all-user.xml"); - public static final File COLLECTION_AUDIT_FILE = new File(COMMON_DIR, "object-collection-all-audit-records.xml"); - public static final File COLLECTION_ASSIGNMENT_HOLDER_FILE = new File(COMMON_DIR, "object-collection-all-assignment-holder.xml"); - public static final File COLLECTION_SHADOW_FILE = new File(COMMON_DIR, "object-collection-shadow-of-resource.xml"); - public static final File DASHBOARD_DEFAULT_COLUMNS_FILE = new File(COMMON_DIR, "dashboard-default-columns.xml"); - public static final File DASHBOARD_VIEW_FILE = new File(COMMON_DIR, "dashboard-with-view.xml"); - public static final File COLLECTION_ROLE_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-role-with-view.xml"); - public static final File COLLECTION_RESOURCE_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-resource-with-view.xml"); - public static final File COLLECTION_TASK_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-task-with-view.xml"); - public static final File COLLECTION_USER_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-user-with-view.xml"); - public static final File COLLECTION_AUDIT_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-audit-records-with-view.xml"); - public static final File COLLECTION_AUDIT_EMPTY_FILE = new File(COMMON_DIR, "object-collection-audit-empty.xml"); - public static final File COLLECTION_EMPTY_FILE = new File(COMMON_DIR, "object-collection-empty.xml"); - public static final File COLLECTION_ASSIGNMENT_HOLDER_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-all-assignment-holder-with-view.xml"); - public static final File COLLECTION_SHADOW_WITH_VIEW_FILE = new File(COMMON_DIR, "object-collection-shadow-of-resource-with-view.xml"); - public static final File DASHBOARD_TRIPLE_VIEW_FILE = new File(COMMON_DIR, "dashboard-with-triple-view.xml"); - public static final File DASHBOARD_EMPTY_FILE = new File(COMMON_DIR, "dashboard-empty.xml"); - public static final File COLLECTION_BASIC = new File(COMMON_DIR, "object-collection-basic-filter.xml"); - - public static final File REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-default-column.xml"); - public static final File REPORT_DASHBOARD_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-view.xml"); - public static final File REPORT_DASHBOARD_WITH_TRIPLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-with-triple-view.xml"); - public static final File REPORT_DASHBOARD_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-dashboard-empty.xml"); - - public static final File REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-default-column.xml"); - public static final File REPORT_AUDIT_COLLECTION_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-view.xml"); - public static final File REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-double-view.xml"); - public static final File REPORT_AUDIT_COLLECTION_WITH_CONDITION_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-with-condition.xml"); - public static final File REPORT_AUDIT_COLLECTION_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-audit-collection-empty.xml"); - - public static final File REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-default-column.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-view.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-double-view.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_FILTER_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-filter.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-filter-and-basic-collection.xml"); - public static final File REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-filter-and-basic-collection-without-view.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-condition.xml"); - public static final File REPORT_OBJECT_COLLECTION_EMPTY_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-empty.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-param.xml"); - public static final File REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE = new File(TEST_REPORTS_DIR, "report-object-collection-with-subreport-param.xml"); - public static final File REPORT_WITH_IMPORT_SCRIPT = new File(TEST_REPORTS_DIR, "report-with-import-script.xml"); - - public static final String REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8582"; - public static final String REPORT_DASHBOARD_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8533"; - public static final String REPORT_DASHBOARD_WITH_TRIPLE_VIEW_OID = "2b87aa2e-dd86-4842-bcf5-76200a9a8533"; - public static final String REPORT_DASHBOARD_EMPTY_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a8eq2"; - - public static final String REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85bc"; - public static final String REPORT_AUDIT_COLLECTION_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85cd"; - public static final String REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85fg"; - public static final String REPORT_AUDIT_COLLECTION_WITH_CONDITION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85rr"; - public static final String REPORT_AUDIT_COLLECTION_EMPTY_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85qf"; - - public static final String REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ab"; - public static final String REPORT_OBJECT_COLLECTION_WITH_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85de"; - public static final String REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ef"; - public static final String REPORT_OBJECT_COLLECTION_WITH_FILTER_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85gh"; - public static final String REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85hi"; - public static final String REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85r7"; - public static final String REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a851a"; - public static final String REPORT_OBJECT_COLLECTION_EMPTY_LIST_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85sq"; - public static final String REPORT_WITH_IMPORT_SCRIPT_OID = "2b44aa2e-dd86-4842-bcf5-762c8c4a851a"; - public static final String REPORT_OBJECT_COLLECTION_WITH_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85ew"; - public static final String REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID = "2b44aa2e-dd86-4842-bcf5-762c8a9a85qq"; - - public static final String RESOURCE_DUMMY_OID = "10000000-0000-0000-0000-000000000004"; - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - - CleanupPolicyType policy = new CleanupPolicyType(); - policy.setMaxRecords(0); - modelAuditService.cleanupAudit(policy, initTask, initResult); - - DummyResourceContoller dummyResourceCtl = DummyResourceContoller.create(null); - dummyResourceCtl.extendSchemaPirate(); - PrismObject resourceDummy = importAndGetObjectFromFile(ResourceType.class, RESOURCE_DUMMY_FILE, RESOURCE_DUMMY_OID, initTask, initResult); - dummyResourceCtl.setResource(resourceDummy); - assignAccountToUser(USER_JACK_OID, RESOURCE_DUMMY_OID, null, initTask, initResult); - importObjectFromFile(COLLECTION_BASIC, initResult); - importObjectFromFile(USER_WILL_FILE, initResult); - importObjectFromFile(COLLECTION_ROLE_FILE, initResult); - importObjectFromFile(COLLECTION_USER_FILE, initResult); - importObjectFromFile(COLLECTION_RESOURCE_FILE, initResult); - importObjectFromFile(COLLECTION_TASK_FILE, initResult); - importObjectFromFile(COLLECTION_AUDIT_FILE, initResult); - importObjectFromFile(COLLECTION_ASSIGNMENT_HOLDER_FILE, initResult); - importObjectFromFile(COLLECTION_SHADOW_FILE, initResult); - importObjectFromFile(DASHBOARD_DEFAULT_COLUMNS_FILE, initResult); - importObjectFromFile(DASHBOARD_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_ROLE_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_USER_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_RESOURCE_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_TASK_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_AUDIT_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_AUDIT_EMPTY_FILE, initResult); - importObjectFromFile(COLLECTION_ASSIGNMENT_HOLDER_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_SHADOW_WITH_VIEW_FILE, initResult); - importObjectFromFile(COLLECTION_EMPTY_FILE, initResult); - importObjectFromFile(DASHBOARD_TRIPLE_VIEW_FILE, initResult); - importObjectFromFile(DASHBOARD_EMPTY_FILE, initResult); - - importObjectFromFile(REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_FILE, initResult); - importObjectFromFile(REPORT_DASHBOARD_WITH_VIEW_FILE, initResult); - importObjectFromFile(REPORT_DASHBOARD_WITH_TRIPLE_VIEW_FILE, initResult); - importObjectFromFile(REPORT_DASHBOARD_EMPTY_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_VIEW_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_FILE, initResult); - importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_FILE, initResult); - importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_VIEW_FILE, initResult); - importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_FILE, initResult); - importObjectFromFile(REPORT_AUDIT_COLLECTION_WITH_CONDITION_FILE, initResult); - importObjectFromFile(REPORT_AUDIT_COLLECTION_EMPTY_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_FILTER_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_CONDITION_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_EMPTY_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_PARAM_FILE, initResult); - importObjectFromFile(REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_FILE, initResult); - importObjectFromFile(REPORT_WITH_IMPORT_SCRIPT, initResult); - } - - @Test - public void test001CreateDashboardReportWithDefaultColumn() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_DEFAULT_COLUMN_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test002CreateDashboardReportWithView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test003CreateDashboardReportWithTripleView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_WITH_TRIPLE_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test004CreateDashboardReportEmpty() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_DASHBOARD_EMPTY_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test101CreateAuditCollectionReportWithDefaultColumn() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_DEFAULT_COLUMN_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test102CreateAuditCollectionReportWithView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test103CreateAuditCollectionReportWithDoubleView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_DOUBLE_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test104CreateAuditCollectionReportWithCondition() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_WITH_CONDITION_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test105CreateAuditCollectionReportEmpty() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_AUDIT_COLLECTION_EMPTY_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test110CreateObjectCollectionReportWithDefaultColumn() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test111CreateObjectCollectionReportWithView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test112CreateObjectCollectionReportWithDoubleView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_DOUBLE_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test113CreateObjectCollectionReportWithFilter() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_FILTER_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test114CreateObjectCollectionReportWithFilterAndBasicCollection() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_FILTER_AND_BASIC_COLLECTION_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test115CreateObjectCollectionReportWithCondition() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test116CreateObjectCollectionEmptyReport() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_EMPTY_LIST_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test117CreateObjectCollectionReportWithFilterAndBasicCollectionWithoutView() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_FILTER_BASIC_COLLECTION_WITHOUT_VIEW_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - @Test - public void test118CreateObjectCollectionWithParamReport() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_PARAM_OID); - runReport(report, getParameters("givenName", String.class, "Will"), false); - basicCheckOutputFile(report); - } - - @Test - public void test119CreateObjectCollectionWithSubreportParamReport() throws Exception { - PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_SUBREPORT_PARAM_OID); - runReport(report, false); - basicCheckOutputFile(report); - } - - private PrismContainer getParameters(String name, Class type, Object realValue) throws SchemaException { - PrismContainerDefinition paramContainerDef = prismContext.getSchemaRegistry().findContainerDefinitionByElementName(ReportConstants.REPORT_PARAMS_PROPERTY_NAME); - PrismContainer paramContainer; - paramContainer = paramContainerDef.instantiate(); - ReportParameterType reportParam = new ReportParameterType(); - PrismContainerValue reportParamValue = reportParam.asPrismContainerValue(); - reportParamValue.revive(prismContext); - paramContainer.add(reportParamValue); - - QName typeName = prismContext.getSchemaRegistry().determineTypeForClass(type); - MutablePrismPropertyDefinition def = prismContext.definitionFactory().createPropertyDefinition( - new QName(ReportConstants.NS_EXTENSION, name), typeName); - def.setDynamic(true); - def.setRuntimeSchema(true); - def.toMutable().setMaxOccurs(1); - - PrismProperty prop = def.instantiate(); - prop.addRealValue(realValue); - reportParamValue.add(prop); - - return paramContainer; - } - - protected PrismObject runReport(PrismObject report, boolean errorOk) throws Exception { - return runReport(report, null, errorOk); - } - - protected PrismObject runReport(PrismObject report, PrismContainer params, boolean errorOk) throws Exception { - Task task = createTask(OP_CREATE_REPORT); - OperationResult result = task.getResult(); - PrismObject reportBefore = report.clone(); - report.asObjectable().setFileFormat(getFileFormatConfiguration()); - ObjectDelta diffDelta = reportBefore.diff(report, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS); - executeChanges(diffDelta, ModelExecuteOptions.createRaw(), task, result); - - // WHEN - when(); - reportManager.runReport(report, params, task, result); - - assertInProgress(result); - - display("Background task (running)", task); - - waitForTaskFinish(task.getOid(), false, DEFAULT_TASK_WAIT_TIMEOUT, errorOk); - - // THEN - then(); - PrismObject finishedTask = getTask(task.getOid()); - display("Background task (finished)", finishedTask); - - return finishedTask; - } - - protected PrismObject importReport(PrismObject report, String pathToImportFile, boolean errorOk) throws Exception { - Task task = createTask(OP_IMPORT_REPORT); - OperationResult result = task.getResult(); - PrismObject reportBefore = report.clone(); - report.asObjectable().setFileFormat(getFileFormatConfiguration()); - ObjectDelta diffDelta = reportBefore.diff(report, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS); - executeChanges(diffDelta, ModelExecuteOptions.createRaw(), task, result); - - PrismObject reportData = prismContext.getSchemaRegistry() - .findObjectDefinitionByCompileTimeClass(ReportDataType.class).instantiate(); - reportData.asObjectable().setFileFormat(getFileFormatConfiguration().getType()); - reportData.asObjectable().setFilePath(new File(pathToImportFile).getAbsolutePath()); - reportData.asObjectable().setName(new PolyStringType(report.getName())); - String reportDataOid = addObject(reportData, task, result); - reportData.setOid(reportDataOid); - - // WHEN - when(); - reportManager.importReport(report, reportData, task, result); - - assertInProgress(result); - - display("Background task (running)", task); - - waitForTaskFinish(task.getOid(), false, DEFAULT_TASK_WAIT_TIMEOUT, errorOk); - - // THEN - then(); - PrismObject finishedTask = getTask(task.getOid()); - display("Background task (finished)", finishedTask); - - return finishedTask; - } - - protected abstract FileFormatConfigurationType getFileFormatConfiguration(); - - protected List basicCheckOutputFile(PrismObject report) throws IOException, SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { - File outputFile = findOutputFile(report); - displayValue("Found report file", outputFile); - assertNotNull("No output file for " + report, outputFile); - List lines = Files.readAllLines(Paths.get(outputFile.getPath())); - displayValue("Report content (" + lines.size() + " lines)", String.join("\n", lines)); - outputFile.renameTo(new File(outputFile.getParentFile(), "processed-" + outputFile.getName())); - return lines; - } - - protected File findOutputFile(PrismObject report) { - String filePrefix = report.getName().getOrig(); - File[] matchingFiles = EXPORT_DIR.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith(filePrefix); - } - }); - if (matchingFiles.length == 0) { - return null; - } - if (matchingFiles.length > 1) { - throw new IllegalStateException("Found more than one output files for " + report + ": " + Arrays.toString(matchingFiles)); - } - return matchingFiles[0]; - } -} diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java index 0c959aaf518..fe320161d0b 100644 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java +++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReport.java @@ -8,8 +8,6 @@ import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; @@ -37,7 +35,7 @@ * @author skublik */ -public class TestCsvReport extends BasicNewReportTest { +public class TestCsvReport extends AbstractReportIntegrationTest { public static final File REPORT_IMPORT_OBJECT_COLLECTION_WITH_VIEW_FILE = new File(TEST_REPORTS_DIR, "report-import-object-collection-with-view.xml"); @@ -184,8 +182,25 @@ public void test119CreateObjectCollectionWithSubreportParamReport() throws Excep expectedColumns = 2; expectedRow = 2; lastLine = "\"will\";\"TestRole1230,TestRole123010\""; - super.test119CreateObjectCollectionWithSubreportParamReport(); - lastLine = null; + try { + super.test119CreateObjectCollectionWithSubreportParamReport(); + } finally { + lastLine = null; + } + } + + @Test + public void test120RunMidpointUsers() throws Exception { + expectedColumns = 6; + expectedRow = 4; + super.test120RunMidpointUsers(); + } + + @Test + public void test121RunMidpointUsersScript() throws Exception { + expectedColumns = 6; + expectedRow = 4; + super.test121RunMidpointUsersScript(); } @Test @@ -220,7 +235,7 @@ public void test200ImportReportForUser() throws Exception { } @Test(dependsOnMethods = {"test115CreateObjectCollectionReportWithCondition"}) - public void test201ImportReportfromExportedReport() throws Exception { + public void test201ImportReportFromExportedReport() throws Exception { PrismObject report = getObject(ReportType.class, REPORT_OBJECT_COLLECTION_WITH_CONDITION_OID); runReport(report, false); File outputFile = findOutputFile(report); diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestHtmlReport.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestHtmlReport.java index 16d756a4ac7..0b7bb90466c 100644 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestHtmlReport.java +++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestHtmlReport.java @@ -19,7 +19,7 @@ * @author skublik */ -public class TestHtmlReport extends BasicNewReportTest { +public class TestHtmlReport extends AbstractReportIntegrationTest { @Override protected FileFormatConfigurationType getFileFormatConfiguration() { diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReport.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReport.java deleted file mode 100644 index 96a10bff8fe..00000000000 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReport.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2010-2019 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.report; - -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.io.FilenameFilter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; - -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.prism.PrismObject; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.util.MidPointTestConstants; -import com.evolveum.midpoint.test.util.TestUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.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.ReportType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; - -/** - * Basic report tests. - */ -@ContextConfiguration(locations = { "classpath:ctx-report-test-main.xml" }) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestReport extends AbstractReportIntegrationTest { - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - - repoAddObjectFromFile(REPORT_USER_LIST_FILE, ReportType.class, initResult); - repoAddObjectFromFile(REPORT_USER_LIST_EXPRESSIONS_CSV_FILE, ReportType.class, initResult); - repoAddObjectFromFile(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_QUERY_CSV_FILE, ReportType.class, initResult); - repoAddObjectFromFile(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_FIELD_CSV_FILE, ReportType.class, initResult); - repoAddObjectFromFile(REPORT_USER_LIST_SCRIPT_FILE, ReportType.class, initResult); - - repoAddObjectFromFile(REPORT_AUDIT_CSV_FILE, ReportType.class, initResult); - repoAddObjectFromFile(REPORT_AUDIT_CSV_LEGACY_FILE, ReportType.class, initResult); - - // Let's make this more interesting by adding a couple of users - importObjectsFromFileNotRaw(USERS_MONKEY_ISLAND_FILE, initTask, initResult); - } - - - @Test - public void test100ReportUserList() throws Exception { - Task task = getTestTask(); - OperationResult result = task.getResult(); - - PrismObject report = getObject(ReportType.class, REPORT_USER_LIST_OID); - - // WHEN - when(); - reportManager.runReport(report, null, task, result); - - assertInProgress(result); - - display("Background task", task); - - waitForTaskFinish(task.getOid(), false); - - // THEN - then(); - PrismObject finishedTask = getTask(task.getOid()); - display("Background task", finishedTask); - - assertSuccess("Report task result", finishedTask.asObjectable().getResult()); - } - - /** - * Ordinary user list report. Should work well under all circumstances. - * Even with safe expression profile. - */ - @Test - public void test110ReportUserListExpressionsCsv() throws Exception { - testReportListUsersCsv(REPORT_USER_LIST_EXPRESSIONS_CSV_OID); - } - - /** - * Reports with poisonous operations in the query. This should work with null profile. - * But it should fail with safe profile. - * Field operations are safe in this report, just the query is poisonous. - */ - @Test - public void test112ReportUserListExpressionsPoisonousQueryCsv() throws Exception { - testReportListUsersCsv(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_QUERY_CSV_OID); - } - - /** - * Reports with poisonous operations in the field expression. This should work with null profile. - * But it should fail with safe profile. - * Query expression is safe in this report, just fields are poisonous. - */ - @Test - public void test114ReportUserListExpressionsPoisonousFieldCsv() throws Exception { - testReportListUsersCsv(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_FIELD_CSV_OID); - } - - @Test - public void test200ReportUserListScript() throws Exception { - if (!isOsUnix()) { - displaySkip(); - return; - } - - Task task = getTestTask(); - OperationResult result = task.getResult(); - - PrismObject report = getObject(ReportType.class, REPORT_USER_LIST_SCRIPT_OID); - - // WHEN - when(); - reportManager.runReport(report, null, task, result); - - assertInProgress(result); - - display("Background task", task); - - waitForTaskFinish(task.getOid(), false); - - // THEN - then(); - PrismObject finishedTask = getTask(task.getOid()); - display("Background task", finishedTask); - - TestUtil.assertSuccess("Report task result", finishedTask.asObjectable().getResult()); - - File targetFile = new File(MidPointTestConstants.TARGET_DIR_PATH, "report-users.pdf"); - assertTrue("Target file is not there", targetFile.exists()); - } - - /** - * Reports with report.searchAuditRecords() operation in the query expression. This should work with null profile. - * But it should fail with safe profile. - */ - @Test - public void test300ReportAuditLegacy() throws Exception { - testReportAuditCsvSuccess(REPORT_AUDIT_CSV_LEGACY_OID); - } - - @Test - public void test310ReportAudit() throws Exception { - testReportAuditCsvSuccess(REPORT_AUDIT_CSV_OID); - } - - protected void testReportListUsersCsv(String reportOid) throws Exception { - PrismObject report = getObject(ReportType.class, reportOid); - - PrismObject finishedTask = runReport(report, false); - - assertSuccess("Finished report task result", finishedTask.asObjectable().getResult()); - - checkCsvUserReport(report); - } - - protected void testReportListUsersCsvFailure(String reportOid) throws Exception { - PrismObject report = getObject(ReportType.class, reportOid); - - PrismObject finishedTask = runReport(report, true); - - assertFailure("Finished report task result", finishedTask.asObjectable().getResult()); - - assertNoCsvReport(report); - } - - protected PrismObject runReport(PrismObject report, boolean errorOk) throws Exception { - Task task = getTestTask(); - OperationResult result = task.getResult(); - - // WHEN - when(); - reportManager.runReport(report, null, task, result); - - assertInProgress(result); - - display("Background task (running)", task); - - waitForTaskFinish(task.getOid(), false, DEFAULT_TASK_WAIT_TIMEOUT, errorOk); - - // THEN - then(); - PrismObject finishedTask = getTask(task.getOid()); - display("Background task (finished)", finishedTask); - - return finishedTask; - } - - - protected void checkCsvUserReport(PrismObject report) throws IOException, SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { - File outputFile = findOutputFile(report); - displayValue("Found report file", outputFile); - assertNotNull("No output file for "+report, outputFile); - List lines = Files.readAllLines(Paths.get(outputFile.getPath())); - displayValue("Report content ("+lines.size()+" lines)", String.join("\n", lines)); - outputFile.renameTo(new File(outputFile.getParentFile(), "processed-"+outputFile.getName())); - - Task task = getTestTask(); - OperationResult result = task.getResult(); - SearchResultList> currentUsers = modelService.searchObjects(UserType.class, null, null, task, result); - displayValue("Current users in midPoint ("+currentUsers.size()+" users)", currentUsers.toString()); - - assertEquals("Unexpected number of report lines", currentUsers.size() + 1, lines.size()); - } - - protected void assertNoCsvReport(PrismObject report) { - File outputFile = findOutputFile(report); - displayValue("Found report file (expected null)", outputFile); - assertNull("Unexpected output file for "+report+": "+outputFile, outputFile); - } - - protected void testReportAuditCsvSuccess(String reportOid) throws Exception { - - PrismObject report = getObject(ReportType.class, reportOid); - - PrismObject finishedTask = runReport(report, false); - - assertSuccess("Report task result", finishedTask.asObjectable().getResult()); - - checkCsvAuditReport(report); - } - - protected void testReportAuditCsvFailure(String reportOid) throws Exception { - PrismObject report = getObject(ReportType.class, reportOid); - - PrismObject finishedTask = runReport(report, true); - - assertFailure("Finished report task result", finishedTask.asObjectable().getResult()); - - assertNoCsvReport(report); - } - - protected void checkCsvAuditReport(PrismObject report) throws IOException { - File outputFile = findOutputFile(report); - displayValue("Found report file", outputFile); - assertNotNull("No output file for "+report, outputFile); - List lines = Files.readAllLines(Paths.get(outputFile.getPath())); - displayValue("Report content ("+lines.size()+" lines)", String.join("\n", lines)); - outputFile.renameTo(new File(outputFile.getParentFile(), "processed-"+outputFile.getName())); - - if (lines.size() < 10) { - fail("Adit report CSV too short ("+lines.size()+" lines)"); - } - } - - protected File findOutputFile(PrismObject report) { - String filePrefix = report.getName().getOrig(); - File[] matchingFiles = EXPORT_DIR.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith(filePrefix); - } - }); - if (matchingFiles.length == 0) { - return null; - } - if (matchingFiles.length > 1) { - throw new IllegalStateException("Found more than one output files for "+report+": "+Arrays.toString(matchingFiles)); - } - return matchingFiles[0]; - } -} diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportJasper.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportJasper.java deleted file mode 100644 index 4d50b4539dc..00000000000 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportJasper.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2010-2017 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.report; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import com.evolveum.midpoint.task.api.RunningTask; -import net.sf.jasperreports.engine.JasperCompileManager; -import net.sf.jasperreports.engine.JasperExportManager; -import net.sf.jasperreports.engine.JasperFillManager; -import net.sf.jasperreports.engine.JasperPrint; -import net.sf.jasperreports.engine.JasperReport; -import net.sf.jasperreports.engine.design.JasperDesign; -import net.sf.jasperreports.engine.xml.JRXmlLoader; - -import org.springframework.beans.factory.annotation.Autowired; -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.icf.dummy.resource.DummyResource; -import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.report.impl.ReportJasperCreateTaskHandler; -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.ResourceType; - -/** - * Looks like this test goes directly to Jasper. - * - * This test does not work. It is NOT ENABLED in testng XML files. - */ -@ContextConfiguration(locations = { "classpath:ctx-report-test-main.xml" }) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestReportJasper extends AbstractReportIntegrationTest { - - @Autowired(required=true) - ExpressionFactory expressionFactory; - - protected static DummyResource dummyResource; - protected static DummyResourceContoller dummyResourceCtl; - protected ResourceType resourceDummyType; - protected PrismObject resourceDummy; - - @Autowired(required = true) - ReportJasperCreateTaskHandler reportTaskHandler; - - @Override - protected void startResources() throws Exception { - openDJController.startCleanServer(); - } - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - - importObjectFromFile(RESOURCE_OPENDJ_FILE, initResult); - -// caseIgnoreMatchingRule = matchingRuleRegistry.getMatchingRule(StringIgnoreCaseMatchingRule.NAME, DOMUtil.XSD_STRING); - -// importSystemTasks(initResult); - } - - - @Test - public void f() throws Exception{ - OperationResult initResult = new OperationResult("generate report"); - JasperDesign jd = JRXmlLoader.load(new File("src/test/resources/reports/report-users-ds.jrxml")); - JasperReport jr = JasperCompileManager.compileReport(jd); - - RunningTask task = taskManager.createFakeRunningTask(taskManager.createTaskInstance(), "dummy"); - Map params = new HashMap<>(); -// params.put(MidPointQueryExecutorFactory.PARAMETER_MIDPOINT_CONNECTION, modelService); -// params.put(MidPointQueryExecutorFactory.PARAMETER_PRISM_CONTEXT, prismContext); -// params.put(MidPointQueryExecutorFactory.PARAMETER_TASK_MANAGER, taskManager); -// params.put(MidPointQueryExecutorFactory.PARAMETER_EXPRESSION_FACTORY, expressionFactory); - params.put("userName", new PolyString("administrator")); - - - reportTaskHandler.run(task); - -// byte[] reportTemplatebase64 = "".getBytes(); -// byte[] reportTemplate = Base64.decodeBase64("UEdwaGMzQmxjbEpsY0c5eWRDQU5DaUFnSUNBSkNYaHRiRzV6UFNKb2RIUndPaTh2YW1GemNHVnljbVZ3YjNKMGN5NXpiM1Z5WTJWbWIzSm5aUzV1WlhRdmFtRnpjR1Z5Y21Wd2IzSjBjeUlnRFFvSkNRbDRiV3h1Y3pwNGMyazlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURFdldFMU1VMk5vWlcxaExXbHVjM1JoYm1ObElpQU5DZ2tKQ1hoemFUcHpZMmhsYldGTWIyTmhkR2x2YmowaWFIUjBjRG92TDJwaGMzQmxjbkpsY0c5eWRITXVjMjkxY21ObFptOXlaMlV1Ym1WMEwycGhjM0JsY25KbGNHOXlkSE1nYUhSMGNEb3ZMMnBoYzNCbGNuSmxjRzl5ZEhNdWMyOTFjbU5sWm05eVoyVXVibVYwTDNoelpDOXFZWE53WlhKeVpYQnZjblF1ZUhOa0lpQU5DZ2tKQ1c1aGJXVTlJbkpsY0c5eWRGVnpaWEpCWTJOdmRXNTBjeUlnRFFvSkNRbGpiMngxYlc1RGIzVnVkRDBpTWlJZ0RRb0pDUWx3WVdkbFYybGtkR2c5SWpFNE1DSWdEUW9KQ1Fsd1lXZGxTR1ZwWjJoMFBTSXhPQ0lnRFFvSkNRbDNhR1Z1VG05RVlYUmhWSGx3WlQwaVFXeHNVMlZqZEdsdmJuTk9iMFJsZEdGcGJDSWdEUW9KQ1FsamIyeDFiVzVYYVdSMGFEMGlPRGtpSUEwS0NRa0pZMjlzZFcxdVUzQmhZMmx1WnowaU1TSWdEUW9KQ1Fsc1pXWjBUV0Z5WjJsdVBTSXdJaUFOQ2drSkNYSnBaMmgwVFdGeVoybHVQU0l3SWlBTkNna0pDWFJ2Y0UxaGNtZHBiajBpTUNJZ0RRb0pDUWxpYjNSMGIyMU5ZWEpuYVc0OUlqQWlJQTBLQ1FrSmRYVnBaRDBpTmpkbE5EWTFZelV0TkRabFlTMDBNR1F5TFdKbFlUQXRORFk1WXpaalpqTTRPVE0zSWo0TkNna0pDVHh3Y205d1pYSjBlU0J1WVcxbFBTSnVaWFF1YzJZdWFtRnpjR1Z5Y21Wd2IzSjBjeTVoZDNRdWFXZHViM0psTG0xcGMzTnBibWN1Wm05dWRDSWdkbUZzZFdVOUluUnlkV1VpTHo0TkNna0pDVHh3Y205d1pYSjBlU0J1WVcxbFBTSnVaWFF1YzJZdWFtRnpjR1Z5Y21Wd2IzSjBjeTVsZUhCdmNuUXVjR1JtTG1admNtTmxMbXhwYm1WaWNtVmhheTV3YjJ4cFkza2lJSFpoYkhWbFBTSjBjblZsSWk4K0RRb0pDUWs4YzNSNWJHVWdabTl1ZEU1aGJXVTlJa1JsYW1GV2RTQlRZVzV6SWlCbWIyNTBVMmw2WlQwaU1UQWlJR2hCYkdsbmJqMGlUR1ZtZENJZ2FYTkVaV1poZFd4MFBTSjBjblZsSWlCcGMxQmtaa1Z0WW1Wa1pHVmtQU0owY25WbElpQU5DZ2tKQ1FrZ0lDQnVZVzFsUFNKQ1lYTmxJaUJ3WkdaRmJtTnZaR2x1WnowaVNXUmxiblJwZEhrdFNDSWdjR1JtUm05dWRFNWhiV1U5SWtSbGFtRldkVk5oYm5NdWRIUm1JaUIyUVd4cFoyNDlJazFwWkdSc1pTSStEUW9KQ1FrOEwzTjBlV3hsUGcwS0NRa0pQSE4wZVd4bElHbHpRbTlzWkQwaVptRnNjMlVpSUdselJHVm1ZWFZzZEQwaVptRnNjMlVpSUc1aGJXVTlJa1JsZEdGcGJDSWdjM1I1YkdVOUlrSmhjMlVpTHo0TkNna0pDVHh3WVhKaGJXVjBaWElnYm1GdFpUMGlkWE5sY2s5cFpDSWdZMnhoYzNNOUltcGhkbUV1YkdGdVp5NVRkSEpwYm1jaUx6NE5DZ2tKQ1R4d1lYSmhiV1YwWlhJZ2JtRnRaVDBpYUhGc1VYVmxjbmxCWTJOdmRXNTBjeUlnWTJ4aGMzTTlJbXBoZG1FdWJHRnVaeTVUZEhKcGJtY2lMejROQ2drSkNUeHhkV1Z5ZVZOMGNtbHVaeUJzWVc1bmRXRm5aVDBpYUhGc0lqNDhJVnREUkVGVVFWc2tVQ0Y3YUhGc1VYVmxjbmxCWTJOdmRXNTBjMzFkWFQ0OEwzRjFaWEo1VTNSeWFXNW5QZzBLQ1FrSlBHWnBaV3hrSUc1aGJXVTlJbUZqWTI5MWJuUk9ZVzFsSWlCamJHRnpjejBpYW1GMllTNXNZVzVuTGxOMGNtbHVaeUl2UGcwS0NRa0pQR1pwWld4a0lHNWhiV1U5SW5KbGMyOTFjbU5sVG1GdFpTSWdZMnhoYzNNOUltcGhkbUV1YkdGdVp5NVRkSEpwYm1jaUx6NE5DZ2tKQ1R4a1pYUmhhV3crRFFvSkNRa0pQR0poYm1RZ2FHVnBaMmgwUFNJeE9DSWdjM0JzYVhSVWVYQmxQU0pUZEhKbGRHTm9JajROQ2drSkNRa0pQR1p5WVcxbFBnMEtDUWtKQ1FrSlBISmxjRzl5ZEVWc1pXMWxiblFnZFhWcFpEMGlNMlU0Wm1Sa05tUXRZVFptWmkwME5EQTNMVGxoTVdVdE5XUTJZalEzTURZek1EQmhJaUJ3YjNOcGRHbHZibFI1Y0dVOUlrWnNiMkYwSWlCemRIbHNaVDBpUkdWMFlXbHNJaUJ0YjJSbFBTSlBjR0Z4ZFdVaUlIZzlJakFpSUhrOUlqRWlJSGRwWkhSb1BTSXhPREFpSUdobGFXZG9kRDBpTVRjaUx6NE5DZ2tKQ1FrSkNUeHNhVzVsUGcwS0NRa0pDUWtKQ1R4eVpYQnZjblJGYkdWdFpXNTBJSFYxYVdROUlqUTNaamt4T0RBeExXTm1OV1l0TkdKbFpDMWlNVGxqTFdOaE16a3pNV05pWmprNFpDSWdjRzl6YVhScGIyNVVlWEJsUFNKR2FYaFNaV3hoZEdsMlpWUnZWRzl3SWlCNFBTSXdJaUI1UFNJd0lpQjNhV1IwYUQwaU1UZ3dJaUJvWldsbmFIUTlJakVpSUdadmNtVmpiMnh2Y2owaUl6TXpNek16TXlJK0RRb0pDUWtKQ1FrSkNUeHdjbWx1ZEZkb1pXNUZlSEJ5WlhOemFXOXVQandoVzBORVFWUkJXMjVsZHlCcVlYWmhMbXhoYm1jdVFtOXZiR1ZoYmlnb2FXNTBLU1JXZTFKRlVFOVNWRjlEVDFWT1ZIMHVhVzUwVm1Gc2RXVW9LU0U5TVNsZFhUNDhMM0J5YVc1MFYyaGxia1Y0Y0hKbGMzTnBiMjQrRFFvSkNRa0pDUWtKUEM5eVpYQnZjblJGYkdWdFpXNTBQZzBLQ1FrSkNRa0pDVHhuY21Gd2FHbGpSV3hsYldWdWRENE5DZ2tKQ1FrSkNRa0pQSEJsYmlCc2FXNWxWMmxrZEdnOUlqQXVOU0lnYkdsdVpVTnZiRzl5UFNJak9UazVPVGs1SWk4K0RRb0pDUWtKQ1FrSlBDOW5jbUZ3YUdsalJXeGxiV1Z1ZEQ0TkNna0pDUWtKQ1R3dmJHbHVaVDROQ2drSkNRa0pDVHgwWlhoMFJtbGxiR1FnYVhOVGRISmxkR05vVjJsMGFFOTJaWEptYkc5M1BTSjBjblZsSWo0TkNna0pDUWtKQ1FrOGNtVndiM0owUld4bGJXVnVkQ0IxZFdsa1BTSmxZbUZsWmpFMlpDMHlPVEF6TFRRd01qa3RPV0UyWWkxa05HUXlORFExTlRoaFpUa2lJSEJ2YzJsMGFXOXVWSGx3WlQwaVJteHZZWFFpSUhOMGNtVjBZMmhVZVhCbFBTSlNaV3hoZEdsMlpWUnZWR0ZzYkdWemRFOWlhbVZqZENJZ2MzUjViR1U5SWtSbGRHRnBiQ0lnZUQwaU1DSWdlVDBpTWlJZ2QybGtkR2c5SWpFNE1DSWdhR1ZwWjJoMFBTSXhNeUl2UGcwS0NRa0pDUWtKQ1R4MFpYaDBSV3hsYldWdWRDQjJaWEowYVdOaGJFRnNhV2R1YldWdWREMGlUV2xrWkd4bElpOCtJQTBLQ1FrSkNRa0pDVHgwWlhoMFJtbGxiR1JGZUhCeVpYTnphVzl1UGp3aFcwTkVRVlJCV3lSR2UzSmxjMjkxY21ObFRtRnRaWDBySUNJNklDSWdLeUFrUm50aFkyTnZkVzUwVG1GdFpYMWRYVDQ4TDNSbGVIUkdhV1ZzWkVWNGNISmxjM05wYjI0K0RRb0pDUWtKQ1FrOEwzUmxlSFJHYVdWc1pENE5DZ2tKQ1FrSlBDOW1jbUZ0WlQ0TkNna0pDUWs4TDJKaGJtUStEUW9KQ1FrOEwyUmxkR0ZwYkQ0TkNna0pQQzlxWVhOd1pYSlNaWEJ2Y25RKw==".getBytes()); -// -// byte[] decoded = Base64.decodeBase64(reportTemplate); -// String s = new String(decoded); -// System.out.println(s); - File f = new File("src/test/resources/reports/reportAccounts.txt"); -// DataOutputStream fos = new DataOutputStream(new FileOutputStream(f)); -// fos.writeUTF(s); -// fos.close(); - JasperPrint jasperPrint = JasperFillManager.fillReport(jr, params); - - f = new File("src/test/resources/reports/report5.pdf"); - JasperExportManager.exportReportToPdfFile(jasperPrint, f.getAbsolutePath()); -// System.out.println("output: " + output); -// jr. -// jr.getQuery().getLanguage(); -// jr.getQuery().getText(); - } -} diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportSafe.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportSafe.java deleted file mode 100644 index 8c784a2029f..00000000000 --- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestReportSafe.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2010-2019 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.report; - -import java.io.File; - -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.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; - -/** - * Basic report test, using "safe" expression profile. - */ -@ContextConfiguration(locations = { "classpath:ctx-report-test-main.xml" }) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestReportSafe extends TestReport { - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - } - - @Override - protected File getSystemConfigurationFile() { - return SYSTEM_CONFIGURATION_SAFE_FILE; - } - - /** - * Reports with poisonous operations in the query. This should work with null profile. - * But it should fail with safe profile. - * Field operations are safe in this report, just the query is poisonous. - */ - @Test - @Override - public void test112ReportUserListExpressionsPoisonousQueryCsv() throws Exception { - testReportListUsersCsvFailure(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_QUERY_CSV_OID); - } - - /** - * Reports with poisonous operations in the field expression. This should work with null profile. - * But it should fail with safe profile. - * Query expression is safe in this report, just fields are poisonous. - */ - @Test - public void test114ReportUserListExpressionsPoisonousFieldCsv() throws Exception { - testReportListUsersCsvFailure(REPORT_USER_LIST_EXPRESSIONS_POISONOUS_FIELD_CSV_OID); - } - - /** - * Reports with report.searchAuditRecords() operation in the query expression. This should work with null profile. - * But it should fail with safe profile. - */ - @Test - public void test300ReportAuditLegacy() throws Exception { - testReportAuditCsvFailure(REPORT_AUDIT_CSV_LEGACY_OID); - } -} diff --git a/model/report-impl/src/test/resources/reports/report-audit-ds.jrxml b/model/report-impl/src/test/resources/reports/report-audit-ds.jrxml deleted file mode 100644 index 4974358beb5..00000000000 --- a/model/report-impl/src/test/resources/reports/report-audit-ds.jrxml +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <band height="168" splitType="Stretch"> - <frame> - <reportElement mode="Opaque" x="0" y="0" width="800" height="67" backcolor="#267994" uuid="44bedacc-fa23-4fe1-b71f-e5afa943f553"/> - <staticText> - <reportElement x="10" y="13" width="266" height="38" uuid="f2d99cad-9d84-4f50-b455-453c87f62c4c"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[Audit Log Report]]></text> - </staticText> - </frame> - <staticText> - <reportElement x="2" y="85" width="100" height="20" uuid="e035dbd5-dc2f-45cb-936c-a08e9c011e43"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[From:]]></text> - </staticText> - <textField pattern="EEEEE dd MMMMM yyyy, HH:mm:ss"> - <reportElement isPrintRepeatedValues="false" x="110" y="85" width="644" height="20" uuid="28bb9b47-a69c-48e1-9073-d54d926242e8"/> - <textElement verticalAlignment="Middle"> - <font isBold="false"/> - </textElement> - <textFieldExpression><![CDATA[$P{from}]]></textFieldExpression> - </textField> - <staticText> - <reportElement x="2" y="115" width="100" height="20" uuid="e035dbd5-dc2f-45cb-936c-a08e9c011e43"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[To:]]></text> - </staticText> - <textField pattern="EEEEE dd MMMMM yyyy, HH:mm:ss"> - <reportElement isPrintRepeatedValues="false" x="110" y="115" width="644" height="20" uuid="28bb9b47-a69c-48e1-9073-d54d926242e8"/> - <textElement verticalAlignment="Middle"> - <font isBold="false"/> - </textElement> - <textFieldExpression><![CDATA[$P{to}]]></textFieldExpression> - </textField> - <staticText> - <reportElement x="2" y="145" width="100" height="20" uuid="e035dbd5-dc2f-45cb-936c-a08e9c011e43"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[Event Type:]]></text> - </staticText> - <textField> - <reportElement isPrintRepeatedValues="false" x="110" y="145" width="644" height="20" uuid="28bb9b47-a69c-48e1-9073-d54d926242e8"/> - <textElement verticalAlignment="Middle"> - <font isBold="false"/> - </textElement> - <textFieldExpression><![CDATA[$P{eventType} != null ? $P{eventDescription} : "All"]]></textFieldExpression> - </textField> - </band> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/model/report-impl/src/test/resources/reports/report-user-list-expressions-csv.xml b/model/report-impl/src/test/resources/reports/report-user-list-expressions-csv.xml deleted file mode 100644 index 33ebabb7c12..00000000000 --- a/model/report-impl/src/test/resources/reports/report-user-list-expressions-csv.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - Users in MidPoint - report with expressions - Users listed in MidPoint. - - - - true - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - csv - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - diff --git a/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-field-csv.xml b/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-field-csv.xml deleted file mode 100644 index ba44d922796..00000000000 --- a/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-field-csv.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - Users in MidPoint - report with poisonous field expressions - Users listed in MidPoint. - - - - true - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - csv - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - diff --git a/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-query-csv.xml b/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-query-csv.xml deleted file mode 100644 index 74bff95a4a3..00000000000 --- a/model/report-impl/src/test/resources/reports/report-user-list-expressions-poisonous-query-csv.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - Users in MidPoint - report with poisonous query expressions - Users listed in MidPoint. - - - - true - - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - csv - JRSwapFileVirtualizer - 300 - 10000 - 300000 - - diff --git a/model/report-impl/src/test/resources/reports/report-user-list-script.xml b/model/report-impl/src/test/resources/reports/report-user-list-script.xml index 19a66adb138..fa1bc59053b 100644 --- a/model/report-impl/src/test/resources/reports/report-user-list-script.xml +++ b/model/report-impl/src/test/resources/reports/report-user-list-script.xml @@ -14,26 +14,148 @@ xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"> report-users Users listed in MidPoint. - - 2016-11-03T19:52:40.643+01:00 - - http://midpoint.evolveum.com/xml/ns/public/common/channels-3#objectImport - 2016-11-03T19:57:22.109+01:00 - - http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user - - - true - - PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgamFzcGVyVGVtcGxhdGUNCiAgUFVCTElDICItLy9KYXNwZXJSZXBvcnRzLy9EVEQgVGVtcGxhdGUvL0VOIg0KICAiaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2R0ZHMvamFzcGVydGVtcGxhdGUuZHRkIj4NCjxqYXNwZXJUZW1wbGF0ZT4NCiAgICAgICAgCTxzdHlsZSBmb250TmFtZT0iRGVqYVZ1IFNhbnMiIGZvbnRTaXplPSIxMCIgaEFsaWduPSJMZWZ0IiBpc0RlZmF1bHQ9InRydWUiIGlzUGRmRW1iZWRkZWQ9InRydWUiIA0KCQkJCSAgIG5hbWU9IkJhc2UiIHBkZkVuY29kaW5nPSJJZGVudGl0eS1IIiBwZGZGb250TmFtZT0iRGVqYVZ1U2Fucy50dGYiIHZBbGlnbj0iTWlkZGxlIj4NCgkJCTwvc3R5bGU+DQoJCQk8c3R5bGUgYmFja2NvbG9yPSIjMjY3OTk0IiBmb250U2l6ZT0iMjYiIGZvcmVjb2xvcj0iI0ZGRkZGRiIgaXNEZWZhdWx0PSJmYWxzZSINCiAgICAgICAgICAgICAgICAgICBtb2RlPSJPcGFxdWUiIG5hbWU9IlRpdGxlIiBzdHlsZT0iQmFzZSIvPiANCgkJCTxzdHlsZSBmb250U2l6ZT0iMTIiIGZvcmVjb2xvcj0iIzAwMDAwMCIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iUGFnZSBoZWFkZXIiDQogICAgICAgICAgICAgICAgICAgc3R5bGU9IkJhc2UiLz4NCgkJCTxzdHlsZSBiYWNrY29sb3I9IiMzMzMzMzMiIGZvbnRTaXplPSIxMiIgZm9yZWNvbG9yPSIjRkZGRkZGIiBoQWxpZ249IkNlbnRlciINCiAgICAgICAgICAgICAgICAgICBpc0RlZmF1bHQ9ImZhbHNlIiBtb2RlPSJPcGFxdWUiIG5hbWU9IkNvbHVtbiBoZWFkZXIiIHN0eWxlPSJCYXNlIi8+DQoJCQk8c3R5bGUgaXNCb2xkPSJmYWxzZSIgaXNEZWZhdWx0PSJmYWxzZSIgbmFtZT0iRGV0YWlsIiBzdHlsZT0iQmFzZSIvPg0KICAgICAgICAgICAgPHN0eWxlIGlzQm9sZD0iZmFsc2UiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IkNvZGUiIHN0eWxlPSJCYXNlIiBmb250U2l6ZT0iOSIvPg0KCQkJPHN0eWxlIGZvbnRTaXplPSI5IiBmb3JlY29sb3I9IiMwMDAwMDAiIGlzRGVmYXVsdD0iZmFsc2UiIG5hbWU9IlBhZ2UgZm9vdGVyIg0KICAgICAgICAgICAgICAgICAgIHN0eWxlPSJCYXNlIi8+DQoJCTwvamFzcGVyVGVtcGxhdGU+ - pdf - JRSwapFileVirtualizer - 300 - 10000 - 300000 - + + + + + + activation/administrativeStatus + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/construction/resourceRef + + filterAll + + + + + + + + activation + ActivationStatusType + + + + + + organization + c:ObjectReferenceType + c:OrgType + + + + + + role + c:ObjectReferenceType + c:RoleType + + + + + + resource + c:ObjectReferenceType + c:ResourceType + + + + + + UserType + + file @@ -48,6 +170,6 @@ shell - cp %file% "target/%name%.pdf" + cp %file% "target/%name%" diff --git a/model/report-impl/src/test/resources/reports/report-user-list.xml b/model/report-impl/src/test/resources/reports/report-user-list.xml index aacbcd0c79c..cbab9b451a1 100644 --- a/model/report-impl/src/test/resources/reports/report-user-list.xml +++ b/model/report-impl/src/test/resources/reports/report-user-list.xml @@ -1,39 +1,157 @@ + - Users in MidPoint - Users listed in MidPoint. - - 2016-11-03T19:52:40.643+01:00 - - http://midpoint.evolveum.com/xml/ns/public/common/channels-3#objectImport - 2016-11-03T19:57:22.109+01:00 - - http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user - - - true - - - UEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWo4K0RRbzhJVVJQUTFSWlVFVWdhbUZ6Y0dWeVZHVnRjR3hoZEdVTkNpQWdVRlZDVEVsRElDSXRMeTlLWVhOd1pYSlNaWEJ2Y25Sekx5OUVWRVFnVkdWdGNHeGhkR1V2TDBWT0lnMEtJQ0FpYUhSMGNEb3ZMMnBoYzNCbGNuSmxjRzl5ZEhNdWMyOTFjbU5sWm05eVoyVXVibVYwTDJSMFpITXZhbUZ6Y0dWeWRHVnRjR3hoZEdVdVpIUmtJajROQ2p4cVlYTndaWEpVWlcxd2JHRjBaVDROQ2lBZ0lDQWdJQ0FnQ1R4emRIbHNaU0JtYjI1MFRtRnRaVDBpUkdWcVlWWjFJRk5oYm5NaUlHWnZiblJUYVhwbFBTSXhNQ0lnYUVGc2FXZHVQU0pNWldaMElpQnBjMFJsWm1GMWJIUTlJblJ5ZFdVaUlHbHpVR1JtUlcxaVpXUmtaV1E5SW5SeWRXVWlJQTBLQ1FrSkNTQWdJRzVoYldVOUlrSmhjMlVpSUhCa1prVnVZMjlrYVc1blBTSkpaR1Z1ZEdsMGVTMUlJaUJ3WkdaR2IyNTBUbUZ0WlQwaVJHVnFZVloxVTJGdWN5NTBkR1lpSUhaQmJHbG5iajBpVFdsa1pHeGxJajROQ2drSkNUd3ZjM1I1YkdVK0RRb0pDUWs4YzNSNWJHVWdZbUZqYTJOdmJHOXlQU0lqTWpZM09UazBJaUJtYjI1MFUybDZaVDBpTWpZaUlHWnZjbVZqYjJ4dmNqMGlJMFpHUmtaR1JpSWdhWE5FWldaaGRXeDBQU0ptWVd4elpTSU5DaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J0YjJSbFBTSlBjR0Z4ZFdVaUlHNWhiV1U5SWxScGRHeGxJaUJ6ZEhsc1pUMGlRbUZ6WlNJdlBpQU5DZ2tKQ1R4emRIbHNaU0JtYjI1MFUybDZaVDBpTVRJaUlHWnZjbVZqYjJ4dmNqMGlJekF3TURBd01DSWdhWE5FWldaaGRXeDBQU0ptWVd4elpTSWdibUZ0WlQwaVVHRm5aU0JvWldGa1pYSWlEUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzNSNWJHVTlJa0poYzJVaUx6NE5DZ2tKQ1R4emRIbHNaU0JpWVdOclkyOXNiM0k5SWlNek16TXpNek1pSUdadmJuUlRhWHBsUFNJeE1pSWdabTl5WldOdmJHOXlQU0lqUmtaR1JrWkdJaUJvUVd4cFoyNDlJa05sYm5SbGNpSU5DaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYzBSbFptRjFiSFE5SW1aaGJITmxJaUJ0YjJSbFBTSlBjR0Z4ZFdVaUlHNWhiV1U5SWtOdmJIVnRiaUJvWldGa1pYSWlJSE4wZVd4bFBTSkNZWE5sSWk4K0RRb0pDUWs4YzNSNWJHVWdhWE5DYjJ4a1BTSm1ZV3h6WlNJZ2FYTkVaV1poZFd4MFBTSm1ZV3h6WlNJZ2JtRnRaVDBpUkdWMFlXbHNJaUJ6ZEhsc1pUMGlRbUZ6WlNJdlBnMEtJQ0FnSUNBZ0lDQWdJQ0FnUEhOMGVXeGxJR2x6UW05c1pEMGlabUZzYzJVaUlHbHpSR1ZtWVhWc2REMGlabUZzYzJVaUlHNWhiV1U5SWtOdlpHVWlJSE4wZVd4bFBTSkNZWE5sSWlCbWIyNTBVMmw2WlQwaU9TSXZQZzBLQ1FrSlBITjBlV3hsSUdadmJuUlRhWHBsUFNJNUlpQm1iM0psWTI5c2IzSTlJaU13TURBd01EQWlJR2x6UkdWbVlYVnNkRDBpWm1Gc2MyVWlJRzVoYldVOUlsQmhaMlVnWm05dmRHVnlJZzBLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhOMGVXeGxQU0pDWVhObElpOCtEUW9KQ1R3dmFtRnpjR1Z5VkdWdGNHeGhkR1Ur - pdf - JRSwapFileVirtualizer - 300 - 10000 - 300000 - + xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" + oid="00000000-0000-0000-0000-000000000110"> + Users in MidPoint + Users listed in MidPoint. + + + + + + activation/administrativeStatus + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/targetRef + + filterAll + + + + + assignment/construction/resourceRef + + filterAll + + + + + + + + activation + ActivationStatusType + + + + + + organization + c:ObjectReferenceType + c:OrgType + + + + + + role + c:ObjectReferenceType + c:RoleType + + + + + + resource + c:ObjectReferenceType + c:ResourceType + + + + + + UserType + + diff --git a/model/report-impl/src/test/resources/reports/report-users-ds.jrxml b/model/report-impl/src/test/resources/reports/report-users-ds.jrxml deleted file mode 100644 index 6fbce0659b0..00000000000 --- a/model/report-impl/src/test/resources/reports/report-users-ds.jrxml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - c:UserType - - - - ]]> - - - - - - - - - - - - - - <band height="110" splitType="Stretch"> - <frame> - <reportElement mode="Opaque" x="1" y="0" width="799" height="67" backcolor="#267994" uuid="44bedacc-fa23-4fe1-b71f-e5afa943f553"/> - <staticText> - <reportElement x="10" y="13" width="266" height="38" uuid="f2d99cad-9d84-4f50-b455-453c87f62c4c"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[User Report]]></text> - </staticText> - </frame> - <staticText> - <reportElement x="400" y="87" width="150" height="20" uuid="3ff78fbf-8fce-4072-b691-7af047ea92a7"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[Number of records:]]></text> - </staticText> - <textField pattern="EEEEE dd MMMMM yyyy, HH:mm:ss"> - <reportElement x="550" y="67" width="250" height="20" uuid="09a7e272-204e-4078-8a5e-e472757424c1"/> - <textElement textAlignment="Right" verticalAlignment="Middle"> - <font isBold="false"/> - </textElement> - <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> - </textField> - <staticText> - <reportElement x="400" y="67" width="150" height="20" uuid="b0b9714f-96f5-4f58-824b-c81fd4d321f7"/> - <textElement verticalAlignment="Middle"/> - <text><![CDATA[Report generated on:]]></text> - </staticText> - <textField evaluationTime="Report" isBlankWhenNull="true"> - <reportElement x="550" y="87" width="250" height="20" uuid="89251211-3f49-471d-b88d-5564c1bd04d1"/> - <textElement textAlignment="Right" verticalAlignment="Middle"> - <font isBold="false"/> - </textElement> - <textFieldExpression><![CDATA[$V{REPORT_COUNT}]]></textFieldExpression> - </textField> - - </band> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/model/report-impl/testng-integration.xml b/model/report-impl/testng-integration.xml index fa99d637fda..bc7c2109ddb 100644 --- a/model/report-impl/testng-integration.xml +++ b/model/report-impl/testng-integration.xml @@ -9,8 +9,6 @@ - - From 5d640fe24ec27820c83c37161c132a24d0eae6e0 Mon Sep 17 00:00:00 2001 From: lskublik Date: Wed, 28 Apr 2021 13:55:01 +0200 Subject: [PATCH 05/15] clean up of code after removing of jasper report --- .../000-system-configuration.xml | 5 - gui/admin-gui/pom.xml | 23 - .../impl/component/menu/LeftMenuPanel.java | 7 - .../AutoCompleteReferencePanelFactory.java | 5 +- .../midpoint/init/InitialDataImport.java | 6 - .../page/admin/reports/PageJasperReport.html | 22 - .../page/admin/reports/PageJasperReport.java | 328 --------- .../web/page/admin/reports/PageNewReport.html | 55 -- .../web/page/admin/reports/PageNewReport.java | 254 ------- .../web/page/admin/reports/PageReports.java | 8 +- ...ashboardReportBasicConfigurationPanel.html | 43 -- ...ashboardReportBasicConfigurationPanel.java | 144 ---- .../component/EngineReportTabPanel.java | 74 +- .../JasperReportBasicConfigurationPanel.html | 30 - .../JasperReportBasicConfigurationPanel.java | 125 ---- .../JasperReportConfigurationPanel.html | 43 -- .../JasperReportConfigurationPanel.java | 375 ---------- .../ParameterPropertiesPopupPanel.html | 69 -- .../ParameterPropertiesPopupPanel.java | 108 --- .../component/ReportConfigurationPanel.html | 12 - .../component/ReportConfigurationPanel.java | 39 -- .../component/RunReportPopupPanel.java | 108 --- .../reports/dto/AuditEventRecordProvider.java | 4 +- .../admin/reports/dto/JasperReportDto.java | 164 ----- .../reports/dto/JasperReportFieldDto.java | 65 -- .../reports/dto/JasperReportParameterDto.java | 174 ----- .../JasperReportParameterPropertiesDto.java | 111 --- .../reports/dto/JasperReportRealValueDto.java | 22 - .../reports/dto/JasperReportValueDto.java | 38 -- .../web/page/admin/reports/dto/ReportDto.java | 18 +- .../page/admin/server/TaskErrorsTabPanel.java | 4 - .../000-system-configuration.xml | 5 - .../resources/common/system-configuration.xml | 5 - infra/schema/pom.xml | 8 - .../midpoint/schema/util/ReportTypeUtil.java | 163 ----- .../diff/system-configuration-after.xml | 5 - .../diff/system-configuration-before.xml | 160 +++-- .../src/main/resources/reports/_readme.txt | 3 - .../main/resources/reports/non-responders.xml | 232 ------- .../model/api/ModelInteractionService.java | 2 +- .../ModelInteractionServiceImpl.java | 2 +- model/report-impl/pom.xml | 15 - .../report/impl/CustomDataWriter.java | 76 --- .../report/impl/JRMidpointCompiler.java | 107 --- .../report/impl/JRMidpointEvaluator.java | 269 -------- .../impl/MidPointAbstractDataSource.java | 95 --- .../report/impl/MidPointDataSource.java | 135 ---- .../impl/MidPointLocalQueryExecutor.java | 149 ---- .../report/impl/MidPointQueryExecutor.java | 203 ------ .../impl/MidPointQueryExecutorFactory.java | 44 -- .../impl/ReportJasperCreateTaskHandler.java | 639 ------------------ .../report/impl/ReportManagerImpl.java | 176 +---- .../midpoint/report/impl/ReportUtils.java | 20 - .../report/impl/SpringApplicationContext.java | 33 - .../fileformat/FileFormatController.java | 2 +- .../main/resources/jasperreports.properties | 5 - .../report/AbstractReportIntegrationTest.java | 2 - pom.xml | 84 +-- .../modify/system-configuration-after.xml | 5 - .../modify/system-configuration-before.xml | 162 +++-- 60 files changed, 209 insertions(+), 5080 deletions(-) delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageJasperReport.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageJasperReport.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageNewReport.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageNewReport.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/DashboardReportBasicConfigurationPanel.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/DashboardReportBasicConfigurationPanel.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/JasperReportBasicConfigurationPanel.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/JasperReportBasicConfigurationPanel.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/JasperReportConfigurationPanel.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/JasperReportConfigurationPanel.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/ParameterPropertiesPopupPanel.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/ParameterPropertiesPopupPanel.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/ReportConfigurationPanel.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/ReportConfigurationPanel.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportDto.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportFieldDto.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportParameterDto.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportParameterPropertiesDto.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportRealValueDto.java delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/JasperReportValueDto.java delete mode 100644 infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ReportTypeUtil.java delete mode 100644 model/certification-impl/src/main/resources/reports/_readme.txt delete mode 100644 model/certification-impl/src/main/resources/reports/non-responders.xml delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/CustomDataWriter.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/JRMidpointCompiler.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/JRMidpointEvaluator.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/MidPointAbstractDataSource.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/MidPointDataSource.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/MidPointLocalQueryExecutor.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/MidPointQueryExecutor.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/MidPointQueryExecutorFactory.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportJasperCreateTaskHandler.java delete mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/SpringApplicationContext.java delete mode 100644 model/report-impl/src/main/resources/jasperreports.properties diff --git a/config/initial-objects/000-system-configuration.xml b/config/initial-objects/000-system-configuration.xml index 3d6814bd377..dfa28d0f829 100644 --- a/config/initial-objects/000-system-configuration.xml +++ b/config/initial-objects/000-system-configuration.xml @@ -54,11 +54,6 @@ OFF org.hibernate.internal.ExceptionMapperStandardImpl - - - OFF - net.sf.jasperreports.engine.fill.JRFillDataset - diff --git a/gui/admin-gui/pom.xml b/gui/admin-gui/pom.xml index 445193c6f8e..9f99f073e42 100644 --- a/gui/admin-gui/pom.xml +++ b/gui/admin-gui/pom.xml @@ -747,29 +747,6 @@ - - - net.sf.jasperreports - jasperreports - - - bouncycastle - bcmail-jdk14 - - - bouncycastle - bcprov-jdk14 - - - bouncycastle - bctsp-jdk14 - - - org.bouncycastle - bcprov-jdk15on - - - org.apache.poi diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/menu/LeftMenuPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/menu/LeftMenuPanel.java index bcd6d85df98..99755980053 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/menu/LeftMenuPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/menu/LeftMenuPanel.java @@ -396,14 +396,7 @@ private MainMenuItem createReportsItems() { reportsMenu.addMenuItem(edit); } - if (classMatches(PageJasperReport.class)) { - MenuItem configure = new MenuItem("PageAdmin.menu.top.reports.configure", - PageJasperReport.class); - reportsMenu.addMenuItem(configure); - } - reportsMenu.addMenuItem(new MenuItem("PageAdmin.menu.top.reports.created", PageCreatedReports.class)); - reportsMenu.addMenuItem(new MenuItem("PageAdmin.menu.top.reports.new", PageNewReport.class)); // if (WebComponentUtil.isAuthorized(ModelAuthorizationAction.AUDIT_READ.getUrl())) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java index 71f5ca79373..aeee61092c6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/AutoCompleteReferencePanelFactory.java @@ -56,8 +56,9 @@ public Integer getOrder() { @Override public > boolean match(IW wrapper) { - return QNameUtil.match(ObjectReferenceType.COMPLEX_TYPE, wrapper.getTypeName()) && - ReportConstants.NS_EXTENSION.equals(wrapper.getNamespace()); + return QNameUtil.match(ObjectReferenceType.COMPLEX_TYPE, wrapper.getTypeName()) + && ReportConstants.NS_EXTENSION.equals(wrapper.getNamespace()) + && wrapper.getParent() == null; } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/init/InitialDataImport.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/init/InitialDataImport.java index 9af2c76d0ea..77bc05f795c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/init/InitialDataImport.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/init/InitialDataImport.java @@ -28,7 +28,6 @@ import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ReportTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; @@ -37,7 +36,6 @@ 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.ReportType; /** * Imports initial data objects as needed, ignoring already imported objects. @@ -103,10 +101,6 @@ private ImportResult importInitialObjectsResource( String objectText = IOUtils.toString(resourceInputStream, StandardCharsets.UTF_8); object = prismContext.parseObject(objectText); } - if (ReportType.class.equals(object.getCompileTimeClass())) { - //noinspection unchecked - ReportTypeUtil.applyDefinition((PrismObject) object, prismContext); - } return importObject(object, resource.getFilename(), task, mainResult, overwrite); } catch (Exception ex) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageJasperReport.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageJasperReport.html deleted file mode 100644 index da0b214909e..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageJasperReport.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - -
-