From ab16b01236875b7e80af60883ecb8edee51242cf Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Sat, 6 Jun 2015 22:15:55 +0200 Subject: [PATCH 01/16] remote jasper report query executer + datasource. --- .../prism/parser/PrismBeanConverter.java | 2 +- .../midpoint/prism/parser/QueryConvertor.java | 37 ++- .../main/resources/xml/ns/public/query-3.xsd | 9 + infra/schema/pom.xml | 2 +- .../schema/MidPointPrismContextFactory.java | 3 + .../midpoint/schema/RetrieveOption.java | 12 + .../schema/constants/SchemaConstants.java | 1 + .../midpoint/schema/util/MiscSchemaUtil.java | 44 ++- .../resources/META-INF/catalog-runtime.xml | 3 + .../META-INF/jax-ws-catalog-compile-time.xml | 4 +- .../META-INF/jax-ws-catalog-report.xml | 5 +- .../xml/ns/public/common/audit-3.xsd | 9 +- .../xml/ns/public/report/report-3.wsdl | 258 ++++++++++++--- .../com/evolveum/midpoint/util/MiscUtil.java | 18 ++ .../src/compile/resources/jax-ws-catalog.xml | 3 + .../resources/META-INF/jax-ws-catalog.xml | 3 + .../midpoint/report/api/ReportPort.java | 10 + model/report-ds-impl/pom.xml | 8 - .../report/ds/impl/CustomDataWriter.java | 74 +++++ .../ds/impl/CustomWrappedOutInterceptor.java | 122 +++++++ .../ds/impl/MidPointClientConfiguration.java | 4 +- .../report/ds/impl/MidPointDataSource.java | 20 +- .../ds/impl/MidPointLocalQueryExecutor.java | 249 +++++++++++++++ .../report/ds/impl/MidPointQueryExecutor.java | 218 ------------- .../ds/impl/MidPointQueryExecutorFactory.java | 2 +- .../ds/impl/MidPointRemoteDataSource.java | 154 +++++++++ .../ds/impl/MidPointRemoteQueryExecutor.java | 297 +++++++++--------- .../MidPointRemoteQueryExecutorFactory.java | 15 +- .../ds/impl/MidpointDataSourceProvider.java | 2 +- .../test/MidPointRemoteQueryExecuterTest.java | 136 ++++++++ ...ies => jasperreports_extension.properties} | 0 .../report/impl/ReportServiceImpl.java | 10 +- .../report/impl/ReportWebService.java | 227 +++++++++---- .../report/impl/ReportWebServiceRaw.java | 206 ++++++++++++ .../src/main/resources/ctx-report.xml | 2 +- .../midpoint/audit/api/AuditEventRecord.java | 62 ++++ 36 files changed, 1689 insertions(+), 542 deletions(-) create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomDataWriter.java create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomWrappedOutInterceptor.java create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointLocalQueryExecutor.java delete mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java rename model/report-ds-impl/src/main/resources/{jasperreports.properties => jasperreports_extension.properties} (100%) create mode 100644 model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java index 2ad98c6ca14..ae223d3b88b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.prism.parser; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Objectable; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObjectDefinition; @@ -664,7 +665,6 @@ public XNode marshall(T bean) throws SchemaException { } else if (prismContext != null && prismContext.getSchemaRegistry().determineDefinitionFromClass(bean.getClass()) != null){ return prismContext.getXnodeProcessor().serializeObject(((Objectable)bean).asPrismObject()).getSubnode(); } - // Note: SearchFilterType is treated below Class beanClass = bean.getClass(); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java index 376f891e97c..15ccd942497 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java @@ -47,6 +47,7 @@ import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.InOidFilter; +import com.evolveum.midpoint.prism.query.NoneFilter; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -101,6 +102,8 @@ public class QueryConvertor { public static final QName KEY_FILTER_TYPE_TYPE = new QName(NS_QUERY, "type"); public static final QName KEY_FILTER_TYPE_FILTER = new QName(NS_QUERY, "filter"); + public static final QName KEY_FILTER_NONE_TYPE = new QName(NS_QUERY, "none"); + public static final QName KEY_FILTER_ORG_REF = new QName(NS_QUERY, "orgRef"); public static final QName KEY_FILTER_ORG_REF_OID = new QName(NS_QUERY, "oid"); public static final QName KEY_FILTER_ORG_SCOPE = new QName(NS_QUERY, "scope"); @@ -228,6 +231,10 @@ private static ObjectFilter parseFilterContainer(XNode if (QNameUtil.match(filterQName, KEY_FILTER_IN_OID)) { return parseInOidFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); } + + if (QNameUtil.match(filterQName, KEY_FILTER_NONE_TYPE)) { + return new NoneFilter(); + } throw new UnsupportedOperationException("Unsupported query filter " + filterQName); @@ -361,7 +368,7 @@ private static TypeFilter parseTypeFilter(XNode xnode, PrismContainerDefinition XNode subXFilter = xmap.get(KEY_FILTER_TYPE_FILTER); ObjectFilter subFilter = null; PrismObjectDefinition def = prismContext.getSchemaRegistry().findObjectDefinitionByType(type); - if (subXFilter != null) { + if (subXFilter != null && subXFilter instanceof MapXNode) { subFilter = parseFilter((MapXNode) subXFilter, def); } @@ -616,37 +623,41 @@ public static MapXNode serializeFilter(ObjectFilter filter, PrismContext prismCo return serializeFilter(filter, PrismUtil.getXnodeProcessor(prismContext).createSerializer()); } - public static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnodeSerilizer) throws SchemaException{ + public static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ if (filter == null) { return null; } if (filter instanceof AndFilter) { - return serializeAndFilter((AndFilter) filter, xnodeSerilizer); + return serializeAndFilter((AndFilter) filter, xnodeSerializer); } if (filter instanceof OrFilter) { - return serializeOrFilter((OrFilter) filter, xnodeSerilizer); + return serializeOrFilter((OrFilter) filter, xnodeSerializer); } if (filter instanceof NotFilter) { - return serializeNotFilter((NotFilter) filter, xnodeSerilizer); + return serializeNotFilter((NotFilter) filter, xnodeSerializer); } if (filter instanceof EqualFilter) { - return serializeEqualsFilter((EqualFilter) filter, xnodeSerilizer); + return serializeEqualsFilter((EqualFilter) filter, xnodeSerializer); } if (filter instanceof RefFilter) { - return serializeRefFilter((RefFilter) filter, xnodeSerilizer); + return serializeRefFilter((RefFilter) filter, xnodeSerializer); } if (filter instanceof SubstringFilter) { - return serializeSubstringFilter((SubstringFilter) filter, xnodeSerilizer); + return serializeSubstringFilter((SubstringFilter) filter, xnodeSerializer); } if (filter instanceof OrgFilter) { - return serializeOrgFilter((OrgFilter) filter, xnodeSerilizer); + return serializeOrgFilter((OrgFilter) filter, xnodeSerializer); } if (filter instanceof TypeFilter) { - return serializeTypeFilter((TypeFilter) filter, xnodeSerilizer); + return serializeTypeFilter((TypeFilter) filter, xnodeSerializer); + } + + if (filter instanceof NoneFilter) { + return serializeNoneFilter((NoneFilter) filter, xnodeSerializer); } throw new UnsupportedOperationException("Unsupported filter type: " + filter); @@ -751,6 +762,12 @@ private static MapXNode serializeTypeFilter(TypeFilter filter, XNodeSerializer x } + private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer xnodeSerializer) { + MapXNode map = new MapXNode(); + map.put(KEY_FILTER_NONE_TYPE, new PrimitiveXNode<>()); + return map; + } + private static MapXNode serializeOrgFilter(OrgFilter filter, XNodeSerializer xnodeSerializer) { // TODO return null; diff --git a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd index 87fa1b0fc99..aa5ad2803b6 100644 --- a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd @@ -284,6 +284,14 @@ + + + + + + + + @@ -313,6 +321,7 @@ + diff --git a/infra/schema/pom.xml b/infra/schema/pom.xml index ff95bcafa3a..068b2069b1c 100644 --- a/infra/schema/pom.xml +++ b/infra/schema/pom.xml @@ -259,7 +259,7 @@ -nexclude http://prism.evolveum.com/xml/ns/public/query-3 - -nexclude + -nexclude http://midpoint.evolveum.com/xml/ns/public/common/common-3 -nexclude http://www.w3.org/2001/04/xmlenc diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java index 9ea9bc5783d..a03a45cefe2 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/MidPointPrismContextFactory.java @@ -131,6 +131,9 @@ private void registerBuiltinSchemas(SchemaRegistry schemaRegistry) throws Schema schemaRegistry.registerPrismSchemasFromWsdlResource("xml/ns/public/model/model-3.wsdl", Arrays.asList(com.evolveum.midpoint.xml.ns._public.model.model_3.ObjectFactory.class.getPackage())); + schemaRegistry.registerPrismSchemasFromWsdlResource("xml/ns/public/report/report-3.wsdl", + Arrays.asList(com.evolveum.midpoint.xml.ns._public.report.report_3.ObjectFactory.class.getPackage())); + // schemaRegistry.registerPrismSchemasFromWsdlResource("xml/ns/public/report/report-3.wsdl", // Arrays.asList(com.evolveum.midpoint.xml.ns._public.report.report_3.ObjectFactory.class.getPackage())); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/RetrieveOption.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/RetrieveOption.java index 538bd58e988..f12585ae857 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/RetrieveOption.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/RetrieveOption.java @@ -31,5 +31,17 @@ public static RetrieveOption fromRetrieveOptionType(RetrieveOptionType retrieveO default: throw new IllegalStateException("Unsupported RetrieveOptionType: " + retrieveOptionType); } } + + public static RetrieveOptionType toRetrieveOptionType(RetrieveOption retrieveOption) { + if (retrieveOption == null) { + return RetrieveOptionType.DEFAULT; + } + switch(retrieveOption) { + case DEFAULT: return RetrieveOptionType.DEFAULT; + case INCLUDE: return RetrieveOptionType.INCLUDE; + case EXCLUDE: return RetrieveOptionType.EXCLUDE; + default: throw new IllegalStateException("Unsupported RetrieveOption: " + retrieveOption); + } + } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 02fea8375ff..470850d38d1 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -158,6 +158,7 @@ public abstract class SchemaConstants { public static final String NS_MODEL_WS = NS_MODEL + "/model-3"; public static final String NS_REPORT = NS_MIDPOINT_PUBLIC + "/report"; + public static final String NS_REPORT_WS = NS_REPORT + "/report-3"; public static final String NS_MODEL_CHANNEL = NS_MODEL + "/channels-3"; public static final QName CHANNEL_WEB_SERVICE_QNAME = new QName(NS_MODEL_CHANNEL, "webService"); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java index 1d3d2569496..1d28cd2da5d 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java @@ -146,8 +146,46 @@ public static Collection itemReferenceListTypeToItemPathList(PropertyR } return itemPathList; } + + public static SelectorQualifiedGetOptionsType optionsToOptionsType(Collection> options){ + SelectorQualifiedGetOptionsType optionsType = new SelectorQualifiedGetOptionsType(); + List retval = new ArrayList<>(); + for (SelectorOptions option: options){ + retval.add(selectorOptionToSelectorQualifiedGetOptionType(option)); + } + optionsType.getOption().addAll(retval); + return optionsType; + } + + private static SelectorQualifiedGetOptionType selectorOptionToSelectorQualifiedGetOptionType(SelectorOptions selectorOption){ + ObjectSelectorType selectorType = selectorToSelectorType(selectorOption.getSelector()); + GetOperationOptionsType getOptionsType = getOptionsToGetOptionsType(selectorOption.getOptions()); + SelectorQualifiedGetOptionType selectorOptionType = new SelectorQualifiedGetOptionType(); + selectorOptionType.setOptions(getOptionsType); + selectorOptionType.setSelector(selectorType); + return selectorOptionType; + } - public static List> optionsTypeToOptions(SelectorQualifiedGetOptionsType objectOptionsType) { + private static ObjectSelectorType selectorToSelectorType(ObjectSelector selector) { + if (selector == null) { + return null; + } + ObjectSelectorType selectorType = new ObjectSelectorType(); + selectorType.setPath(new ItemPathType(selector.getPath())); + return selectorType; + } + + private static GetOperationOptionsType getOptionsToGetOptionsType(GetOperationOptions options) { + GetOperationOptionsType optionsType = new GetOperationOptionsType(); + optionsType.setRetrieve(RetrieveOption.toRetrieveOptionType(options.getRetrieve())); + optionsType.setResolve(options.getResolve()); + optionsType.setNoFetch(options.getNoFetch()); + optionsType.setRaw(options.getRaw()); + optionsType.setNoDiscovery(options.getDoNotDiscovery()); + return optionsType; + } + + public static List> optionsTypeToOptions(SelectorQualifiedGetOptionsType objectOptionsType) { if (objectOptionsType == null) { return null; } @@ -160,11 +198,11 @@ public static List> optionsTypeToOptions(Se private static SelectorOptions selectorQualifiedGetOptionTypeToSelectorOption(SelectorQualifiedGetOptionType objectOptionsType) { ObjectSelector selector = selectorTypeToSelector(objectOptionsType.getSelector()); - GetOperationOptions options = getOptionsTypeToOptions(objectOptionsType.getOptions()); + GetOperationOptions options = getOptionsTypeToGetOptions(objectOptionsType.getOptions()); return new SelectorOptions<>(selector, options); } - private static GetOperationOptions getOptionsTypeToOptions(GetOperationOptionsType optionsType) { + private static GetOperationOptions getOptionsTypeToGetOptions(GetOperationOptionsType optionsType) { GetOperationOptions options = new GetOperationOptions(); options.setRetrieve(RetrieveOption.fromRetrieveOptionType(optionsType.getRetrieve())); options.setResolve(optionsType.isResolve()); diff --git a/infra/schema/src/main/resources/META-INF/catalog-runtime.xml b/infra/schema/src/main/resources/META-INF/catalog-runtime.xml index fedb13884a0..af435bcf0c8 100644 --- a/infra/schema/src/main/resources/META-INF/catalog-runtime.xml +++ b/infra/schema/src/main/resources/META-INF/catalog-runtime.xml @@ -27,6 +27,9 @@ + + + diff --git a/infra/schema/src/main/resources/META-INF/jax-ws-catalog-compile-time.xml b/infra/schema/src/main/resources/META-INF/jax-ws-catalog-compile-time.xml index a2e1f3f80dc..46cdf0a83b7 100644 --- a/infra/schema/src/main/resources/META-INF/jax-ws-catalog-compile-time.xml +++ b/infra/schema/src/main/resources/META-INF/jax-ws-catalog-compile-time.xml @@ -34,7 +34,9 @@ - + + + - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + parsedQuery + + + + + + @@ -99,7 +102,7 @@ - + @@ -145,7 +148,7 @@ - + Parameters needed for script evaluation @@ -175,6 +178,140 @@ + + + + A request for searchObjects operation. + + + + + + + + Script to evaluate + + + + + + + Parameters needed for script evaluation + + + + + + + + + + + A response from searchObjects operation. + + + + + + + List of objects that match given criteria. + + + + + + + + + + + + A response from searchObjects operation. + + + + + + + Name of the jasper report parameter + + + + + + + Object to iterate + + + + + + + + + + + + + A response from searchObjects operation. + + + + + + + Name of the jasper report parameter + + + + + + + + + + + + + A response from searchObjects operation. + + + + + + + Remote parameters + + + + + + + + + + + A response from searchObjects operation. + + + + + + + Name of the jasper report parameter + + + + + + + + + + + + + @@ -186,12 +323,12 @@ - - - - - - + + + + + + @@ -207,15 +344,29 @@ + + + + + + + + + + + + + + - - - - + + + + @@ -224,6 +375,14 @@ + + + + + + + + @@ -238,15 +397,15 @@ - - - - - - - - - + + + + + + + + + @@ -265,6 +424,25 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/model/model-client/src/main/resources/META-INF/jax-ws-catalog.xml b/model/model-client/src/main/resources/META-INF/jax-ws-catalog.xml index 3af4e947ce3..ffe28717d13 100644 --- a/model/model-client/src/main/resources/META-INF/jax-ws-catalog.xml +++ b/model/model-client/src/main/resources/META-INF/jax-ws-catalog.xml @@ -29,6 +29,9 @@ + + + diff --git a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java index 583023785ba..59ae6da9b32 100644 --- a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java +++ b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java @@ -1,8 +1,18 @@ package com.evolveum.midpoint.report.api; +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.schema.constants.SchemaConstants; + public interface ReportPort { String CLASS_NAME_WITH_DOT = ReportPort.class.getName() + "."; String PROCESS_REPORT = CLASS_NAME_WITH_DOT + "processReport"; + + public static final QName PARSE_QUERY_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "parseQueryResponse"); + public static final QName EVALUATE_SCRIPT_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "evaluateScriptResponse"); + public static final QName EVALUATE_AUDIT_SCRIPT_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "evaluateAuditScriptResponse"); + public static final QName SEARCH_OBJECTS_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "searchObjectsResponse"); + public static final QName GET_FIELD_VALUE_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "getFieldValueResponse"); } diff --git a/model/report-ds-impl/pom.xml b/model/report-ds-impl/pom.xml index 2cb10d115fa..656e3024bef 100644 --- a/model/report-ds-impl/pom.xml +++ b/model/report-ds-impl/pom.xml @@ -77,14 +77,6 @@ org.apache.cxf.xjc-utils cxf-xjc-runtime - - org.apache.cxf - cxf-rt-frontend-jaxws - - - com.sun.xml.bind - jaxb-impl - com.sun.xml.bind jaxb-core diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomDataWriter.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomDataWriter.java new file mode 100644 index 00000000000..f4c2b082cd7 --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomDataWriter.java @@ -0,0 +1,74 @@ +package com.evolveum.midpoint.report.ds.impl; + +import java.util.Collection; + +import javax.xml.validation.Schema; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.cxf.databinding.DataWriter; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.jaxb.JAXBDataBinding; +import org.apache.cxf.jaxb.io.DataWriterImpl; +import org.apache.cxf.message.Attachment; +import org.apache.cxf.service.model.MessagePartInfo; +import org.apache.cxf.staxutils.StaxUtils; +import org.w3c.dom.Element; + +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.util.exception.SchemaException; + +public class CustomDataWriter implements DataWriter{ + + private PrismContext prismContex; + + + public CustomDataWriter(PrismContext prismContex) { + this.prismContex = prismContex; + } + + + @Override + public void write(Object obj, MessagePartInfo part, XMLStreamWriter output) { + QName rootElement = part.getElementQName(); + Element serialized; + try { + serialized = prismContex.serializeAnyDataToElement(obj, rootElement); + StaxUtils.copy(serialized, output); +// output.writeCharacters(serialized); + } catch (SchemaException | XMLStreamException e) { + // TODO Auto-generated catch block + throw new Fault(e); + } + + + } + + @Override + public void setAttachments(Collection arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setProperty(String arg0, Object arg1) { + // TODO Auto-generated method stub + + } + + @Override + public void setSchema(Schema arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void write(Object arg0, XMLStreamWriter arg1) { + // TODO Auto-generated method stub + + } + +} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomWrappedOutInterceptor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomWrappedOutInterceptor.java new file mode 100644 index 00000000000..fb81aa89915 --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/CustomWrappedOutInterceptor.java @@ -0,0 +1,122 @@ +package com.evolveum.midpoint.report.ds.impl; + +import java.io.OutputStream; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.stream.events.XMLEvent; + +import org.apache.cxf.databinding.DataWriter; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.interceptor.Interceptor; +import org.apache.cxf.message.Exchange; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageContentsList; +import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.phase.PhaseInterceptor; +import org.apache.cxf.service.Service; +import org.apache.cxf.service.model.BindingOperationInfo; +import org.apache.cxf.service.model.MessagePartInfo; +import org.apache.cxf.staxutils.CachingXmlEventWriter; +import org.apache.cxf.staxutils.StaxUtils; +import org.apache.cxf.wsdl.interceptors.BareOutInterceptor; + +import com.evolveum.midpoint.prism.PrismContext; + +public class CustomWrappedOutInterceptor extends BareOutInterceptor{ + + private PrismContext prismContext; + + public CustomWrappedOutInterceptor(PrismContext prismContext) { + this.prismContext = prismContext; + } + + @Override + public void handleMessage(Message message) { + super.handleMessage(message); + Interceptor defaultInterceptor = null; + for (Iterator> iterator = message.getInterceptorChain().getIterator(); iterator.hasNext();) { + Interceptor interceptor = iterator.next(); + if (interceptor instanceof BareOutInterceptor) { + defaultInterceptor = interceptor; + } + } + message.getInterceptorChain().remove(defaultInterceptor); + } + + @Override + protected void writeParts(Message message, Exchange exchange, + BindingOperationInfo operation, MessageContentsList objs, + List parts) { + // TODO Auto-generated method stub + OutputStream out = message.getContent(OutputStream.class); + XMLStreamWriter origXmlWriter = message.getContent(XMLStreamWriter.class); + Service service = exchange.getService(); + XMLStreamWriter xmlWriter = origXmlWriter; + CachingXmlEventWriter cache = null; + + Object en = message.getContextualProperty(OUT_BUFFERING); + boolean allowBuffer = true; + boolean buffer = false; + if (en != null) { + buffer = Boolean.TRUE.equals(en) || "true".equals(en); + allowBuffer = !(Boolean.FALSE.equals(en) || "false".equals(en)); + } + // need to cache the events in case validation fails or buffering is enabled + if (buffer || (allowBuffer && shouldValidate(message) && !isRequestor(message))) { + cache = new CachingXmlEventWriter(); + try { + cache.setNamespaceContext(origXmlWriter.getNamespaceContext()); + } catch (XMLStreamException e) { + //ignorable, will just get extra namespace decls + } + xmlWriter = cache; + out = null; + } + + if (out != null + && writeToOutputStream(message, operation.getBinding(), service) + && !MessageUtils.isTrue(message.getContextualProperty(DISABLE_OUTPUTSTREAM_OPTIMIZATION))) { + if (xmlWriter != null) { + try { + xmlWriter.writeCharacters(""); + xmlWriter.flush(); + } catch (XMLStreamException e) { + throw new Fault(e); + } + } + + DataWriter osWriter = getDataWriter(message, service, OutputStream.class); + + for (MessagePartInfo part : parts) { + if (objs.hasValue(part)) { + Object o = objs.get(part); + osWriter.write(o, part, out); + } + } + } else { + DataWriter dataWriter = new CustomDataWriter(prismContext); + + for (MessagePartInfo part : parts) { + if (objs.hasValue(part)) { + Object o = objs.get(part); + dataWriter.write(o, part, xmlWriter); + } + } + } + if (cache != null) { + try { + for (XMLEvent event : cache.getEvents()) { + StaxUtils.writeEvent(event, origXmlWriter); + } + } catch (XMLStreamException e) { + throw new Fault(e); + } + } + } + + +} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java index 6d72339ac23..fd7d7d46d36 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java @@ -12,6 +12,7 @@ import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.handler.WSHandlerConstants; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportService; @@ -26,7 +27,7 @@ public MidPointClientConfiguration() { } - public ReportPortType createReportPort() { + public ReportPortType createReportPort(PrismContext prismContext) { System.out.println("creating endpoint with credentials " + username + ": " + password); System.out.println("Endpoint URL: "+ endpoint); ClientPasswordHandler.setPassword(password); @@ -52,6 +53,7 @@ public ReportPortType createReportPort() { WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); cxfEndpoint.getOutInterceptors().add(wssOut); +// cxfEndpoint.getOutInterceptors().add(new CustomWrappedOutInterceptor(prismContext)); // enable the following to get client-side logging of outgoing requests and incoming responses cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor()); cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor()); diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointDataSource.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointDataSource.java index 58fafa79046..d459c8bd4eb 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointDataSource.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointDataSource.java @@ -38,25 +38,7 @@ public MidPointDataSource(Collection> results) iterator = results.iterator(); } } - - public MidPointDataSource(ObjectListType results){ - resultList = new ArrayList<>(); - for (ObjectType objType : results.getObject()){ - resultList.add(((Objectable)objType).asPrismObject()); - } - iterator = resultList.iterator(); - } - -// public MidPointDataSource(ObjectListType results, PrismContext context){ -// resultList = new ArrayList<>(); -// for (ObjectType objType : results.getObject()){ -// PrismObject prism = ((Objectable)objType).asPrismObject(); -// prism.revive(context); -// -// resultList.add(prism); -// } -// iterator = resultList.iterator(); -// } + @Override public boolean next() throws JRException { diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointLocalQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointLocalQueryExecutor.java new file mode 100644 index 00000000000..a02c385174a --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointLocalQueryExecutor.java @@ -0,0 +1,249 @@ +package com.evolveum.midpoint.report.ds.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; +import net.sf.jasperreports.engine.JRValueParameter; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.base.JRBaseParameter; +import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; +import net.sf.jasperreports.engine.fill.JRFillParameter; + +import org.apache.commons.lang.StringUtils; + +import com.evolveum.midpoint.audit.api.AuditEventRecord; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.report.api.ReportService; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +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.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +public class MidPointLocalQueryExecutor extends MidPointQueryExecutor{ + + private static final Trace LOGGER = TraceManager.getTrace(MidPointLocalQueryExecutor.class); + private ObjectQuery query; + private String script; + private Class type; + private ReportService reportService; + + + public MidPointLocalQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, + Map parametersMap, ReportService reportService){ + super(jasperReportsContext, dataset, parametersMap); + } + + protected MidPointLocalQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, + Map parametersMap) { + super(jasperReportsContext, dataset, parametersMap); + + JRFillParameter fillparam = (JRFillParameter) parametersMap.get(JRParameter.REPORT_PARAMETERS_MAP); + Map reportParams = (Map) fillparam.getValue(); + reportService = (ReportService) parametersMap.get(ReportService.PARAMETER_REPORT_SERVICE).getValue(); + + parseQuery(); + } + + @Override + protected Object getParsedQuery(String query, Map expressionParameters) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException { + return reportService.parseQuery(query, expressionParameters); + } + + @Override + protected Collection searchObjects(Object query, Collection> options) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException{ + return reportService.searchObjects((ObjectQuery) query, SelectorOptions.createCollection(GetOperationOptions.createRaw())); + } + + @Override + protected Collection evaluateScript(String script, + Map parameters) throws SchemaException, ObjectNotFoundException, + SecurityViolationException, CommunicationException, ConfigurationException, + ExpressionEvaluationException { + return reportService.evaluateScript(script, getParameters()); + } + + @Override + protected Collection searchAuditRecords(String script, Map parameters) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { + return reportService.evaluateAuditScript(script, parameters); + } + + @Override + protected JRDataSource createDataSource(Collection results) { + return new MidPointDataSource(results); + } + + + public String getScript() { + return script; + } + public ObjectQuery getQuery() { + return query; + } + public Class getType() { + return type; + } + +// private Object getObjectQueryFromParameters(){ +// JRParameter[] params = dataset.getParameters(); +// Map expressionParameters = new HashMap(); +// for (JRParameter param : params){ +// if ("finalQuery".equals(param.getName())){ +// return getParameterValue(param.getName()); +// } +// } +// return null; +// } +// +// private Map getParameters(){ +// JRParameter[] params = dataset.getParameters(); +// Map expressionParameters = new HashMap(); +// for (JRParameter param : params){ +// LOGGER.trace(((JRBaseParameter)param).getName()); +// Object v = getParameterValue(param.getName()); +// try{ +// expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); +// } catch (Exception e){ +// //just skip properties that are not important for midpoint +// } +// +// LOGGER.trace("p.val: {}", v); +// } +// return expressionParameters; +// } +// +// private Map getPromptingParameters(){ +// JRParameter[] params = dataset.getParameters(); +// Map expressionParameters = new HashMap(); +// for (JRParameter param : params){ +// if (param.isSystemDefined()){ +// continue; +// } +// if (!param.isForPrompting()){ +// continue; +// } +// LOGGER.trace(((JRBaseParameter)param).getName()); +// Object v = getParameterValue(param.getName()); +// try{ +// expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); +// } catch (Exception e){ +// //just skip properties that are not important for midpoint +// } +// +// LOGGER.trace("p.val: {}", v); +// } +// return expressionParameters; +// } +// +// @Override +// protected void parseQuery() { +// // TODO Auto-generated method stub +// +// +// +// String s = dataset.getQuery().getText(); +// +// JRBaseParameter p = (JRBaseParameter) dataset.getParameters()[0]; +// +// Map expressionParameters = getParameters(); +// LOGGER.info("query: " + s); +// if (StringUtils.isEmpty(s)){ +// query = null; +// } else { +// try { +// if (s.startsWith("", ""); +// script = normalized.replace("", ""); +// +// } +// } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +// +// } +// + // @Override +// public JRDataSource createDatasource() throws JRException { +// Collection> results = new ArrayList<>(); +// +// try { +// if (query == null && script == null){ +// throw new JRException("Neither query, nor script defined in the report."); +// } +// +// if (query != null){ +// results = reportService.searchObjects(query, SelectorOptions.createCollection(GetOperationOptions.createRaw())); +// } else { +// if (script.contains("AuditEventRecord")){ +// Collection audtiEventRecords = reportService.evaluateAuditScript(script, getPromptingParameters()); +// return new JRBeanCollectionDataSource(audtiEventRecords); +// } else { +// results = reportService.evaluateScript(script, getParameters()); +// } +// } +// } catch (SchemaException | ObjectNotFoundException | SecurityViolationException +// | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { +// // TODO Auto-generated catch block +// throw new JRException(e); +// } +// +// MidPointDataSource mds = new MidPointDataSource(results); +// +// return mds; +// } +// +// +// @Override +// public void close() { +//// throw new UnsupportedOperationException("QueryExecutor.close() not supported"); +// //nothing to DO +// } +// +// @Override +// public boolean cancelQuery() throws JRException { +// throw new UnsupportedOperationException("QueryExecutor.cancelQuery() not supported"); +// } +// +// @Override +// protected String getParameterReplacement(String parameterName) { +// throw new UnsupportedOperationException("QueryExecutor.getParameterReplacement() not supported"); +// } + + + + + + +} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java deleted file mode 100644 index a1ad0b88c68..00000000000 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.evolveum.midpoint.report.ds.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; - -import net.sf.jasperreports.engine.JRDataSource; -import net.sf.jasperreports.engine.JRDataset; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JRParameter; -import net.sf.jasperreports.engine.JRValueParameter; -import net.sf.jasperreports.engine.JasperReportsContext; -import net.sf.jasperreports.engine.base.JRBaseParameter; -import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; -import net.sf.jasperreports.engine.fill.JRFillParameter; -import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter; - -import org.apache.commons.lang.StringUtils; - -import com.evolveum.midpoint.audit.api.AuditEventRecord; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.report.api.ReportService; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -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.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; - -public class MidPointQueryExecutor extends JRAbstractQueryExecuter{ - - private static final Trace LOGGER = TraceManager.getTrace(MidPointQueryExecutor.class); - private ObjectQuery query; - private String script; - private Class type; - private ReportService reportService; - - public String getScript() { - return script; - } - public ObjectQuery getQuery() { - return query; - } - public Class getType() { - return type; - } - - private Object getObjectQueryFromParameters(){ - JRParameter[] params = dataset.getParameters(); - Map expressionParameters = new HashMap(); - for (JRParameter param : params){ - if ("finalQuery".equals(param.getName())){ - return getParameterValue(param.getName()); - } - } - return null; - } - - private Map getParameters(){ - JRParameter[] params = dataset.getParameters(); - Map expressionParameters = new HashMap(); - for (JRParameter param : params){ - LOGGER.trace(((JRBaseParameter)param).getName()); - Object v = getParameterValue(param.getName()); - try{ - expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); - } catch (Exception e){ - //just skip properties that are not important for midpoint - } - - LOGGER.trace("p.val: {}", v); - } - return expressionParameters; - } - - private Map getPromptingParameters(){ - JRParameter[] params = dataset.getParameters(); - Map expressionParameters = new HashMap(); - for (JRParameter param : params){ - if (param.isSystemDefined()){ - continue; - } - if (!param.isForPrompting()){ - continue; - } - LOGGER.trace(((JRBaseParameter)param).getName()); - Object v = getParameterValue(param.getName()); - try{ - expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); - } catch (Exception e){ - //just skip properties that are not important for midpoint - } - - LOGGER.trace("p.val: {}", v); - } - return expressionParameters; - } - - @Override - protected void parseQuery() { - // TODO Auto-generated method stub - - - - String s = dataset.getQuery().getText(); - - JRBaseParameter p = (JRBaseParameter) dataset.getParameters()[0]; - - Map expressionParameters = getParameters(); - LOGGER.info("query: " + s); - if (StringUtils.isEmpty(s)){ - query = null; - } else { - try { - if (s.startsWith("", ""); - script = normalized.replace("", ""); - - } - } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - } - - - public MidPointQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, - Map parametersMap, ReportService reportService){ - super(jasperReportsContext, dataset, parametersMap); - } - - protected MidPointQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, - Map parametersMap) { - super(jasperReportsContext, dataset, parametersMap); - - JRFillParameter fillparam = (JRFillParameter) parametersMap.get(JRParameter.REPORT_PARAMETERS_MAP); - Map reportParams = (Map) fillparam.getValue(); - reportService = (ReportService) parametersMap.get(ReportService.PARAMETER_REPORT_SERVICE).getValue(); - - parseQuery(); - } - - @Override - public JRDataSource createDatasource() throws JRException { - Collection> results = new ArrayList<>(); - - try { - if (query == null && script == null){ - throw new JRException("Neither query, nor script defined in the report."); - } - - if (query != null){ - results = reportService.searchObjects(query, SelectorOptions.createCollection(GetOperationOptions.createRaw())); - } else { - if (script.contains("AuditEventRecord")){ - Collection audtiEventRecords = reportService.evaluateAuditScript(script, getPromptingParameters()); - return new JRBeanCollectionDataSource(audtiEventRecords); - } else { - results = reportService.evaluateScript(script, getParameters()); - } - } - } catch (SchemaException | ObjectNotFoundException | SecurityViolationException - | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { - // TODO Auto-generated catch block - throw new JRException(e); - } - - MidPointDataSource mds = new MidPointDataSource(results); - - return mds; - } - - - @Override - public void close() { -// throw new UnsupportedOperationException("QueryExecutor.close() not supported"); - //nothing to DO - } - - @Override - public boolean cancelQuery() throws JRException { - throw new UnsupportedOperationException("QueryExecutor.cancelQuery() not supported"); - } - - @Override - protected String getParameterReplacement(String parameterName) { - throw new UnsupportedOperationException("QueryExecutor.getParameterReplacement() not supported"); - } - - - -} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutorFactory.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutorFactory.java index 98474550b7f..e6ecec034c0 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutorFactory.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutorFactory.java @@ -46,7 +46,7 @@ public Object[] getBuiltinParameters() { public JRQueryExecuter createQueryExecuter(JasperReportsContext jasperReportsContext, JRDataset dataset, Map parameters) throws JRException { - return new MidPointQueryExecutor(jasperReportsContext, dataset, parameters); + return new MidPointLocalQueryExecutor(jasperReportsContext, dataset, parameters); } @Override diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java new file mode 100644 index 00000000000..4141f499a2f --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java @@ -0,0 +1,154 @@ +package com.evolveum.midpoint.report.ds.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRField; + +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.Objectable; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.Referencable; +import com.evolveum.midpoint.prism.parser.JaxbDomHack; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.reportPortImpl; + +public class MidPointRemoteDataSource implements JRDataSource { + + Collection resultList = null; + Iterator iterator = null; + ObjectType currentObject = null; + + private ReportPortType reportPort; + + public MidPointRemoteDataSource(Collection results) { + this.resultList = results; + if (results != null) { + iterator = results.iterator(); + } + } + + public MidPointRemoteDataSource(Collection results, ReportPortType reportPort) { + this.reportPort = reportPort; + resultList = new ArrayList<>(); + for (ObjectType objType : results) { + ((Collection) resultList).add(objType); + } + iterator = resultList.iterator(); + } + + // public MidPointDataSource(ObjectListType results, PrismContext context){ + // resultList = new ArrayList<>(); + // for (ObjectType objType : results.getObject()){ + // PrismObject prism = ((Objectable)objType).asPrismObject(); + // prism.revive(context); + // + // resultList.add(prism); + // } + // iterator = resultList.iterator(); + // } + + @Override + public boolean next() throws JRException { + // TODO Auto-generated method stub + boolean hasNext = false; + if (this.iterator != null) { + hasNext = this.iterator.hasNext(); + + if (hasNext) { + this.currentObject = iterator.next(); + } + } + + return hasNext; + // } + // throw new + // UnsupportedOperationException("dataSource.next() not supported"); + // return false; + } + + @Override + public Object getFieldValue(JRField jrField) throws JRException { + // TODO Auto-generated method stub + String fieldName = jrField.getName(); + if (fieldName.equals("oid")) { + return currentObject.getOid(); + } + + RemoteReportParameterType param = reportPort.getFieldValue( + QNameUtil.qNameToUri(new QName(fieldName)), currentObject); + + if (param == null) { + return null; + } + + if (param.getAny() == null || param.getAny().isEmpty()) { + return null; + } + + try { + JAXBContext jaxbContext = JAXBContext + .newInstance("com.evolveum.midpoint.xml.ns._public.common.common_3"); + + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + + if (param.getAny().size() == 1) { + + Object val = param.getAny().iterator().next(); + return unmarshallValue(jrField, val, jaxbUnmarshaller); + } + + List values = new ArrayList<>(); + for (Object val : param.getAny()) { + values.add(unmarshallValue(jrField, val, jaxbUnmarshaller)); + } + + return values; + } catch (JAXBException e) { + // TODO Auto-generated catch block + throw new JRException(e); + } + + } + + private Object unmarshallValue(JRField jrField, Object val, Unmarshaller jaxbUnmarshaller) throws JAXBException{ + if (val instanceof Element) { + if (jrField.getValueClass()!= null && List.class.isAssignableFrom(jrField.getValueClass())){ + Object unmarshalled = jaxbUnmarshaller.unmarshal((Node) val); + if (unmarshalled instanceof JAXBElement){ + return ((JAXBElement) unmarshalled).getValue(); + } + } + JAXBElement jaxb = jaxbUnmarshaller.unmarshal((Node) val, jrField.getValueClass()); + return jaxb.getValue(); + } else if (val instanceof JAXBElement){ + return ((JAXBElement) val).getValue(); + } else { + return val; + } + } + +} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java index 727d47d911d..15bbe745ac1 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java @@ -1,12 +1,17 @@ package com.evolveum.midpoint.report.ds.impl; +import groovy.lang.Singleton; + import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRDataset; @@ -15,43 +20,58 @@ import net.sf.jasperreports.engine.JRValueParameter; import net.sf.jasperreports.engine.JasperReportsContext; import net.sf.jasperreports.engine.base.JRBaseParameter; -import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.xml.sax.SAXException; +import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.prism.Objectable; +import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.query.InOidFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.PropertyValueFilter; +import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +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.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.GetOperationOptionsType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionsType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordListType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.EntryType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ParamsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParametersType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; -public class MidPointRemoteQueryExecutor extends JRAbstractQueryExecuter{ +public class MidPointRemoteQueryExecutor extends MidPointQueryExecutor{ - // Configuration -// public static final String ADM_USERNAME = "administrator"; -// public static final String ADM_PASSWORD = "5ecr3t"; -// private static final String DEFAULT_ENDPOINT_URL = "http://localhost:8080/midpoint/ws/report-3"; - private String query; private ReportPortType reportPort; + private PrismContext prismContext; private static final Trace LOGGER = TraceManager.getTrace(MidPointRemoteQueryExecutor.class); + private ClassPathXmlApplicationContext applicationContext; public String getQuery() { @@ -60,175 +80,144 @@ public String getQuery() { @Override - protected void parseQuery() { - query = getStringQuery(); - } + protected Object getParsedQuery(String query, Map expressionParameters) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException { - - private boolean containsExpression(ObjectFilter subFilter){ - if (subFilter instanceof PropertyValueFilter){ - return ((PropertyValueFilter) subFilter).getExpression() != null; - } else if (subFilter instanceof InOidFilter){ - return ((InOidFilter) subFilter).getExpression() != null; - } + RemoteReportParametersType reportParamters = converToReportParameterType(expressionParameters); - return false; + return reportPort.parseQuery(query, reportParamters); +// return getStringQuery(); } - - protected MidPointRemoteQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, - Map parametersMap) { - super(jasperReportsContext, dataset, parametersMap); - ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ctx-report-ds-context.xml"); - MidPointClientConfiguration clientConfig = (MidPointClientConfiguration) applicationContext.getBean("clientConfig"); -// Properties prop = new Properties(); -// String propFileName = "client.properties"; -// -// InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName); -// -// try { -// prop.load(inputStream); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// -// MidPointClientConfiguration clientConfig = new MidPointClientConfiguration(); -// clientConfig.setEndpoint((String) prop.get("service.endpoint")); -// clientConfig.setUsername((String) prop.get("auth.username")); -// clientConfig.setPassword((String) prop.get("auht.password")); - reportPort = clientConfig.createReportPort(); -// reportPort = createReportPort(); - parseQuery(); + private RemoteReportParametersType converToReportParameterType(Map expressionParameters) throws SchemaException { + Set> paramSet = expressionParameters.entrySet(); + if (paramSet == null || paramSet.isEmpty()){ + return null; + } + RemoteReportParametersType reportParams = new RemoteReportParametersType(); + for (Entry param : paramSet){ + RemoteReportParameterType remoteParam = new RemoteReportParameterType(); + remoteParam.setParameterName(param.getKey().getLocalPart()); + remoteParam.getAny().add(((PrismPropertyValue)param.getValue()).getValue()); + reportParams.getRemoteParameter().add(remoteParam); + } + return reportParams; } + @Override - public JRDataSource createDatasource() throws JRException { - SelectorQualifiedGetOptionsType options = new SelectorQualifiedGetOptionsType(); - SelectorQualifiedGetOptionType option = new SelectorQualifiedGetOptionType(); - GetOperationOptionsType getOptions = new GetOperationOptionsType(); - getOptions.setRaw(Boolean.TRUE); - option.setOptions(getOptions); - - options.getOption().add(option); - - String queryString = getStringQuery(); - - ObjectListType results = null; - if (queryString.startsWith("", ""); - String script = normalized.replace("", ""); - ParamsType parameters = getParameters(); - results = reportPort.evaluateScript(script, parameters); - - } else { - throw new IllegalArgumentException("Neither query nor filter defined in query"); - } - MidPointPrismContextFactory factory = new MidPointPrismContextFactory(); - try { - PrismContext prismContext = factory.createInitializedPrismContext(); - - Collection> resultPrismList = new ArrayList<>(); - for (ObjectType objType : results.getObject()){ - PrismObject prism = ((Objectable)objType).asPrismObject(); - prism.revive(prismContext); - - resultPrismList.add(prism); - } - MidPointDataSource mds = new MidPointDataSource(resultPrismList); - - return mds; - } catch (SchemaException | SAXException | IOException e) { - throw new JRException("Could not execute query " + e.getMessage(), e); + protected Collection searchObjects(Object query, + Collection> options) throws SchemaException, + ObjectNotFoundException, SecurityViolationException, CommunicationException, + ConfigurationException { + // TODO Auto-generated method stub + SelectorQualifiedGetOptionsType optionsType = MiscSchemaUtil.optionsToOptionsType(options); + + ObjectListType results = reportPort.searchObjects((String) query, optionsType); + if (results == null){ + return new ArrayList<>(); } - + return results.getObject(); } +// private Collection> toPrismList(ObjectListType results) throws SchemaException{ +// Collection> resultPrismList = new ArrayList<>(); +// for (ObjectType objType : results.getObject()){ +// PrismObject prism = ((Objectable)objType).asPrismObject(); +// prism.revive(prismContext); +// +// resultPrismList.add(prism); +// } +// return resultPrismList; +// +// } - @Override - public void close() { -// throw new UnsupportedOperationException("QueryExecutor.close() not supported"); - //nothing to DO - } - - @Override - public boolean cancelQuery() throws JRException { - throw new UnsupportedOperationException("QueryExecutor.cancelQuery() not supported"); + private Collection toAuditRecordList(AuditEventRecordListType results) throws SchemaException{ + Collection resultPrismList = new ArrayList<>(); + for (AuditEventRecordType objType : results.getObject()){ + AuditEventRecord auditRecord = AuditEventRecord.createAuditEventRecord(objType); + resultPrismList.add(auditRecord); + } + return resultPrismList; + } - + @Override - protected String getParameterReplacement(String parameterName) { - throw new UnsupportedOperationException("QueryExecutor.getParameterReplacement() not supported"); + protected JRDataSource createDataSource(Collection results) { + return new MidPointRemoteDataSource(results, reportPort); } -// private static ReportPortType createReportPort(String[] args) { -// String endpointUrl = DEFAULT_ENDPOINT_URL; -// -// if (args != null && args.length > 0) { -// endpointUrl = args[0]; -// } -// -// System.out.println("Endpoint URL: "+endpointUrl); -// -// // uncomment this if you want to use Fiddler or any other proxy -// //ProxySelector.setDefault(new MyProxySelector("127.0.0.1", 8888)); -// -// ReportService reportService = new ReportService(); -// ReportPortType reportPort = reportService.getReportPort(); -// BindingProvider bp = (BindingProvider)reportPort; -// Map requestContext = bp.getRequestContext(); -// requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl); -// -// org.apache.cxf.endpoint.Client client = ClientProxy.getClient(reportPort); -// org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); -// -// Map outProps = new HashMap(); -// -// outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); -// outProps.put(WSHandlerConstants.USER, ADM_USERNAME); -// outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); -// outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName()); -// -// WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); -// cxfEndpoint.getOutInterceptors().add(wssOut); -// // enable the following to get client-side logging of outgoing requests and incoming responses -// cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor()); -// cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor()); -// -// return reportPort; -// } - private String getStringQuery(){ - if (dataset.getQuery() == null){ -// query = null; - return null; + protected MidPointRemoteQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, + Map parametersMap) { + super(jasperReportsContext, dataset, parametersMap); + MidPointPrismContextFactory factory = new MidPointPrismContextFactory(); +// try { +// if (prismContext == null) { +// prismContext = factory.createInitializedPrismContext(); +// } +// } catch (SchemaException | SAXException | IOException e) { +// throw new SystemException(e.getMessage(), e); +// } + if (applicationContext == null) { + applicationContext = new ClassPathXmlApplicationContext("ctx-report-ds-context.xml"); + } + MidPointClientConfiguration clientConfig = applicationContext.getBean("clientConfig", + MidPointClientConfiguration.class); + if (reportPort == null) { + reportPort = clientConfig.createReportPort(prismContext); } - return dataset.getQuery().getText(); + parseQuery(); } + + private String getStringQuery(){ + if (dataset.getQuery() == null){ +// query = null; + return null; + } + return dataset.getQuery().getText(); + } + - private ParamsType getParameters(){ - JRParameter[] params = dataset.getParameters(); - ParamsType parameters = new ParamsType(); - for (JRParameter param : params){ - if (param.isSystemDefined()){ - continue; + @Override + protected Collection evaluateScript(String script, + Map parameters) throws SchemaException, ObjectNotFoundException, + SecurityViolationException, CommunicationException, ConfigurationException, + ExpressionEvaluationException { + // TODO Auto-generated method stu + LOGGER.debug("evaluating script: {} with parameters: {}", script, parameters); + + RemoteReportParametersType reportParamters = converToReportParameterType(parameters); + if (reportParamters == null){ + return new ArrayList<>(); } - LOGGER.trace(((JRBaseParameter)param).getName()); - try{ - Serializable v = (Serializable) getParameterValue(param.getName()); - EntryType entry = new EntryType(); - entry.setKey(param.getName()); - entry.setEntryValue(new JAXBElement(SchemaConstantsGenerated.C_PARAM_VALUE, Serializable.class, v)); - parameters.getEntry().add(entry); - LOGGER.trace("p.val: {}", v); - } catch (Exception e){ - //just skip properties that are not important for midpoint + LOGGER.debug("coverted to report parameters: {}", reportParamters); + ObjectListType results = reportPort.evaluateScript(script, reportParamters); + if (results == null){ + return new ArrayList<>(); } + return results.getObject(); + } + + + @Override + protected Collection searchAuditRecords(String script, Map parameters) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { + // TODO Auto-generated method stub + RemoteReportParametersType reportParamters = converToReportParameterType(parameters); - + if (reportParamters == null){ + return new ArrayList<>(); + } + AuditEventRecordListType results = reportPort.evaluateAuditScript(script, reportParamters); + return toAuditRecordList(results); } - return parameters; - } + + @Override + public void close() { + applicationContext.destroy(); +// throw new UnsupportedOperationException("QueryExecutor.close() not supported"); + //nothing to DO + } + } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutorFactory.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutorFactory.java index aeeb7999c44..82b9accd01f 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutorFactory.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutorFactory.java @@ -9,7 +9,9 @@ import net.sf.jasperreports.engine.query.AbstractQueryExecuterFactory; import net.sf.jasperreports.engine.query.JRQueryExecuter; +import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportService; +import com.sun.tools.xjc.model.Model; @@ -17,29 +19,22 @@ public class MidPointRemoteQueryExecutorFactory extends AbstractQueryExecuterFac public final static String PARAMETER_MIDPOINT_CONNECTION = "MIDPOINT_CONNECTION"; - public final static String PARAMETER_PRISM_CONTEXT = "PRISM_CONTEXT"; - public final static String PARAMETER_TASK_MANAGER = "TASK_MANAGER"; - public final static String PARAMETER_EXPRESSION_FACTORY = "EXPRESSION_FACTORY"; - public final static String PARAMETER_OBJECT_RESOLVER = "OBJECT_RESOLVER"; - public final static String PARAMETER_MIDPOINT_FUNCTION = "MIDPOINT_FUNCTION"; - public final static String PARAMETER_AUDIT_SERVICE = "AUDIT_SERVICE"; - public final static String PARAMETER_REPORT_FUNCTIONS = "reportFunctions"; private final static Object[] MIDPOINT_BUILTIN_PARAMETERS = { - PARAMETER_MIDPOINT_CONNECTION, PARAMETER_PRISM_CONTEXT, PARAMETER_TASK_MANAGER, "midpoint.connection" + PARAMETER_MIDPOINT_CONNECTION, "midpoint.connection" }; @Override public Object[] getBuiltinParameters() { - return MIDPOINT_BUILTIN_PARAMETERS; + return null; +// return MIDPOINT_BUILTIN_PARAMETERS; } @Override public JRQueryExecuter createQueryExecuter(JasperReportsContext jasperReportsContext, JRDataset dataset, Map parameters) throws JRException { - return new MidPointRemoteQueryExecutor(jasperReportsContext, dataset, parameters); } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java index 590309a58e3..3f1081201b0 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java @@ -97,7 +97,7 @@ public JRDataSource create(JasperReport report) throws JRException { reportType.setTemplate(jrxmlBase64); ObjectListType olt = reportPort.processReport(reportType); - return new MidPointDataSource(olt); + return new MidPointRemoteDataSource(olt.getObject()); } catch (Exception e){ System.out.println("exception: " +e); e.printStackTrace(System.out); diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java new file mode 100644 index 00000000000..4048265d450 --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java @@ -0,0 +1,136 @@ +package com.evolveum.midpoint.report.ds.impl.test; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.ws.BindingProvider; + +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.interceptor.Interceptor; +import org.apache.cxf.interceptor.LoggingInInterceptor; +import org.apache.cxf.interceptor.LoggingOutInterceptor; +import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; +import org.apache.cxf.wsdl.interceptors.BareOutInterceptor; +import org.apache.wss4j.dom.WSConstants; +import org.apache.wss4j.dom.handler.WSHandlerConstants; +import org.xml.sax.SAXException; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.query.EqualFilter; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.report.ds.impl.ClientPasswordHandler; +import com.evolveum.midpoint.report.ds.impl.CustomWrappedOutInterceptor; +import com.evolveum.midpoint.schema.MidPointPrismContextFactory; +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.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParametersType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportService; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + + +public class MidPointRemoteQueryExecuterTest { + + public Object getParsedQuery(PrismContext prismContext, ReportPortType reportPort) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException { + + RemoteReportParametersType reportParameters = new RemoteReportParametersType(); + + RemoteReportParameterType reportParameter = new RemoteReportParameterType(); + reportParameter.setParameterName("stringExample"); + reportParameter.getAny().add("someString"); + + reportParameters.getRemoteParameter().add(reportParameter); + + reportParameter = new RemoteReportParameterType(); + reportParameter.setParameterName("intExample"); + reportParameter.getAny().add(11); + + reportParameters.getRemoteParameter().add(reportParameter); + + reportParameter = new RemoteReportParameterType(); + reportParameter.setParameterName("nullExample"); + + reportParameters.getRemoteParameter().add(reportParameter); + + EqualFilter f = EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, PrismTestUtil.createPolyString("someName")); + SearchFilterType filterType = QueryConvertor.createSearchFilterType(f, prismContext); + + return reportPort.parseQuery(prismContext.serializeAtomicValue(filterType, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML), reportParameters); +// return getStringQuery(); + } + + public static void main(String[] args) { + PrismContext prismContext; + try { + + PrismTestUtil.resetPrismContext(new MidPointPrismContextFactory()); + + MidPointRemoteQueryExecuterTest t = new MidPointRemoteQueryExecuterTest(); + + ReportPortType reportPort = createReportPort(PrismTestUtil.getPrismContext()); + + String f = (String) t.getParsedQuery(PrismTestUtil.getPrismContext(), reportPort); + System.out.println("returned filter: " + f); + } catch (SchemaException | SAXException | IOException | ObjectNotFoundException | ExpressionEvaluationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static ReportPortType createReportPort(PrismContext prismContext) { + ClientPasswordHandler.setPassword("5ecr3t"); + + // uncomment this if you want to use Fiddler or any other proxy + //ProxySelector.setDefault(new MyProxySelector("127.0.0.1", 8888)); + + ReportService reportService = new ReportService(); + ReportPortType reportPort = reportService.getReportPort(); + BindingProvider bp = (BindingProvider)reportPort; + Map requestContext = bp.getRequestContext(); + requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/midpoint/ws/report-3"); + + org.apache.cxf.endpoint.Client client = ClientProxy.getClient(reportPort); + org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); + + Map outProps = new HashMap(); + + outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); + outProps.put(WSHandlerConstants.USER, "administrator"); + outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); + outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName()); + + WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); + BareOutInterceptor bareOutInterceptor = null; + for (Interceptor in : cxfEndpoint.getOutInterceptors()){ + if (in instanceof BareOutInterceptor){ + bareOutInterceptor = (BareOutInterceptor) in; + } + } + cxfEndpoint.getOutInterceptors().remove(bareOutInterceptor); + cxfEndpoint.getOutInterceptors().add(wssOut); + cxfEndpoint.getOutInterceptors().add(new CustomWrappedOutInterceptor(prismContext)); + + // enable the following to get client-side logging of outgoing requests and incoming responses + cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor()); + cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor()); + + return reportPort; + } + +// protected Collection> searchObjects(Object query, +// Collection> options) throws SchemaException, +// ObjectNotFoundException, SecurityViolationException, CommunicationException, +// ConfigurationException { +// // TODO Auto-generated method stub +// SelectorQualifiedGetOptionsType optionsType = MiscSchemaUtil.optionsToOptionsType(options); +// +// ObjectListType results = reportPort.searchObjects((String) query, optionsType); +// +// return toPrismList(results); +// } + +} diff --git a/model/report-ds-impl/src/main/resources/jasperreports.properties b/model/report-ds-impl/src/main/resources/jasperreports_extension.properties similarity index 100% rename from model/report-ds-impl/src/main/resources/jasperreports.properties rename to model/report-ds-impl/src/main/resources/jasperreports_extension.properties 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 7d9dc9a0ac8..05f7a937822 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 @@ -124,15 +124,7 @@ public ObjectQuery parseQuery(String query, Map parameters) throw } - private boolean containsExpression(ObjectFilter subFilter){ - if (subFilter instanceof PropertyValueFilter){ - return ((PropertyValueFilter) subFilter).getExpression() != null; - } else if (subFilter instanceof InOidFilter){ - return ((InOidFilter) subFilter).getExpression() != null; - } - - return false; - } + @Override public Collection> searchObjects(ObjectQuery query, diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java index 090e620bc66..43148f753cd 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java @@ -1,41 +1,54 @@ package com.evolveum.midpoint.report.impl; -import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; +import net.sf.jasperreports.engine.JRException; + +import org.apache.cxf.interceptor.Fault; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.evolveum.midpoint.audit.api.AuditEventRecord; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; import com.evolveum.midpoint.report.api.ReportPort; import com.evolveum.midpoint.report.api.ReportService; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.util.QNameUtil; 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.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.EntryType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordListType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ParamsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParametersType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; @Service public class ReportWebService implements ReportPortType, ReportPort { @@ -44,18 +57,6 @@ public class ReportWebService implements ReportPortType, ReportPort { @Autowired(required = true) private PrismContext prismContext; -// -// @Autowired(required = true) -// private TaskManager taskManager; -// -// @Autowired(required = true) -// private ModelService model; -// -// @Autowired(required = true) -// private ObjectResolver objectResolver; -// -// @Autowired(required = true) -// private AuditService auditService; @Autowired(required = true) private ReportService reportService; @@ -119,77 +120,106 @@ public ObjectListType processReport(ReportType report) { } -// @Override -// private QueryType parseQuery(String query, ParamsType parameters) { -// + @Override + public String parseQuery(String query, RemoteReportParametersType parametersType) { + // Map params = getParamsMap(parameters); -// -// try { -// ObjectQuery q = reportService.parseQuery(query, params); -// return QueryJaxbConvertor.createQueryType(q, prismContext); -// } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// return null; -// } -// -// } + + + try { + Map parametersMap = getParamsMap(parametersType); + + ObjectQuery q = reportService.parseQuery(query, parametersMap); + SearchFilterType filterType = QueryConvertor.createSearchFilterType(q.getFilter(), prismContext); + return prismContext.serializeAtomicValue(filterType, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML); + } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { + // TODO Auto-generated catch block + throw new Fault(e); + } + + } @Override - public ObjectListType searchObjects(String query, ParamsType parameters, SelectorQualifiedGetOptionsType options) { + public ObjectListType searchObjects(String query, SelectorQualifiedGetOptionsType options) { try { - Map params = getParamsMap(parameters); - ObjectQuery objectQuery = reportService.parseQuery(query, params); - GetOperationOptions getOpts = GetOperationOptions.createRaw(); - getOpts.setResolveNames(Boolean.TRUE); +// Map params = getParamsMap(parameters); +// ObjectQuery objectQuery = reportService.parseQuery(query, null); +// GetOperationOptions getOpts = GetOperationOptions.createRaw(); +// getOpts.setResolveNames(Boolean.TRUE); + SearchFilterType filterType = prismContext.parseAtomicValue(query, SearchFilterType.COMPLEX_TYPE); +// ObjectFilter filter = QueryConvertor.parseFilter(query, UserType.class, prismContext); + ObjectQuery objectQuery = ObjectQuery.createObjectQuery(QueryJaxbConvertor.createObjectFilter(UserType.class, filterType, prismContext)); - Collection> resultList = reportService.searchObjects(objectQuery, SelectorOptions.createCollection(getOpts)); + Collection> resultList = reportService.searchObjects(objectQuery, MiscSchemaUtil.optionsTypeToOptions(options)); return createObjectListType(resultList); } catch (SchemaException | ObjectNotFoundException | SecurityViolationException - | CommunicationException | ExpressionEvaluationException | ConfigurationException e) { + | CommunicationException | ConfigurationException e) { // TODO Auto-generated catch block - e.printStackTrace(); - return null; + throw new Fault(e); } } -// @Override - public ObjectListType evaluateScript(String script, ParamsType parameters){ - Map params = getParamsMap(parameters); - + @Override + public ObjectListType evaluateScript(String script, RemoteReportParametersType parameters){ try { + Map params = getParamsMap(parameters); Collection> resultList = reportService.evaluateScript(script, params); return createObjectListType(resultList); } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException e) { // TODO Auto-generated catch block - e.printStackTrace(); - return null; + throw new Fault(e); } } + + @Override + public AuditEventRecordListType evaluateAuditScript(String script, RemoteReportParametersType parameters){ + + try { + Map params = getParamsMap(parameters); + Collection resultList = reportService.evaluateAuditScript(script, params); + return createAuditEventRecordListType(resultList); + } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException e) { + // TODO Auto-generated catch block + throw new Fault(e); + } + + + } + + - private Map getParamsMap(ParamsType parameters){ - - Map params = null; - if (parameters != null) { - params = new HashMap(); - for (EntryType entry : parameters.getEntry()) { - Object obj = entry.getEntryValue(); - Serializable value = null; - if (obj instanceof JAXBElement){ - value = (Serializable) ((JAXBElement) obj).getValue(); - } else { - value = (Serializable) entry.getEntryValue(); - } - params.put(new QName(entry.getKey()), value); + private Map getParamsMap(RemoteReportParametersType parametersType) throws SchemaException{ + +// prismContext.adopt(parametersType); +// PrismContainerValue parameter = parametersType.asPrismContainerValue(); + Map parametersMap = new HashMap<>(); + if (parametersType != null){ + for (RemoteReportParameterType item : parametersType.getRemoteParameter()){ + parametersMap.put(new QName(item.getParameterName()), item.getAny()); } } - return params; + return parametersMap; +// Map params = null; +// if (parameters != null) { +// params = new HashMap(); +// for (EntryType entry : parameters.getEntry()) { +// Object obj = entry.getEntryValue(); +// Serializable value = null; +// if (obj instanceof JAXBElement){ +// value = (Serializable) ((JAXBElement) obj).getValue(); +// } else { +// value = (Serializable) entry.getEntryValue(); +// } +// params.put(new QName(entry.getKey()), value); +// } +// } +// return params; } @@ -205,4 +235,77 @@ private ObjectListType createObjectListType(Collection resultList){ + if (resultList == null){ + return new AuditEventRecordListType(); + } + + AuditEventRecordListType results = new AuditEventRecordListType(); + for (AuditEventRecord auditRecord : resultList){ + results.getObject().add(auditRecord.createAuditEventRecordType()); + } + + return results; + } + + + @Override + public RemoteReportParameterType getFieldValue(String parameterName, ObjectType object) { + try { + prismContext.adopt(object); + } catch (SchemaException e) { + throw new Fault(e); + } + + PrismObject prismObject = object.asPrismObject(); + + QName itemName = QNameUtil.uriToQName(parameterName); + + Item i = prismObject.findItem(itemName); + if (i == null){ + return null; +// throw new JRException("Object of type " + currentObject.getCompileTimeClass().getSimpleName() + " does not contain field " + fieldName +"."); + } + + RemoteReportParameterType param = new RemoteReportParameterType(); + + if (i instanceof PrismProperty){ + if (i.isSingleValue()){ + param.getAny().add(((PrismProperty) i).getRealValue()); + } else { + for (Object o : ((PrismProperty) i).getRealValues()){ + param.getAny().add(o); + } + } + } else if (i instanceof PrismReference){ + if (i.isSingleValue()){ + param.getAny().add(((PrismReference) i).getValue().asReferencable()); + } else { + for (PrismReferenceValue refVal : ((PrismReference) i).getValues()){ + param.getAny().add(refVal.asReferencable()); + } + } + } else if (i instanceof PrismContainer){ + if (i.isSingleValue()){ + param.getAny().add(((PrismContainer) i).getValue().asContainerable()); + } else { + for (Object pcv : i.getValues()){ + if (pcv instanceof PrismContainerValue){ + param.getAny().add(((PrismContainerValue) pcv).asContainerable()); + } + } + } + + } else + throw new Fault(new IllegalArgumentException("Could not get value of the field: " + itemName)); + + return param; +// return +// throw new UnsupportedOperationException("dataSource.getFiledValue() not supported"); + + } + + + } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java new file mode 100644 index 00000000000..3c7d9e7572d --- /dev/null +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java @@ -0,0 +1,206 @@ +package com.evolveum.midpoint.report.impl; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.xml.namespace.QName; +import javax.xml.soap.Detail; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPFactory; +import javax.xml.soap.SOAPFault; +import javax.xml.transform.dom.DOMSource; +import javax.xml.ws.Holder; +import javax.xml.ws.Provider; +import javax.xml.ws.soap.SOAPFaultException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.report.api.ReportPort; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordListType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage; +import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateAuditScriptResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateAuditScriptType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateScriptResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateScriptType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.GetFieldValueResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.GetFieldValueType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ParseQueryResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ParseQueryType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.SearchObjectsResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.SearchObjectsType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + +@Service +public class ReportWebServiceRaw implements Provider { + + private static transient Trace LOGGER = TraceManager.getTrace(ReportWebService.class); + + public static final String NS_SOAP11_ENV = "http://schemas.xmlsoap.org/soap/envelope/"; + public static final String NS_SOAP11_ENV_PREFIX = "SOAP-ENV"; + public static final QName SOAP11_FAULT = new QName(NS_SOAP11_ENV, "Fault"); + public static final QName SOAP11_FAULTCODE = new QName("", "faultcode"); + public static final String SOAP11_FAULTCODE_SERVER = NS_SOAP11_ENV_PREFIX + ":Server"; + public static final QName SOAP11_FAULTSTRING = new QName("", "faultstring"); + public static final QName SOAP11_FAULTACTOR = new QName("", "faultactor"); + public static final QName SOAP11_FAULT_DETAIL = new QName("", "detail"); + public static final String ACTOR = "TODO"; + + @Autowired(required = true) + private PrismContext prismContext; + + @Autowired(required = true) + private ReportWebService reportService; + + @Override + public DOMSource invoke(DOMSource request) { + try { + return invokeAllowingFaults(request); + } catch (FaultMessage faultMessage) { + try { + SOAPFactory factory = SOAPFactory.newInstance(); + SOAPFault soapFault = factory.createFault(); + soapFault.setFaultCode(SOAP11_FAULTCODE_SERVER); // todo here is a constant until we have a mechanism to determine the correct value (client / server) + soapFault.setFaultString(faultMessage.getMessage()); + Detail detail = soapFault.addDetail(); + serializeFaultMessage(detail, faultMessage); + // fault actor? + // stack trace of the outer exception (FaultMessage) is unimportant, because it is always created at one place + // todo consider providing stack trace of the inner exception + //Detail detail = soapFault.addDetail(); + //detail.setTextContent(getStackTraceAsString(faultMessage)); + throw new SOAPFaultException(soapFault); + } catch (SOAPException e) { + throw new RuntimeException("SOAP Exception: " + e.getMessage(), e); + } + } + } + + public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { + Node rootNode = request.getNode(); + Element rootElement; + if (rootNode instanceof Document) { + rootElement = ((Document) rootNode).getDocumentElement(); + } else if (rootNode instanceof Element) { + rootElement = (Element) rootNode; + } else { +// throw ws.createIllegalArgumentFault("Unexpected DOM node type: " + rootNode); + throw new FaultMessage("Unexpected DOM node type: " + rootNode); + } + + Object requestObject; + try { + requestObject = prismContext.parseAnyValue(rootElement); + } catch (SchemaException e) { + throw new FaultMessage("Couldn't parse SOAP request body because of schema exception: " + e.getMessage()); +// throw ws.createIllegalArgumentFault("Couldn't parse SOAP request body because of schema exception: " + e.getMessage()); + } + + Node response; + Holder operationResultTypeHolder = new Holder<>(); + try { + if (requestObject instanceof ParseQueryType){ + ParseQueryType p = (ParseQueryType) requestObject; + String parsed = reportService.parseQuery(p.getQuery(), p.getParameters()); + ParseQueryResponseType pr = new ParseQueryResponseType(); + pr.setParsedQuery(parsed); + response = prismContext.serializeAnyDataToElement(pr, ReportPort.PARSE_QUERY_RESPONSE); + } else if (requestObject instanceof SearchObjectsType){ + SearchObjectsType s = (SearchObjectsType) requestObject; + ObjectListType olt = reportService.searchObjects(s.getQuery(), s.getOptions()); + SearchObjectsResponseType sr = new SearchObjectsResponseType(); + sr.setObjectList(olt); + response = prismContext.serializeAnyDataToElement(sr, ReportPort.SEARCH_OBJECTS_RESPONSE); + } else if (requestObject instanceof EvaluateScriptType){ + EvaluateScriptType s = (EvaluateScriptType) requestObject; + ObjectListType olt = reportService.evaluateScript(s.getScript(), s.getParameters()); + EvaluateScriptResponseType sr = new EvaluateScriptResponseType(); + sr.setObjectList(olt); + response = prismContext.serializeAnyDataToElement(sr, ReportPort.EVALUATE_SCRIPT_RESPONSE); + } else if (requestObject instanceof EvaluateAuditScriptType){ + EvaluateAuditScriptType s = (EvaluateAuditScriptType) requestObject; + AuditEventRecordListType olt = reportService.evaluateAuditScript(s.getScript(), s.getParameters()); + EvaluateAuditScriptResponseType sr = new EvaluateAuditScriptResponseType(); + sr.setObjectList(olt); + response = prismContext.serializeAnyDataToElement(sr, ReportPort.EVALUATE_AUDIT_SCRIPT_RESPONSE); + } else if (requestObject instanceof GetFieldValueType){ + GetFieldValueType g = (GetFieldValueType) requestObject; + RemoteReportParameterType param = reportService.getFieldValue(g.getParameterName(), g.getObject()); + GetFieldValueResponseType gr = new GetFieldValueResponseType(); + gr.setValue(param); + response = prismContext.serializeAnyDataToElement(gr, ReportPort.GET_FIELD_VALUE_RESPONSE); + } else { + throw new FaultMessage("Unsupported request type: " + requestObject); + } + } catch (SchemaException e) { + throwFault(e, operationResultTypeHolder.value); + // not reached + return null; + } + + // brutal hack for MID-2001 (serializing and parsing eliminates the problem!) + //String serialized = DOMUtil.printDom(response).toString(); + //LOGGER.trace("WEB SERVICE RESPONSE:\n{}", serialized); + //response = DOMUtil.parseDocument(serialized); + + return new DOMSource(response); + } + + private void serializeFaultMessage(Detail detail, FaultMessage faultMessage) { + try { + XNode faultMessageXnode = prismContext.getBeanConverter().marshall(faultMessage.getFaultInfo()); + RootXNode xroot = new RootXNode(SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, faultMessageXnode); + xroot.setExplicitTypeDeclaration(true); + QName faultType = prismContext.getBeanConverter().determineTypeForClass(faultMessage.getFaultInfo().getClass()); + xroot.setTypeQName(faultType); + prismContext.getParserDom().serializeUnderElement(xroot, SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, detail); + } catch (SchemaException e) { + LOGGER.error("Error serializing fault message (SOAP fault detail): {}", e.getMessage(), e); + } + } + +// private DOMSource serializeFaultMessage(FaultMessage faultMessage) { +// Element faultElement = DOMUtil.createElement(SOAP11_FAULT); +// Element faultCodeElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTCODE); +// faultCodeElement.setTextContent(SOAP11_FAULTCODE_SERVER); // todo here is a constant until we have a mechanism to determine the correct value (client / server) +// Element faultStringElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTSTRING); +// faultStringElement.setTextContent(faultMessage.getMessage()); +// Element faultActorElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTACTOR); +// faultActorElement.setTextContent("TODO"); // todo +// Element faultDetailElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULT_DETAIL); +// faultDetailElement.setTextContent(getStackTraceAsString(faultMessage)); +// return new DOMSource(faultElement.getOwnerDocument()); +// } + + private String getStackTraceAsString(FaultMessage faultMessage) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + faultMessage.printStackTrace(pw); + pw.close(); + return sw.toString(); + } + + private void throwFault(Exception ex, OperationResultType resultType) throws FaultMessage { + if (resultType != null) { + throw new FaultMessage(ex.getMessage()); +// ws.throwFault(ex, OperationResult.createOperationResult(resultType)); + } else { + throw new FaultMessage(ex.getMessage()); +// ws.throwFault(ex, null); + } + } + +} diff --git a/model/report-impl/src/main/resources/ctx-report.xml b/model/report-impl/src/main/resources/ctx-report.xml index 5de0c5cadbd..e0444c33f09 100644 --- a/model/report-impl/src/main/resources/ctx-report.xml +++ b/model/report-impl/src/main/resources/ctx-report.xml @@ -42,7 +42,7 @@ endpointName="report:reportPort" xmlns:report="http://midpoint.evolveum.com/xml/ns/public/report/report-3"> - + diff --git a/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java b/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java index 779159846ae..ae6975a5d64 100644 --- a/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java +++ b/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java @@ -19,15 +19,26 @@ import java.util.ArrayList; import java.util.Collection; +import javax.xml.datatype.XMLGregorianCalendar; + import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** @@ -281,6 +292,57 @@ public void checkConsistence() { // } // } } + + public AuditEventRecordType createAuditEventRecordType(){ + AuditEventRecordType auditRecordType = new AuditEventRecordType(); + auditRecordType.setChannel(channel); + auditRecordType.setEventIdentifier(eventIdentifier); + auditRecordType.setEventStage(AuditEventStage.fromAuditEventStage(eventStage)); + auditRecordType.setEventType(AuditEventType.fromAuditEventType(eventType)); + auditRecordType.setHostIdentifier(hostIdentifier); + auditRecordType.setInitiatorRef(ObjectTypeUtil.createObjectRef(initiator)); + auditRecordType.setMessage(message); + auditRecordType.setOutcome(OperationResultStatus.createStatusType(outcome)); + auditRecordType.setParameter(parameter); + auditRecordType.setResult(result); + auditRecordType.setSessionIdentifier(sessionIdentifier); + auditRecordType.setTargetOwnerRef(ObjectTypeUtil.createObjectRef(targetOwner)); + auditRecordType.setTargetRef(ObjectTypeUtil.createObjectRef(target)); + auditRecordType.setTaskIdentifier(taskIdentifier); + auditRecordType.setTaskOID(taskOID); + auditRecordType.setTimestamp(MiscUtil.asXMLGregorianCalendar(timestamp)); + return auditRecordType; + } + + public static AuditEventRecord createAuditEventRecord(AuditEventRecordType auditEventRecordType){ + AuditEventRecord auditRecord = new AuditEventRecord(); + auditRecord.setChannel(auditEventRecordType.getChannel()); + auditRecord.setEventIdentifier(auditEventRecordType.getEventIdentifier()); + auditRecord.setEventStage(AuditEventStage.toAuditEventStage(auditEventRecordType.getEventStage())); + auditRecord.setEventType(AuditEventType.toAuditEventType(auditEventRecordType.getEventType())); + auditRecord.setHostIdentifier(auditEventRecordType.getHostIdentifier()); + auditRecord.setInitiator(getObjectFromObjectReferenceType(auditEventRecordType.getInitiatorRef())); + auditRecord.setMessage(auditEventRecordType.getMessage()); + auditRecord.setOutcome(OperationResultStatus.parseStatusType(auditEventRecordType.getOutcome())); + auditRecord.setParameter(auditEventRecordType.getParameter()); + auditRecord.setResult(auditEventRecordType.getResult()); + auditRecord.setSessionIdentifier(auditEventRecordType.getSessionIdentifier()); + auditRecord.setTarget(getObjectFromObjectReferenceType(auditEventRecordType.getTargetRef())); + auditRecord.setTargetOwner(getObjectFromObjectReferenceType(auditEventRecordType.getTargetOwnerRef())); + auditRecord.setTaskIdentifier(auditEventRecordType.getTaskIdentifier()); + auditRecord.setTaskOID(auditEventRecordType.getTaskOID()); + auditRecord.setTimestamp(MiscUtil.asLong(auditEventRecordType.getTimestamp())); + return auditRecord; + } + + private static PrismObject getObjectFromObjectReferenceType(ObjectReferenceType ref){ + if (ref == null){ + return null; + } + + PrismReferenceValue prismRef = ref.asReferenceValue(); + return prismRef.getObject(); + } public AuditEventRecord clone() { AuditEventRecord clone = new AuditEventRecord(); From 00a6cae007863e9978c67aa382b9e9c836785203 Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Tue, 9 Jun 2015 19:08:36 +0200 Subject: [PATCH 02/16] fixing script evaluation. adding support for container value --- .../model/common/expression/script/ScriptExpression.java | 4 ++-- .../expression/script/jsr223/Jsr223ScriptEvaluator.java | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java index 780ff491735..87080e5bf0c 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java @@ -97,7 +97,7 @@ public void setFunctions(Collection functions) { this.functions = functions; } - public List> evaluate(ExpressionVariables variables, ScriptExpressionReturnTypeType suggestedReturnType, + public List evaluate(ExpressionVariables variables, ScriptExpressionReturnTypeType suggestedReturnType, boolean useNew, String contextDescription, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { @@ -107,7 +107,7 @@ public List> evaluate(ExpressionVariables variables, S try { context.setupThreadLocal(); - List> expressionResult = evaluator.evaluate(scriptType, variables, outputDefinition, suggestedReturnType, objectResolver, functions, contextDescription, result); + List expressionResult = evaluator.evaluate(scriptType, variables, outputDefinition, suggestedReturnType, objectResolver, functions, contextDescription, result); traceExpressionSuccess(variables, contextDescription, expressionResult); return expressionResult; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java index 833285854ea..8fcabeb9389 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java @@ -41,8 +41,10 @@ import com.evolveum.midpoint.model.common.expression.functions.BasicExpressionFunctions; import com.evolveum.midpoint.model.common.expression.functions.FunctionLibrary; import com.evolveum.midpoint.model.common.expression.script.ScriptEvaluator; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; @@ -161,6 +163,13 @@ public List evaluate(ScriptExpressionEvaluatorType if (allowEmptyValues || !isEmpty(evalResult)) { if (outputDefinition instanceof PrismReferenceDefinition){ pval = (V) ((ObjectReferenceType)evalResult).asReferenceValue(); + } else if (outputDefinition instanceof PrismContainerDefinition){ + try { + prismContext.adopt((Containerable)evalResult); + } catch (SchemaException e) { + throw new ExpressionEvaluationException(e.getMessage() + " " + contextDescription, e); + } + pval = (V) ((Containerable)evalResult).asPrismContainerValue(); } else { pval = (V) new PrismPropertyValue(evalResult); } From 630cd515460fa159b8afa25fc627aff82ef6401a Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Tue, 9 Jun 2015 19:09:01 +0200 Subject: [PATCH 03/16] improving remote jaspersoft studio plugin --- .../ds/impl/MidPointClientConfiguration.java | 3 +-- .../ds/impl/MidPointRemoteDataSource.java | 3 +-- .../ds/impl/MidPointRemoteQueryExecutor.java | 19 +++++++++++-- .../test/MidPointRemoteQueryExecuterTest.java | 6 ++++- .../main/resources/ctx-report-ds-context.xml | 27 +++++++++++++++++++ 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java index fd7d7d46d36..229121da4df 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointClientConfiguration.java @@ -42,7 +42,7 @@ public ReportPortType createReportPort(PrismContext prismContext) { requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint); org.apache.cxf.endpoint.Client client = ClientProxy.getClient(reportPort); - org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); + org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); Map outProps = new HashMap(); @@ -57,7 +57,6 @@ public ReportPortType createReportPort(PrismContext prismContext) { // enable the following to get client-side logging of outgoing requests and incoming responses cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor()); cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor()); - return reportPort; } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java index 4141f499a2f..9d2a8be37ce 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java @@ -115,8 +115,7 @@ public Object getFieldValue(JRField jrField) throws JRException { Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - if (param.getAny().size() == 1) { - + if (param.getAny().size() == 1 && !List.class.isAssignableFrom(jrField.getValueClass())) { Object val = param.getAny().iterator().next(); return unmarshallValue(jrField, val, jaxbUnmarshaller); } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java index 15bbe745ac1..f8cb7022f13 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java @@ -6,6 +6,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -21,6 +22,8 @@ import net.sf.jasperreports.engine.JasperReportsContext; import net.sf.jasperreports.engine.base.JRBaseParameter; +import org.apache.cxf.helpers.DOMUtils; +import org.apache.xml.serializer.dom3.DOM3SerializerImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.xml.sax.SAXException; @@ -32,6 +35,8 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.parser.DomParser; +import com.evolveum.midpoint.prism.parser.JaxbDomHack; import com.evolveum.midpoint.prism.query.InOidFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.PropertyValueFilter; @@ -40,6 +45,7 @@ import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; @@ -97,7 +103,13 @@ private RemoteReportParametersType converToReportParameterType(Map param : paramSet){ RemoteReportParameterType remoteParam = new RemoteReportParameterType(); remoteParam.setParameterName(param.getKey().getLocalPart()); - remoteParam.getAny().add(((PrismPropertyValue)param.getValue()).getValue()); + DOM3SerializerImpl domser = new DOM3SerializerImpl(null); + Object value = ((PrismPropertyValue)param.getValue()).getValue(); + if (value!= null && List.class.isAssignableFrom(value.getClass())){ + remoteParam.getAny().addAll((List) value); + } else { + remoteParam.getAny().add(value); + } reportParams.getRemoteParameter().add(remoteParam); } return reportParams; @@ -164,8 +176,11 @@ protected MidPointRemoteQueryExecutor(JasperReportsContext jasperReportsContext, MidPointClientConfiguration clientConfig = applicationContext.getBean("clientConfig", MidPointClientConfiguration.class); if (reportPort == null) { - reportPort = clientConfig.createReportPort(prismContext); + reportPort = applicationContext.getBean("reportPort", ReportPortType.class); } +// if (reportPort == null) { +// reportPort = clientConfig.createReportPort(prismContext); +// } parseQuery(); } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java index 4048265d450..634d61e4930 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java @@ -13,6 +13,7 @@ import org.apache.cxf.wsdl.interceptors.BareOutInterceptor; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.handler.WSHandlerConstants; +import org.springframework.context.support.ClassPathXmlApplicationContext; import org.xml.sax.SAXException; import com.evolveum.midpoint.prism.PrismContext; @@ -70,8 +71,11 @@ public static void main(String[] args) { PrismTestUtil.resetPrismContext(new MidPointPrismContextFactory()); MidPointRemoteQueryExecuterTest t = new MidPointRemoteQueryExecuterTest(); + ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("ctx-report-ds-context.xml"); - ReportPortType reportPort = createReportPort(PrismTestUtil.getPrismContext()); + ReportPortType reportPort = applicationContext.getBean("reportPort", ReportPortType.class); + +// ReportPortType reportPort = createReportPort(PrismTestUtil.getPrismContext()); String f = (String) t.getParsedQuery(PrismTestUtil.getPrismContext(), reportPort); System.out.println("returned filter: " + f); diff --git a/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml b/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml index ac39a7ea57a..d33704d6b9f 100644 --- a/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml +++ b/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml @@ -43,6 +43,33 @@ p:username="${auth.username}" p:password="${auht.password}" p:endpoint="${service.endpoint}"/> + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 40aba5afffecb9f0ef15dcb4644e0d3f59c1abfd Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Tue, 16 Jun 2015 21:03:47 +0200 Subject: [PATCH 04/16] imrpovements for remote query executer - improving report WS.. --- .../midpoint/prism/parser/QueryConvertor.java | 3 +- .../prism/parser/XNodeSerializer.java | 4 +- .../prism/query/TestQueryConvertors.java | 66 ++-- .../resources/query/filter-type-user-none.xml | 28 ++ .../xml/ns/public/report/report-3.wsdl | 29 +- .../midpoint/report/api/ReportPort.java | 1 + .../report/ds/impl/MidPointQueryExecutor.java | 193 +++++++++++ .../ds/impl/MidPointRemoteDataSource.java | 23 +- .../ds/impl/MidPointRemoteQueryExecutor.java | 37 +- .../ds/impl/MidpointDataSourceProvider.java | 2 +- .../test/MidPointRemoteQueryExecuterTest.java | 9 +- .../main/resources/ctx-report-ds-context.xml | 2 + .../report/impl/ReportWebService.java | 327 +++++++++--------- .../report/impl/ReportWebServiceRaw.java | 23 +- 14 files changed, 492 insertions(+), 255 deletions(-) create mode 100644 infra/prism/src/test/resources/query/filter-type-user-none.xml create mode 100644 model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java index 15ccd942497..2c3f3c65fff 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java @@ -764,7 +764,8 @@ private static MapXNode serializeTypeFilter(TypeFilter filter, XNodeSerializer x private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer xnodeSerializer) { MapXNode map = new MapXNode(); - map.put(KEY_FILTER_NONE_TYPE, new PrimitiveXNode<>()); + MapXNode none = new MapXNode(); + map.put(KEY_FILTER_NONE_TYPE, none); return map; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java index 7804456eabe..9edcff84466 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java @@ -185,7 +185,7 @@ public XNode serializeItemValue(V itemValue, ItemDefiniti if (beanConverter.getPrismContext() == null) { throw new IllegalStateException("No prismContext in beanConverter!"); } - if (definition == null){ + if (definition == null && itemValue instanceof PrismPropertyValue){ // if (itemValue instanceof PrismPropertyValue && beanConverter.canProcess(((PrismPropertyValue) itemValue).getValue().getClass())){ // xnode = beanConverter.marshall(((PrismPropertyValue)itemValue).getValue()); // xnode.setExplicitTypeDeclaration(true); @@ -202,7 +202,7 @@ public XNode serializeItemValue(V itemValue, ItemDefiniti } else { throw new IllegalArgumentException("Unsupported value type "+itemValue.getClass()); } - if (definition.isDynamic()) { + if (definition != null && definition.isDynamic()) { xnode.setExplicitTypeDeclaration(true); } Object commentValue = itemValue.getUserData(USER_DATA_KEY_COMMENT); diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java index 13c3fbcd037..52d876909c7 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java @@ -17,17 +17,19 @@ package com.evolveum.midpoint.prism.query; import static com.evolveum.midpoint.prism.PrismInternalTestUtil.DEFAULT_NAMESPACE_PREFIX; -import static com.evolveum.midpoint.prism.util.PrismTestUtil.*; -import static org.testng.AssertJUnit.*; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.createPolyString; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.displayQuery; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.displayTestTitle; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.getFilterCondition; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; import java.io.File; import java.io.IOException; -import java.util.List; import javax.xml.namespace.QName; -import com.evolveum.midpoint.prism.parser.DomParser; -import com.evolveum.midpoint.prism.util.PrismUtil; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; import org.w3c.dom.Element; @@ -35,33 +37,18 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismInternalTestUtil; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.foo.UserType; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.LogicalFilter; -import com.evolveum.midpoint.prism.query.NaryLogicalFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; -import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xnode.ListXNode; import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DomAsserts; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.prism.xml.ns._public.query_3.PagingType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; @@ -74,6 +61,7 @@ public class TestQueryConvertors { private static final File FILTER_USER_NAME_FILE = new File(TEST_DIR, "filter-user-name.xml"); private static final File FILTER_USER_AND_FILE = new File(TEST_DIR, "filter-user-and.xml"); + private static final File FILTER_TYPE_USER_NONE = new File(TEST_DIR, "filter-type-user-none.xml"); @BeforeSuite public void setupDebug() throws SchemaException, SAXException, IOException { @@ -169,6 +157,44 @@ public void testFilterUserAndJaxb() throws Exception { DomAsserts.assertTextContent(secondValueElement, "Caribbean"); } + @Test + public void testFilterTypeUserNone() throws Exception { + displayTestTitle("testFilterTypeUserNone"); + + + SearchFilterType filterType = PrismTestUtil.parseAnyValue(FILTER_TYPE_USER_NONE); + + ObjectQuery query = toObjectQuery(UserType.class, filterType); + displayQuery(query); + + assertNotNull(query); + + ObjectFilter filter = query.getFilter(); + assertTrue("Filter is not of TYPE type", filter instanceof TypeFilter); + + ObjectFilter subFilter = ((TypeFilter) filter).getFilter(); + assertTrue("Filter is not of NONE type", subFilter instanceof NoneFilter); + + QueryType convertedQueryType = toQueryType(query); + System.out.println("Re-converted query type"); + System.out.println(convertedQueryType.debugDump()); + + Element filterClauseElement = convertedQueryType.getFilter().getFilterClauseAsElement(); + LOGGER.info(convertedQueryType.getFilter().getFilterClauseXNode().debugDump()); + + + System.out.println("Serialized filter (JAXB->DOM)"); + String filterAsString = DOMUtil.serializeDOMToString(filterClauseElement); + System.out.println(filterAsString); + LOGGER.info(filterAsString); + + DomAsserts.assertElementQName(filterClauseElement, new QName(PrismConstants.NS_QUERY, "type")); + + + + } + + private ObjectQuery toObjectQuery(Class type, QueryType queryType) throws Exception { ObjectQuery query = QueryJaxbConvertor.createObjectQuery(type, queryType, getPrismContext()); diff --git a/infra/prism/src/test/resources/query/filter-type-user-none.xml b/infra/prism/src/test/resources/query/filter-type-user-none.xml new file mode 100644 index 00000000000..7004152ace1 --- /dev/null +++ b/infra/prism/src/test/resources/query/filter-type-user-none.xml @@ -0,0 +1,28 @@ + + + + + + + UserType + + + + + \ No newline at end of file diff --git a/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl b/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl index 0e513c27aba..336024edd00 100644 --- a/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl +++ b/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl @@ -26,11 +26,13 @@ xmlns:apit="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" xmlns:aud="http://midpoint.evolveum.com/xml/ns/public/common/audit-3" xmlns:f="http://midpoint.evolveum.com/xml/ns/public/common/fault-3" + xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" > Web service interface for jasper report data source provider + @@ -43,11 +45,15 @@ schemaLocation="http://midpoint.evolveum.com/xml/ns/public/common/audit-3"/> - + + - + + + @@ -69,13 +75,14 @@ + - + parsedQuery @@ -87,6 +94,7 @@ + @@ -95,7 +103,7 @@ - + Search criteria. If not specified, all objects of a given type are returned. @@ -257,7 +265,7 @@ - + Name of the jasper report parameter @@ -269,12 +277,15 @@ - + A response from searchObjects operation. + + + @@ -293,6 +304,9 @@ A response from searchObjects operation. + + + @@ -309,7 +323,7 @@ - + @@ -415,6 +429,7 @@ + diff --git a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java index 59ae6da9b32..0d90b64f36f 100644 --- a/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java +++ b/model/report-api/src/main/java/com/evolveum/midpoint/report/api/ReportPort.java @@ -11,6 +11,7 @@ public interface ReportPort { public static final QName PARSE_QUERY_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "parseQueryResponse"); + public static final QName PROCESS_REPORT_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "processReportResponse"); public static final QName EVALUATE_SCRIPT_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "evaluateScriptResponse"); public static final QName EVALUATE_AUDIT_SCRIPT_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "evaluateAuditScriptResponse"); public static final QName SEARCH_OBJECTS_RESPONSE = new QName(SchemaConstants.NS_REPORT_WS, "searchObjectsResponse"); diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java new file mode 100644 index 00000000000..062fe11c168 --- /dev/null +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointQueryExecutor.java @@ -0,0 +1,193 @@ +package com.evolveum.midpoint.report.ds.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; +import net.sf.jasperreports.engine.JRValueParameter; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.base.JRBaseParameter; +import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; +import net.sf.jasperreports.engine.fill.JRFillParameter; +import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter; + +import org.apache.commons.lang.StringUtils; + +import com.evolveum.midpoint.audit.api.AuditEventRecord; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.report.api.ReportService; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +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.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +public abstract class MidPointQueryExecutor extends JRAbstractQueryExecuter{ + + private static final Trace LOGGER = TraceManager.getTrace(MidPointLocalQueryExecutor.class); + private Object query; + private String script; + private Class type; + private ReportService reportService; + + public String getScript() { + return script; + } + public Object getQuery() { + return query; + } + public Class getType() { + return type; + } + + protected Map getParameters(){ + JRParameter[] params = dataset.getParameters(); + Map expressionParameters = new HashMap(); + for (JRParameter param : params){ + if (param.isSystemDefined()){ + continue; + } + LOGGER.trace(((JRBaseParameter)param).getName()); + Object v = getParameterValue(param.getName()); + try{ + expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); + } catch (Exception e){ + //just skip properties that are not important for midpoint + } + + LOGGER.trace("p.val: {}", v); + } + return expressionParameters; + } + + protected Map getPromptingParameters(){ + JRParameter[] params = dataset.getParameters(); + Map expressionParameters = new HashMap(); + for (JRParameter param : params){ + if (param.isSystemDefined()){ + continue; + } + if (!param.isForPrompting()){ + continue; + } + LOGGER.trace(((JRBaseParameter)param).getName()); + Object v = getParameterValue(param.getName()); + try{ + expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); + } catch (Exception e){ + //just skip properties that are not important for midpoint + } + + LOGGER.trace("p.val: {}", v); + } + return expressionParameters; + } + + protected abstract Object getParsedQuery(String query, Map expressionParameters) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException; + + protected String getParsedScript(String script){ + String normalized = script.replace("", ""); + return normalized.replace("", ""); + } + + @Override + protected void parseQuery() { + String s = dataset.getQuery().getText(); + + Map expressionParameters = getParameters(); + LOGGER.trace("query: " + s); + if (StringUtils.isEmpty(s)) { + query = null; + } else { + try { + if (s.startsWith(" parametersMap) { + super(jasperReportsContext, dataset, parametersMap); + } + + protected abstract Collection searchObjects(Object query, Collection> options) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException; + + protected abstract Collection evaluateScript(String script, Map parameters) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException; + + protected abstract Collection searchAuditRecords(String script, Map parameters) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException; + + protected abstract JRDataSource createDataSource(Collection results); + + @Override + public JRDataSource createDatasource() throws JRException { + Collection> results = new ArrayList<>(); + + try { + if (query == null && script == null){ + throw new JRException("Neither query, nor script defined in the report."); + } + + if (query != null){ + results = searchObjects(query, SelectorOptions.createCollection(GetOperationOptions.createRaw())); + } else { + if (script.contains("AuditEventRecord")){ + Collection audtiEventRecords = searchAuditRecords(script, getPromptingParameters()); + return new JRBeanCollectionDataSource(audtiEventRecords); + } else { + results = evaluateScript(script, getParameters()); + } + } + } catch (SchemaException | ObjectNotFoundException | SecurityViolationException + | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { + // TODO Auto-generated catch block + throw new JRException(e); + } + + return createDataSource(results); + + } + + + @Override + public void close() { +// throw new UnsupportedOperationException("QueryExecutor.close() not supported"); + //nothing to DO + } + + @Override + public boolean cancelQuery() throws JRException { + throw new UnsupportedOperationException("QueryExecutor.cancelQuery() not supported"); + } + + @Override + protected String getParameterReplacement(String parameterName) { + throw new UnsupportedOperationException("QueryExecutor.getParameterReplacement() not supported"); + } + + + +} diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java index 9d2a8be37ce..a084c7cf7d7 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteDataSource.java @@ -11,30 +11,17 @@ import javax.xml.bind.Unmarshaller; import javax.xml.namespace.QName; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.Referencable; -import com.evolveum.midpoint.prism.parser.JaxbDomHack; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportParameterType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; -import com.evolveum.midpoint.xml.ns._public.report.report_3.reportPortImpl; public class MidPointRemoteDataSource implements JRDataSource { @@ -98,7 +85,7 @@ public Object getFieldValue(JRField jrField) throws JRException { return currentObject.getOid(); } - RemoteReportParameterType param = reportPort.getFieldValue( + ReportParameterType param = reportPort.getFieldValue( QNameUtil.qNameToUri(new QName(fieldName)), currentObject); if (param == null) { diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java index f8cb7022f13..7024cd5c53c 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java @@ -1,9 +1,5 @@ package com.evolveum.midpoint.report.ds.impl; -import groovy.lang.Singleton; - -import java.io.IOException; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -11,64 +7,39 @@ import java.util.Map.Entry; import java.util.Set; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRDataset; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JRValueParameter; import net.sf.jasperreports.engine.JasperReportsContext; -import net.sf.jasperreports.engine.base.JRBaseParameter; -import org.apache.cxf.helpers.DOMUtils; -import org.apache.xml.serializer.dom3.DOM3SerializerImpl; -import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.xml.sax.SAXException; import com.evolveum.midpoint.audit.api.AuditEventRecord; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.parser.DomParser; -import com.evolveum.midpoint.prism.parser.JaxbDomHack; -import com.evolveum.midpoint.prism.query.InOidFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.PropertyValueFilter; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; -import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.util.DOMUtil; 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.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.api_types_3.GetOperationOptionsType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; -import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionsType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordListType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.EntryType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ParamsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportParameterType; import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParametersType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; -import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; +import com.evolveum.prism.xml.ns._public.query_3.QueryType; public class MidPointRemoteQueryExecutor extends MidPointQueryExecutor{ @@ -103,10 +74,10 @@ private RemoteReportParametersType converToReportParameterType(Map param : paramSet){ RemoteReportParameterType remoteParam = new RemoteReportParameterType(); remoteParam.setParameterName(param.getKey().getLocalPart()); - DOM3SerializerImpl domser = new DOM3SerializerImpl(null); +// DOM3SerializerImpl domser = new DOM3SerializerImpl(null); Object value = ((PrismPropertyValue)param.getValue()).getValue(); if (value!= null && List.class.isAssignableFrom(value.getClass())){ - remoteParam.getAny().addAll((List) value); + remoteParam.getAny().addAll((List) value); } else { remoteParam.getAny().add(value); } @@ -124,7 +95,7 @@ protected Collection searchObjects(Object query, // TODO Auto-generated method stub SelectorQualifiedGetOptionsType optionsType = MiscSchemaUtil.optionsToOptionsType(options); - ObjectListType results = reportPort.searchObjects((String) query, optionsType); + ObjectListType results = reportPort.searchObjects((QueryType)query, optionsType); if (results == null){ return new ArrayList<>(); } diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java index 3f1081201b0..883d3e16557 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidpointDataSourceProvider.java @@ -96,7 +96,7 @@ public JRDataSource create(JasperReport report) throws JRException { ReportType reportType = new ReportType(); reportType.setTemplate(jrxmlBase64); - ObjectListType olt = reportPort.processReport(reportType); + ObjectListType olt = new ObjectListType();//.processReport(reportType); return new MidPointRemoteDataSource(olt.getObject()); } catch (Exception e){ System.out.println("exception: " +e); diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java index 634d61e4930..9a407b28fea 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java @@ -26,11 +26,13 @@ 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.xml.ns._public.common.common_3.ReportParameterType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParametersType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportService; +import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; @@ -39,7 +41,6 @@ public class MidPointRemoteQueryExecuterTest { public Object getParsedQuery(PrismContext prismContext, ReportPortType reportPort) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException { RemoteReportParametersType reportParameters = new RemoteReportParametersType(); - RemoteReportParameterType reportParameter = new RemoteReportParameterType(); reportParameter.setParameterName("stringExample"); reportParameter.getAny().add("someString"); @@ -59,6 +60,8 @@ public Object getParsedQuery(PrismContext prismContext, ReportPortType reportPor EqualFilter f = EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, PrismTestUtil.createPolyString("someName")); SearchFilterType filterType = QueryConvertor.createSearchFilterType(f, prismContext); + QueryType q = new QueryType(); + q.setFilter(filterType); return reportPort.parseQuery(prismContext.serializeAtomicValue(filterType, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML), reportParameters); // return getStringQuery(); @@ -77,8 +80,8 @@ public static void main(String[] args) { // ReportPortType reportPort = createReportPort(PrismTestUtil.getPrismContext()); - String f = (String) t.getParsedQuery(PrismTestUtil.getPrismContext(), reportPort); - System.out.println("returned filter: " + f); + QueryType f = (QueryType) t.getParsedQuery(PrismTestUtil.getPrismContext(), reportPort); + System.out.println("returned filter: " + f.debugDump()); } catch (SchemaException | SAXException | IOException | ObjectNotFoundException | ExpressionEvaluationException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml b/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml index d33704d6b9f..d46523277e6 100644 --- a/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml +++ b/model/report-ds-impl/src/main/resources/ctx-report-ds-context.xml @@ -44,6 +44,8 @@ p:password="${auht.password}" p:endpoint="${service.endpoint}"/> + + (); -// if (queryExecutor.getQuery() != null) { -// results = ReportUtils.getReportData(model, queryExecutor.getType(), queryExecutor.getQuery(), -// task, parentResult); -// } else { -// ReportFunctions reportFunctions = new ReportFunctions(prismContext, model, taskManager, -// auditService); -// results = ReportUtils.getReportData(prismContext, task, reportFunctions, -// queryExecutor.getScript(), queryExecutor.getVariables(), objectResolver); -// } -// -// ObjectListType listType = new ObjectListType(); -// for (Object o : results) { -// if (o instanceof PrismObject) { -// listType.getObject().add((ObjectType) ((PrismObject) o).asObjectable()); -// } else { -// listType.getObject().add((ObjectType) o); -// } -// } -// return listType; -// } catch (SchemaException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (ObjectNotFoundException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (SecurityViolationException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (CommunicationException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (ConfigurationException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (ExpressionEvaluationException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// - return null; - - } + public QueryType parseQuery(String query, RemoteReportParametersType parametersType) { + // Map params = getParamsMap(parameters); - @Override - public String parseQuery(String query, RemoteReportParametersType parametersType) { - -// Map params = getParamsMap(parameters); - - try { Map parametersMap = getParamsMap(parametersType); - - ObjectQuery q = reportService.parseQuery(query, parametersMap); + + ObjectQuery q = reportService.parseQuery(query, parametersMap); SearchFilterType filterType = QueryConvertor.createSearchFilterType(q.getFilter(), prismContext); - return prismContext.serializeAtomicValue(filterType, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML); + QueryType queryType = new QueryType(); + queryType.setFilter(filterType); + return queryType; + // return prismContext.serializeAtomicValue(filterType, + // SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML); } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { // TODO Auto-generated catch block throw new Fault(e); } - - } + } @Override - public ObjectListType searchObjects(String query, SelectorQualifiedGetOptionsType options) { - + public ObjectListType searchObjects(QueryType query, SelectorQualifiedGetOptionsType options) { + try { -// Map params = getParamsMap(parameters); -// ObjectQuery objectQuery = reportService.parseQuery(query, null); -// GetOperationOptions getOpts = GetOperationOptions.createRaw(); -// getOpts.setResolveNames(Boolean.TRUE); - SearchFilterType filterType = prismContext.parseAtomicValue(query, SearchFilterType.COMPLEX_TYPE); -// ObjectFilter filter = QueryConvertor.parseFilter(query, UserType.class, prismContext); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(QueryJaxbConvertor.createObjectFilter(UserType.class, filterType, prismContext)); - - Collection> resultList = reportService.searchObjects(objectQuery, MiscSchemaUtil.optionsTypeToOptions(options)); - + // Map params = getParamsMap(parameters); + // ObjectQuery objectQuery = reportService.parseQuery(query, null); + // GetOperationOptions getOpts = GetOperationOptions.createRaw(); + // getOpts.setResolveNames(Boolean.TRUE); + // SearchFilterType filterType = + // prismContext.parseAtomicValue(query, + // SearchFilterType.COMPLEX_TYPE); + // ObjectFilter filter = QueryConvertor.parseFilter(query, + // UserType.class, prismContext); + ObjectQuery objectQuery = QueryJaxbConvertor.createObjectQuery(UserType.class, query, + prismContext); + + Collection> resultList = reportService.searchObjects( + objectQuery, MiscSchemaUtil.optionsTypeToOptions(options)); + return createObjectListType(resultList); } catch (SchemaException | ObjectNotFoundException | SecurityViolationException - | CommunicationException | ConfigurationException e) { + | CommunicationException | ConfigurationException e) { // TODO Auto-generated catch block throw new Fault(e); } } - + @Override - public ObjectListType evaluateScript(String script, RemoteReportParametersType parameters){ + public ObjectListType evaluateScript(String script, RemoteReportParametersType parameters) { try { Map params = getParamsMap(parameters); - Collection> resultList = reportService.evaluateScript(script, params); + Collection> resultList = reportService.evaluateScript(script, + params); return createObjectListType(resultList); } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException e) { // TODO Auto-generated catch block throw new Fault(e); } - - + } - + @Override - public AuditEventRecordListType evaluateAuditScript(String script, RemoteReportParametersType parameters){ - + public AuditEventRecordListType evaluateAuditScript(String script, RemoteReportParametersType parameters) { + try { Map params = getParamsMap(parameters); Collection resultList = reportService.evaluateAuditScript(script, params); @@ -187,125 +137,170 @@ public AuditEventRecordListType evaluateAuditScript(String script, RemoteReportP // TODO Auto-generated catch block throw new Fault(e); } - - + } - - - - - private Map getParamsMap(RemoteReportParametersType parametersType) throws SchemaException{ - -// prismContext.adopt(parametersType); -// PrismContainerValue parameter = parametersType.asPrismContainerValue(); + + private Map getParamsMap(RemoteReportParametersType parametersType) throws SchemaException { + + // prismContext.adopt(parametersType); + // PrismContainerValue parameter = + // parametersType.asPrismContainerValue(); Map parametersMap = new HashMap<>(); - if (parametersType != null){ - for (RemoteReportParameterType item : parametersType.getRemoteParameter()){ - parametersMap.put(new QName(item.getParameterName()), item.getAny()); + if (parametersType == null || parametersType.getRemoteParameter() == null + || parametersType.getRemoteParameter().isEmpty()) { + return parametersMap; + } + List items = parametersType.getRemoteParameter(); + for (RemoteReportParameterType item : items) { + QName paramName = new QName(SchemaConstants.NS_REPORT, item.getParameterName()); + if (item.getAny().size() == 1) { + parametersMap.put(paramName, item.getAny().get(0)); + } else { + parametersMap.put(paramName, item.getAny()); } + } + return parametersMap; -// Map params = null; -// if (parameters != null) { -// params = new HashMap(); -// for (EntryType entry : parameters.getEntry()) { -// Object obj = entry.getEntryValue(); -// Serializable value = null; -// if (obj instanceof JAXBElement){ -// value = (Serializable) ((JAXBElement) obj).getValue(); -// } else { -// value = (Serializable) entry.getEntryValue(); -// } -// params.put(new QName(entry.getKey()), value); -// } -// } -// return params; - + // Map params = null; + // if (parameters != null) { + // params = new HashMap(); + // for (EntryType entry : parameters.getEntry()) { + // Object obj = entry.getEntryValue(); + // Serializable value = null; + // if (obj instanceof JAXBElement){ + // value = (Serializable) ((JAXBElement) obj).getValue(); + // } else { + // value = (Serializable) entry.getEntryValue(); + // } + // params.put(new QName(entry.getKey()), value); + // } + // } + // return params; + } - - private ObjectListType createObjectListType(Collection> resultList){ - if (resultList == null){ + + private ObjectListType createObjectListType(Collection> resultList) { + if (resultList == null) { return new ObjectListType(); } - + ObjectListType results = new ObjectListType(); - for (PrismObject prismObject : resultList){ + for (PrismObject prismObject : resultList) { results.getObject().add(prismObject.asObjectable()); } - + return results; } - - private AuditEventRecordListType createAuditEventRecordListType(Collection resultList){ - if (resultList == null){ + + private AuditEventRecordListType createAuditEventRecordListType(Collection resultList) { + if (resultList == null) { return new AuditEventRecordListType(); } - + AuditEventRecordListType results = new AuditEventRecordListType(); - for (AuditEventRecord auditRecord : resultList){ + for (AuditEventRecord auditRecord : resultList) { results.getObject().add(auditRecord.createAuditEventRecordType()); } - + return results; } - @Override - public RemoteReportParameterType getFieldValue(String parameterName, ObjectType object) { + public ReportParameterType getFieldValue(String parameterName, ObjectType object) { try { prismContext.adopt(object); } catch (SchemaException e) { throw new Fault(e); } - + PrismObject prismObject = object.asPrismObject(); - + QName itemName = QNameUtil.uriToQName(parameterName); - + Item i = prismObject.findItem(itemName); - if (i == null){ + if (i == null) { return null; -// throw new JRException("Object of type " + currentObject.getCompileTimeClass().getSimpleName() + " does not contain field " + fieldName +"."); + // throw new JRException("Object of type " + + // currentObject.getCompileTimeClass().getSimpleName() + + // " does not contain field " + fieldName +"."); } - - RemoteReportParameterType param = new RemoteReportParameterType(); - - if (i instanceof PrismProperty){ - if (i.isSingleValue()){ - param.getAny().add(((PrismProperty) i).getRealValue()); + + ReportParameterType param = new ReportParameterType(); + + if (i instanceof PrismProperty) { + + if (i.isSingleValue()) { + param.getAny().add( + new JAXBElement(i.getElementName(), ((PrismProperty) i).getValueClass(), + ((PrismProperty) i).getRealValue())); } else { - for (Object o : ((PrismProperty) i).getRealValues()){ - param.getAny().add(o); + for (Object o : ((PrismProperty) i).getRealValues()) { + param.getAny().add(new JAXBElement(i.getElementName(), o.getClass(), o)); } } - } else if (i instanceof PrismReference){ - if (i.isSingleValue()){ - param.getAny().add(((PrismReference) i).getValue().asReferencable()); + } else if (i instanceof PrismReference) { + if (i.isSingleValue()) { + param.getAny().add( + new JAXBElement(i.getElementName(), ObjectReferenceType.class, ((PrismReference) i) + .getValue().asReferencable())); } else { - for (PrismReferenceValue refVal : ((PrismReference) i).getValues()){ - param.getAny().add(refVal.asReferencable()); + for (PrismReferenceValue refVal : ((PrismReference) i).getValues()) { + param.getAny().add( + new JAXBElement(i.getElementName(), ObjectReferenceType.class, refVal + .asReferencable())); } } - } else if (i instanceof PrismContainer){ - if (i.isSingleValue()){ - param.getAny().add(((PrismContainer) i).getValue().asContainerable()); + } else if (i instanceof PrismContainer) { + if (i.isSingleValue()) { + param.getAny().add( + new JAXBElement(i.getElementName(), ObjectReferenceType.class, ((PrismContainer) i) + .getValue().asContainerable())); } else { - for (Object pcv : i.getValues()){ - if (pcv instanceof PrismContainerValue){ - param.getAny().add(((PrismContainerValue) pcv).asContainerable()); + for (Object pcv : i.getValues()) { + if (pcv instanceof PrismContainerValue) { + param.getAny().add( + new JAXBElement(i.getElementName(), ObjectReferenceType.class, + ((PrismContainerValue) pcv).asContainerable())); } } } - + } else throw new Fault(new IllegalArgumentException("Could not get value of the field: " + itemName)); - + + // ReportParameterType param = new ReportParameterType(); + // PrismContainerValue pcv = param.asPrismContainerValue(); + // try { + // pcv.add(i.clone()); + // } catch (SchemaException e) { + // throw new Fault(e); + // } + return param; -// return -// throw new UnsupportedOperationException("dataSource.getFiledValue() not supported"); - + // return + // throw new + // UnsupportedOperationException("dataSource.getFiledValue() not supported"); + } + @Override + public ObjectListType processReport(String query, RemoteReportParametersType parameters, + SelectorQualifiedGetOptionsType options) { + + try { + Map parametersMap = getParamsMap(parameters); + ObjectQuery q = reportService.parseQuery(query, parametersMap); + Collection> resultList = reportService.searchObjects(q, + MiscSchemaUtil.optionsTypeToOptions(options)); + + return createObjectListType(resultList); + } catch (SchemaException | ObjectNotFoundException | SecurityViolationException + | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { + // TODO Auto-generated catch block + throw new Fault(e); + } + + } - } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java index 3c7d9e7572d..a7d95636ed1 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java @@ -20,6 +20,7 @@ import org.w3c.dom.Node; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.xnode.MapXNode; import com.evolveum.midpoint.prism.xnode.RootXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.report.api.ReportPort; @@ -30,6 +31,7 @@ import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordListType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportParameterType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage; import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateAuditScriptResponseType; import com.evolveum.midpoint.xml.ns._public.report.report_3.EvaluateAuditScriptType; @@ -39,10 +41,12 @@ import com.evolveum.midpoint.xml.ns._public.report.report_3.GetFieldValueType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ParseQueryResponseType; import com.evolveum.midpoint.xml.ns._public.report.report_3.ParseQueryType; -import com.evolveum.midpoint.xml.ns._public.report.report_3.RemoteReportParameterType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ProcessReportResponseType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ProcessReportType; +import com.evolveum.midpoint.xml.ns._public.report.report_3.ReportPortType; import com.evolveum.midpoint.xml.ns._public.report.report_3.SearchObjectsResponseType; import com.evolveum.midpoint.xml.ns._public.report.report_3.SearchObjectsType; -import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; +import com.evolveum.prism.xml.ns._public.query_3.QueryType; @Service public class ReportWebServiceRaw implements Provider { @@ -114,7 +118,7 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { try { if (requestObject instanceof ParseQueryType){ ParseQueryType p = (ParseQueryType) requestObject; - String parsed = reportService.parseQuery(p.getQuery(), p.getParameters()); + QueryType parsed = reportService.parseQuery(p.getQuery(), p.getParameters()); ParseQueryResponseType pr = new ParseQueryResponseType(); pr.setParsedQuery(parsed); response = prismContext.serializeAnyDataToElement(pr, ReportPort.PARSE_QUERY_RESPONSE); @@ -138,10 +142,21 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { response = prismContext.serializeAnyDataToElement(sr, ReportPort.EVALUATE_AUDIT_SCRIPT_RESPONSE); } else if (requestObject instanceof GetFieldValueType){ GetFieldValueType g = (GetFieldValueType) requestObject; - RemoteReportParameterType param = reportService.getFieldValue(g.getParameterName(), g.getObject()); + ReportParameterType param = reportService.getFieldValue(g.getParameterName(), g.getObject()); GetFieldValueResponseType gr = new GetFieldValueResponseType(); gr.setValue(param); +// XNode valueNode = prismContext.getXnodeProcessor().serializeItemValue(param.asPrismContainerValue()); +// MapXNode paramXnode = new MapXNode(); +// paramXnode.put(new QName(SchemaConstants.NS_REPORT_WS, "value"), valueNode); +// RootXNode rootXNode = new RootXNode(ReportPort.GET_FIELD_VALUE_RESPONSE, paramXnode); +// response = prismContext.getParserDom().serializeXRootToElement(rootXNode); response = prismContext.serializeAnyDataToElement(gr, ReportPort.GET_FIELD_VALUE_RESPONSE); + } else if (requestObject instanceof ProcessReportType){ + ProcessReportType p = (ProcessReportType) requestObject; + ObjectListType olt = reportService.processReport(p.getQuery(), p.getParameters(), p.getOptions()); + ProcessReportResponseType pr = new ProcessReportResponseType(); + pr.setObjectList(olt); + response = prismContext.serializeAnyDataToElement(pr, ReportPort.PROCESS_REPORT_RESPONSE); } else { throw new FaultMessage("Unsupported request type: " + requestObject); } From b1ef5c65e8d86995cf1af114c02b282b91ad628b Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Fri, 19 Jun 2015 17:53:18 +0200 Subject: [PATCH 05/16] config for unix story test --- .../story/src/test/resources/schema/unix.xsd | 60 +++ .../test/resources/unix/resource-opendj.xml | 387 ++++++++++++++++++ 2 files changed, 447 insertions(+) create mode 100644 testing/story/src/test/resources/schema/unix.xsd create mode 100644 testing/story/src/test/resources/unix/resource-opendj.xml diff --git a/testing/story/src/test/resources/schema/unix.xsd b/testing/story/src/test/resources/schema/unix.xsd new file mode 100644 index 00000000000..d24300d0c6f --- /dev/null +++ b/testing/story/src/test/resources/schema/unix.xsd @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + true + + + + + + + diff --git a/testing/story/src/test/resources/unix/resource-opendj.xml b/testing/story/src/test/resources/unix/resource-opendj.xml new file mode 100644 index 00000000000..5465a775e6f --- /dev/null +++ b/testing/story/src/test/resources/unix/resource-opendj.xml @@ -0,0 +1,387 @@ + + + + + + + + Embedded Test OpenDJ + + + Dummy description, just for the test + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + + 10389 + localhost + dc=example,dc=com + cn=directory manager + secret + auto + entryUUID + ds-pwp-account-disabled + isMemberOf + + + + false + false + false + + + + + + + + account + default + Default Account + true + ri:inetOrgPerson + posixAccount + + ri:dn + Distinguished Name + mr:stringIgnoreCase + + + + $user/name + + + + + + + + + ri:cn + Common Name + + + $user/fullName + + + + weak + + $user/fullName + + + + + + ri:sn + + + familyName + + + + weak + + $user/familyName + + + + + + ri:givenName + + + givenName + + + + weak + + $user/givenName + + + + + + ri:uid + mr:stringIgnoreCase + + + weak + + $user/name + + + + weak + + $user/name + + + + + + ri:ldapGroup + LDAP Group Membership + entitlement + ldapGroup + objectToSubject + ri:uniqueMember + ri:dn + ri:isMemberOf + ri:dn + true + + + + ri:unixGroup + UNIX Group Membership + posixAccount + entitlement + unixGroup + objectToSubject + ri:memberUid + ri:uidNumber + true + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + uid=idm,ou=Administrators,dc=example,dc=com + + + + + + + + + + + + + + + + weak + + + + + + + + + + + entitlement + ldapGroup + LDAP Group + ri:groupOfUniqueNames + + ri:dn + mr:stringIgnoreCase + + + + $focus/name + + + + + + + + ri:cn + mr:stringIgnoreCase + + + weak + + $focus/name + + + + + ri:description + + strong + + description + + + + + + + entitlement + unixGroup + UNIX Group + ri:posixGroup + + ri:dn + mr:stringIgnoreCase + + + + $focus/name + + + + + + + + ri:cn + mr:stringIgnoreCase + + + weak + + $focus/name + + + + + ri:description + + strong + + description + + + + + ri:gidNumber + + strong + + extension/gidNumber + + + + + + + + + + + + ri:ds-pwp-account-disabled + + true + + + + + + + + ri:inetOrgPerson + true + + + c:name + + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"; + $shadow/attributes/ri:uid + + + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + From b2b0c624a992088d4029283758d24c08a3c50839 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Fri, 19 Jun 2015 17:53:33 +0200 Subject: [PATCH 06/16] Schema for auxiliary object classes in constructions and associations --- .../xml/ns/public/common/common-3.xsd | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd index afbfbf1d56e..9f666fec6f6 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd @@ -4356,6 +4356,14 @@ + + + + This association is considered valid only if the resource object (subject) + has the specified auxiliary object class. + + + @@ -7415,6 +7423,18 @@ + + + + The reference to additional type definitions for this object. These auxiliary object + classes will be added to the resource object when the construction is provisioned. + + The reference should + point to object class definition (complex type definition in resource schema) and + this definition should be marked as auxiliary. + + + From 61dba61377506d8afab3fddb021c3ca478a91200 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 22 Jun 2015 09:23:40 +0200 Subject: [PATCH 07/16] Basic aux test --- .../midpoint/testing/story/TestUnix.java | 1176 +++++++++++++++++ .../story/src/test/resources/unix/struct.ldif | 4 + 2 files changed, 1180 insertions(+) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java create mode 100644 testing/story/src/test/resources/unix/struct.ldif diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java new file mode 100644 index 00000000000..ecaefd63153 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -0,0 +1,1176 @@ +package com.evolveum.midpoint.testing.story; +/* + * Copyright (c) 2015 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import static com.evolveum.midpoint.test.IntegrationTestTools.display; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.util.Collection; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.opends.server.types.DirectoryException; +import org.opends.server.types.SearchResultEntry; +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.AfterClass; +import org.testng.annotations.Test; + +import com.evolveum.icf.dummy.resource.DummyAccount; +import com.evolveum.icf.dummy.resource.DummyObjectClass; +import com.evolveum.icf.dummy.resource.DummyResource; +import com.evolveum.icf.dummy.resource.DummySyncStyle; +import com.evolveum.midpoint.model.impl.sync.ReconciliationTaskHandler; +import com.evolveum.midpoint.model.impl.util.DebugReconciliationTaskResultListener; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.test.util.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.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +/** + * @author Radovan Semancik + * + */ +@ContextConfiguration(locations = {"classpath:ctx-story-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestUnix extends AbstractStoryTest { + + public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "unix"); + + protected static final File RESOURCE_OPENDJ_FILE = new File(TEST_DIR, "resource-opendj.xml"); + protected static final String RESOURCE_OPENDJ_OID = "10000000-0000-0000-0000-000000000003"; + protected static final String RESOURCE_OPENDJ_NAMESPACE = MidPointConstants.NS_RI; + protected static final QName OPENDJ_ASSOCIATION_LDAP_GROUP_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "ldapGroup"); + protected static final QName OPENDJ_ASSOCIATION_UNIX_GROUP_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "unixGroup"); + + public static final File ROLE_BASIC_FILE = new File(TEST_DIR, "role-basic.xml"); + public static final String ROLE_BASIC_OID = "10000000-0000-0000-0000-000000000601"; + + public static final File ROLE_META_UNIXGROUP_FILE = new File(TEST_DIR, "role-meta-unixgroup.xml"); + public static final String ROLE_META_UNIXGROUP_OID = "10000000-0000-0000-0000-000000006601"; + + private static final String ACCOUNT_HERMAN_USERNAME = "ht"; + private static final String ACCOUNT_HERMAN_FIST_NAME = "Herman"; + private static final String ACCOUNT_HERMAN_LAST_NAME = "Toothrot"; + + private static final String ACCOUNT_LEMONHEAD_USERNAME = "lemonhead"; + private static final String ACCOUNT_LEMONHEAD_FIST_NAME = "Lemonhead"; + private static final String ACCOUNT_LEMONHEAD_LAST_NAME = "Canibal"; + + private static final String ACCOUNT_SHARPTOOTH_USERNAME = "sharptooth"; + private static final String ACCOUNT_SHARPTOOTH_FIST_NAME = "Sharptooth"; + private static final String ACCOUNT_SHARPTOOTH_LAST_NAME = "Canibal"; + + private static final String ACCOUNT_REDSKULL_USERNAME = "redskull"; + private static final String ACCOUNT_REDSKULL_FIST_NAME = "Redskull"; + private static final String ACCOUNT_REDSKULL_LAST_NAME = "Canibal"; + + private static final String ACCOUNT_GUYBRUSH_USERNAME = "guybrush"; + private static final String ACCOUNT_GUYBRUSH_FIST_NAME = "Guybrush"; + private static final String ACCOUNT_GUYBRUSH_LAST_NAME = "Threepwood"; + + private static final String ACCOUNT_MANCOMB_USERNAME = "mancomb"; + private static final String ACCOUNT_MANCOMB_FIST_NAME = "Mancomb"; + private static final String ACCOUNT_MANCOMB_LAST_NAME = "Seepgood"; + + private static final String ACCOUNT_COBB_USERNAME = "cobb"; + private static final String ACCOUNT_COBB_FIST_NAME = "Cobb"; + private static final String ACCOUNT_COBB_LAST_NAME = "Loom"; + + private static final String ACCOUNT_LARGO_USERNAME = "largo"; + private static final String ACCOUNT_LARGO_FIST_NAME = "Largo"; + private static final String ACCOUNT_LARGO_LAST_NAME = "LaGrande"; + + private static final String ACCOUNT_STAN_USERNAME = "stan"; + private static final String ACCOUNT_STAN_FIST_NAME = "Stan"; + private static final String ACCOUNT_STAN_LAST_NAME = "Salesman"; + + private static final String ACCOUNT_CAPSIZE_USERNAME = "capsize"; + private static final String ACCOUNT_CAPSIZE_FIST_NAME = "Kate"; + private static final String ACCOUNT_CAPSIZE_LAST_NAME = "Capsize"; + + private static final String ACCOUNT_WALLY_USERNAME = "wally"; + private static final String ACCOUNT_WALLY_FIST_NAME = "Wally"; + private static final String ACCOUNT_WALLY_LAST_NAME = "Feed"; + + private static final String ACCOUNT_AUGUSTUS_USERNAME = "augustus"; + private static final String ACCOUNT_AUGUSTUS_FIST_NAME = "Augustus"; + private static final String ACCOUNT_AUGUSTUS_LAST_NAME = "DeWaat"; + + private static final File STRUCT_LDIF_FILE = new File(TEST_DIR, "struct.ldif"); + + @Autowired(required=true) + private ReconciliationTaskHandler reconciliationTaskHandler; + + private DebugReconciliationTaskResultListener reconciliationTaskResultListener; + + protected ResourceType resourceOpenDjType; + protected PrismObject resourceOpenDj; + + @Override + protected void startResources() throws Exception { + openDJController.startCleanServer(); + } + + @AfterClass + public static void stopResources() throws Exception { + openDJController.stop(); + } + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + + reconciliationTaskResultListener = new DebugReconciliationTaskResultListener(); + reconciliationTaskHandler.setReconciliationTaskResultListener(reconciliationTaskResultListener); + + // Resources + resourceOpenDj = importAndGetObjectFromFile(ResourceType.class, RESOURCE_OPENDJ_FILE, RESOURCE_OPENDJ_OID, initTask, initResult); + resourceOpenDjType = resourceOpenDj.asObjectable(); + openDJController.setResource(resourceOpenDj); + + // LDAP content + openDJController.addEntriesFromLdifFile(STRUCT_LDIF_FILE.getPath()); + + + // Role + importObjectFromFile(ROLE_BASIC_FILE, initResult); + } + + @Test + public void test000Sanity() throws Exception { + final String TEST_NAME = "test000Sanity"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + OperationResult testResultHr = modelService.testResource(RESOURCE_DUMMY_HR_OID, task); + TestUtil.assertSuccess(testResultHr); + + OperationResult testResultOpenDj = modelService.testResource(RESOURCE_OPENDJ_OID, task); + TestUtil.assertSuccess(testResultOpenDj); + + waitForTaskStart(TASK_TRIGGER_SCANNER_OID, true); + waitForTaskStart(TASK_VALIDITY_SCANNER_OID, true); + waitForTaskStart(TASK_LIVE_SYNC_DUMMY_HR_OID, false); + + dumpOrgTree(); + } + + /** + * First account on Monkey Island. The Monkey Island org should be created. + */ + @Test + public void test100AddHrAccountHerman() throws Exception { + final String TEST_NAME = "test100AddHrAccountHerman"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_HERMAN_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_HERMAN_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_HERMAN_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_HERMAN_USERNAME); + assertNotNull("No herman user", user); + display("User", user); + assertUserHerman(user); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + orgMonkeyIslandOid = org.getOid(); + assertAssignedOrg(user, org.getOid()); + assertHasOrg(user, org.getOid()); + assertHasOrg(org, ORG_TOP_OID); + + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Second account on Monkey Island. The existing org should be reused. + */ + @Test + public void test105AddHrAccountLemonhead() throws Exception { + final String TEST_NAME = "test105AddHrAccountLemonhead"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_LEMONHEAD_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_LEMONHEAD_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_LEMONHEAD_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_LEMONHEAD_USERNAME); + assertNotNull("No lemonhead user", user); + display("User", user); + assertUser(user, ACCOUNT_LEMONHEAD_USERNAME, ACCOUNT_LEMONHEAD_FIST_NAME, ACCOUNT_LEMONHEAD_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + assertAssignedOrg(user, org.getOid()); + assertHasOrg(user, org.getOid()); + assertHasOrg(org, ORG_TOP_OID); + + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + + assertBasicRoleAndResources(user); + roleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); + assertAssignments(user, 3); + } + + /** + * Yet another canibal. Same org, same responsibility. Make sure everything is reused and not created again. + */ + @Test + public void test106AddHrAccountSharptooth() throws Exception { + final String TEST_NAME = "test106AddHrAccountSharptooth"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_SHARPTOOTH_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_SHARPTOOTH_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_SHARPTOOTH_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_SHARPTOOTH_USERNAME); + assertNotNull("No sharptooth user", user); + display("User", user); + assertUser(user, ACCOUNT_SHARPTOOTH_USERNAME, ACCOUNT_SHARPTOOTH_FIST_NAME, ACCOUNT_SHARPTOOTH_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + assertAssignedOrg(user, org.getOid()); + assertHasOrg(user, org.getOid()); + assertHasOrg(org, ORG_TOP_OID); + assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertBasicRoleAndResources(user); + String thisRoleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); + assertEquals("Canibalism role OID has changed", roleCanibalismOid, thisRoleCanibalismOid); + assertAssignments(user, 3); + } + + /** + * Yet another canibal to play with. + */ + @Test + public void test107AddHrAccountRedskull() throws Exception { + final String TEST_NAME = "test107AddHrAccountRedskull"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_REDSKULL_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_REDSKULL_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_REDSKULL_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); + assertNotNull("No redskull user", user); + display("User", user); + assertUser(user, ACCOUNT_REDSKULL_USERNAME, ACCOUNT_REDSKULL_FIST_NAME, ACCOUNT_REDSKULL_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + assertAssignedOrg(user, org.getOid()); + assertHasOrg(user, org.getOid()); + assertHasOrg(org, ORG_TOP_OID); + assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertBasicRoleAndResources(user); + String thisRoleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); + assertEquals("Canibalism role OID has changed", roleCanibalismOid, thisRoleCanibalismOid); + assertAssignments(user, 3); + } + + /** + * Remove "canibalism" responsibility from redskull. + */ + @Test + public void test108RedskullGoesVegeratian() throws Exception { + final String TEST_NAME = "test108RedskullGoesVegeratian"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount account = dummyResourceHr.getAccountByUsername(ACCOUNT_REDSKULL_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + account.removeAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + TestUtil.displayThen(TEST_NAME); + PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); + assertNotNull("No redskull user", user); + display("User", user); + assertUser(user, ACCOUNT_REDSKULL_USERNAME, ACCOUNT_REDSKULL_FIST_NAME, ACCOUNT_REDSKULL_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + assertAssignedOrg(user, org.getOid()); + assertHasOrg(user, org.getOid()); + assertHasOrg(org, ORG_TOP_OID); + + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + + assertBasicRoleAndResources(user); + roleCanibalismOid = assertNoResponsibility(user, RESP_CANIBALISM); + assertAssignments(user, 2); + } + + /** + * Vegetarian cannibal? Not really! + */ + @Test + public void test109HrDeleteRedskull() throws Exception { + final String TEST_NAME = "test109HrDeleteRedskull"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + dummyResourceHr.deleteAccountByName(ACCOUNT_REDSKULL_USERNAME); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + TestUtil.displayThen(TEST_NAME); + PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); + display("User", user); + assertNull("Redskull user not gone", user); + + dumpOrgTree(); + + PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); + assertHasOrg(org, ORG_TOP_OID); + assertSubOrgs(org,0); + assertSubOrgs(ORG_TOP_OID,1); + + assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + } + + /** + * Two-level orgpath. Both orgs should be created. + */ + @Test + public void test110AddHrAccountGuybrush() throws Exception { + final String TEST_NAME = "test110AddHrAccountGuybrush"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_GUYBRUSH_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_GUYBRUSH_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_GUYBRUSH_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_FREELANCE); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_GUYBRUSH_USERNAME); + assertNotNull("No guybrush user", user); + display("User", user); + assertUserGuybrush(user); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgFreelance = getAndAssertReplicatedOrg("Freelance"); + PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); + orgMoROid = orgMoR.getOid(); + + assertAssignedOrg(user, orgFreelance.getOid()); + assertHasOrg(user, orgFreelance.getOid()); + assertHasOrg(orgFreelance, orgMoR.getOid()); + assertHasOrg(orgMoR, ORG_TOP_OID); + + assertSubOrgs(orgFreelance,0); + assertSubOrgs(orgMoR,1); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,2); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Two-level orgpath, partially created. Only scumm bar should be crated. Ministry should be reused. + */ + @Test + public void test115AddHrAccountMancomb() throws Exception { + final String TEST_NAME = "test115AddHrAccountMancomb"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_MANCOMB_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_MANCOMB_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_MANCOMB_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_MANCOMB_USERNAME); + assertNotNull("No mancomb user", user); + display("User", user); + assertUser(user, ACCOUNT_MANCOMB_USERNAME, ACCOUNT_MANCOMB_FIST_NAME, ACCOUNT_MANCOMB_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); + orgScummBarOid = orgScummBar.getOid(); + PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); + + assertAssignedOrg(user, orgScummBar.getOid()); + assertHasOrg(user, orgScummBar.getOid()); + assertHasOrg(orgScummBar, orgMoR.getOid()); + assertHasOrg(orgMoR, ORG_TOP_OID); + + assertSubOrgs(orgScummBar,0); + assertSubOrgs(orgMoR,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,2); + + assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Two-level orgpath, completely created. No new orgs should be created. + */ + @Test + public void test117AddHrAccountCobb() throws Exception { + final String TEST_NAME = "test117AddHrAccountCobb"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_COBB_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_COBB_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_COBB_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_COBB_USERNAME); + assertNotNull("No cobb user", user); + display("User", user); + assertUser(user, ACCOUNT_COBB_USERNAME, ACCOUNT_COBB_FIST_NAME, ACCOUNT_COBB_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); + PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); + + assertAssignedOrg(user, orgScummBar.getOid()); + assertHasOrg(user, orgScummBar.getOid()); + assertHasOrg(orgScummBar, orgMoR.getOid()); + assertHasOrg(orgMoR, ORG_TOP_OID); + + assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); + assertEquals("Scumm bar Org OID has changed", orgScummBarOid, orgScummBar.getOid()); + + assertSubOrgs(orgScummBar,0); + assertSubOrgs(orgMoR,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,2); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Four-level orgpath, completely new. + */ + @Test + public void test130AddHrAccountLargo() throws Exception { + final String TEST_NAME = "test130AddHrAccountLargo"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_LARGO_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_LARGO_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_LARGO_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_BRUTE); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_LARGO_USERNAME); + assertNotNull("No largo user", user); + display("User", user); + assertUser(user, ACCOUNT_LARGO_USERNAME, ACCOUNT_LARGO_FIST_NAME, ACCOUNT_LARGO_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgMoO = getAndAssertReplicatedOrg("Ministry of Offense"); + PrismObject orgDoM = getAndAssertReplicatedOrg("Department of Mischief"); + PrismObject orgVSec = getAndAssertReplicatedOrg("Violence Section"); + PrismObject orgBOff = getAndAssertReplicatedOrg("Brute Office"); + + assertAssignedOrg(user, orgBOff.getOid()); + assertHasOrg(user, orgBOff.getOid()); + assertHasOrg(orgBOff, orgVSec.getOid()); + assertHasOrg(orgVSec, orgDoM.getOid()); + assertHasOrg(orgDoM, orgMoO.getOid()); + assertHasOrg(orgMoO, ORG_TOP_OID); + + assertSubOrgs(orgBOff,0); + assertSubOrgs(orgVSec,1); + assertSubOrgs(orgDoM,1); + assertSubOrgs(orgMoO,1); + assertSubOrgs(orgScummBarOid,0); + assertSubOrgs(orgMoROid,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,3); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Two-level orgpath, upper org is only as ou in LDAP, it is not in midpoint. + */ + @Test + public void test140AddHrAccountWally() throws Exception { + final String TEST_NAME = "test140AddHrAccountWally"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_WALLY_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_WALLY_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_WALLY_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_CARTOGRAPHY); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_WALLY_USERNAME); + assertNotNull("No cobb user", user); + display("User", user); + assertUser(user, ACCOUNT_WALLY_USERNAME, ACCOUNT_WALLY_FIST_NAME, ACCOUNT_WALLY_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgCartography = getAndAssertReplicatedOrg("Cartography"); + PrismObject orgScabb = getAndAssertReplicatedOrg(ORGPATH_SCABB_ISLAND); + + assertAssignedOrg(user, orgCartography.getOid()); + assertHasOrg(user, orgCartography.getOid()); + assertHasOrg(orgCartography, orgScabb.getOid()); + assertHasOrg(orgScabb, ORG_TOP_OID); + + assertSubOrgs(orgCartography,0); + assertSubOrgs(orgScabb,1); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,4); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Two-level orgpath, both orgs are only as ou in LDAP, not in midpoint. + */ + @Test + public void test142AddHrAccountAugustus() throws Exception { + final String TEST_NAME = "test142AddHrAccountAugustus"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_AUGUSTUS_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_AUGUSTUS_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_AUGUSTUS_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_BOOTY_ISLAND_LOOKOUT); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_AUGUSTUS_USERNAME); + assertNotNull("No cobb user", user); + display("User", user); + assertUser(user, ACCOUNT_AUGUSTUS_USERNAME, ACCOUNT_AUGUSTUS_FIST_NAME, ACCOUNT_AUGUSTUS_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgLookout = getAndAssertReplicatedOrg("Lookout"); + PrismObject orgBooty = getAndAssertReplicatedOrg(ORGPATH_BOOTY_ISLAND); + + assertAssignedOrg(user, orgLookout.getOid()); + assertHasOrg(user, orgLookout.getOid()); + assertHasOrg(orgLookout, orgBooty.getOid()); + assertHasOrg(orgBooty, ORG_TOP_OID); + + assertSubOrgs(orgLookout,0); + assertSubOrgs(orgBooty,1); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,5); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Some national characters there. + */ + @Test + public void test185AddHrAccountStan() throws Exception { + final String TEST_NAME = "test185AddHrAccountStan"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_STAN_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_STAN_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_STAN_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_DOCKS); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_STAN_USERNAME); + assertNotNull("No largo user", user); + display("User", user); + assertUser(user, ACCOUNT_STAN_USERNAME, ACCOUNT_STAN_FIST_NAME, ACCOUNT_STAN_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgDocks = getAndAssertReplicatedOrg("Docks"); + PrismObject orgMelee = getAndAssertReplicatedOrg(ORGPATH_MELEE_ISLAND); + + assertAssignedOrg(user, orgDocks.getOid()); + assertHasOrg(user, orgDocks.getOid()); + assertHasOrg(orgDocks, orgMelee.getOid()); + assertHasOrg(orgMelee, ORG_TOP_OID); + + assertSubOrgs(orgDocks,0); + assertSubOrgs(orgMelee,1); + assertSubOrgs(orgScummBarOid,0); + assertSubOrgs(orgMoROid,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,6); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Commas in the org structure. + */ + @Test + public void test186AddHrAccountCapsize() throws Exception { + final String TEST_NAME = "test186AddHrAccountCapsize"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_CAPSIZE_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_CAPSIZE_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_CAPSIZE_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_CAPSIZE); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_CAPSIZE_USERNAME); + assertNotNull("No largo user", user); + display("User", user); + assertUser(user, ACCOUNT_CAPSIZE_USERNAME, ACCOUNT_CAPSIZE_FIST_NAME, ACCOUNT_CAPSIZE_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgCapsize = getAndAssertReplicatedOrg("Cruises, Charter and Capsize"); + PrismObject orgTour = getAndAssertReplicatedOrg("Tourist Industries, Tri-Island Area"); + + assertAssignedOrg(user, orgCapsize.getOid()); + assertHasOrg(user, orgCapsize.getOid()); + assertHasOrg(orgCapsize, orgTour.getOid()); + assertHasOrg(orgTour, ORG_TOP_OID); + + assertSubOrgs(orgCapsize,0); + assertSubOrgs(orgTour,1); + assertSubOrgs(orgScummBarOid,0); + assertSubOrgs(orgMoROid,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,7); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Comma in username + */ + @Test + public void test187AddHrAccountRogersSr() throws Exception { + final String TEST_NAME = "test187AddHrAccountRogersSr"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_ROGERSSR_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_ROGERSSR_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_ROGERSSR_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_ROGERSSR_USERNAME); + assertNotNull("No largo user", user); + display("User", user); + assertUser(user, ACCOUNT_ROGERSSR_USERNAME, ACCOUNT_ROGERSSR_FIST_NAME, ACCOUNT_ROGERSSR_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); + PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); + + assertAssignedOrg(user, orgScummBar.getOid()); + assertHasOrg(user, orgScummBar.getOid()); + assertHasOrg(orgScummBar, orgMoR.getOid()); + assertHasOrg(orgMoR, ORG_TOP_OID); + + assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); + assertEquals("Scumm bar Org OID has changed", orgScummBarOid, orgScummBar.getOid()); + + assertSubOrgs(orgScummBarOid,0); + assertSubOrgs(orgMoROid,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,7); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + /** + * Lot of national characters here. + */ + @Test + public void test190AddHrAccountTeleke() throws Exception { + final String TEST_NAME = "test190AddHrAccountTeleke"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + + DummyAccount newAccount = new DummyAccount(ACCOUNT_TELEKE_USERNAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_TELEKE_FIST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_TELEKE_LAST_NAME); + newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_HRAD); + + // WHEN + dummyResourceHr.addAccount(newAccount); + waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + + // THEN + PrismObject user = findUserByUsername(ACCOUNT_TELEKE_USERNAME); + assertNotNull("No largo user", user); + display("User", user); + assertUser(user, ACCOUNT_TELEKE_USERNAME, ACCOUNT_TELEKE_FIST_NAME, ACCOUNT_TELEKE_LAST_NAME); + assertAccount(user, RESOURCE_DUMMY_HR_OID); + + dumpOrgTree(); + + PrismObject orgHrad = getAndAssertReplicatedOrg(HRAD); + PrismObject orgKarpatula = getAndAssertReplicatedOrg(ORGPATH_KARPATULA); + + assertAssignedOrg(user, orgHrad.getOid()); + assertHasOrg(user, orgHrad.getOid()); + assertHasOrg(orgHrad, orgKarpatula.getOid()); + assertHasOrg(orgKarpatula, ORG_TOP_OID); + + assertSubOrgs(orgHrad,0); + assertSubOrgs(orgKarpatula,1); + assertSubOrgs(orgScummBarOid,0); + assertSubOrgs(orgMoROid,2); + assertSubOrgs(orgMonkeyIslandOid,0); + assertSubOrgs(ORG_TOP_OID,8); + + assertBasicRoleAndResources(user); + assertAssignments(user, 2); + } + + + @Test + public void test500ReconcileOpenDJDefault() throws Exception { + final String TEST_NAME = "test500ReconcileOpenDJDefault"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); + + List> users = modelService.searchObjects(UserType.class, null, null, task, result); + display("Users before recon", users); + assertUsers(15); + + reconciliationTaskResultListener.clear(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + importObjectFromFile(TASK_RECON_OPENDJ_DEFAULT_SINGLE_FILE); + + // THEN + TestUtil.displayThen(TEST_NAME); + + waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); + + // THEN + TestUtil.displayThen(TEST_NAME); + + reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 17, 0, 0); + + users = modelService.searchObjects(UserType.class, null, null, task, result); + display("Users after recon", users); + + assertUsers(18); + + // Task result + PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); + OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); + display("Recon task result", reconTaskResult); + TestUtil.assertSuccess(reconTaskResult); + } + + @Test + public void test502ReconcileOpenDJDefaultAgain() throws Exception { + final String TEST_NAME = "test502ReconcileOpenDJDefaultAgain"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); + + assertUsers(18); + reconciliationTaskResultListener.clear(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + restartTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + + waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); + + // THEN + TestUtil.displayThen(TEST_NAME); + + reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 17, 0, 0); + + assertUsers(18); + + // Task result + PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); + OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); + display("Recon task result", reconTaskResult); + TestUtil.assertSuccess(reconTaskResult); + } + + @Test + public void test510ReconcileOpenDJLdapGroup() throws Exception { + final String TEST_NAME = "test510ReconcileOpenDJLdapGroup"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); + + List> users = modelService.searchObjects(UserType.class, null, null, task, result); + display("Users before recon", users); + assertUsers(18); + + reconciliationTaskResultListener.clear(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + importObjectFromFile(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_FILE); + + // THEN + TestUtil.displayThen(TEST_NAME); + + waitForTaskFinish(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_OID, false); + + // THEN + TestUtil.displayThen(TEST_NAME); + + reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 2, 0, 0); + + users = modelService.searchObjects(UserType.class, null, null, task, result); + display("Users after recon", users); + + assertUsers(18); + + // Task result + PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_OID); + OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); + display("Recon task result", reconTaskResult); + TestUtil.assertSuccess(reconTaskResult); + } + + @Test + public void test550ReconcileOpenDJAfterMembershipChange() throws Exception { + final String TEST_NAME = "test550ReconcileOpenDJAfterMembershipChange"; + TestUtil.displayTestTile(this, TEST_NAME); + + // We manually remove Lemonhead from R_canibalism group + // And check whether reconciliation re-adds him again + + // GIVEN + Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); + + Collection membersBeforeTest = openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN); + System.out.println("group members before test = " + membersBeforeTest); + assertTrue(RESP_CANIBALISM_DN + " does not contain " + ACCOUNT_LEMONHEAD_DN, membersBeforeTest.contains(ACCOUNT_LEMONHEAD_DN)); + + openDJController.removeGroupUniqueMember(RESP_CANIBALISM_DN, ACCOUNT_LEMONHEAD_DN); + + System.out.println("group members after removal = " + openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN)); + + openDJController.assertNoUniqueMember(RESP_CANIBALISM_DN, ACCOUNT_LEMONHEAD_DN); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + restartTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + + waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); + + // THEN + TestUtil.displayThen(TEST_NAME); + + // Task result + PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); + OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); + display("Recon task result", reconTaskResult); + TestUtil.assertSuccess(reconTaskResult); + + Collection membersAfterTest = openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN); + System.out.println("group members after test = " + membersAfterTest); + assertTrue(RESP_CANIBALISM_DN + " does not contain " + ACCOUNT_LEMONHEAD_DN, membersAfterTest.contains(ACCOUNT_LEMONHEAD_DN.toLowerCase())); // ...it seems to get lowercased during the reconciliation + } + + + protected void assertUserGuybrush(PrismObject user) { + assertUser(user, ACCOUNT_GUYBRUSH_USERNAME, ACCOUNT_GUYBRUSH_FIST_NAME, ACCOUNT_GUYBRUSH_LAST_NAME); + } + + protected void assertUserHerman(PrismObject user) { + assertUser(user, ACCOUNT_HERMAN_USERNAME, ACCOUNT_HERMAN_FIST_NAME, ACCOUNT_HERMAN_LAST_NAME); + } + + protected void assertUser(PrismObject user, String username, String firstName, String lastName) { + assertUser(user, user.getOid(), username, firstName + " " + lastName, + firstName, lastName); + } + + private PrismObject getAndAssertReplicatedOrg(String orgName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { + PrismObject org = getOrg(orgName); + PrismAsserts.assertPropertyValue(org, OrgType.F_ORG_TYPE, "replicated"); + assertAssignedRole(org, ROLE_META_REPLICATED_ORG_OID); + PrismReferenceValue linkRef = getSingleLinkRef(org); + // We are bold enough to get the whole shadow + PrismObject shadow = getShadowModel(linkRef.getOid()); + display("Org "+orgName+" shadow", shadow); + // TODO assert shadow content + + SearchResultEntry ouEntry = openDJController.searchSingle("ou="+orgName); + assertNotNull("No ou LDAP entry for "+orgName); + display("OU entry", ouEntry); + openDJController.assertObjectClass(ouEntry, "organizationalUnit"); + + return org; + } + + private PrismObject getOrg(String orgName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { + PrismObject org = findObjectByName(OrgType.class, orgName); + assertNotNull("The org "+orgName+" is missing!", org); + display("Org "+orgName, org); + PrismAsserts.assertPropertyValue(org, OrgType.F_NAME, PrismTestUtil.createPolyString(orgName)); + return org; + } + + private void assertBasicRoleAndResources(PrismObject user) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { + assertAssignedRole(user, ROLE_BASIC_OID); + PrismReferenceValue linkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); + PrismObject shadow = getShadowModel(linkRef.getOid()); + display("OpenDJ shadow linked to "+user, shadow); + // TODO assert shadow content + } + + private String assertResponsibility(PrismObject user, String respName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { + String respRoleName = "R_"+respName; + PrismObject respRole = searchObjectByName(RoleType.class, respRoleName); + assertNotNull("No role for responsibility "+respName); + display("Responsibility role for "+respName, respRole); + assertAssignedRole(user, respRole.getOid()); + + PrismReferenceValue linkRef = getSingleLinkRef(respRole); + PrismObject shadow = getShadowModel(linkRef.getOid()); + display("Role "+respRoleName+" shadow", shadow); + // TODO assert shadow content + + String groupDn = "cn="+respRoleName+",ou=groups,"+openDJController.getSuffix(); + SearchResultEntry groupEntry = openDJController.fetchAndAssertEntry(groupDn, "groupOfUniqueNames"); + display("Group entry", groupEntry); + + PrismReferenceValue accountLinkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); + PrismObject accountShadow = getShadowModel(accountLinkRef.getOid()); + String accountDn = IntegrationTestTools.getSecondaryIdentifier(accountShadow); + openDJController.assertUniqueMember(groupEntry, accountDn); + + IntegrationTestTools.assertAssociation(accountShadow, OPENDJ_ASSOCIATION_GROUP_NAME, shadow.getOid()); + + return respRole.getOid(); + } + + private String assertNoResponsibility(PrismObject user, String respName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { + String respRoleName = "R_"+respName; + PrismObject respRole = searchObjectByName(RoleType.class, respRoleName); + assertNotNull("No role for responsibility "+respName); + display("Responsibility role for "+respName, respRole); + assertNotAssignedRole(user, respRole.getOid()); + + PrismReferenceValue linkRef = getSingleLinkRef(respRole); + PrismObject shadow = getShadowModel(linkRef.getOid()); + display("Role "+respRoleName+" shadow", shadow); + // TODO assert shadow content + + String groupDn = "cn="+respRoleName+",ou=groups,"+openDJController.getSuffix(); + SearchResultEntry groupEntry = openDJController.fetchAndAssertEntry(groupDn, "groupOfUniqueNames"); + display("Group entry", groupEntry); + + PrismReferenceValue accountLinkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); + PrismObject accountShadow = getShadowModel(accountLinkRef.getOid()); + String accountDn = IntegrationTestTools.getSecondaryIdentifier(accountShadow); + openDJController.assertNoUniqueMember(groupEntry, accountDn); + + IntegrationTestTools.assertNoAssociation(accountShadow, OPENDJ_ASSOCIATION_GROUP_NAME, shadow.getOid()); + + return respRole.getOid(); + } + + private void dumpOrgTree() throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { + display("Org tree", dumpOrgTree(ORG_TOP_OID)); + } + + +} diff --git a/testing/story/src/test/resources/unix/struct.ldif b/testing/story/src/test/resources/unix/struct.ldif new file mode 100644 index 00000000000..7d98c3dd0c6 --- /dev/null +++ b/testing/story/src/test/resources/unix/struct.ldif @@ -0,0 +1,4 @@ +dn: ou=unixgroups,dc=example,dc=com +ou: unixgroups +objectclass: top +objectclass: organizationalUnit \ No newline at end of file From f4511d96787b233689dff400e04a988cf7d19a0a Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 22 Jun 2015 19:50:29 +0200 Subject: [PATCH 08/16] More work on aux object class test. Fixing some provisioning and common issues. --- .../RefinedAssociationDefinition.java | 8 +- .../RefinedObjectClassDefinition.java | 21 +- .../refinery/RefinedResourceSchema.java | 14 +- .../midpoint/test/ldap/OpenDJController.java | 6 + .../test/AbstractModelIntegrationTest.java | 19 + .../impl/EntitlementConverter.java | 6 + .../midpoint/testing/story/TestUnix.java | 1068 ++--------------- .../story/src/test/resources/schema/unix.xsd | 2 +- .../test/resources/unix/resource-opendj.xml | 17 +- .../src/test/resources/unix/role-basic.xml | 32 + .../src/test/resources/unix/role-unix.xml | 33 + tools/test-ng/.gitignore | 1 + 12 files changed, 264 insertions(+), 963 deletions(-) create mode 100644 testing/story/src/test/resources/unix/role-basic.xml create mode 100644 testing/story/src/test/resources/unix/role-unix.xml diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java index dead3e65060..c2a0ad25adb 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Evolveum + * Copyright (c) 2014-2015 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,12 @@ public ShadowKindType getKind() { public Collection getIntents() { return resourceObjectAssociationType.getIntent(); } + + public QName getAuxiliaryObjectClass() { + return resourceObjectAssociationType.getAuxiliaryObjectClass(); + } - public MappingType getOutboundMappingType() { + public MappingType getOutboundMappingType() { return resourceObjectAssociationType.getOutbound(); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index 91af0b686bf..a0ef7fef30d 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -253,6 +253,18 @@ public Collection getNamesOfAssociationsWithOutboundExpressions public Collection getAuxiliaryObjectClassDefinitions() { return auxiliaryObjectClassDefinitions; } + + public boolean hasAuxiliaryObjectClass(QName expectedObjectClassName) { + if (auxiliaryObjectClassDefinitions == null) { + return false; + } + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + if (auxiliaryObjectClassDefinition.getTypeName().equals(expectedObjectClassName)) { + return true; + } + } + return false; + } public Collection getProtectedObjectPatterns() { if (protectedObjectPatterns == null) { @@ -500,9 +512,6 @@ static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefini RefinedObjectClassDefinition rOcDef = new RefinedObjectClassDefinition(prismContext, resourceType, objectClassDef); String intent = objectClassDef.getIntent(); - if (intent == null) { - intent = SchemaConstants.INTENT_DEFAULT; - } rOcDef.setIntent(intent); if (objectClassDef.getDisplayName() != null) { @@ -613,6 +622,9 @@ private static RefinedObjectClassDefinition parseRefinedObjectClass(ResourceObje } public void parseAssociations(RefinedResourceSchema rSchema) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + return; + } for (ResourceObjectAssociationType resourceObjectAssociationType: schemaHandlingObjectTypeDefinitionType.getAssociation()) { RefinedAssociationDefinition rAssocDef = new RefinedAssociationDefinition(resourceObjectAssociationType); ShadowKindType assocKind = rAssocDef.getKind(); @@ -623,6 +635,9 @@ public void parseAssociations(RefinedResourceSchema rSchema) throws SchemaExcept } public void parseAuxiliaryObjectClasses(RefinedResourceSchema rSchema) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + return; + } List auxiliaryObjectClassQNames = schemaHandlingObjectTypeDefinitionType.getAuxiliaryObjectClass(); auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index e16e3ef2918..3c9d9caea2f 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -405,6 +405,13 @@ public static RefinedResourceSchema parse(ResourceType resourceType, PrismContex parseObjectTypesFromSchema(rSchema, resourceType, prismContext, "definition of "+resourceType); + // We need to parse associations and auxiliary object classes in a second pass. We need to have all object classes parsed before correctly setting association + // targets + for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { + rOcDef.parseAssociations(rSchema); + rOcDef.parseAuxiliaryObjectClasses(rSchema); + } + return rSchema; } @@ -442,13 +449,6 @@ private static void parseObjectTypeDefsFromSchemaHandling(RefinedResourceSchema rSchema.add(rOcDef); } - - // We need to parse associations and auxiliary object classes in a second pass. We need to have all object classes parsed before correctly setting association - // targets - for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { - rOcDef.parseAssociations(rSchema); - rOcDef.parseAuxiliaryObjectClasses(rSchema); - } } private static void parseObjectTypesFromSchema(RefinedResourceSchema rSchema, ResourceType resourceType, diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java index 76a5019e5e4..637257b73a8 100755 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java @@ -569,6 +569,12 @@ public static void assertObjectClass(SearchResultEntry response, String expected AssertJUnit.assertTrue("Wrong objectclass for entry "+getDn(response)+", expected "+expected+" but got "+objectClassValues, objectClassValues.contains(expected)); } + + public static void assertNoObjectClass(SearchResultEntry response, String unexpected) throws DirectoryException { + Collection objectClassValues = getAttributeValues(response, "objectClass"); + AssertJUnit.assertFalse("Unexpected objectclass for entry "+getDn(response)+": "+unexpected+", got "+objectClassValues, + objectClassValues.contains(unexpected)); + } public void assertUniqueMember(SearchResultEntry groupEntry, String accountDn) throws DirectoryException { Collection members = getAttributeValues(groupEntry, "uniqueMember"); diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 6a65deac217..043c149f84b 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -1497,6 +1497,25 @@ protected PrismObject createUser(String name, String fullName, Boolean return user; } + protected PrismObject createUser(String name, String givenName, String familyName, Boolean enabled) throws SchemaException { + PrismObject user = getUserDefinition().instantiate(); + UserType userType = user.asObjectable(); + userType.setName(PrismTestUtil.createPolyStringType(name)); + userType.setGivenName(PrismTestUtil.createPolyStringType(givenName)); + userType.setFamilyName(PrismTestUtil.createPolyStringType(familyName)); + userType.setFullName(PrismTestUtil.createPolyStringType(givenName + " " + familyName)); + if (enabled != null) { + ActivationType activation = new ActivationType(); + userType.setActivation(activation); + if (enabled) { + activation.setAdministrativeStatus(ActivationStatusType.ENABLED); + } else { + activation.setAdministrativeStatus(ActivationStatusType.DISABLED); + } + } + return user; + } + protected void fillinUser(PrismObject user, String name, String fullName) { user.asObjectable().setName(PrismTestUtil.createPolyStringType(name)); user.asObjectable().setFullName(PrismTestUtil.createPolyStringType(fullName)); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java index 96c751c9274..f282ab3f3ce 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java @@ -213,6 +213,12 @@ private void postProcessEntitlementEntitlementToSubject throw new SchemaException("No name in entitlement association "+assocDefType+" in "+resourceType); } + QName associationAuxiliaryObjectClass = assocDefType.getAuxiliaryObjectClass(); + if (associationAuxiliaryObjectClass != null && !subjectCtx.getObjectClassDefinition().hasAuxiliaryObjectClass(associationAuxiliaryObjectClass)) { + LOGGER.trace("Ignoring association {} because subject does not have auxiliary object class {}", associationName, associationAuxiliaryObjectClass); + return; + } + QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute(); if (assocAttrName == null) { throw new SchemaException("No association attribute defined in entitlement association '"+associationName+"' in "+resourceType); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index ecaefd63153..5b71214664b 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -41,25 +41,35 @@ import com.evolveum.icf.dummy.resource.DummyObjectClass; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.DummySyncStyle; +import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.sync.ReconciliationTaskHandler; import com.evolveum.midpoint.model.impl.util.DebugReconciliationTaskResultListener; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceSchema; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; @@ -78,21 +88,37 @@ public class TestUnix extends AbstractStoryTest { public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "unix"); + protected static final String EXTENSION_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/story/unix/ext"; + protected static final QName EXTENSION_UID_NUMBER_NAME = new QName(EXTENSION_NAMESPACE, "uidNumber"); + protected static final QName EXTENSION_GID_NUMBER_NAME = new QName(EXTENSION_NAMESPACE, "gidNumber"); + protected static final File RESOURCE_OPENDJ_FILE = new File(TEST_DIR, "resource-opendj.xml"); protected static final String RESOURCE_OPENDJ_OID = "10000000-0000-0000-0000-000000000003"; protected static final String RESOURCE_OPENDJ_NAMESPACE = MidPointConstants.NS_RI; + protected static final QName OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "inetOrgPerson"); + protected static final QName OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "posixAccount"); + protected static final QName OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "posixGroup"); protected static final QName OPENDJ_ASSOCIATION_LDAP_GROUP_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "ldapGroup"); protected static final QName OPENDJ_ASSOCIATION_UNIX_GROUP_NAME = new QName(RESOURCE_OPENDJ_NAMESPACE, "unixGroup"); public static final File ROLE_BASIC_FILE = new File(TEST_DIR, "role-basic.xml"); public static final String ROLE_BASIC_OID = "10000000-0000-0000-0000-000000000601"; - + + public static final File ROLE_UNIX_FILE = new File(TEST_DIR, "role-unix.xml"); + public static final String ROLE_UNIX_OID = "744a54f8-18e5-11e5-808f-001e8c717e5b"; + public static final File ROLE_META_UNIXGROUP_FILE = new File(TEST_DIR, "role-meta-unixgroup.xml"); public static final String ROLE_META_UNIXGROUP_OID = "10000000-0000-0000-0000-000000006601"; - private static final String ACCOUNT_HERMAN_USERNAME = "ht"; - private static final String ACCOUNT_HERMAN_FIST_NAME = "Herman"; - private static final String ACCOUNT_HERMAN_LAST_NAME = "Toothrot"; + private static final String USER_HERMAN_USERNAME = "ht"; + private static final String USER_HERMAN_FIST_NAME = "Herman"; + private static final String USER_HERMAN_LAST_NAME = "Toothrot"; + + private static final String USER_MANCOMB_USERNAME = "mancomb"; + private static final String USER_MANCOMB_FIST_NAME = "Mancomb"; + private static final String USER_MANCOMB_LAST_NAME = "Seepgood"; + + private static final String ACCOUNT_LEMONHEAD_USERNAME = "lemonhead"; private static final String ACCOUNT_LEMONHEAD_FIST_NAME = "Lemonhead"; @@ -110,9 +136,6 @@ public class TestUnix extends AbstractStoryTest { private static final String ACCOUNT_GUYBRUSH_FIST_NAME = "Guybrush"; private static final String ACCOUNT_GUYBRUSH_LAST_NAME = "Threepwood"; - private static final String ACCOUNT_MANCOMB_USERNAME = "mancomb"; - private static final String ACCOUNT_MANCOMB_FIST_NAME = "Mancomb"; - private static final String ACCOUNT_MANCOMB_LAST_NAME = "Seepgood"; private static final String ACCOUNT_COBB_USERNAME = "cobb"; private static final String ACCOUNT_COBB_FIST_NAME = "Cobb"; @@ -176,6 +199,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti // Role importObjectFromFile(ROLE_BASIC_FILE, initResult); + importObjectFromFile(ROLE_UNIX_FILE, initResult); } @Test @@ -184,897 +208,124 @@ public void test000Sanity() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - OperationResult testResultHr = modelService.testResource(RESOURCE_DUMMY_HR_OID, task); - TestUtil.assertSuccess(testResultHr); - OperationResult testResultOpenDj = modelService.testResource(RESOURCE_OPENDJ_OID, task); TestUtil.assertSuccess(testResultOpenDj); waitForTaskStart(TASK_TRIGGER_SCANNER_OID, true); waitForTaskStart(TASK_VALIDITY_SCANNER_OID, true); - waitForTaskStart(TASK_LIVE_SYNC_DUMMY_HR_OID, false); - - dumpOrgTree(); - } - - /** - * First account on Monkey Island. The Monkey Island org should be created. - */ - @Test - public void test100AddHrAccountHerman() throws Exception { - final String TEST_NAME = "test100AddHrAccountHerman"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_HERMAN_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_HERMAN_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_HERMAN_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_HERMAN_USERNAME); - assertNotNull("No herman user", user); - display("User", user); - assertUserHerman(user); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - orgMonkeyIslandOid = org.getOid(); - assertAssignedOrg(user, org.getOid()); - assertHasOrg(user, org.getOid()); - assertHasOrg(org, ORG_TOP_OID); - - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); } - /** - * Second account on Monkey Island. The existing org should be reused. - */ @Test - public void test105AddHrAccountLemonhead() throws Exception { - final String TEST_NAME = "test105AddHrAccountLemonhead"; + public void test010Schema() throws Exception { + final String TEST_NAME = "test010Schema"; TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_LEMONHEAD_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_LEMONHEAD_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_LEMONHEAD_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_LEMONHEAD_USERNAME); - assertNotNull("No lemonhead user", user); - display("User", user); - assertUser(user, ACCOUNT_LEMONHEAD_USERNAME, ACCOUNT_LEMONHEAD_FIST_NAME, ACCOUNT_LEMONHEAD_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - dumpOrgTree(); - - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - assertAssignedOrg(user, org.getOid()); - assertHasOrg(user, org.getOid()); - assertHasOrg(org, ORG_TOP_OID); - - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); - - assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); - - assertBasicRoleAndResources(user); - roleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); - assertAssignments(user, 3); - } - - /** - * Yet another canibal. Same org, same responsibility. Make sure everything is reused and not created again. - */ - @Test - public void test106AddHrAccountSharptooth() throws Exception { - final String TEST_NAME = "test106AddHrAccountSharptooth"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_SHARPTOOTH_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_SHARPTOOTH_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_SHARPTOOTH_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_SHARPTOOTH_USERNAME); - assertNotNull("No sharptooth user", user); - display("User", user); - assertUser(user, ACCOUNT_SHARPTOOTH_USERNAME, ACCOUNT_SHARPTOOTH_FIST_NAME, ACCOUNT_SHARPTOOTH_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); + resourceOpenDj = getObject(ResourceType.class, RESOURCE_OPENDJ_OID); + resourceOpenDjType = resourceOpenDj.asObjectable(); - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - assertAssignedOrg(user, org.getOid()); - assertHasOrg(user, org.getOid()); - assertHasOrg(org, ORG_TOP_OID); - assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resourceOpenDj, prismContext); + display("OpenDJ schema (resource)", resourceSchema); - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); - - assertBasicRoleAndResources(user); - String thisRoleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); - assertEquals("Canibalism role OID has changed", roleCanibalismOid, thisRoleCanibalismOid); - assertAssignments(user, 3); - } - - /** - * Yet another canibal to play with. - */ - @Test - public void test107AddHrAccountRedskull() throws Exception { - final String TEST_NAME = "test107AddHrAccountRedskull"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + ObjectClassComplexTypeDefinition ocDefPosixAccount = resourceSchema.findObjectClassDefinition(OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME); + assertNotNull("No objectclass "+OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME+" in resource schema", ocDefPosixAccount); + assertTrue("Objectclass "+OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME+" is not auxiliary", ocDefPosixAccount.isAuxiliary()); - DummyAccount newAccount = new DummyAccount(ACCOUNT_REDSKULL_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_REDSKULL_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_REDSKULL_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_MONKEY_ISLAND); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + ObjectClassComplexTypeDefinition ocDefPosixGroup = resourceSchema.findObjectClassDefinition(OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME); + assertNotNull("No objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" in resource schema", ocDefPosixGroup); + assertTrue("Objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" is not auxiliary", ocDefPosixGroup.isAuxiliary()); - // THEN - PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); - assertNotNull("No redskull user", user); - display("User", user); - assertUser(user, ACCOUNT_REDSKULL_USERNAME, ACCOUNT_REDSKULL_FIST_NAME, ACCOUNT_REDSKULL_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); + RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceOpenDj); + display("OpenDJ schema (refined)", refinedSchema); - dumpOrgTree(); + RefinedObjectClassDefinition rOcDefPosixAccount = refinedSchema.getRefinedDefinition(OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME); + assertNotNull("No refined objectclass "+OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME+" in resource schema", rOcDefPosixAccount); + assertTrue("Refined objectclass "+OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME+" is not auxiliary", rOcDefPosixAccount.isAuxiliary()); - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - assertAssignedOrg(user, org.getOid()); - assertHasOrg(user, org.getOid()); - assertHasOrg(org, ORG_TOP_OID); - assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); + RefinedObjectClassDefinition rOcDefPosixGroup = refinedSchema.getRefinedDefinition(OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME); + assertNotNull("No refined objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" in resource schema", rOcDefPosixGroup); + assertTrue("Refined objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" is not auxiliary", rOcDefPosixGroup.isAuxiliary()); - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); + // TODO - assertBasicRoleAndResources(user); - String thisRoleCanibalismOid = assertResponsibility(user, RESP_CANIBALISM); - assertEquals("Canibalism role OID has changed", roleCanibalismOid, thisRoleCanibalismOid); - assertAssignments(user, 3); } - /** - * Remove "canibalism" responsibility from redskull. - */ @Test - public void test108RedskullGoesVegeratian() throws Exception { - final String TEST_NAME = "test108RedskullGoesVegeratian"; + public void test100AddUserHermanBasic() throws Exception { + final String TEST_NAME = "test100AddHrAccountHerman"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount account = dummyResourceHr.getAccountByUsername(ACCOUNT_REDSKULL_USERNAME); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - account.removeAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_RESPONSIBILITIES, RESP_CANIBALISM); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - TestUtil.displayThen(TEST_NAME); - PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); - assertNotNull("No redskull user", user); - display("User", user); - assertUser(user, ACCOUNT_REDSKULL_USERNAME, ACCOUNT_REDSKULL_FIST_NAME, ACCOUNT_REDSKULL_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); + OperationResult result = task.getResult(); - dumpOrgTree(); - - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - assertAssignedOrg(user, org.getOid()); - assertHasOrg(user, org.getOid()); - assertHasOrg(org, ORG_TOP_OID); - - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); - - assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); - - assertBasicRoleAndResources(user); - roleCanibalismOid = assertNoResponsibility(user, RESP_CANIBALISM); - assertAssignments(user, 2); - } - - /** - * Vegetarian cannibal? Not really! - */ - @Test - public void test109HrDeleteRedskull() throws Exception { - final String TEST_NAME = "test109HrDeleteRedskull"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + PrismObject user = createUser(USER_HERMAN_USERNAME, USER_HERMAN_FIST_NAME, USER_HERMAN_LAST_NAME, null, ROLE_BASIC_OID); // WHEN - TestUtil.displayWhen(TEST_NAME); - dummyResourceHr.deleteAccountByName(ACCOUNT_REDSKULL_USERNAME); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); + TestUtil.displayWhen(TEST_NAME); + addObject(user, task, result); // THEN TestUtil.displayThen(TEST_NAME); - PrismObject user = findUserByUsername(ACCOUNT_REDSKULL_USERNAME); - display("User", user); - assertNull("Redskull user not gone", user); - - dumpOrgTree(); - - PrismObject org = getAndAssertReplicatedOrg(ORGPATH_MONKEY_ISLAND); - assertHasOrg(org, ORG_TOP_OID); - assertSubOrgs(org,0); - assertSubOrgs(ORG_TOP_OID,1); - - assertEquals("Monkey island Org OID has changed", orgMonkeyIslandOid, org.getOid()); - } - - /** - * Two-level orgpath. Both orgs should be created. - */ - @Test - public void test110AddHrAccountGuybrush() throws Exception { - final String TEST_NAME = "test110AddHrAccountGuybrush"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_GUYBRUSH_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_GUYBRUSH_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_GUYBRUSH_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_FREELANCE); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_GUYBRUSH_USERNAME); - assertNotNull("No guybrush user", user); - display("User", user); - assertUserGuybrush(user); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgFreelance = getAndAssertReplicatedOrg("Freelance"); - PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); - orgMoROid = orgMoR.getOid(); - - assertAssignedOrg(user, orgFreelance.getOid()); - assertHasOrg(user, orgFreelance.getOid()); - assertHasOrg(orgFreelance, orgMoR.getOid()); - assertHasOrg(orgMoR, ORG_TOP_OID); - - assertSubOrgs(orgFreelance,0); - assertSubOrgs(orgMoR,1); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,2); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Two-level orgpath, partially created. Only scumm bar should be crated. Ministry should be reused. - */ - @Test - public void test115AddHrAccountMancomb() throws Exception { - final String TEST_NAME = "test115AddHrAccountMancomb"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_MANCOMB_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_MANCOMB_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_MANCOMB_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_MANCOMB_USERNAME); - assertNotNull("No mancomb user", user); - display("User", user); - assertUser(user, ACCOUNT_MANCOMB_USERNAME, ACCOUNT_MANCOMB_FIST_NAME, ACCOUNT_MANCOMB_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); - orgScummBarOid = orgScummBar.getOid(); - PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); - - assertAssignedOrg(user, orgScummBar.getOid()); - assertHasOrg(user, orgScummBar.getOid()); - assertHasOrg(orgScummBar, orgMoR.getOid()); - assertHasOrg(orgMoR, ORG_TOP_OID); - - assertSubOrgs(orgScummBar,0); - assertSubOrgs(orgMoR,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,2); - - assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Two-level orgpath, completely created. No new orgs should be created. - */ - @Test - public void test117AddHrAccountCobb() throws Exception { - final String TEST_NAME = "test117AddHrAccountCobb"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_COBB_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_COBB_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_COBB_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_COBB_USERNAME); - assertNotNull("No cobb user", user); - display("User", user); - assertUser(user, ACCOUNT_COBB_USERNAME, ACCOUNT_COBB_FIST_NAME, ACCOUNT_COBB_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); - PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); - - assertAssignedOrg(user, orgScummBar.getOid()); - assertHasOrg(user, orgScummBar.getOid()); - assertHasOrg(orgScummBar, orgMoR.getOid()); - assertHasOrg(orgMoR, ORG_TOP_OID); - - assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); - assertEquals("Scumm bar Org OID has changed", orgScummBarOid, orgScummBar.getOid()); - - assertSubOrgs(orgScummBar,0); - assertSubOrgs(orgMoR,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,2); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Four-level orgpath, completely new. - */ - @Test - public void test130AddHrAccountLargo() throws Exception { - final String TEST_NAME = "test130AddHrAccountLargo"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_LARGO_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_LARGO_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_LARGO_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_BRUTE); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_LARGO_USERNAME); - assertNotNull("No largo user", user); - display("User", user); - assertUser(user, ACCOUNT_LARGO_USERNAME, ACCOUNT_LARGO_FIST_NAME, ACCOUNT_LARGO_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgMoO = getAndAssertReplicatedOrg("Ministry of Offense"); - PrismObject orgDoM = getAndAssertReplicatedOrg("Department of Mischief"); - PrismObject orgVSec = getAndAssertReplicatedOrg("Violence Section"); - PrismObject orgBOff = getAndAssertReplicatedOrg("Brute Office"); - - assertAssignedOrg(user, orgBOff.getOid()); - assertHasOrg(user, orgBOff.getOid()); - assertHasOrg(orgBOff, orgVSec.getOid()); - assertHasOrg(orgVSec, orgDoM.getOid()); - assertHasOrg(orgDoM, orgMoO.getOid()); - assertHasOrg(orgMoO, ORG_TOP_OID); - - assertSubOrgs(orgBOff,0); - assertSubOrgs(orgVSec,1); - assertSubOrgs(orgDoM,1); - assertSubOrgs(orgMoO,1); - assertSubOrgs(orgScummBarOid,0); - assertSubOrgs(orgMoROid,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,3); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); + PrismObject userAfter = findUserByUsername(USER_HERMAN_USERNAME); + assertNotNull("No herman user", userAfter); + display("User after", userAfter); + assertUserHerman(userAfter); + String accountOid = getSingleLinkOid(userAfter); + + PrismObject shadow = getShadowModel(accountOid); + display("Shadow (model)", shadow); + assertBasicAccount(shadow); } - - /** - * Two-level orgpath, upper org is only as ou in LDAP, it is not in midpoint. - */ - @Test - public void test140AddHrAccountWally() throws Exception { - final String TEST_NAME = "test140AddHrAccountWally"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_WALLY_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_WALLY_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_WALLY_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_CARTOGRAPHY); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_WALLY_USERNAME); - assertNotNull("No cobb user", user); - display("User", user); - assertUser(user, ACCOUNT_WALLY_USERNAME, ACCOUNT_WALLY_FIST_NAME, ACCOUNT_WALLY_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - dumpOrgTree(); - - PrismObject orgCartography = getAndAssertReplicatedOrg("Cartography"); - PrismObject orgScabb = getAndAssertReplicatedOrg(ORGPATH_SCABB_ISLAND); - - assertAssignedOrg(user, orgCartography.getOid()); - assertHasOrg(user, orgCartography.getOid()); - assertHasOrg(orgCartography, orgScabb.getOid()); - assertHasOrg(orgScabb, ORG_TOP_OID); - - assertSubOrgs(orgCartography,0); - assertSubOrgs(orgScabb,1); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,4); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Two-level orgpath, both orgs are only as ou in LDAP, not in midpoint. - */ @Test - public void test142AddHrAccountAugustus() throws Exception { - final String TEST_NAME = "test142AddHrAccountAugustus"; + public void test110AddUserMancombUnix() throws Exception { + final String TEST_NAME = "test110AddUserMancombUnix"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_AUGUSTUS_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_AUGUSTUS_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_AUGUSTUS_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_BOOTY_ISLAND_LOOKOUT); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_AUGUSTUS_USERNAME); - assertNotNull("No cobb user", user); - display("User", user); - assertUser(user, ACCOUNT_AUGUSTUS_USERNAME, ACCOUNT_AUGUSTUS_FIST_NAME, ACCOUNT_AUGUSTUS_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgLookout = getAndAssertReplicatedOrg("Lookout"); - PrismObject orgBooty = getAndAssertReplicatedOrg(ORGPATH_BOOTY_ISLAND); - - assertAssignedOrg(user, orgLookout.getOid()); - assertHasOrg(user, orgLookout.getOid()); - assertHasOrg(orgLookout, orgBooty.getOid()); - assertHasOrg(orgBooty, ORG_TOP_OID); - - assertSubOrgs(orgLookout,0); - assertSubOrgs(orgBooty,1); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,5); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Some national characters there. - */ - @Test - public void test185AddHrAccountStan() throws Exception { - final String TEST_NAME = "test185AddHrAccountStan"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_STAN_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_STAN_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_STAN_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_DOCKS); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_STAN_USERNAME); - assertNotNull("No largo user", user); - display("User", user); - assertUser(user, ACCOUNT_STAN_USERNAME, ACCOUNT_STAN_FIST_NAME, ACCOUNT_STAN_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgDocks = getAndAssertReplicatedOrg("Docks"); - PrismObject orgMelee = getAndAssertReplicatedOrg(ORGPATH_MELEE_ISLAND); - - assertAssignedOrg(user, orgDocks.getOid()); - assertHasOrg(user, orgDocks.getOid()); - assertHasOrg(orgDocks, orgMelee.getOid()); - assertHasOrg(orgMelee, ORG_TOP_OID); - - assertSubOrgs(orgDocks,0); - assertSubOrgs(orgMelee,1); - assertSubOrgs(orgScummBarOid,0); - assertSubOrgs(orgMoROid,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,6); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Commas in the org structure. - */ - @Test - public void test186AddHrAccountCapsize() throws Exception { - final String TEST_NAME = "test186AddHrAccountCapsize"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_CAPSIZE_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_CAPSIZE_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_CAPSIZE_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_CAPSIZE); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_CAPSIZE_USERNAME); - assertNotNull("No largo user", user); - display("User", user); - assertUser(user, ACCOUNT_CAPSIZE_USERNAME, ACCOUNT_CAPSIZE_FIST_NAME, ACCOUNT_CAPSIZE_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgCapsize = getAndAssertReplicatedOrg("Cruises, Charter and Capsize"); - PrismObject orgTour = getAndAssertReplicatedOrg("Tourist Industries, Tri-Island Area"); - - assertAssignedOrg(user, orgCapsize.getOid()); - assertHasOrg(user, orgCapsize.getOid()); - assertHasOrg(orgCapsize, orgTour.getOid()); - assertHasOrg(orgTour, ORG_TOP_OID); - - assertSubOrgs(orgCapsize,0); - assertSubOrgs(orgTour,1); - assertSubOrgs(orgScummBarOid,0); - assertSubOrgs(orgMoROid,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,7); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Comma in username - */ - @Test - public void test187AddHrAccountRogersSr() throws Exception { - final String TEST_NAME = "test187AddHrAccountRogersSr"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_ROGERSSR_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_ROGERSSR_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_ROGERSSR_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_SCUMM_BAR); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_ROGERSSR_USERNAME); - assertNotNull("No largo user", user); - display("User", user); - assertUser(user, ACCOUNT_ROGERSSR_USERNAME, ACCOUNT_ROGERSSR_FIST_NAME, ACCOUNT_ROGERSSR_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgScummBar = getAndAssertReplicatedOrg("Scumm Bar"); - PrismObject orgMoR = getAndAssertReplicatedOrg("Ministry of Rum"); - - assertAssignedOrg(user, orgScummBar.getOid()); - assertHasOrg(user, orgScummBar.getOid()); - assertHasOrg(orgScummBar, orgMoR.getOid()); - assertHasOrg(orgMoR, ORG_TOP_OID); - - assertEquals("MoR Org OID has changed", orgMoROid, orgMoR.getOid()); - assertEquals("Scumm bar Org OID has changed", orgScummBarOid, orgScummBar.getOid()); - - assertSubOrgs(orgScummBarOid,0); - assertSubOrgs(orgMoROid,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,7); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - /** - * Lot of national characters here. - */ - @Test - public void test190AddHrAccountTeleke() throws Exception { - final String TEST_NAME = "test190AddHrAccountTeleke"; - TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); - - DummyAccount newAccount = new DummyAccount(ACCOUNT_TELEKE_USERNAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_FIRST_NAME, ACCOUNT_TELEKE_FIST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_LAST_NAME, ACCOUNT_TELEKE_LAST_NAME); - newAccount.addAttributeValue(DUMMY_ACCOUNT_ATTRIBUTE_HR_ORGPATH, ORGPATH_HRAD); - - // WHEN - dummyResourceHr.addAccount(newAccount); - waitForTaskNextRun(TASK_LIVE_SYNC_DUMMY_HR_OID, true); - - // THEN - PrismObject user = findUserByUsername(ACCOUNT_TELEKE_USERNAME); - assertNotNull("No largo user", user); - display("User", user); - assertUser(user, ACCOUNT_TELEKE_USERNAME, ACCOUNT_TELEKE_FIST_NAME, ACCOUNT_TELEKE_LAST_NAME); - assertAccount(user, RESOURCE_DUMMY_HR_OID); - - dumpOrgTree(); - - PrismObject orgHrad = getAndAssertReplicatedOrg(HRAD); - PrismObject orgKarpatula = getAndAssertReplicatedOrg(ORGPATH_KARPATULA); - - assertAssignedOrg(user, orgHrad.getOid()); - assertHasOrg(user, orgHrad.getOid()); - assertHasOrg(orgHrad, orgKarpatula.getOid()); - assertHasOrg(orgKarpatula, ORG_TOP_OID); - - assertSubOrgs(orgHrad,0); - assertSubOrgs(orgKarpatula,1); - assertSubOrgs(orgScummBarOid,0); - assertSubOrgs(orgMoROid,2); - assertSubOrgs(orgMonkeyIslandOid,0); - assertSubOrgs(ORG_TOP_OID,8); - - assertBasicRoleAndResources(user); - assertAssignments(user, 2); - } - - - @Test - public void test500ReconcileOpenDJDefault() throws Exception { - final String TEST_NAME = "test500ReconcileOpenDJDefault"; - TestUtil.displayTestTile(this, TEST_NAME); - - // GIVEN - Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - - List> users = modelService.searchObjects(UserType.class, null, null, task, result); - display("Users before recon", users); - assertUsers(15); - reconciliationTaskResultListener.clear(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - importObjectFromFile(TASK_RECON_OPENDJ_DEFAULT_SINGLE_FILE); - - // THEN - TestUtil.displayThen(TEST_NAME); - - waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); - - // THEN - TestUtil.displayThen(TEST_NAME); - - reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 17, 0, 0); + PrismObject user = createUser(USER_MANCOMB_USERNAME, USER_MANCOMB_FIST_NAME, USER_MANCOMB_LAST_NAME, 1001, ROLE_UNIX_OID); - users = modelService.searchObjects(UserType.class, null, null, task, result); - display("Users after recon", users); - - assertUsers(18); - - // Task result - PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); - OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); - display("Recon task result", reconTaskResult); - TestUtil.assertSuccess(reconTaskResult); - } - - @Test - public void test502ReconcileOpenDJDefaultAgain() throws Exception { - final String TEST_NAME = "test502ReconcileOpenDJDefaultAgain"; - TestUtil.displayTestTile(this, TEST_NAME); - - // GIVEN - Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - - assertUsers(18); - reconciliationTaskResultListener.clear(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - restartTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); - - // THEN - TestUtil.displayThen(TEST_NAME); - - waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); + // WHEN + TestUtil.displayWhen(TEST_NAME); + addObject(user, task, result); // THEN TestUtil.displayThen(TEST_NAME); - - reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 17, 0, 0); - - assertUsers(18); - - // Task result - PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); - OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); - display("Recon task result", reconTaskResult); - TestUtil.assertSuccess(reconTaskResult); + PrismObject userAfter = findUserByUsername(USER_MANCOMB_USERNAME); + assertNotNull("No herman user", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_MANCOMB_USERNAME, USER_MANCOMB_FIST_NAME, USER_MANCOMB_LAST_NAME); + String accountOid = getSingleLinkOid(userAfter); + + PrismObject shadow = getShadowModel(accountOid); + display("Shadow (model)", shadow); + assertPosixAccount(shadow); } - @Test - public void test510ReconcileOpenDJLdapGroup() throws Exception { - final String TEST_NAME = "test510ReconcileOpenDJLdapGroup"; - TestUtil.displayTestTile(this, TEST_NAME); - - // GIVEN - Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - - List> users = modelService.searchObjects(UserType.class, null, null, task, result); - display("Users before recon", users); - assertUsers(18); - - reconciliationTaskResultListener.clear(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - importObjectFromFile(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_FILE); - - // THEN - TestUtil.displayThen(TEST_NAME); - - waitForTaskFinish(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_OID, false); - - // THEN - TestUtil.displayThen(TEST_NAME); - - reconciliationTaskResultListener.assertResult(RESOURCE_OPENDJ_OID, 0, 2, 0, 0); - - users = modelService.searchObjects(UserType.class, null, null, task, result); - display("Users after recon", users); - - assertUsers(18); - - // Task result - PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_LDAPGROUP_SINGLE_OID); - OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); - display("Recon task result", reconTaskResult); - TestUtil.assertSuccess(reconTaskResult); - } - - @Test - public void test550ReconcileOpenDJAfterMembershipChange() throws Exception { - final String TEST_NAME = "test550ReconcileOpenDJAfterMembershipChange"; - TestUtil.displayTestTile(this, TEST_NAME); - - // We manually remove Lemonhead from R_canibalism group - // And check whether reconciliation re-adds him again - - // GIVEN - Task task = createTask(TestUnix.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - - Collection membersBeforeTest = openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN); - System.out.println("group members before test = " + membersBeforeTest); - assertTrue(RESP_CANIBALISM_DN + " does not contain " + ACCOUNT_LEMONHEAD_DN, membersBeforeTest.contains(ACCOUNT_LEMONHEAD_DN)); - - openDJController.removeGroupUniqueMember(RESP_CANIBALISM_DN, ACCOUNT_LEMONHEAD_DN); - - System.out.println("group members after removal = " + openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN)); - - openDJController.assertNoUniqueMember(RESP_CANIBALISM_DN, ACCOUNT_LEMONHEAD_DN); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - restartTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); - - // THEN - TestUtil.displayThen(TEST_NAME); - - waitForTaskFinish(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID, false); - - // THEN - TestUtil.displayThen(TEST_NAME); - - // Task result - PrismObject reconTaskAfter = getTask(TASK_RECON_OPENDJ_DEFAULT_SINGLE_OID); - OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult(); - display("Recon task result", reconTaskResult); - TestUtil.assertSuccess(reconTaskResult); - - Collection membersAfterTest = openDJController.getGroupUniqueMembers(RESP_CANIBALISM_DN); - System.out.println("group members after test = " + membersAfterTest); - assertTrue(RESP_CANIBALISM_DN + " does not contain " + ACCOUNT_LEMONHEAD_DN, membersAfterTest.contains(ACCOUNT_LEMONHEAD_DN.toLowerCase())); // ...it seems to get lowercased during the reconciliation - } - - - protected void assertUserGuybrush(PrismObject user) { - assertUser(user, ACCOUNT_GUYBRUSH_USERNAME, ACCOUNT_GUYBRUSH_FIST_NAME, ACCOUNT_GUYBRUSH_LAST_NAME); + private PrismObject createUser(String username, String givenName, String familyName, Integer uidNumber, String roleOid) throws SchemaException { + PrismObject user = createUser(username, givenName, familyName, true); + AssignmentType roleAssignemnt = new AssignmentType(); + ObjectReferenceType roleTargetRef = new ObjectReferenceType(); + roleTargetRef.setOid(roleOid); + roleTargetRef.setType(RoleType.COMPLEX_TYPE); + roleAssignemnt.setTargetRef(roleTargetRef); + user.asObjectable().getAssignment().add(roleAssignemnt); + if (uidNumber != null) { + PrismPropertyDefinition uidNumberPropertyDef = new PrismPropertyDefinition<>(EXTENSION_UID_NUMBER_NAME, + DOMUtil.XSD_STRING, prismContext); + PrismProperty uidNumberProperty = uidNumberPropertyDef.instantiate(); + uidNumberProperty.setRealValue(uidNumber.toString()); + user.createExtension().add(uidNumberProperty); + PrismPropertyDefinition gidNumberPropertyDef = new PrismPropertyDefinition<>(EXTENSION_GID_NUMBER_NAME, + DOMUtil.XSD_STRING, prismContext); + PrismProperty gidNumberProperty = gidNumberPropertyDef.instantiate(); + gidNumberProperty.setRealValue(uidNumber.toString()); + user.getExtension().add(gidNumberProperty); + } + return user; } protected void assertUserHerman(PrismObject user) { - assertUser(user, ACCOUNT_HERMAN_USERNAME, ACCOUNT_HERMAN_FIST_NAME, ACCOUNT_HERMAN_LAST_NAME); + assertUser(user, USER_HERMAN_USERNAME, USER_HERMAN_FIST_NAME, USER_HERMAN_LAST_NAME); } protected void assertUser(PrismObject user, String username, String firstName, String lastName) { @@ -1082,95 +333,32 @@ protected void assertUser(PrismObject user, String username, String fi firstName, lastName); } - private PrismObject getAndAssertReplicatedOrg(String orgName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { - PrismObject org = getOrg(orgName); - PrismAsserts.assertPropertyValue(org, OrgType.F_ORG_TYPE, "replicated"); - assertAssignedRole(org, ROLE_META_REPLICATED_ORG_OID); - PrismReferenceValue linkRef = getSingleLinkRef(org); - // We are bold enough to get the whole shadow - PrismObject shadow = getShadowModel(linkRef.getOid()); - display("Org "+orgName+" shadow", shadow); - // TODO assert shadow content - - SearchResultEntry ouEntry = openDJController.searchSingle("ou="+orgName); - assertNotNull("No ou LDAP entry for "+orgName); - display("OU entry", ouEntry); - openDJController.assertObjectClass(ouEntry, "organizationalUnit"); - - return org; + private void assertBasicAccount(PrismObject shadow) throws DirectoryException { + ShadowType shadowType = shadow.asObjectable(); + assertEquals("Wrong objectclass in "+shadow, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME, shadowType.getObjectClass()); + assertTrue("Unexpected auxiliary objectclasses in "+shadow + ": "+shadowType.getAuxiliaryObjectClass(), + shadowType.getAuxiliaryObjectClass().isEmpty()); + String dn = (String) ShadowUtil.getSecondaryIdentifiers(shadow).iterator().next().getRealValue(); + + SearchResultEntry entry = openDJController.fetchEntry(dn); + assertNotNull("No ou LDAP entry for "+dn); + display("Posix account entry", entry); + openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME.getLocalPart()); + openDJController.assertNoObjectClass(entry, OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME.getLocalPart()); } - private PrismObject getOrg(String orgName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - PrismObject org = findObjectByName(OrgType.class, orgName); - assertNotNull("The org "+orgName+" is missing!", org); - display("Org "+orgName, org); - PrismAsserts.assertPropertyValue(org, OrgType.F_NAME, PrismTestUtil.createPolyString(orgName)); - return org; + private void assertPosixAccount(PrismObject shadow) throws DirectoryException { + ShadowType shadowType = shadow.asObjectable(); + assertEquals("Wrong objectclass in "+shadow, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME, shadowType.getObjectClass()); + PrismAsserts.assertEqualsCollectionUnordered("Wrong auxiliary objectclasses in "+shadow, + shadowType.getAuxiliaryObjectClass(), OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME); + String dn = (String) ShadowUtil.getSecondaryIdentifiers(shadow).iterator().next().getRealValue(); + + SearchResultEntry entry = openDJController.fetchEntry(dn); + assertNotNull("No ou LDAP entry for "+dn); + display("Posix account entry", entry); + openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME.getLocalPart()); + openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME.getLocalPart()); } - - private void assertBasicRoleAndResources(PrismObject user) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { - assertAssignedRole(user, ROLE_BASIC_OID); - PrismReferenceValue linkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); - PrismObject shadow = getShadowModel(linkRef.getOid()); - display("OpenDJ shadow linked to "+user, shadow); - // TODO assert shadow content - } - - private String assertResponsibility(PrismObject user, String respName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { - String respRoleName = "R_"+respName; - PrismObject respRole = searchObjectByName(RoleType.class, respRoleName); - assertNotNull("No role for responsibility "+respName); - display("Responsibility role for "+respName, respRole); - assertAssignedRole(user, respRole.getOid()); - - PrismReferenceValue linkRef = getSingleLinkRef(respRole); - PrismObject shadow = getShadowModel(linkRef.getOid()); - display("Role "+respRoleName+" shadow", shadow); - // TODO assert shadow content - - String groupDn = "cn="+respRoleName+",ou=groups,"+openDJController.getSuffix(); - SearchResultEntry groupEntry = openDJController.fetchAndAssertEntry(groupDn, "groupOfUniqueNames"); - display("Group entry", groupEntry); - - PrismReferenceValue accountLinkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); - PrismObject accountShadow = getShadowModel(accountLinkRef.getOid()); - String accountDn = IntegrationTestTools.getSecondaryIdentifier(accountShadow); - openDJController.assertUniqueMember(groupEntry, accountDn); - - IntegrationTestTools.assertAssociation(accountShadow, OPENDJ_ASSOCIATION_GROUP_NAME, shadow.getOid()); - - return respRole.getOid(); - } - - private String assertNoResponsibility(PrismObject user, String respName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { - String respRoleName = "R_"+respName; - PrismObject respRole = searchObjectByName(RoleType.class, respRoleName); - assertNotNull("No role for responsibility "+respName); - display("Responsibility role for "+respName, respRole); - assertNotAssignedRole(user, respRole.getOid()); - PrismReferenceValue linkRef = getSingleLinkRef(respRole); - PrismObject shadow = getShadowModel(linkRef.getOid()); - display("Role "+respRoleName+" shadow", shadow); - // TODO assert shadow content - - String groupDn = "cn="+respRoleName+",ou=groups,"+openDJController.getSuffix(); - SearchResultEntry groupEntry = openDJController.fetchAndAssertEntry(groupDn, "groupOfUniqueNames"); - display("Group entry", groupEntry); - - PrismReferenceValue accountLinkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); - PrismObject accountShadow = getShadowModel(accountLinkRef.getOid()); - String accountDn = IntegrationTestTools.getSecondaryIdentifier(accountShadow); - openDJController.assertNoUniqueMember(groupEntry, accountDn); - - IntegrationTestTools.assertNoAssociation(accountShadow, OPENDJ_ASSOCIATION_GROUP_NAME, shadow.getOid()); - - return respRole.getOid(); - } - - private void dumpOrgTree() throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - display("Org tree", dumpOrgTree(ORG_TOP_OID)); - } - - } diff --git a/testing/story/src/test/resources/schema/unix.xsd b/testing/story/src/test/resources/schema/unix.xsd index d24300d0c6f..143dca2efd7 100644 --- a/testing/story/src/test/resources/schema/unix.xsd +++ b/testing/story/src/test/resources/schema/unix.xsd @@ -16,7 +16,7 @@ ~ limitations under the License. --> diff --git a/testing/story/src/test/resources/unix/resource-opendj.xml b/testing/story/src/test/resources/unix/resource-opendj.xml index 5465a775e6f..2afcc71dd10 100644 --- a/testing/story/src/test/resources/unix/resource-opendj.xml +++ b/testing/story/src/test/resources/unix/resource-opendj.xml @@ -28,7 +28,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" xmlns:func="http://midpoint.evolveum.com/xml/ns/public/function/basic-3" - xmlns:ext="http://midpoint.evolveum.com/xml/ns/story/orgsync/ext"> + xmlns:ext="http://midpoint.evolveum.com/xml/ns/story/unix/ext"> Embedded Test OpenDJ @@ -48,7 +48,7 @@ 10389 localhost dc=example,dc=com - cn=directory manager + uid=idm,ou=Administrators,dc=example,dc=com secret auto entryUUID @@ -72,7 +72,6 @@ Default Account true ri:inetOrgPerson - posixAccount ri:dn Distinguished Name @@ -272,12 +271,12 @@ entitlement unixGroup UNIX Group - ri:posixGroup + ri:groupOfNames + ri:posixGroup ri:dn mr:stringIgnoreCase - $focus/name @@ -299,8 +298,6 @@ ri:cn mr:stringIgnoreCase - weak $focus/name @@ -316,7 +313,7 @@ - + + diff --git a/testing/story/src/test/resources/unix/role-basic.xml b/testing/story/src/test/resources/unix/role-basic.xml new file mode 100644 index 00000000000..b83a2131111 --- /dev/null +++ b/testing/story/src/test/resources/unix/role-basic.xml @@ -0,0 +1,32 @@ + + + + Basic User + + + + + + account + + + + diff --git a/testing/story/src/test/resources/unix/role-unix.xml b/testing/story/src/test/resources/unix/role-unix.xml new file mode 100644 index 00000000000..94869dd340a --- /dev/null +++ b/testing/story/src/test/resources/unix/role-unix.xml @@ -0,0 +1,33 @@ + + + + Unix User + + + + + + account + ri:posixAccount + + + + diff --git a/tools/test-ng/.gitignore b/tools/test-ng/.gitignore index ea8c4bf7f35..29546b567bd 100644 --- a/tools/test-ng/.gitignore +++ b/tools/test-ng/.gitignore @@ -1 +1,2 @@ /target +/target/ From 7a9487a0dd31c035638996e3a8cdc4736a342966 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 22 Jun 2015 22:16:31 +0200 Subject: [PATCH 09/16] Basic auxiliary object class support in model almost works --- .../midpoint/prism/delta/DeltaSetTriple.java | 13 +++ .../prism/delta/PrismValueDeltaSetTriple.java | 13 --- .../model/common/mapping/Mapping.java | 12 ++- .../model/common/mapping/MappingFactory.java | 2 +- .../PrismValueDeltaSetTripleProducer.java | 39 +++++++++ .../common/mapping/MappingTestEvaluator.java | 16 ++-- .../model/impl/lens/Construction.java | 67 ++++++++++++--- .../impl/lens/EvaluatedAssignmentImpl.java | 3 +- .../model/impl/lens/ItemValueWithOrigin.java | 12 +-- .../impl/lens/LensProjectionContext.java | 10 +++ .../midpoint/model/impl/lens/LensUtil.java | 15 ++-- .../projector/ConsolidationProcessor.java | 81 +++++++++++++++++-- .../impl/lens/projector/MappingExtractor.java | 4 +- .../lens/projector/OutboundProcessor.java | 6 +- .../projector/ReconciliationProcessor.java | 7 +- .../impl/lens/TestAssignmentEvaluator.java | 9 ++- .../impl/lens/TestAssignmentProcessor.java | 15 ++-- .../midpoint/testing/story/TestUnix.java | 8 +- .../src/test/resources/unix/role-unix.xml | 32 ++++++++ 19 files changed, 289 insertions(+), 75 deletions(-) create mode 100644 model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/PrismValueDeltaSetTripleProducer.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/DeltaSetTriple.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/DeltaSetTriple.java index 9a6615cc46b..7af59e13d6d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/DeltaSetTriple.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/DeltaSetTriple.java @@ -268,6 +268,19 @@ public Collection union() { return MiscUtil.union(zeroSet, plusSet, minusSet); } + public T getAnyValue() { + if (zeroSet != null && !zeroSet.isEmpty()) { + return zeroSet.iterator().next(); + } + if (plusSet != null && !plusSet.isEmpty()) { + return plusSet.iterator().next(); + } + if (minusSet != null && !minusSet.isEmpty()) { + return minusSet.iterator().next(); + } + return null; + } + public Collection getAllValues() { Collection allValues = new ArrayList(size()); addAllValuesSet(allValues, zeroSet); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/PrismValueDeltaSetTriple.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/PrismValueDeltaSetTriple.java index fc1678fac96..951316a201b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/PrismValueDeltaSetTriple.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/PrismValueDeltaSetTriple.java @@ -100,19 +100,6 @@ public Class getRealValueClass() { } } - private V getAnyValue() { - if (zeroSet != null && !zeroSet.isEmpty()) { - return zeroSet.iterator().next(); - } - if (plusSet != null && !plusSet.isEmpty()) { - return plusSet.iterator().next(); - } - if (minusSet != null && !minusSet.isEmpty()) { - return minusSet.iterator().next(); - } - return null; - } - public boolean isRaw() { return (isRaw(zeroSet) || isRaw(plusSet) || isRaw(minusSet)); } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java index 6823dcaa41b..5319f506d87 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java @@ -105,7 +105,7 @@ * @author Radovan Semancik * */ -public class Mapping implements DebugDumpable { +public class Mapping implements DebugDumpable, PrismValueDeltaSetTripleProducer { private static final QName CONDITION_OUTPUT_NAME = new QName(SchemaConstants.NS_C, "condition"); @@ -458,6 +458,10 @@ public Long getEtime() { return evaluationEndTime - evaluationStartTime; } + /* (non-Javadoc) + * @see com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer#getMappingQName() + */ + @Override public QName getMappingQName() { return mappingQName; } @@ -995,6 +999,10 @@ private void evaluateExpression(Task task, OperationResult result, boolean condi } } + /* (non-Javadoc) + * @see com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer#getOutputTriple() + */ + @Override public PrismValueDeltaSetTriple getOutputTriple() { if (outputTriple != null && InternalsConfig.consistencyChecks) { try { @@ -1038,7 +1046,7 @@ private PrismPropertyValue filterValue(PrismPropertyValue propertyValu /** * Shallow clone. Only the output is cloned deeply. */ - public Mapping clone() { + public PrismValueDeltaSetTripleProducer clone() { Mapping clone = new Mapping<>(mappingType, contextDescription, expressionFactory, securityEnforcer); clone.conditionMaskNew = this.conditionMaskNew; clone.conditionMaskOld = this.conditionMaskOld; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingFactory.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingFactory.java index 943fd4b29c0..4d3de81c533 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingFactory.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingFactory.java @@ -114,7 +114,7 @@ public void setProfiling(boolean profiling) { this.profiling = profiling; } - public Mapping createMapping(MappingType mappingType, String shortDesc) { + public Mapping createMapping(MappingType mappingType, String shortDesc) { Mapping mapping = new Mapping<>(mappingType, shortDesc, expressionFactory, securityEnforcer); mapping.setFilterManager(filterManager); mapping.setProfiling(profiling); diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/PrismValueDeltaSetTripleProducer.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/PrismValueDeltaSetTripleProducer.java new file mode 100644 index 00000000000..5eac3bab892 --- /dev/null +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/PrismValueDeltaSetTripleProducer.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.common.mapping; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType; + +public interface PrismValueDeltaSetTripleProducer { + + QName getMappingQName(); + + PrismValueDeltaSetTriple getOutputTriple(); + + MappingStrengthType getStrength(); + + PrismValueDeltaSetTripleProducer clone(); + + boolean isExclusive(); + + boolean isAuthoritative(); + +} \ No newline at end of file diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java index c978cb610b7..eaa22ac8cbe 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java @@ -114,30 +114,30 @@ public AESProtector getProtector() { return protector; } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, String defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, String defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { return createMapping(filename, testName, policy, toPath(defaultTargetPropertyName), userDelta); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, String defaultTargetPropertyName, + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, String defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { return createMapping(filename, testName, null, toPath(defaultTargetPropertyName), userDelta); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, QName defaultTargetPropertyName, + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, QName defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { return createMapping(filename, testName, null, toPath(defaultTargetPropertyName), userDelta); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, String defaultTargetPropertyName, + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, String defaultTargetPropertyName, ObjectDelta userDelta, PrismObject userOld) throws SchemaException, IOException, JAXBException { return createMapping(filename, testName, null, toPath(defaultTargetPropertyName), userDelta, userOld); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, ItemPath defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, ItemPath defaultTargetPropertyName, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { return createMapping(filename, testName, null, defaultTargetPropertyName, userDelta); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, ItemPath defaultTargetPropertyPath, ObjectDelta userDelta) throws SchemaException, IOException, JAXBException, EncryptionException { PrismObject userOld = null; @@ -147,7 +147,7 @@ public Mapping,PrismPropertyDefinition> createMappi return createMapping(filename, testName, policy, defaultTargetPropertyPath, userDelta, userOld); } - public Mapping,PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, + public Mapping, PrismPropertyDefinition> createMapping(String filename, String testName, final StringPolicyType policy, ItemPath defaultTargetPropertyPath, ObjectDelta userDelta, PrismObject userOld) throws SchemaException, IOException, JAXBException { @@ -208,7 +208,7 @@ public StringPolicyType resolve() { return mapping; } - public Mapping,PrismPropertyDefinition> createInboudMapping(String filename, String testName, ItemDelta delta, UserType user, ShadowType account, ResourceType resource, final StringPolicyType policy) throws SchemaException, IOException, JAXBException{ + public Mapping, PrismPropertyDefinition> createInboudMapping(String filename, String testName, ItemDelta delta, UserType user, ShadowType account, ResourceType resource, final StringPolicyType policy) throws SchemaException, IOException, JAXBException{ MappingType mappingType = PrismTestUtil.parseAtomicValue( new File(TEST_DIR, filename), MappingType.COMPLEX_TYPE); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java index 9b5891facf0..ef89fb6833f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java @@ -19,15 +19,18 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.List; import javax.xml.namespace.QName; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; +import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.MappingFactory; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Definition; import com.evolveum.midpoint.prism.Item; @@ -98,6 +101,7 @@ public class Construction implements DebugDumpable, Seriali private Collection,? extends PrismPropertyDefinition>> attributeMappings; private Collection,PrismContainerDefinition>> associationMappings; private RefinedObjectClassDefinition refinedObjectClassDefinition; + private List auxiliaryObjectClassDefinitions; private AssignmentPathVariables assignmentPathVariables = null; private PrismContext prismContext; private PrismContainerDefinition associationContainerDefinition; @@ -182,6 +186,14 @@ public void setMappingFactory(MappingFactory mappingFactory) { public RefinedObjectClassDefinition getRefinedObjectClassDefinition() { return refinedObjectClassDefinition; } + + public void setRefinedObjectClassDefinition(RefinedObjectClassDefinition refinedObjectClassDefinition) { + this.refinedObjectClassDefinition = refinedObjectClassDefinition; + } + + public List getAuxiliaryObjectClassDefinitions() { + return auxiliaryObjectClassDefinitions; + } public ShadowKindType getKind() { if (refinedObjectClassDefinition == null) { @@ -208,7 +220,7 @@ public Collection,? extends PrismPropert return attributeMappings; } - public Mapping,? extends PrismPropertyDefinition> getAttributeMapping(QName attrName) { + public Mapping, ? extends PrismPropertyDefinition> getAttributeMapping(QName attrName) { for (Mapping,? extends PrismPropertyDefinition> myVc : getAttributeMappings()) { if (myVc.getItemName().equals(attrName)) { return myVc; @@ -278,13 +290,13 @@ public ResourceType getResource(OperationResult result) throws ObjectNotFoundExc } public void evaluate(Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { - evaluateKindIntent(result); + evaluateKindIntentObjectClass(result); assignmentPathVariables = LensUtil.computeAssignmentPathVariables(assignmentPath); evaluateAttributes(task, result); evaluateAssociations(task, result); } - private void evaluateKindIntent(OperationResult result) throws SchemaException, ObjectNotFoundException { + private void evaluateKindIntentObjectClass(OperationResult result) throws SchemaException, ObjectNotFoundException { String resourceOid = null; if (constructionType.getResourceRef() != null) { resourceOid = constructionType.getResourceRef().getOid(); @@ -316,6 +328,15 @@ private void evaluateKindIntent(OperationResult result) throws SchemaException, throw new SchemaException("No default "+kind+" type found in " + resource + " as specified in construction in "+source); } } + + auxiliaryObjectClassDefinitions = new ArrayList<>(constructionType.getAuxiliaryObjectClass().size()); + for (QName auxiliaryObjectClassName: constructionType.getAuxiliaryObjectClass()) { + RefinedObjectClassDefinition auxOcDef = refinedSchema.getRefinedDefinition(auxiliaryObjectClassName); + if (auxOcDef == null) { + throw new SchemaException("No auxiliary object class "+auxiliaryObjectClassName+" found in "+getResource(result)+" as specified in construction in "+source); + } + auxiliaryObjectClassDefinitions.add(auxOcDef); + } } private void evaluateAttributes(Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { @@ -341,7 +362,7 @@ private void evaluateAttributes(Task task, OperationResult result) throws Expres } } - private Mapping,ResourceAttributeDefinition> evaluateAttribute(ResourceAttributeDefinitionType attribudeDefinitionType, + private Mapping, ResourceAttributeDefinition> evaluateAttribute(ResourceAttributeDefinitionType attribudeDefinitionType, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { QName attrName = ItemPathUtil.getOnlySegmentQName(attribudeDefinitionType.getRef()); @@ -362,14 +383,27 @@ private Mapping,ResourceAttributeDefinition> evalua Mapping,ResourceAttributeDefinition> mapping = mappingFactory.createMapping(outboundMappingType, "for attribute " + PrettyPrinter.prettyPrint(attrName) + " in "+source); - Mapping,ResourceAttributeDefinition> evaluatedMapping = evaluateMapping(mapping, attrName, outputDefinition, null, task, result); + Mapping, ResourceAttributeDefinition> evaluatedMapping = evaluateMapping(mapping, attrName, outputDefinition, null, task, result); LOGGER.trace("Evaluated mapping for attribute "+attrName+": "+evaluatedMapping); return evaluatedMapping; } - private ResourceAttributeDefinition findAttributeDefinition(QName attributeName) { - return refinedObjectClassDefinition.findAttributeDefinition(attributeName); + public RefinedAttributeDefinition findAttributeDefinition(QName attributeName) { + if (refinedObjectClassDefinition == null) { + throw new IllegalStateException("Construction "+this+" was not evaluated:\n"+this.debugDump()); + } + RefinedAttributeDefinition attrDef = refinedObjectClassDefinition.findAttributeDefinition(attributeName); + if (attrDef != null) { + return attrDef; + } + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + attrDef = auxiliaryObjectClassDefinition.findAttributeDefinition(attributeName); + if (attrDef != null) { + return attrDef; + } + } + return null; } public boolean hasValueForAttribute(QName attributeName) { @@ -402,7 +436,7 @@ private void evaluateAssociations(Task task, OperationResult result) throws Expr } } - private Mapping,PrismContainerDefinition> evaluateAssociation(ResourceObjectAssociationType associationDefinitionType, + private Mapping, PrismContainerDefinition> evaluateAssociation(ResourceObjectAssociationType associationDefinitionType, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { QName assocName = ItemPathUtil.getOnlySegmentQName(associationDefinitionType.getRef()); @@ -425,14 +459,14 @@ private Mapping,PrismContainerDefinit +" in construction in "+source); } - Mapping,PrismContainerDefinition> evaluatedMapping = evaluateMapping(mapping, assocName, outputDefinition, + Mapping, PrismContainerDefinition> evaluatedMapping = evaluateMapping(mapping, assocName, outputDefinition, rAssocDef.getAssociationTarget(), task, result); LOGGER.trace("Evaluated mapping for association "+assocName+": "+evaluatedMapping); return evaluatedMapping; } - private Mapping evaluateMapping(Mapping mapping, QName mappingQName, D outputDefinition, + private Mapping evaluateMapping(Mapping mapping, QName mappingQName, D outputDefinition, RefinedObjectClassDefinition assocTargetObjectClassDefinition, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { @@ -551,6 +585,17 @@ public String debugDump(int indent) { } else { sb.append(refinedObjectClassDefinition.getShadowDiscriminator()); } + DebugUtil.debugDumpLabel(sb, "auxiliary object classes", indent+1); + if (auxiliaryObjectClassDefinitions == null) { + sb.append(" (null)"); + } else { + sb.append("\n"); + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent+2); + sb.append(auxiliaryObjectClassDefinition.getTypeName()); + } + } if (attributeMappings != null && !attributeMappings.isEmpty()) { sb.append("\n"); DebugUtil.debugDumpLabel(sb, "attribute mappings", indent+1); @@ -576,7 +621,7 @@ public String debugDump(int indent) { @Override public String toString() { - return "Construction(" + (refinedObjectClassDefinition == null ? "unknown" : refinedObjectClassDefinition.getShadowDiscriminator()) + ")"; + return "Construction(" + (refinedObjectClassDefinition == null ? constructionType : refinedObjectClassDefinition.getShadowDiscriminator()) + ")"; } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 3fd4b1dbb55..1c343cf41fc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.model.common.expression.ItemDeltaItem; import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismObject; @@ -263,7 +264,7 @@ public String debugDump(int indent) { if (!focusMappings.isEmpty()) { sb.append("\n"); DebugUtil.debugDumpLabel(sb, "Focus Mappings", indent+1); - for (Mapping,? extends PrismPropertyDefinition> mapping: focusMappings) { + for (PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> mapping: focusMappings) { sb.append("\n"); DebugUtil.indentDebugDump(sb, indent+2); sb.append(mapping.toString()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ItemValueWithOrigin.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ItemValueWithOrigin.java index 5be9a32ced9..14ec5eda571 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ItemValueWithOrigin.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ItemValueWithOrigin.java @@ -18,7 +18,7 @@ import java.util.ArrayList; import java.util.Collection; -import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismValue; @@ -34,11 +34,11 @@ public class ItemValueWithOrigin implements DebugDumpable { private V itemValue; - private Mapping mapping; + private PrismValueDeltaSetTripleProducer mapping; private Construction construction; public ItemValueWithOrigin(V propertyValue, - Mapping mapping, Construction accountConstruction) { + PrismValueDeltaSetTripleProducer mapping, Construction accountConstruction) { super(); this.itemValue = propertyValue; this.mapping = mapping; @@ -60,7 +60,7 @@ public void setItemValue(V value) { this.itemValue = value; } - public Mapping getMapping() { + public PrismValueDeltaSetTripleProducer getMapping() { return mapping; } @@ -91,7 +91,7 @@ protected void copyValues(ItemValueWithOrigin clone) { clone.construction = this.construction; } - public static DeltaSetTriple> createOutputTriple(Mapping mapping) { + public static DeltaSetTriple> createOutputTriple(PrismValueDeltaSetTripleProducer mapping) { PrismValueDeltaSetTriple outputTriple = mapping.getOutputTriple(); if (outputTriple == null) { return null; @@ -103,7 +103,7 @@ public static DeltaSetTriple Collection> convertSet(Collection valueSet, Mapping mapping) { + private static Collection> convertSet(Collection valueSet, PrismValueDeltaSetTripleProducer mapping) { if (valueSet == null) { return null; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index cb11a874a7d..37e22f0cf64 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -170,6 +170,7 @@ public class LensProjectionContext extends LensElementContext implem private transient Map,PrismPropertyDefinition>>> squeezedAttributes; private transient Map,PrismContainerDefinition>>> squeezedAssociations; + private transient Map,PrismPropertyDefinition>>> squeezedAuxiliaryObjectClasses; // Cached copy, to avoid constructing it over and over again private transient PrismObjectDefinition shadowDefinition = null; @@ -481,6 +482,15 @@ public void setSqueezedAssociations( this.squeezedAssociations = squeezedAssociations; } + public Map, PrismPropertyDefinition>>> getSqueezedAuxiliaryObjectClasses() { + return squeezedAuxiliaryObjectClasses; + } + + public void setSqueezedAuxiliaryObjectClasses( + Map, PrismPropertyDefinition>>> squeezedAuxiliaryObjectClasses) { + this.squeezedAuxiliaryObjectClasses = squeezedAuxiliaryObjectClasses; + } + public ResourceObjectTypeDefinitionType getResourceObjectTypeDefinitionType() { if (synchronizationPolicyDecision == SynchronizationPolicyDecision.BROKEN) { return null; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java index 6f15b2ed1d4..55b74d49066 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java @@ -46,6 +46,7 @@ import com.evolveum.midpoint.model.common.expression.script.ScriptExpression; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.MappingFactory; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.model.impl.lens.projector.ValueMatcher; import com.evolveum.midpoint.model.impl.util.Utils; @@ -251,7 +252,7 @@ public void visit(I pvwo) { boolean zeroHasStrong = false; if (!zeroPvwos.isEmpty()) { for (ItemValueWithOrigin pvwo : zeroPvwos) { - Mapping mapping = pvwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = pvwo.getMapping(); if (mapping.getStrength() == MappingStrengthType.STRONG) { zeroHasStrong = true; } @@ -268,7 +269,7 @@ public void visit(I pvwo) { continue; } - Mapping exclusiveMapping = null; + PrismValueDeltaSetTripleProducer exclusiveMapping = null; Collection> pvwosToAdd = null; if (addUnchangedValues) { pvwosToAdd = MiscUtil.union(zeroPvwos, plusPvwos); @@ -282,7 +283,7 @@ public void visit(I pvwo) { // There may be several mappings that imply that value. So check them all for // exclusions and strength for (ItemValueWithOrigin pvwoToAdd : pvwosToAdd) { - Mapping mapping = pvwoToAdd.getMapping(); + PrismValueDeltaSetTripleProducer mapping = pvwoToAdd.getMapping(); if (mapping.getStrength() != MappingStrengthType.WEAK) { weakOnly = false; } @@ -340,7 +341,7 @@ public void visit(I pvwo) { // There may be several mappings that imply that value. So check them all for // exclusions and strength for (ItemValueWithOrigin pvwo : minusPvwos) { - Mapping mapping = pvwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = pvwo.getMapping(); if (mapping.getStrength() != MappingStrengthType.WEAK) { weakOnly = false; } @@ -392,7 +393,7 @@ public void visit(I pvwo) { // There may be several mappings that imply that value. So check them all for // exclusions and strength for (ItemValueWithOrigin pvwo : zeroPvwos) { - Mapping mapping = pvwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = pvwo.getMapping(); if (mapping.getStrength() != MappingStrengthType.WEAK) { weakOnly = false; } @@ -954,7 +955,7 @@ public static boolean isValid(AssignmentType assignmentType, XMLGregorianCalenda return effectiveStatus == ActivationStatusType.ENABLED; } - public static Mapping createFocusMapping(final MappingFactory mappingFactory, + public static Mapping createFocusMapping(final MappingFactory mappingFactory, final LensContext context, final MappingType mappingType, ObjectType originObject, ObjectDeltaObject focusOdo, AssignmentPathVariables assignmentPathVariables, PrismObject configuration, XMLGregorianCalendar now, String contextDesc, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { @@ -973,7 +974,7 @@ public static boolean isValid(AssignmentType assignmentType, XMLGregorianCalenda iteration, iterationToken, configuration, now, contextDesc, result); } - public static Mapping createFocusMapping(final MappingFactory mappingFactory, + public static Mapping createFocusMapping(final MappingFactory mappingFactory, final LensContext context, final MappingType mappingType, ObjectType originObject, ObjectDeltaObject focusOdo, AssignmentPathVariables assignmentPathVariables, Integer iteration, String iterationToken, PrismObject configuration, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java index c104b71468d..93b94d93174 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.model.api.PolicyViolationException; import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision; import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.Construction; import com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin; import com.evolveum.midpoint.model.impl.lens.LensContext; @@ -191,6 +192,50 @@ public Collection,PrismContai if (!squeezedAssociations.isEmpty()) { fillInAssociationNames(squeezedAssociations); } + + MappingExtractor,PrismPropertyDefinition,F> auxiliaryObjectClassExtractor = new MappingExtractor,PrismPropertyDefinition,F>() { + @Override + public Collection,PrismPropertyDefinition>> getMappings(final Construction construction) { + PrismValueDeltaSetTripleProducer,PrismPropertyDefinition> prod = new PrismValueDeltaSetTripleProducer,PrismPropertyDefinition>() { + @Override + public QName getMappingQName() { + return ShadowType.F_AUXILIARY_OBJECT_CLASS; + } + @Override + public PrismValueDeltaSetTriple> getOutputTriple() { + PrismValueDeltaSetTriple> triple = new PrismValueDeltaSetTriple<>(); + if (construction.getAuxiliaryObjectClassDefinitions() != null) { + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: construction.getAuxiliaryObjectClassDefinitions()) { + triple.addToZeroSet(new PrismPropertyValue(auxiliaryObjectClassDefinition.getTypeName())); + } + } + return triple; + } + @Override + public MappingStrengthType getStrength() { + return MappingStrengthType.STRONG; + } + @Override + public PrismValueDeltaSetTripleProducer,PrismPropertyDefinition> clone() { + return this; + } + @Override + public boolean isExclusive() { + return false; + } + @Override + public boolean isAuthoritative() { + return true; + } + }; + Collection,PrismPropertyDefinition>> col = new ArrayList<>(1); + col.add(prod); + return col; + } + }; + Map,PrismPropertyDefinition>>> squeezedAuxiliaryObjectClasses = + sqeeze(projCtx, auxiliaryObjectClassExtractor); + projCtx.setSqueezedAuxiliaryObjectClasses(squeezedAuxiliaryObjectClasses); ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator(); ObjectDelta objectDelta = new ObjectDelta(ShadowType.class, ChangeType.MODIFY, prismContext); @@ -250,6 +295,21 @@ public Collection,PrismContai } } + // AUXILIARY OBJECT CLASSES + for (Entry, PrismPropertyDefinition>>> entry : squeezedAuxiliaryObjectClasses.entrySet()) { + DeltaSetTriple, PrismPropertyDefinition>> ivwoTriple = entry.getValue(); + PropertyDelta propDelta = (PropertyDelta)new PropertyDelta<>(projCtx.getObjectDefinition().findPropertyDefinition(ShadowType.F_AUXILIARY_OBJECT_CLASS), prismContext); + for (ItemValueWithOrigin,PrismPropertyDefinition> ivwo: ivwoTriple.getPlusSet()) { + propDelta.addValueToAdd(ivwo.getItemValue()); + } + for (ItemValueWithOrigin,PrismPropertyDefinition> ivwo: ivwoTriple.getMinusSet()) { + propDelta.addValueToDelete(ivwo.getItemValue()); + } + if (!propDelta.isEmpty()) { + objectDelta.addModification(propDelta); + } + } + return objectDelta; } @@ -275,8 +335,13 @@ private PropertyDelta consolidateAttribute(RefinedOb boolean addUnchangedValues, boolean completeShadow, QName itemName, DeltaSetTriple,PrismPropertyDefinition>> triple) throws SchemaException, ExpressionEvaluationException, PolicyViolationException { + if (triple == null || triple.isEmpty()) { + return null; + } + + RefinedAttributeDefinition attributeDefinition = triple.getAnyValue().getConstruction().findAttributeDefinition(itemName); + ItemPath itemPath = new ItemPath(ShadowType.F_ATTRIBUTES, itemName); - RefinedAttributeDefinition attributeDefinition = rOcDef.findAttributeDefinition(itemName); if (attributeDefinition.isIgnored(LayerType.MODEL)) { LOGGER.trace("Skipping processing mappings for attribute {} because it is ignored", itemName); @@ -441,7 +506,7 @@ private boolean hasActiveWeakMap DeltaSetTriple> ivwoTriple = entry.getValue(); boolean hasWeak = false; for (ItemValueWithOrigin ivwo: ivwoTriple.getAllValues()) { - Mapping mapping = ivwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = ivwo.getMapping(); if (mapping.getStrength() == MappingStrengthType.WEAK) { // We only care about mappings that change something. If the weak mapping is not // changing anything then it will not be applied in this step anyway. Therefore @@ -463,7 +528,7 @@ private boolean hasActiveWeakMap // unless we fetch the real values. if (ivwoTriple.hasMinusSet()) { for (ItemValueWithOrigin ivwo: ivwoTriple.getMinusSet()) { - Mapping mapping = ivwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = ivwo.getMapping(); PrismValueDeltaSetTriple outputTriple = mapping.getOutputTriple(); if (outputTriple != null && !outputTriple.isEmpty()) { return true; @@ -471,7 +536,7 @@ private boolean hasActiveWeakMap } } for (ItemValueWithOrigin ivwo: ivwoTriple.getNonNegativeValues()) { - Mapping mapping = ivwo.getMapping(); + PrismValueDeltaSetTripleProducer mapping = ivwo.getMapping(); PrismValueDeltaSetTriple outputTriple = mapping.getOutputTriple(); if (outputTriple != null && outputTriple.hasMinusSet()) { return true; @@ -707,7 +772,7 @@ private vo private void sqeezeAttributesFromConstruction( Map>> squeezedMap, Construction construction, MappingExtractor extractor) { - for (Mapping mapping: extractor.getMappings(construction)) { + for (PrismValueDeltaSetTripleProducer mapping: extractor.getMappings(construction)) { PrismValueDeltaSetTriple vcTriple = mapping.getOutputTriple(); if (vcTriple == null) { continue; @@ -723,7 +788,7 @@ private vo private void sqeezeAttributesFromConstructionNonminusToPlus( Map>> squeezedMap, Construction construction, MappingExtractor extractor) { - for (Mapping mapping: extractor.getMappings(construction)) { + for (PrismValueDeltaSetTripleProducer mapping: extractor.getMappings(construction)) { PrismValueDeltaSetTriple vcTriple = mapping.getOutputTriple(); if (vcTriple == null) { continue; @@ -739,7 +804,7 @@ private vo private void sqeezeAttributesFromConstructionNonminusToMinus( Map>> squeezedMap, Construction construction, MappingExtractor extractor) { - for (Mapping mapping: extractor.getMappings(construction)) { + for (PrismValueDeltaSetTripleProducer mapping: extractor.getMappings(construction)) { PrismValueDeltaSetTriple vcTriple = mapping.getOutputTriple(); if (vcTriple == null) { continue; @@ -754,7 +819,7 @@ private vo private void convertSqueezeSet(Collection fromSet, Collection> toSet, - Mapping valueConstruction, Construction accountConstruction) { + PrismValueDeltaSetTripleProducer valueConstruction, Construction accountConstruction) { if (fromSet != null) { for (V from: fromSet) { ItemValueWithOrigin pvwo = new ItemValueWithOrigin(from, valueConstruction, accountConstruction); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingExtractor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingExtractor.java index 0561a5277e3..d8c4cbb4370 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingExtractor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingExtractor.java @@ -18,6 +18,7 @@ import java.util.Collection; import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.Construction; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismValue; @@ -25,6 +26,7 @@ public interface MappingExtractor { - Collection> getMappings(Construction construction); + Collection> getMappings(Construction construction); + } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java index db128f2355d..b752785896f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java @@ -31,6 +31,7 @@ import com.evolveum.midpoint.model.common.expression.StringPolicyResolver; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.MappingFactory; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.Construction; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; @@ -117,6 +118,9 @@ public void processOutbound(LensContext context, LensPr ObjectDeltaObject projectionOdo = projCtx.getObjectDeltaObject(); Construction outboundConstruction = new Construction<>(null, projCtx.getResource()); + outboundConstruction.setRefinedObjectClassDefinition(rOcDef); + + // TODO: Auxiliary object classes String operation = projCtx.getOperation().getValue(); @@ -175,7 +179,7 @@ public void processOutbound(LensContext context, LensPr projCtx.setOutboundConstruction(outboundConstruction); } - private Mapping evaluateMapping(final Mapping mapping, QName mappingQName, + private Mapping evaluateMapping(final Mapping mapping, QName mappingQName, D targetDefinition, ObjectDeltaObject focusOdo, ObjectDeltaObject projectionOdo, String operation, RefinedObjectClassDefinition rOcDef, RefinedObjectClassDefinition assocTargetObjectClassDefinition, LensContext context, LensProjectionContext projCtx, Task task, OperationResult result) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java index 962bada5ae8..d4c21fc3b1a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java @@ -39,6 +39,7 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision; import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; @@ -286,7 +287,7 @@ private void reconcileProjectionAttributes( boolean hasValue = false; for (ItemValueWithOrigin,PrismPropertyDefinition> shouldBePvwo : shouldBePValues) { - Mapping shouldBeMapping = shouldBePvwo.getMapping(); + PrismValueDeltaSetTripleProducer shouldBeMapping = shouldBePvwo.getMapping(); if (shouldBeMapping == null) { continue; } @@ -422,7 +423,7 @@ private void reconcileProjectionAssociations( for (ItemValueWithOrigin,PrismContainerDefinition> shouldBeCValue : shouldBeCValues) { sb.append("\n "); sb.append(shouldBeCValue.getItemValue()); - Mapping shouldBeMapping = shouldBeCValue.getMapping(); + PrismValueDeltaSetTripleProducer shouldBeMapping = shouldBeCValue.getMapping(); if (shouldBeMapping.getStrength() == MappingStrengthType.STRONG) { sb.append(" STRONG"); } @@ -494,7 +495,7 @@ private void checkType(Object o) { }; for (ItemValueWithOrigin,PrismContainerDefinition> shouldBeCvwo : shouldBeCValues) { - Mapping shouldBeMapping = shouldBeCvwo.getMapping(); + PrismValueDeltaSetTripleProducer shouldBeMapping = shouldBeCvwo.getMapping(); if (shouldBeMapping == null) { continue; } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentEvaluator.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentEvaluator.java index 877479fe8ca..8d9b5f3cd3d 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentEvaluator.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentEvaluator.java @@ -51,6 +51,7 @@ import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.MappingFactory; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest; import com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator; import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl; @@ -237,7 +238,7 @@ public void testDirectExpressionReplaceDescription() throws Exception { Construction construction = evaluatedAssignment.getConstructions().getZeroSet().iterator().next(); assertNotNull("No object class definition in construction", construction.getRefinedObjectClassDefinition()); assertEquals(1,construction.getAttributeMappings().size()); - Mapping,PrismPropertyDefinition> attributeMapping = (Mapping,PrismPropertyDefinition>) construction.getAttributeMappings().iterator().next(); + Mapping, PrismPropertyDefinition> attributeMapping = (Mapping, PrismPropertyDefinition>) construction.getAttributeMappings().iterator().next(); PrismValueDeltaSetTriple> outputTriple = attributeMapping.getOutputTriple(); PrismAsserts.assertTripleNoZero(outputTriple); PrismAsserts.assertTriplePlus(outputTriple, "The best captain the world has ever seen"); @@ -304,7 +305,7 @@ public void testDirectExpressionReplaceDescriptionFromNull() throws Exception { Construction construction = evaluatedAssignment.getConstructions().getZeroSet().iterator().next(); assertNotNull("No object class definition in construction", construction.getRefinedObjectClassDefinition()); assertEquals(1,construction.getAttributeMappings().size()); - Mapping,PrismPropertyDefinition> attributeMapping = (Mapping,PrismPropertyDefinition>) construction.getAttributeMappings().iterator().next(); + PrismValueDeltaSetTripleProducer, PrismPropertyDefinition> attributeMapping = (PrismValueDeltaSetTripleProducer, PrismPropertyDefinition>) construction.getAttributeMappings().iterator().next(); PrismValueDeltaSetTriple> outputTriple = attributeMapping.getOutputTriple(); PrismAsserts.assertTripleNoZero(outputTriple); PrismAsserts.assertTriplePlus(outputTriple, "The best sailor the world has ever seen"); @@ -634,7 +635,7 @@ public void testRoleManagerRemoveCostCenter() throws Exception { private void assertNoConstruction(EvaluatedAssignmentImpl evaluatedAssignment, PlusMinusZero constructionSet, String attributeName) { Collection> constructions = evaluatedAssignment.getConstructionSet(constructionSet); for (Construction construction : constructions) { - Mapping,? extends PrismPropertyDefinition> mapping = construction.getAttributeMapping(new QName(MidPointConstants.NS_RI, attributeName)); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> mapping = construction.getAttributeMapping(new QName(MidPointConstants.NS_RI, attributeName)); assertNull("Unexpected mapping for " + attributeName, mapping); } } @@ -643,7 +644,7 @@ private void assertConstruction(EvaluatedAssignmentImpl evaluatedAssig Collection> constructions = evaluatedAssignment.getConstructionSet(constructionSet); Set realValues = new HashSet<>(); for (Construction construction : constructions) { - Mapping,? extends PrismPropertyDefinition> mapping = construction.getAttributeMapping(new QName(MidPointConstants.NS_RI, attributeName)); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> mapping = construction.getAttributeMapping(new QName(MidPointConstants.NS_RI, attributeName)); if (mapping != null && mapping.getOutputTriple() != null) { Collection> valsInMapping = mapping.getOutputTriple().getSet(attributeSet); if (valsInMapping != null) { diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor.java index e94c4b6f9ec..6e7cb8fd8a3 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.model.common.mapping.Mapping; +import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.projector.AssignmentProcessor; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; @@ -659,7 +660,7 @@ private void assertAttributeValues(Collection Set getAttributeValues(Collection> accountConstructions, QName attrName, PlusMinusZero attributeSet) { Set retval = new HashSet<>(); for (PrismPropertyValue constructionPropVal : accountConstructions) { - Mapping,? extends PrismPropertyDefinition> mapping = constructionPropVal.getValue().getAttributeMapping(attrName); + Mapping, ? extends PrismPropertyDefinition> mapping = constructionPropVal.getValue().getAttributeMapping(attrName); if (mapping != null && mapping.getOutputTriple() != null) { Collection> values = (Collection) mapping.getOutputTriple().getSet(attributeSet); if (values != null) { @@ -673,7 +674,7 @@ private Set getAttributeValues(Collection void assertPlusAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in plus set", vc); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); Collection actual = getMultiValueFromDeltaSetTriple(triple, triple.getPlusSet()); @@ -681,7 +682,7 @@ private void assertPlusAttributeValues(Construction accountConstruction, QNa } private void assertZeroAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in zero set", vc); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); Collection actual = getMultiValueFromDeltaSetTriple(triple, triple.getZeroSet()); @@ -689,7 +690,7 @@ private void assertZeroAttributeValues(Construction accountConstruction, QNa } private void assertMinusAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in minus set", vc); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); Collection actual = getMultiValueFromDeltaSetTriple(triple, triple.getMinusSet()); @@ -697,19 +698,19 @@ private void assertMinusAttributeValues(Construction accountConstruction, QN } private void assertNoPlusAttributeValues(Construction accountConstruction, QName attrName) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoPlus(triple); } private void assertNoZeroAttributeValues(Construction accountConstruction, QName attrName) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoZero(triple); } private void assertNoMinusAttributeValues(Construction accountConstruction, QName attrName) { - Mapping,? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); + PrismValueDeltaSetTripleProducer, ? extends PrismPropertyDefinition> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoMinus(triple); } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index 5b71214664b..8cca5b3c337 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -253,7 +253,7 @@ public void test010Schema() throws Exception { public void test100AddUserHermanBasic() throws Exception { final String TEST_NAME = "test100AddHrAccountHerman"; TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject user = createUser(USER_HERMAN_USERNAME, USER_HERMAN_FIST_NAME, USER_HERMAN_LAST_NAME, null, ROLE_BASIC_OID); @@ -264,6 +264,8 @@ public void test100AddUserHermanBasic() throws Exception { // THEN TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); PrismObject userAfter = findUserByUsername(USER_HERMAN_USERNAME); assertNotNull("No herman user", userAfter); display("User after", userAfter); @@ -279,7 +281,7 @@ public void test100AddUserHermanBasic() throws Exception { public void test110AddUserMancombUnix() throws Exception { final String TEST_NAME = "test110AddUserMancombUnix"; TestUtil.displayTestTile(this, TEST_NAME); - Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject user = createUser(USER_MANCOMB_USERNAME, USER_MANCOMB_FIST_NAME, USER_MANCOMB_LAST_NAME, 1001, ROLE_UNIX_OID); @@ -290,6 +292,8 @@ public void test110AddUserMancombUnix() throws Exception { // THEN TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); PrismObject userAfter = findUserByUsername(USER_MANCOMB_USERNAME); assertNotNull("No herman user", userAfter); display("User after", userAfter); diff --git a/testing/story/src/test/resources/unix/role-unix.xml b/testing/story/src/test/resources/unix/role-unix.xml index 94869dd340a..0e212b667bd 100644 --- a/testing/story/src/test/resources/unix/role-unix.xml +++ b/testing/story/src/test/resources/unix/role-unix.xml @@ -27,6 +27,38 @@ account ri:posixAccount + + ri:uidNumber + + strong + + extension/uidNumber + + + + + ri:gidNumber + + strong + + extension/uidNumber + + + + + ri:homeDirectory + + strong + + name + + + + + + From 700c72bd8537aaed7237b89d2a43f36605f98f76 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 10:36:20 +0200 Subject: [PATCH 10/16] Possibly fixing intent handling --- .../common/refinery/RefinedObjectClassDefinition.java | 3 +++ .../midpoint/common/refinery/RefinedResourceSchema.java | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index a0ef7fef30d..b64b0bcf539 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -457,6 +457,9 @@ static RefinedObjectClassDefinition parse(ResourceObjectTypeDefinitionType entTy kind = ShadowKindType.ACCOUNT; } String intent = entTypeDefType.getIntent(); + if (intent == null) { + intent = SchemaConstants.INTENT_DEFAULT; + } RefinedObjectClassDefinition rObjectClassDef = parseRefinedObjectClass(entTypeDefType, resourceType, rSchema, prismContext, kind, intent, kind.value(), kind.value() + " type definition '"+intent+"' in " + contextDescription); diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index 3c9d9caea2f..50b1e185841 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -110,7 +110,10 @@ public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, St if (intent == null && acctDef.isDefault()) { return acctDef; } - if (acctDef.getIntent().equals(intent)) { + if (acctDef.getIntent() != null && acctDef.getIntent().equals(intent)) { + return acctDef; + } + if (acctDef.getIntent() == null && intent == null) { return acctDef; } } From 7540ff5cf653f936ef9b8ee5960303002aebd218 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 10:49:28 +0200 Subject: [PATCH 11/16] Fixing TestImportReconDeprecated --- .../model/intest/sync/TestImportReconDeprecated.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportReconDeprecated.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportReconDeprecated.java index 33648de8adf..7571a0d845d 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportReconDeprecated.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportReconDeprecated.java @@ -107,5 +107,11 @@ public void test502ImportAugustusFromResourceDummy() throws Exception { public void test510ImportFromResourceDummy() throws Exception { // Not relevant for deprecated syntax } + + @Override + public void test900DeleteDummyShadows() throws Exception { + // Not relevant for deprecated syntax + } + } From 108ec11becbae08bbd2b0b5ca5206b6016d1e860 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 11:37:58 +0200 Subject: [PATCH 12/16] Fixed intent handling, extended tests --- .../RefinedObjectClassDefinition.java | 3 + .../refinery/RefinedResourceSchema.java | 4 +- .../intest/negative/TestAssignmentErrors.java | 66 +++++++++++++++++++ .../provisioning/test/impl/TestDummy.java | 12 +++- .../midpoint/test/DummyResourceContoller.java | 5 ++ .../resources/orgsync/resource-opendj.xml | 2 + 6 files changed, 87 insertions(+), 5 deletions(-) diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index b64b0bcf539..8a79450fe54 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -515,6 +515,9 @@ static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefini RefinedObjectClassDefinition rOcDef = new RefinedObjectClassDefinition(prismContext, resourceType, objectClassDef); String intent = objectClassDef.getIntent(); + if (intent == null && objectClassDef.isDefaultInAKind()) { + intent = SchemaConstants.INTENT_DEFAULT; + } rOcDef.setIntent(intent); if (objectClassDef.getDisplayName() != null) { diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index 50b1e185841..d03046991c7 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -459,10 +459,10 @@ private static void parseObjectTypesFromSchema(RefinedResourceSchema rSchema, Re RefinedObjectClassDefinition rAccountDefDefault = null; for(ObjectClassComplexTypeDefinition objectClassDef: rSchema.getOriginalResourceSchema().getObjectClassDefinitions()) { - if (rSchema.getRefinedDefinition(objectClassDef.getTypeName()) != null) { + QName objectClassname = objectClassDef.getTypeName(); + if (rSchema.getRefinedDefinition(objectClassname) != null) { continue; } - QName objectClassname = objectClassDef.getTypeName(); RefinedObjectClassDefinition rOcDef = RefinedObjectClassDefinition.parseFromSchema(objectClassDef, resourceType, rSchema, prismContext, "object class " + objectClassname + ", in " + contextDescription); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java index af582ef5f47..031fc776b6f 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java @@ -17,6 +17,8 @@ import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; import static com.evolveum.midpoint.test.util.TestUtil.assertFailure; import static com.evolveum.midpoint.test.IntegrationTestTools.assertNoRepoCache; import static com.evolveum.midpoint.test.IntegrationTestTools.display; @@ -26,6 +28,9 @@ import java.util.Collection; import java.util.Iterator; +import javax.xml.namespace.QName; + +import org.apache.commons.lang.StringUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -33,13 +38,18 @@ import org.testng.annotations.Test; import com.evolveum.icf.dummy.resource.BreakMode; +import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; +import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.intest.AbstractInitializedModelIntegrationTest; import com.evolveum.midpoint.model.intest.TestModelServiceContract; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; @@ -96,6 +106,62 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti super.initSystem(initTask, initResult); } + @Test + public void test010RefinedSchemaWhite() throws Exception { + final String TEST_NAME = "test010RefinedSchemaWhite"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + + // WHEN + PrismObject resourceWhite = getObject(ResourceType.class, RESOURCE_DUMMY_WHITE_OID); + RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceWhite, prismContext); + display("Refined schema", refinedSchema); + + RefinedObjectClassDefinition accountDef = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); + assertNotNull("Account definition is missing", accountDef); + assertNotNull("Null identifiers in account", accountDef.getIdentifiers()); + assertFalse("Empty identifiers in account", accountDef.getIdentifiers().isEmpty()); + assertNotNull("Null secondary identifiers in account", accountDef.getSecondaryIdentifiers()); + assertFalse("Empty secondary identifiers in account", accountDef.getSecondaryIdentifiers().isEmpty()); + assertNotNull("No naming attribute in account", accountDef.getNamingAttribute()); + assertFalse("No nativeObjectClass in account", StringUtils.isEmpty(accountDef.getNativeObjectClass())); + + assertEquals("Unexpected kind in account definition", ShadowKindType.ACCOUNT, accountDef.getKind()); + assertTrue("Account definition in not default", accountDef.isDefaultInAKind()); + assertEquals("Wrong intent in account definition", SchemaConstants.INTENT_DEFAULT, accountDef.getIntent()); + assertFalse("Account definition is deprecated", accountDef.isDeprecated()); + assertFalse("Account definition in auxiliary", accountDef.isAuxiliary()); + + RefinedAttributeDefinition uidDef = accountDef.findAttributeDefinition(ConnectorFactoryIcfImpl.ICFS_UID); + assertEquals(1, uidDef.getMaxOccurs()); + assertEquals(0, uidDef.getMinOccurs()); + assertFalse("No UID display name", StringUtils.isBlank(uidDef.getDisplayName())); + assertFalse("UID has create", uidDef.canAdd()); + assertFalse("UID has update", uidDef.canModify()); + assertTrue("No UID read", uidDef.canRead()); + assertTrue("UID definition not in identifiers", accountDef.getIdentifiers().contains(uidDef)); + + RefinedAttributeDefinition nameDef = accountDef.findAttributeDefinition(ConnectorFactoryIcfImpl.ICFS_NAME); + assertEquals(1, nameDef.getMaxOccurs()); + assertEquals(1, nameDef.getMinOccurs()); + assertFalse("No NAME displayName", StringUtils.isBlank(nameDef.getDisplayName())); + assertTrue("No NAME create", nameDef.canAdd()); + assertTrue("No NAME update", nameDef.canModify()); + assertTrue("No NAME read", nameDef.canRead()); + assertTrue("NAME definition not in identifiers", accountDef.getSecondaryIdentifiers().contains(nameDef)); + + RefinedAttributeDefinition fullnameDef = accountDef.findAttributeDefinition("fullname"); + assertNotNull("No definition for fullname", fullnameDef); + assertEquals(1, fullnameDef.getMaxOccurs()); + assertEquals(1, fullnameDef.getMinOccurs()); + assertTrue("No fullname create", fullnameDef.canAdd()); + assertTrue("No fullname update", fullnameDef.canModify()); + assertTrue("No fullname read", fullnameDef.canRead()); + + assertNull("The _PASSSWORD_ attribute sneaked into schema", + accountDef.findAttributeDefinition(new QName(ConnectorFactoryIcfImpl.NS_ICF_SCHEMA, "password"))); + } + /** * The "white" resource has no outbound mapping and there is also no mapping in the assignment. Therefore * this results in account without any attributes. It should fail. diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java index 0a5c63abf71..06780b86bc5 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java @@ -476,9 +476,9 @@ public void test005ParsedSchema() throws ObjectNotFoundException, CommunicationE } @Test - public void test006RefinedSchema() throws ObjectNotFoundException, CommunicationException, SchemaException, - ConfigurationException { - TestUtil.displayTestTile("test006RefinedSchema"); + public void test006RefinedSchema() throws Exception { + final String TEST_NAME = "test006RefinedSchema"; + TestUtil.displayTestTile(TEST_NAME); // GIVEN // WHEN @@ -500,6 +500,12 @@ public void test006RefinedSchema() throws ObjectNotFoundException, Communication assertFalse("Empty secondary identifiers in account", accountDef.getSecondaryIdentifiers().isEmpty()); assertNotNull("No naming attribute in account", accountDef.getNamingAttribute()); assertFalse("No nativeObjectClass in account", StringUtils.isEmpty(accountDef.getNativeObjectClass())); + + assertEquals("Unexpected kind in account definition", ShadowKindType.ACCOUNT, accountDef.getKind()); + assertTrue("Account definition in not default", accountDef.isDefaultInAKind()); + assertEquals("Wrong intent in account definition", SchemaConstants.INTENT_DEFAULT, accountDef.getIntent()); + assertFalse("Account definition is deprecated", accountDef.isDeprecated()); + assertFalse("Account definition in auxiliary", accountDef.isAuxiliary()); RefinedAttributeDefinition uidDef = accountDef.findAttributeDefinition(ConnectorFactoryIcfImpl.ICFS_UID); assertEquals(1, uidDef.getMaxOccurs()); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java index 8853f3d960a..798b1ace1fa 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyResourceContoller.java @@ -263,6 +263,11 @@ public void assertDummyResourceSchemaSanityExtended(ResourceSchema resourceSchem assertEquals("Unexpected number of defnitions", 17, accountDef.getDefinitions().size()); ResourceAttributeDefinition treasureDef = accountDef.findAttributeDefinition(DUMMY_ACCOUNT_ATTRIBUTE_TREASURE_NAME); assertFalse("Treasure IS returned by default and should not be", treasureDef.isReturnedByDefault()); + assertEquals("Unexpected kind in account definition", ShadowKindType.ACCOUNT, accountDef.getKind()); + assertTrue("Account definition in not default", accountDef.isDefaultInAKind()); + assertNull("Non-null intent in account definition", accountDef.getIntent()); + assertFalse("Account definition is deprecated", accountDef.isDeprecated()); + assertFalse("Account definition in auxiliary", accountDef.isAuxiliary()); } public void assertRefinedSchemaSanity(RefinedResourceSchema refinedSchema) { diff --git a/testing/story/src/test/resources/orgsync/resource-opendj.xml b/testing/story/src/test/resources/orgsync/resource-opendj.xml index dd6d39fdf73..4799fbe76dd 100644 --- a/testing/story/src/test/resources/orgsync/resource-opendj.xml +++ b/testing/story/src/test/resources/orgsync/resource-opendj.xml @@ -177,6 +177,8 @@ objectToSubject ri:uniqueMember ri:dn + ri:isMemberOf + ri:dn From 5da2535cc000ecd89beacdbf73ebd2ace010bcc8 Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Tue, 23 Jun 2015 12:46:54 +0200 Subject: [PATCH 13/16] improving report service, fixing parsing for any elements.. --- .../prism/parser/PrismBeanConverter.java | 43 ++++++++++++++++--- .../prism/parser/PrismBeanInspector.java | 22 ++++++++++ .../midpoint/prism/parser/QueryConvertor.java | 17 ++------ .../xml/ns/public/report/report-3.wsdl | 13 ++++-- .../functions/BasicExpressionFunctions.java | 18 +++++++- .../expression/script/ScriptExpression.java | 4 +- .../expression/script/TestScriptCaching.java | 1 + .../ds/impl/MidPointRemoteQueryExecutor.java | 10 ++--- .../test/MidPointRemoteQueryExecuterTest.java | 4 +- .../midpoint/report/impl/ReportFunctions.java | 14 ++++++ .../report/impl/ReportWebService.java | 32 +++++--------- 11 files changed, 123 insertions(+), 55 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java index 575dc2288d8..433c21a62f2 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java @@ -216,14 +216,27 @@ public T unmarshall(MapXNode xnode, Class beanClass) throws SchemaExcepti objectFactory = instantiateObjectFactory(objectFactoryClass); elementMethod = inspector.findElementMethodInObjectFactory(objectFactoryClass, propName); if (elementMethod == null) { - throw new SchemaException("No field "+propName+" in class "+beanClass+" (and no element method in object factory too)"); + // Check for "any" method + elementMethod = inspector.findAnyMethod(beanClass); + if (elementMethod == null) { + throw new SchemaException("No field "+propName+" in class "+beanClass+" (and no element method in object factory too)"); + } + unmarshallToAny(bean, elementMethod, key, xsubnode); + continue; + } field = inspector.lookupSubstitution(beanClass, elementMethod); if (field == null) { // Check for "any" field field = inspector.findAnyField(beanClass); if (field == null) { - throw new SchemaException("No field "+propName+" in class "+beanClass+" (no suitable substitution and no 'any' field)"); + elementMethod = inspector.findAnyMethod(beanClass); + if (elementMethod == null) { + throw new SchemaException("No field "+propName+" in class "+beanClass+" (and no element method in object factory too)"); + } + unmarshallToAny(bean, elementMethod, key, xsubnode); + continue; +// throw new SchemaException("No field "+propName+" in class "+beanClass+" (no suitable substitution and no 'any' field)"); } unmarshallToAny(bean, field, key, xsubnode); continue; @@ -434,15 +447,29 @@ public T unmarshall(MapXNode xnode, Class beanClass) throws SchemaExcepti return bean; } - private void unmarshallToAny(T bean, Field anyField, QName elementName, XNode xsubnode) throws SchemaException{ + private void unmarshallToAny(T bean, Method getter, QName elementName, XNode xsubnode) throws SchemaException{ Class beanClass = (Class) bean.getClass(); Class objectFactoryClass = inspector.getObjectFactoryClass(elementName.getNamespaceURI()); Object objectFactory = instantiateObjectFactory(objectFactoryClass); Method elementFactoryMethod = inspector.findElementMethodInObjectFactory(objectFactoryClass, elementName.getLocalPart()); Class subBeanClass = (Class) elementFactoryMethod.getParameterTypes()[0]; + + if (xsubnode instanceof ListXNode){ + for (XNode xsubSubNode : ((ListXNode) xsubnode)){ + S subBean = unmarshall(xsubSubNode, subBeanClass); + unmarshallToAnyValue(bean, beanClass, subBean, objectFactoryClass, objectFactory, elementFactoryMethod, getter); + } + } else{ + S subBean = unmarshall(xsubnode, subBeanClass); + unmarshallToAnyValue(bean, beanClass, subBean, objectFactoryClass, objectFactory, elementFactoryMethod, getter); + } + + } + + private void unmarshallToAnyValue(T bean, Class beanClass, S subBean, Class objectFactoryClass, Object objectFactory, Method elementFactoryMethod, Method getter){ + - S subBean = unmarshall(xsubnode, subBeanClass); JAXBElement subBeanElement; try { subBeanElement = (JAXBElement) elementFactoryMethod.invoke(objectFactory, subBean); @@ -450,7 +477,6 @@ private void unmarshallToAny(T bean, Field anyField, QName elementName, XN throw new IllegalArgumentException("Cannot invoke factory method "+elementFactoryMethod+" on "+objectFactoryClass+" with "+subBean+": "+e1, e1); } - Method getter = inspector.findPropertyGetter(beanClass, anyField.getName()); Collection col; Object getterReturn; try { @@ -463,7 +489,12 @@ private void unmarshallToAny(T bean, Field anyField, QName elementName, XN } catch (ClassCastException e) { throw new SystemException("Getter "+getter+" on bean of type "+beanClass+" returned "+getterReturn+" instead of collection"); } - col.add(subBeanElement); + col.add(subBeanElement != null ? subBeanElement.getValue() : subBeanElement); + } + + private void unmarshallToAny(T bean, Field anyField, QName elementName, XNode xsubnode) throws SchemaException{ + Method getter = inspector.findPropertyGetter(bean.getClass(), anyField.getName()); + unmarshallToAny(bean, getter, elementName, xsubnode); } private Object instantiateObjectFactory(Class objectFactoryClass) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanInspector.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanInspector.java index c50303a8188..5f1fbdb4946 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanInspector.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanInspector.java @@ -504,6 +504,19 @@ private Field findField(Class classType, Handler selector) { } return findField(superclass, selector); } + + private Method findMethod(Class classType, Handler selector) { + for (Method field: classType.getDeclaredMethods()) { + if (selector.handle(field)) { + return field; + } + } + Class superclass = classType.getSuperclass(); + if (superclass.equals(Object.class)) { + return null; + } + return findMethod(superclass, selector); + } private List getPropOrderUncached(Class beanClass) { List propOrder; @@ -664,4 +677,13 @@ public boolean handle(Field field) { } }); } + + public Method findAnyMethod(Class beanClass) { + return findMethod(beanClass, new Handler() { + @Override + public boolean handle(Method method) { + return (method.getAnnotation(XmlAnyElement.class) != null); + } + }); + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java index 3f18a0607cc..aa5eab9a51a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java @@ -667,12 +667,9 @@ public static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnod return serializeNoneFilter((NoneFilter) filter, xnodeSerializer); } - if (filter instanceof NoneFilter) { - return serializeNoneFilter((NoneFilter) filter, xnodeSerilizer); - } - + if (filter instanceof AllFilter) { - return serializeAllFilter((AllFilter) filter, xnodeSerilizer); + return serializeAllFilter((AllFilter) filter, xnodeSerializer); } throw new UnsupportedOperationException("Unsupported filter type: " + filter); @@ -779,8 +776,7 @@ private static MapXNode serializeTypeFilter(TypeFilter filter, XNodeSerializer x private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer xnodeSerializer) { MapXNode map = new MapXNode(); - MapXNode none = new MapXNode(); - map.put(KEY_FILTER_NONE_TYPE, none); + map.put(KEY_FILTER_NONE_TYPE, new MapXNode()); return map; } @@ -794,12 +790,7 @@ private static MapXNode serializeOrgFilter(OrgFilter filter, XNodeSerializer xno return xtypeFilter; } - private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ - MapXNode xtypeFilter= new MapXNode(); - xtypeFilter.put(KEY_FILTER_NONE, null); - return xtypeFilter; - - } + private static MapXNode serializeAllFilter(AllFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ MapXNode xtypeFilter= new MapXNode(); diff --git a/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl b/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl index 336024edd00..9549b3877a6 100644 --- a/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl +++ b/infra/schema/src/main/resources/xml/ns/public/report/report-3.wsdl @@ -316,10 +316,15 @@ - - - - + + + + + Name of the jasper report parameter + + + + diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java index 7de2e874d23..c06938f9f07 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.List; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -271,9 +272,9 @@ public Collection getOids(Collection refs){ Collection oids = new ArrayList(); for (ObjectReferenceType ort : refs){ - if (ort.getOid() != null){ + if (StringUtils.isNotBlank(ort.getOid())){ oids.add(ort.getOid()); - } else if (ort.asReferenceValue().getObject() != null){ + } else if (ort.asReferenceValue().getObject() != null && StringUtils.isNotBlank(ort.asReferenceValue().getObject().getOid())){ oids.add(ort.asReferenceValue().getObject().getOid()); } } @@ -282,6 +283,19 @@ public Collection getOids(Collection refs){ } + public Collection getOids(ObjectReferenceType refs){ + List refList = new ArrayList<>(); + refList.add(refs); + return getOids(refList); + } + + public Collection getOids(ObjectType refs){ + List oid = new ArrayList<>(); + oid.add(refs.getOid()); + return oid; + + } + public boolean isEmpty(Object whatever) { if (whatever == null) { return true; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java index 87080e5bf0c..f7e76e374b7 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpression.java @@ -97,7 +97,7 @@ public void setFunctions(Collection functions) { this.functions = functions; } - public List evaluate(ExpressionVariables variables, ScriptExpressionReturnTypeType suggestedReturnType, + public List evaluate(ExpressionVariables variables, ScriptExpressionReturnTypeType suggestedReturnType, boolean useNew, String contextDescription, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { @@ -107,7 +107,7 @@ public List evaluate(ExpressionVariables variables, ScriptExpres try { context.setupThreadLocal(); - List expressionResult = evaluator.evaluate(scriptType, variables, outputDefinition, suggestedReturnType, objectResolver, functions, contextDescription, result); + List expressionResult = evaluator.evaluate(scriptType, variables, outputDefinition, suggestedReturnType, objectResolver, functions, contextDescription, result); traceExpressionSuccess(variables, contextDescription, expressionResult); return expressionResult; diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java index 1ef57569e18..051144e7ffa 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.crypto.AESProtector; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.polystring.PolyString; diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java index 7024cd5c53c..04785f1f219 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/MidPointRemoteQueryExecutor.java @@ -76,11 +76,11 @@ private RemoteReportParametersType converToReportParameterType(Map) value); - } else { - remoteParam.getAny().add(value); - } +// if (value!= null && List.class.isAssignableFrom(value.getClass())){ +// remoteParam.getAny().addAll((List) value); +// } else { +// remoteParam.getAny().add(value); +// } reportParams.getRemoteParameter().add(remoteParam); } return reportParams; diff --git a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java index 9a407b28fea..89ad489ad6f 100644 --- a/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java +++ b/model/report-ds-impl/src/main/java/com/evolveum/midpoint/report/ds/impl/test/MidPointRemoteQueryExecuterTest.java @@ -43,13 +43,13 @@ public Object getParsedQuery(PrismContext prismContext, ReportPortType reportPor RemoteReportParametersType reportParameters = new RemoteReportParametersType(); RemoteReportParameterType reportParameter = new RemoteReportParameterType(); reportParameter.setParameterName("stringExample"); - reportParameter.getAny().add("someString"); +// reportParameter.getAny().add("someString"); reportParameters.getRemoteParameter().add(reportParameter); reportParameter = new RemoteReportParameterType(); reportParameter.setParameterName("intExample"); - reportParameter.getAny().add(11); +// reportParameter.getAny().add(11); reportParameters.getRemoteParameter().add(reportParameter); diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java index 9337ad72f2e..b3c685a3dab 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java @@ -153,6 +153,20 @@ public List> resolveOrgs(Collection assignm return resolveAssignments(assignments, OrgType.class); } + public List> resolveRoles(AssignmentType assignments){ + return resolveAssignments(assignments, RoleType.class); + } + + public List> resolveOrgs(AssignmentType assignments){ + return resolveAssignments(assignments, OrgType.class); + } + + public List> resolveAssignments(AssignmentType assignment, Class type){ + List assignments = new ArrayList<>(); + assignments.add(assignment); + return resolveAssignments(assignments, type); + } + public List> resolveAssignments(Collection assignments, Class type){ List> resolvedAssignments = new ArrayList<>(); if (assignments == null){ diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java index bbaa1250934..308bcbc4d1f 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebService.java @@ -142,9 +142,7 @@ public AuditEventRecordListType evaluateAuditScript(String script, RemoteReportP private Map getParamsMap(RemoteReportParametersType parametersType) throws SchemaException { - // prismContext.adopt(parametersType); - // PrismContainerValue parameter = - // parametersType.asPrismContainerValue(); + prismContext.adopt(parametersType); Map parametersMap = new HashMap<>(); if (parametersType == null || parametersType.getRemoteParameter() == null || parametersType.getRemoteParameter().isEmpty()) { @@ -153,30 +151,21 @@ private Map getParamsMap(RemoteReportParametersType parametersTyp List items = parametersType.getRemoteParameter(); for (RemoteReportParameterType item : items) { QName paramName = new QName(SchemaConstants.NS_REPORT, item.getParameterName()); - if (item.getAny().size() == 1) { - parametersMap.put(paramName, item.getAny().get(0)); + ReportParameterType param = item.getParameterValue(); + if (param == null){ + parametersMap.put(paramName, null); + continue; + } + if (param.getAny().size() == 1) { + parametersMap.put(paramName, param.getAny().get(0)); } else { - parametersMap.put(paramName, item.getAny()); + parametersMap.put(paramName, param.getAny()); } } return parametersMap; - // Map params = null; - // if (parameters != null) { - // params = new HashMap(); - // for (EntryType entry : parameters.getEntry()) { - // Object obj = entry.getEntryValue(); - // Serializable value = null; - // if (obj instanceof JAXBElement){ - // value = (Serializable) ((JAXBElement) obj).getValue(); - // } else { - // value = (Serializable) entry.getEntryValue(); - // } - // params.put(new QName(entry.getKey()), value); - // } - // } - // return params; + } @@ -289,6 +278,7 @@ public ObjectListType processReport(String query, RemoteReportParametersType par SelectorQualifiedGetOptionsType options) { try { + Map parametersMap = getParamsMap(parameters); ObjectQuery q = reportService.parseQuery(query, parametersMap); Collection> resultList = reportService.searchObjects(q, From 96fcafc58bbfe93c9ed14d0322f3fd04d1003576 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 14:13:58 +0200 Subject: [PATCH 14/16] Probably fixing basic auxiliary object classes support in model. --- ...CompositeRefinedObjectClassDefinition.java | 19 ++++- .../refinery/RefinedResourceSchema.java | 31 ++++---- .../impl/lens/LensProjectionContext.java | 73 ++++++++++++++++--- .../projector/ConsolidationProcessor.java | 2 +- .../impl/lens/projector/ContextLoader.java | 2 +- .../lens/projector/CredentialsProcessor.java | 2 +- .../impl/lens/projector/InboundProcessor.java | 2 +- .../lens/projector/OutboundProcessor.java | 2 +- .../projector/ProjectionValuesProcessor.java | 4 +- .../projector/ReconciliationProcessor.java | 37 +++++----- .../projector/ShadowConstraintsChecker.java | 2 +- .../AbstractInternalModelIntegrationTest.java | 2 +- .../lens/TestProjectorRoleEntitlement.java | 2 +- .../provisioning/impl/AccessChecker.java | 5 ++ .../provisioning/impl/ShadowCache.java | 4 + .../story/src/test/resources/logback-test.xml | 15 ++-- 16 files changed, 142 insertions(+), 62 deletions(-) diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java index 2d95a933b57..aece0f0a751 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java @@ -331,9 +331,11 @@ protected String debugDump(int indent, LayerType layer) { for (int i = 0; i < indent; i++) { sb.append(INDENT_STRING); } - sb.append(getDebugDumpClassName()).append("("); + sb.append(getDebugDumpClassName()).append(": "); sb.append(SchemaDebugUtil.prettyPrint(getTypeName())); + sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "structural", structuralObjectClassDefinition, indent + 1); + sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "auxiliary", auxiliaryObjectClassDefinitions, indent + 1); return sb.toString(); } @@ -353,4 +355,19 @@ public String getHumanReadableName() { return getKind()+":"+getIntent(); } } + + @Override + public String toString() { + if (auxiliaryObjectClassDefinitions == null || auxiliaryObjectClassDefinitions.isEmpty()) { + return getDebugDumpClassName() + " ("+getTypeName()+")"; + } else { + StringBuilder sb = new StringBuilder(); + sb.append(getDebugDumpClassName()).append("(").append(getTypeName()); + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + sb.append("+").append(auxiliaryObjectClassDefinition.getTypeName()); + } + sb.append(")"); + return sb.toString(); + } + } } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index d03046991c7..8b0cc84280b 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -141,36 +141,35 @@ public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefini ShadowType shadowType = shadow.asObjectable(); RefinedObjectClassDefinition structuralObjectClassDefinition = null; - Collection auxiliaryObjectClassDefinitions; ShadowKindType kind = shadowType.getKind(); String intent = shadowType.getIntent(); QName structuralObjectClassQName = shadowType.getObjectClass(); + if (kind != null) { structuralObjectClassDefinition = getRefinedDefinition(kind, intent); - } + } + if (structuralObjectClassDefinition == null) { // Fallback to objectclass only if (structuralObjectClassQName == null) { return null; } structuralObjectClassDefinition = getRefinedDefinition(structuralObjectClassQName); - List auxiliaryObjectClassQNames = shadowType.getAuxiliaryObjectClass(); - auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); - for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { - RefinedObjectClassDefinition auxiliaryObjectClassDef = getRefinedDefinition(auxiliaryObjectClassQName); - if (auxiliaryObjectClassDef == null) { - throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+shadow+" does not exist"); - } - auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); - } - } else { - auxiliaryObjectClassDefinitions = structuralObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); } if (structuralObjectClassDefinition == null) { - return null; - } - + return null; + } + List auxiliaryObjectClassQNames = shadowType.getAuxiliaryObjectClass(); + Collection auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); + for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { + RefinedObjectClassDefinition auxiliaryObjectClassDef = getRefinedDefinition(auxiliaryObjectClassQName); + if (auxiliaryObjectClassDef == null) { + throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+shadow+" does not exist"); + } + auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); + } + return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index 37e22f0cf64..5d9b4e7dcdc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -34,6 +35,7 @@ import org.jvnet.jaxb2_commons.lang.Validate; import com.evolveum.midpoint.common.crypto.CryptoUtil; +import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.common.refinery.ResourceShadowDiscriminator; @@ -175,6 +177,9 @@ public class LensProjectionContext extends LensElementContext implem // Cached copy, to avoid constructing it over and over again private transient PrismObjectDefinition shadowDefinition = null; + private transient RefinedObjectClassDefinition structuralObjectClassDefinition; + private transient Collection auxiliaryObjectClassDefinitions; + private ValuePolicyType accountPasswordPolicy; @@ -256,7 +261,7 @@ public boolean compareResourceShadowDiscriminator(ResourceShadowDiscriminator rs } if (rsd.getIntent() == null) { try { - if (!getRefinedAccountDefinition().isDefaultInAKind()) { + if (!getStructuralObjectClassDefinition().isDefaultInAKind()) { return false; } } catch (SchemaException e) { @@ -330,7 +335,7 @@ public void setResource(ResourceType resource) { public PrismObjectDefinition getObjectDefinition() { if (shadowDefinition == null) { try { - shadowDefinition = ShadowUtil.applyObjectClass(super.getObjectDefinition(), getRefinedAccountDefinition()); + shadowDefinition = ShadowUtil.applyObjectClass(super.getObjectDefinition(), getStructuralObjectClassDefinition()); } catch (SchemaException e) { // This should not happen throw new SystemException(e.getMessage(), e); @@ -511,14 +516,64 @@ public RefinedResourceSchema getRefinedResourceSchema() throws SchemaException { return RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, getNotNullPrismContext()); } - public RefinedObjectClassDefinition getRefinedAccountDefinition() throws SchemaException { - RefinedResourceSchema refinedSchema = getRefinedResourceSchema(); - if (refinedSchema == null) { - return null; + public RefinedObjectClassDefinition getStructuralObjectClassDefinition() throws SchemaException { + if (structuralObjectClassDefinition == null) { + RefinedResourceSchema refinedSchema = getRefinedResourceSchema(); + if (refinedSchema == null) { + throw new IllegalStateException("No refined schema"); + } + structuralObjectClassDefinition = refinedSchema.getRefinedDefinition(getResourceShadowDiscriminator().getKind(), getResourceShadowDiscriminator().getIntent()); + } + return structuralObjectClassDefinition; + } + + public Collection getAuxiliaryObjectClassDefinitions() throws SchemaException { + if (auxiliaryObjectClassDefinitions == null) { + RefinedResourceSchema refinedSchema = getRefinedResourceSchema(); + if (refinedSchema == null) { + throw new IllegalStateException("No refined schema"); + } + List auxiliaryObjectClassQNames = new ArrayList<>(); + addAuxiliaryObjectClassNames(auxiliaryObjectClassQNames, getObjectOld()); + addAuxiliaryObjectClassNames(auxiliaryObjectClassQNames, getObjectNew()); + auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); + for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { + RefinedObjectClassDefinition auxiliaryObjectClassDef = refinedSchema.getRefinedDefinition(auxiliaryObjectClassQName); + if (auxiliaryObjectClassDef == null) { + throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+this+" does not exist"); + } + auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); + } + } + return auxiliaryObjectClassDefinitions; + } + + private void addAuxiliaryObjectClassNames(List auxiliaryObjectClassQNames, + PrismObject shadow) { + if (shadow == null) { + return; + } + for (QName aux: shadow.asObjectable().getAuxiliaryObjectClass()) { + if (!auxiliaryObjectClassQNames.contains(aux)) { + auxiliaryObjectClassQNames.add(aux); + } } - return refinedSchema.getRefinedDefinition(getResourceShadowDiscriminator().getKind(), getResourceShadowDiscriminator().getIntent()); } + public RefinedAttributeDefinition findAttributeDefinition(QName attrName) throws SchemaException { + RefinedAttributeDefinition attrDef = getStructuralObjectClassDefinition().findAttributeDefinition(attrName); + if (attrDef != null) { + return attrDef; + } + for (RefinedObjectClassDefinition auxOcDef: getAuxiliaryObjectClassDefinitions()) { + attrDef = auxOcDef.findAttributeDefinition(attrName); + if (attrDef != null) { + return attrDef; + } + } + return null; + } + public Collection getDependencies() { if (dependencies == null) { ResourceObjectTypeDefinitionType resourceAccountTypeDefinitionType = getResourceObjectTypeDefinitionType(); @@ -627,7 +682,7 @@ public void recompute() throws SchemaException { } if (base == null && accDelta.isModify()) { - RefinedObjectClassDefinition rAccountDef = getRefinedAccountDefinition(); + RefinedObjectClassDefinition rAccountDef = getStructuralObjectClassDefinition(); if (rAccountDef != null) { base = (PrismObject) rAccountDef.createBlankShadow(); } @@ -716,7 +771,7 @@ public ObjectDelta getExecutableDelta() throws SchemaException { // We need to convert modify delta to ADD ObjectDelta addDelta = new ObjectDelta(getObjectTypeClass(), ChangeType.ADD, getPrismContext()); - RefinedObjectClassDefinition rAccount = getRefinedAccountDefinition(); + RefinedObjectClassDefinition rAccount = getStructuralObjectClassDefinition(); if (rAccount == null) { throw new IllegalStateException("Definition for account type " + getResourceShadowDiscriminator() diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java index 93b94d93174..5008cf36b37 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java @@ -241,7 +241,7 @@ public boolean isAuthoritative() { ObjectDelta objectDelta = new ObjectDelta(ShadowType.class, ChangeType.MODIFY, prismContext); objectDelta.setOid(projCtx.getOid()); - RefinedObjectClassDefinition rOcDef = projCtx.getRefinedAccountDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); if (rOcDef == null) { LOGGER.error("Definition for account type {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump()); throw new IllegalStateException("Definition for account type " + discr + " not found in the context, but it should be there"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java index 413aa765149..ef6a64f49e9 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java @@ -1003,7 +1003,7 @@ private void finishLoadOfProjectionContext(LensContext } //Determine refined schema and password policies for account type - RefinedObjectClassDefinition rad = projContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition rad = projContext.getStructuralObjectClassDefinition(); if (rad != null) { ObjectReferenceType passwordPolicyRef = rad.getPasswordPolicy(); if (passwordPolicyRef != null && passwordPolicyRef.getOid() != null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java index 4fc62f7adde..8cce65f45d8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java @@ -167,7 +167,7 @@ private void processProjectionPassword(LensContext cont return; } - RefinedObjectClassDefinition refinedAccountDef = accCtx.getRefinedAccountDefinition(); + RefinedObjectClassDefinition refinedAccountDef = accCtx.getStructuralObjectClassDefinition(); if (refinedAccountDef == null){ LOGGER.trace("No RefinedAccountDefinition, therefore also no password outbound definition, skipping credentials processing for account " + rat); return; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java index b35d58823f6..0ddcbd90d69 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java @@ -149,7 +149,7 @@ void processInboundFocal(LensContext context, Task task continue; } - RefinedObjectClassDefinition accountDefinition = accountContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition accountDefinition = accountContext.getStructuralObjectClassDefinition(); if (accountDefinition == null) { LOGGER.error("Definition for account type {} not found in the context, but it " + "should be there, dumping context:\n{}", rat, context.debugDump()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java index b752785896f..ea3b8fbe55c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java @@ -108,7 +108,7 @@ public void processOutbound(LensContext context, LensPr LOGGER.trace("Processing outbound expressions for {} starting", discr); - RefinedObjectClassDefinition rOcDef = projCtx.getRefinedAccountDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); if (rOcDef == null) { LOGGER.error("Definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump()); throw new IllegalStateException("Definition for " + discr + " not found in the context, but it should be there"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java index 5d0bbee3bff..bc6dd7e14fe 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java @@ -463,7 +463,7 @@ private boolean willResetIterationCounter(LensProjectionContext projectionContex if (accountDelta == null) { return false; } - RefinedObjectClassDefinition oOcDef = projectionContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition oOcDef = projectionContext.getStructuralObjectClassDefinition(); for (RefinedAttributeDefinition identifierDef: oOcDef.getIdentifiers()) { ItemPath identifierPath = new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()); if (accountDelta.findPropertyDelta(identifierPath) != null) { @@ -556,7 +556,7 @@ public void checkSchemaAndPolicies(LensContext context return; } - RefinedObjectClassDefinition rAccountDef = accountContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition rAccountDef = accountContext.getStructuralObjectClassDefinition(); if (rAccountDef == null) { throw new SchemaException("No definition for account type '" +accountContext.getResourceShadowDiscriminator()+"' in "+accountContext.getResource()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java index d4c21fc3b1a..372f9cacdfc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java @@ -120,7 +120,7 @@ void processReconciliation(LensContext context, } void processReconciliationFocus(LensContext context, - LensProjectionContext accContext, OperationResult result) throws SchemaException, + LensProjectionContext projCtx, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { @@ -131,50 +131,50 @@ void processReconciliationFocus(LensContext context, // full shadow // reconciliation is cheap if the shadow is already fetched // therefore just do it - if (!accContext.isDoReconciliation() && !accContext.isFullShadow()) { + if (!projCtx.isDoReconciliation() && !projCtx.isFullShadow()) { return; } - SynchronizationPolicyDecision policyDecision = accContext.getSynchronizationPolicyDecision(); + SynchronizationPolicyDecision policyDecision = projCtx.getSynchronizationPolicyDecision(); if (policyDecision != null && (policyDecision == SynchronizationPolicyDecision.DELETE || policyDecision == SynchronizationPolicyDecision.UNLINK)) { return; } - if (accContext.getObjectCurrent() == null) { + if (projCtx.getObjectCurrent() == null) { LOGGER.warn("Can't do reconciliation. Account context doesn't contain current version of account."); return; } - if (!accContext.isFullShadow()) { + if (!projCtx.isFullShadow()) { // We need to load the object PrismObject objectOld = provisioningService.getObject(ShadowType.class, - accContext.getOid(), SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()) + projCtx.getOid(), SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()) , null, result); ShadowType oldShadow = objectOld.asObjectable(); - accContext.determineFullShadowFlag(oldShadow.getFetchResult()); - accContext.setLoadedObject(objectOld); + projCtx.determineFullShadowFlag(oldShadow.getFetchResult()); + projCtx.setLoadedObject(objectOld); - accContext.recompute(); + projCtx.recompute(); } - RefinedObjectClassDefinition accountDefinition = accContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); - Map,PrismPropertyDefinition>>> squeezedAttributes = accContext + Map,PrismPropertyDefinition>>> squeezedAttributes = projCtx .getSqueezedAttributes(); if (squeezedAttributes != null && !squeezedAttributes.isEmpty()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Attribute reconciliation processing {}", accContext.getHumanReadableName()); + LOGGER.trace("Attribute reconciliation processing {}", projCtx.getHumanReadableName()); } - reconcileProjectionAttributes(accContext, squeezedAttributes, accountDefinition); + reconcileProjectionAttributes(projCtx, squeezedAttributes, rOcDef); } - Map,PrismContainerDefinition>>> squeezedAssociations = accContext.getSqueezedAssociations(); + Map,PrismContainerDefinition>>> squeezedAssociations = projCtx.getSqueezedAssociations(); if (squeezedAssociations != null && !squeezedAssociations.isEmpty()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Association reconciliation processing {}", accContext.getHumanReadableName()); + LOGGER.trace("Association reconciliation processing {}", projCtx.getHumanReadableName()); } - reconcileProjectionAssociations(accContext, squeezedAssociations, accountDefinition); + reconcileProjectionAssociations(projCtx, squeezedAssociations, rOcDef); } } catch (RuntimeException e) { @@ -191,7 +191,7 @@ void processReconciliationFocus(LensContext context, private void reconcileProjectionAttributes( LensProjectionContext projCtx, Map,PrismPropertyDefinition>>> squeezedAttributes, - RefinedObjectClassDefinition accountDefinition) throws SchemaException { + RefinedObjectClassDefinition rOcDef) throws SchemaException { PrismObject shadowNew = projCtx.getObjectNew(); @@ -201,8 +201,7 @@ private void reconcileProjectionAttributes( for (QName attrName : attributeNames) { // LOGGER.trace("Attribute reconciliation processing attribute {}",attrName); - RefinedAttributeDefinition attributeDefinition = accountDefinition - .getAttributeDefinition(attrName); + RefinedAttributeDefinition attributeDefinition = projCtx.findAttributeDefinition(attrName); if (attributeDefinition == null) { throw new SchemaException("No definition for attribute " + attrName + " in " + projCtx.getResourceShadowDiscriminator()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java index 8d62c2be412..16fe52b448d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java @@ -105,7 +105,7 @@ public PrismObject getConflictingShadow() { public void check(OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - RefinedObjectClassDefinition projDef = projectionContext.getRefinedAccountDefinition(); + RefinedObjectClassDefinition projDef = projectionContext.getStructuralObjectClassDefinition(); PrismObject projectionNew = projectionContext.getObjectNew(); if (projectionNew == null) { // This must be delete diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java index 218c8ab1512..4881b0bf05c 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java @@ -409,7 +409,7 @@ protected ObjectDelta createAccountDelta(LensProjectionContext a ResourceType resourceType = accCtx.getResource(); QName attrQName = new QName(ResourceTypeUtil.getResourceNamespace(resourceType), attributeLocalName); ItemPath attrPath = new ItemPath(ShadowType.F_ATTRIBUTES, attrQName); - RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getRefinedAccountDefinition(); + RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getStructuralObjectClassDefinition(); RefinedAttributeDefinition attrDef = refinedAccountDefinition.findAttributeDefinition(attrQName); assertNotNull("No definition of attribute "+attrQName+" in account def "+refinedAccountDefinition, attrDef); ObjectDelta accountDelta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestProjectorRoleEntitlement.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestProjectorRoleEntitlement.java index b0618239426..f0f99bc9410 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestProjectorRoleEntitlement.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestProjectorRoleEntitlement.java @@ -170,7 +170,7 @@ public void test100AddEntitlementToPirateDirect() throws Exception { accountToAddPrimary.findProperty(ShadowType.F_OBJECT_CLASS).getRealValue()); PrismReference resourceRef = accountToAddPrimary.findReference(ShadowType.F_RESOURCE_REF); assertEquals(resourceDummyType.getOid(), resourceRef.getOid()); - PrismAsserts.assertNoEmptyItem(accountToAddPrimary); + accountToAddPrimary.checkConsistence(); ObjectDelta projSecondaryDelta = projContext.getSecondaryDelta(); assertEquals(ChangeType.MODIFY, projSecondaryDelta.getChangeType()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/AccessChecker.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/AccessChecker.java index 7ba266f058d..a18eee36ca9 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/AccessChecker.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/AccessChecker.java @@ -63,6 +63,11 @@ public void checkAdd(ProvisioningContext ctx, PrismObject shadow, Op RefinedAttributeDefinition attrDef = ctx.getObjectClassDefinition().findAttributeDefinition(attribute.getElementName()); // Need to check model layer, not schema. Model means IDM logic which can be overridden in schemaHandling, // schema layer is the original one. + if (attrDef == null) { + String msg = "No definition for attribute "+attribute.getElementName()+" in "+ctx.getObjectClassDefinition(); + result.recordFatalError(msg); + throw new SchemaException(msg); + } PropertyLimitations limitations = attrDef.getLimitations(LayerType.MODEL); if (limitations == null) { continue; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 41cd1d310a0..b72b306ec09 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -341,6 +341,10 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr return null; } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Definition:\n{}", ctx.getObjectClassDefinition().debugDump()); + } + PrismContainer attributesContainer = shadow.findContainer( ShadowType.F_ATTRIBUTES); if (attributesContainer == null || attributesContainer.isEmpty()) { diff --git a/testing/story/src/test/resources/logback-test.xml b/testing/story/src/test/resources/logback-test.xml index 408bb5d1a3b..5e7874f294e 100644 --- a/testing/story/src/test/resources/logback-test.xml +++ b/testing/story/src/test/resources/logback-test.xml @@ -38,20 +38,21 @@ - - - - - + + + + + - + - + + From 2ea0819dc15c28d6f838b147a1962f87479e6ad1 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 15:25:43 +0200 Subject: [PATCH 15/16] This check was not a good idea ... --- .../midpoint/model/impl/lens/LensProjectionContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index 5d9b4e7dcdc..523b6bf6442 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -520,7 +520,7 @@ public RefinedObjectClassDefinition getStructuralObjectClassDefinition() throws if (structuralObjectClassDefinition == null) { RefinedResourceSchema refinedSchema = getRefinedResourceSchema(); if (refinedSchema == null) { - throw new IllegalStateException("No refined schema"); + return null; } structuralObjectClassDefinition = refinedSchema.getRefinedDefinition(getResourceShadowDiscriminator().getKind(), getResourceShadowDiscriminator().getIntent()); } @@ -531,7 +531,7 @@ public Collection getAuxiliaryObjectClassDefinitio if (auxiliaryObjectClassDefinitions == null) { RefinedResourceSchema refinedSchema = getRefinedResourceSchema(); if (refinedSchema == null) { - throw new IllegalStateException("No refined schema"); + return null; } List auxiliaryObjectClassQNames = new ArrayList<>(); addAuxiliaryObjectClassNames(auxiliaryObjectClassQNames, getObjectOld()); From 529fad471911a1422309ba47e19286f36d4b8e17 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 23 Jun 2015 15:50:58 +0200 Subject: [PATCH 16/16] Extended TestUnix --- .../midpoint/testing/story/TestUnix.java | 207 ++++++++++++++++-- 1 file changed, 193 insertions(+), 14 deletions(-) diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index 8cca5b3c337..da7c17b3213 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -117,7 +117,10 @@ public class TestUnix extends AbstractStoryTest { private static final String USER_MANCOMB_USERNAME = "mancomb"; private static final String USER_MANCOMB_FIST_NAME = "Mancomb"; private static final String USER_MANCOMB_LAST_NAME = "Seepgood"; - + + private static final String USER_LARGO_USERNAME = "largo"; + private static final String USER_LARGO_FIST_NAME = "Largo"; + private static final String USER_LARGO_LAST_NAME = "LaGrande"; private static final String ACCOUNT_LEMONHEAD_USERNAME = "lemonhead"; @@ -141,9 +144,7 @@ public class TestUnix extends AbstractStoryTest { private static final String ACCOUNT_COBB_FIST_NAME = "Cobb"; private static final String ACCOUNT_COBB_LAST_NAME = "Loom"; - private static final String ACCOUNT_LARGO_USERNAME = "largo"; - private static final String ACCOUNT_LARGO_FIST_NAME = "Largo"; - private static final String ACCOUNT_LARGO_LAST_NAME = "LaGrande"; + private static final String ACCOUNT_STAN_USERNAME = "stan"; private static final String ACCOUNT_STAN_FIST_NAME = "Stan"; @@ -171,6 +172,12 @@ public class TestUnix extends AbstractStoryTest { protected ResourceType resourceOpenDjType; protected PrismObject resourceOpenDj; + private String accountMancombOid; + private String accountMancombDn; + + private String accountLargoOid; + private String accountLargoDn; + @Override protected void startResources() throws Exception { openDJController.startCleanServer(); @@ -245,8 +252,6 @@ public void test010Schema() throws Exception { assertNotNull("No refined objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" in resource schema", rOcDefPosixGroup); assertTrue("Refined objectclass "+OPENDJ_GROUP_POSIX_AUXILIARY_OBJECTCLASS_NAME+" is not auxiliary", rOcDefPosixGroup.isAuxiliary()); - // TODO - } @Test @@ -298,6 +303,117 @@ public void test110AddUserMancombUnix() throws Exception { assertNotNull("No herman user", userAfter); display("User after", userAfter); assertUser(userAfter, USER_MANCOMB_USERNAME, USER_MANCOMB_FIST_NAME, USER_MANCOMB_LAST_NAME); + accountMancombOid = getSingleLinkOid(userAfter); + + PrismObject shadow = getShadowModel(accountMancombOid); + display("Shadow (model)", shadow); + accountMancombDn = assertPosixAccount(shadow); + } + + @Test + public void test119DeleteUserMancombUnix() throws Exception { + final String TEST_NAME = "test119DeleteUserMancombUnix"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = findUserByUsername(USER_MANCOMB_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + deleteObject(UserType.class, userBefore.getOid(), task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_MANCOMB_USERNAME); + display("User after", userAfter); + assertNull("User mancomb sneaked in", userAfter); + + assertUser(userAfter, USER_MANCOMB_USERNAME, USER_MANCOMB_FIST_NAME, USER_MANCOMB_LAST_NAME); + assertLinks(userAfter, 0); + + assertNoObject(ShadowType.class, accountMancombOid, task, result); + + openDJController.assertNoEntry(accountMancombDn); + } + + @Test + public void test120AddUserLargo() throws Exception { + final String TEST_NAME = "test120AddUserLargo"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject user = createUser(USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME, 1002, null); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + addObject(user, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_LARGO_USERNAME); + assertNotNull("No user after", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME); + assertLinks(userAfter, 0); + } + + @Test + public void test122AssignUserLargoBasic() throws Exception { + final String TEST_NAME = "test122AssignUserLargoBasic"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = findUserByUsername(USER_LARGO_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + assignRole(userBefore.getOid(), ROLE_BASIC_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_LARGO_USERNAME); + assertNotNull("No user after", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME); + + accountLargoOid = getSingleLinkOid(userAfter); + + PrismObject shadow = getShadowModel(accountLargoOid); + display("Shadow (model)", shadow); + accountLargoDn = assertBasicAccount(shadow); + } + + @Test + public void test124AssignUserLargoUnix() throws Exception { + final String TEST_NAME = "test124AssignUserLargoUnix"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = findUserByUsername(USER_LARGO_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + assignRole(userBefore.getOid(), ROLE_UNIX_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_LARGO_USERNAME); + assertNotNull("No user after", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME); + String accountOid = getSingleLinkOid(userAfter); PrismObject shadow = getShadowModel(accountOid); @@ -305,14 +421,73 @@ public void test110AddUserMancombUnix() throws Exception { assertPosixAccount(shadow); } + @Test + public void test126UnAssignUserLargoUnix() throws Exception { + final String TEST_NAME = "test126UnAssignUserLargoUnix"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = findUserByUsername(USER_LARGO_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + unassignRole(userBefore.getOid(), ROLE_UNIX_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_LARGO_USERNAME); + assertNotNull("No user after", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME); + + String accountOid = getSingleLinkOid(userAfter); + + PrismObject shadow = getShadowModel(accountOid); + display("Shadow (model)", shadow); + assertBasicAccount(shadow); + } + + @Test + public void test128UnAssignUserLargoBasic() throws Exception { + final String TEST_NAME = "test122AssignUserLargoBasic"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject userBefore = findUserByUsername(USER_LARGO_USERNAME); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + unassignRole(userBefore.getOid(), ROLE_BASIC_OID); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + PrismObject userAfter = findUserByUsername(USER_LARGO_USERNAME); + assertNotNull("No user after", userAfter); + display("User after", userAfter); + assertUser(userAfter, USER_LARGO_USERNAME, USER_LARGO_FIST_NAME, USER_LARGO_LAST_NAME); + assertLinks(userAfter, 0); + + assertNoObject(ShadowType.class, accountLargoOid, task, result); + + openDJController.assertNoEntry(accountLargoDn); + } + private PrismObject createUser(String username, String givenName, String familyName, Integer uidNumber, String roleOid) throws SchemaException { PrismObject user = createUser(username, givenName, familyName, true); - AssignmentType roleAssignemnt = new AssignmentType(); - ObjectReferenceType roleTargetRef = new ObjectReferenceType(); - roleTargetRef.setOid(roleOid); - roleTargetRef.setType(RoleType.COMPLEX_TYPE); - roleAssignemnt.setTargetRef(roleTargetRef); - user.asObjectable().getAssignment().add(roleAssignemnt); + if (roleOid != null) { + AssignmentType roleAssignemnt = new AssignmentType(); + ObjectReferenceType roleTargetRef = new ObjectReferenceType(); + roleTargetRef.setOid(roleOid); + roleTargetRef.setType(RoleType.COMPLEX_TYPE); + roleAssignemnt.setTargetRef(roleTargetRef); + user.asObjectable().getAssignment().add(roleAssignemnt); + } if (uidNumber != null) { PrismPropertyDefinition uidNumberPropertyDef = new PrismPropertyDefinition<>(EXTENSION_UID_NUMBER_NAME, DOMUtil.XSD_STRING, prismContext); @@ -337,7 +512,7 @@ protected void assertUser(PrismObject user, String username, String fi firstName, lastName); } - private void assertBasicAccount(PrismObject shadow) throws DirectoryException { + private String assertBasicAccount(PrismObject shadow) throws DirectoryException { ShadowType shadowType = shadow.asObjectable(); assertEquals("Wrong objectclass in "+shadow, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME, shadowType.getObjectClass()); assertTrue("Unexpected auxiliary objectclasses in "+shadow + ": "+shadowType.getAuxiliaryObjectClass(), @@ -349,9 +524,11 @@ private void assertBasicAccount(PrismObject shadow) throws Directory display("Posix account entry", entry); openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME.getLocalPart()); openDJController.assertNoObjectClass(entry, OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME.getLocalPart()); + + return entry.getDN().toString(); } - private void assertPosixAccount(PrismObject shadow) throws DirectoryException { + private String assertPosixAccount(PrismObject shadow) throws DirectoryException { ShadowType shadowType = shadow.asObjectable(); assertEquals("Wrong objectclass in "+shadow, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME, shadowType.getObjectClass()); PrismAsserts.assertEqualsCollectionUnordered("Wrong auxiliary objectclasses in "+shadow, @@ -363,6 +540,8 @@ private void assertPosixAccount(PrismObject shadow) throws Directory display("Posix account entry", entry); openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_STRUCTURAL_OBJECTCLASS_NAME.getLocalPart()); openDJController.assertObjectClass(entry, OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME.getLocalPart()); + + return entry.getDN().toString(); } }