<div dir="ltr"><div dir="ltr"><div>Hi all,</div><div><br></div><div>There seems to be a bug with the way template object assignment mappings are processed (specifically how deltas are established for assignments: plus set, minus set, and zero set).</div><div>(This functioned correctly when our implementation was on MidPoint version 3.6.1, but since has experienced the issue below after upgrading to MidPoint 3.8 and 3.9)</div><div><br></div><div>Given the following:</div><div>- A defined user template mapping used for automatic assignment of an organization to a user using `assignmentTargetSearch`</div><div>- Assignment is based on multiple sources where a source element can and is expected to be null occasionally (does/should not affect resulting assignment, additional attribute is used solely for parametric assignment attributes)</div><div>- Assignment is authoritative</div><div>- A range is specified so that assignments can be automatically removed when they no longer apply according to the mapping</div><div>- User attributes are set via inbound mappings from a source-of-truth resource (HR system) (not necessary to reproduce error, same issue will surface when changes originate using midpoint GUI)</div><div><br></div><div>During normal execution, all source elements are accounted for and used to execute the mapping expression. The resulting organization found by the `assignmentTargetSearch` is assigned to the user.</div><div><br></div><div>An additional source element (in this example, a user schema extension attribute named transfer_date) for the mapping is used to determine assignment activation dates if the source element is present.  If not present, no activation date is applied to the assignment (note, this particular example uses the additional source element for activation dates, but the problem exists in all scenarios with source elements - in fact, a source element need not even be used in the mapping expression otherwise)</div><div><br></div><div>Scenarios:</div><div>1. A User transfer date is NOT specified.</div><div>Expectation: Assignment mapping assigns the Department Organization (without an activation date)</div><div>Reality: Matches Expectation</div><div><br></div><div>2. A User Transfer date is specified</div><div>Expectation: Assignment mapping removes the Department Organization assignment (without an activation date), and replaces it with a Department Organization assignment with an activation date)</div><div>Reality: Matches Expectation</div><div><br></div><div>3.  A user Transfer date is removed</div><div>Expectation: Assignment mapping removes the Department Organization assignment with an activation date, and replaces it with a Department Organization assignment (without an activation date)</div><div>Reality: On initial user template mapping processing (via import from resource or otherwise), the assignment mapping only removes the Department Organization assignment with an activation date.  It does NOT replace it with a Department Organization assignment (without an activation date).  Later reconciliation of the user results in assignment of the Department Organization accordingly.  However, this results in a brief period of time where the assignment on the user does not exist, which triggers account changes on all resources that the assignment influences.</div><div><br></div><div>Upon further investigation and debugging, I found that the delta being created for this assignment mapping in scenario 3 does not contain a plus set delta to add the new assignment, but rather, only a minus set delta removing the old assignment. </div><div><br></div><div>This issue does not surface when the transfer date source element simply changes value (for instance date change from 11/29/18 to 11/28/18 (or from NULL to 11/27/18), but only when a source element changes from having a value to NULL)</div><div><br></div><div>Below is the mapping trace indicating the reality during scenario 3:</div><div>2018-11-19 17:07:36,052 [] [http-nio-8080-exec-113] INFO (com.evolveum.midpoint.model.common.mapping.MappingImpl): Mapping trace:</div><div>---[ MAPPING 'Job Department Org mapping'  in template mapping 'Job Department Org mapping' in objectTemplate:6350aab5-a943-4d61-a934-ac20517084e3(Default User Template)]---------------------------</div><div>Stregth: STRONG</div><div>Source department:</div><div>  old: PP({<a href="http://example.com/xml/ns/mySchema}department):[PPV(String:154">http://example.com/xml/ns/mySchema}department):[PPV(String:154</a> - South Berkeley)]</div><div>  delta: null</div><div>  new: PP({<a href="http://example.com/xml/ns/mySchema}department):[PPV(String:154">http://example.com/xml/ns/mySchema}department):[PPV(String:154</a> - South Berkeley)]</div><div>Source transfer_date:</div><div>  old: PP({<a href="http://example.com/xml/ns/mySchema}transfer_date):[PPV(XMLGregorianCalendarImpl:2018-11-28T00:00:00.000-05:00">http://example.com/xml/ns/mySchema}transfer_date):[PPV(XMLGregorianCalendarImpl:2018-11-28T00:00:00.000-05:00</a>)]</div><div>  delta: PropertyDelta(extension / transfer_date, REPLACE)</div><div><b><i>  new: PP({<a href="http://example.com/xml/ns/mySchema}transfer_date):[]">http://example.com/xml/ns/mySchema}transfer_date):[]</a></i></b></div><div>Source transfer_department:</div><div>  old: null</div><div>  delta: null</div><div>  new: null</div><div>Target: PCD:{.../common/common-3}assignment {.../common/common-3}AssignmentType[0,-1],RAM</div><div>Expression: assignmentExpression</div><div>Condition: true -> true</div><div><b><i>Result: removed: id=null: 4 items</i></b></div><div>------------------------------------------------------</div><div><br></div><div>Does anyone have a method to get around this issue or might there be a bug fix in the works for this already? I've spent considerable time debugging the ObjectTemplateProcessor and related code, but am having trouble getting closer to the root of the problem.</div><div><br></div><div>Below is the example Object Template (attached for reference as well):</div><div><br></div><div><?xml version="1.0" encoding="UTF-8"?></div><div><!--</div><div><span style="white-space:pre">   </span>~ Default User Template</div><div>--></div><div><br></div><div><objectTemplate xmlns="<a href="http://midpoint.evolveum.com/xml/ns/public/common/common-3">http://midpoint.evolveum.com/xml/ns/public/common/common-3</a>"</div><div>                xmlns:q="<a href="http://prism.evolveum.com/xml/ns/public/query-3">http://prism.evolveum.com/xml/ns/public/query-3</a>"</div><div>                xmlns:c="<a href="http://midpoint.evolveum.com/xml/ns/public/common/common-3">http://midpoint.evolveum.com/xml/ns/public/common/common-3</a>"</div><div>                xmlns:t="<a href="http://prism.evolveum.com/xml/ns/public/types-3">http://prism.evolveum.com/xml/ns/public/types-3</a>"</div><div>                xmlns:org="<a href="http://midpoint.evolveum.com/xml/ns/public/common/org-3">http://midpoint.evolveum.com/xml/ns/public/common/org-3</a>"</div><div>                xmlns:icfs="<a href="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3">http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3</a>"</div><div>                xmlns:ri="<a href="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3">http://midpoint.evolveum.com/xml/ns/public/resource/instance-3</a>"</div><div>                xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"</div><div>                oid="6350aab5-a943-4d61-a934-ac20517084e3"</div><div>                version="18"></div><div>    <name>Default User Template</name></div><div>    <description></div><div>        User Template Object</div><div>    </description></div><div><br></div><div>    <mapping></div><div>        <name>Job Department Org mapping</name></div><div>        <trace>true</trace></div><div>        <description></div><div>            Look for appropriate Org objects by using the user's department property</div><div>            as the name of the org object. When no such object is found we want to create it on</div><div>            demand. We want to populate new Org object with a name derived from the user.</div><div>        </description></div><div>        <authoritative>true</authoritative></div><div>        <strength>strong</strength></div><div>        <source></div><div>            <name>department</name></div><div>            <c:path>extension/department</c:path></div><div>        </source></div><div>        <source></div><div>            <name>transfer_date</name></div><div>            <c:path>extension/transfer_date</c:path></div><div>        </source></div><div>        <expression></div><div>            <assignmentTargetSearch xsi:type="c:SearchObjectRefExpressionEvaluatorType"></div><div>                <targetType>c:OrgType</targetType></div><div>                <filter></div><div>                    <q:equal></div><div>                        <q:path>c:name</q:path></div><div>                        <expression></div><div>                            <path>$user/extension/department</path></div><div>                        </expression></div><div>                    </q:equal></div><div>                </filter></div><div><br></div><div>                <!-- Populate assignment fields --></div><div>                <populate></div><div>                    <populateItem></div><div>                        <expression></div><div>                            <script></div><div>                                <code><![CDATA[</div><div>                                    if (transfer_date != null) {</div><div>                                        return transfer_date</div><div>                                    }</div><div>                                ]]></code></div><div>                            </script></div><div>                        </expression></div><div>                        <target></div><div>                            <path>activation/validTo</path></div><div>                        </target></div><div>                    </populateItem></div><div>                    <populateItem></div><div>                        <target></div><div>                            <path>description</path></div><div>                        </target></div><div>                        <expression></div><div>                            <value>Department</value></div><div>                        </expression></div><div>                    </populateItem></div><div>                    <populateItem></div><div>                        <target></div><div>                            <path>extension/assignmentType</path></div><div>                        </target></div><div>                        <expression></div><div>                            <value>DEPARTMENT</value></div><div>                        </expression></div><div>                    </populateItem></div><div>                </populate></div><div><br></div><div>                <createOnDemand>true</createOnDemand></div><div>                <!-- Populate organization fields --></div><div>                <populateObject></div><div>                    <populateItem></div><div>                        <expression></div><div>                            <c:path xsi:type="t:ItemPathType">$user/extension/department</c:path></div><div>                        </expression></div><div>                        <target></div><div>                            <c:path>name</c:path></div><div>                        </target></div><div>                    </populateItem></div><div>                    <populateItem></div><div>                        <expression></div><div>                            <value>Job Department</value></div><div>                        </expression></div><div>                        <target></div><div>                            <c:path>orgType</c:path></div><div>                        </target></div><div>                    </populateItem></div><div>                    <populateItem></div><div>                        <expression></div><div>                            <assignmentTargetSearch xsi:type="c:SearchObjectRefExpressionEvaluatorType"></div><div>                                <targetType>c:OrgType</targetType></div><div>                                <filter></div><div>                                    <q:equal></div><div>                                        <q:path>c:name</q:path></div><div>                                        <expression></div><div>                                            <value>Job Department</value></div><div>                                        </expression></div><div>                                    </q:equal></div><div>                                </filter></div><div>                            </assignmentTargetSearch></div><div>                        </expression></div><div>                        <target></div><div>                            <c:path>assignment</c:path></div><div>                        </target></div><div>                    </populateItem></div><div>                </populateObject></div><div>            </assignmentTargetSearch></div><div>        </expression></div><div>        <condition></div><div>            <script></div><div>                <code></div><div>                    department != null</div><div>                </code></div><div>            </script></div><div>        </condition></div><div>        <target></div><div>            <c:path>assignment</c:path></div><div>            <set></div><div>                <condition></div><div>                    <script></div><div>                        <code><![CDATA[</div><div>                            import javax.xml.namespace.QName;</div><div><br></div><div>                            // Get Assignment Extension attributes</div><div>                            def ext = input.getExtension()</div><div>                            if (ext == null) return false;</div><div><br></div><div>                            // Get Extension Attribute "assignmentType"</div><div>                            ASSIGNMENT_TYPE_QNAME = new QName("<a href="http://example.com/xml/ns/mySchema">http://example.com/xml/ns/mySchema</a>", "assignmentType");</div><div>                            def assignmentType = ext.asPrismContainerValue().findProperty(ASSIGNMENT_TYPE_QNAME);</div><div>                            if( assignmentType == null) return false;</div><div><br></div><div>                            <a href="http://log.info">log.info</a>("DEPARTMENT CONDITION - ASSIGNMENT TYPE: {}", assignmentType.getValue().getValue() );</div><div>                            <a href="http://log.info">log.info</a>("DEPARTMENT CONDITION - ASSIGNMENT TYPE MATCH: {}", assignmentType.getValue().getValue() == "DEPARTMENT" );</div><div>                            return assignmentType.getValue().getValue() == "DEPARTMENT" </div><div>                            </div><div>                        ]]></code></div><div>                    </script></div><div>                </condition></div><div>            </set></div><div>        </target></div><div>    </mapping></div><div><br></div><div></objectTemplate></div><div><br></div><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div style="text-align:left"><br></div><div style="text-align:left">Brandon Powers</div><div><div style="text-align:left"><span>Exclamation Labs</span></div><span><div style="text-align:left">300 Washington Street</div></span><span><div style="text-align:left">Cumberland, MD 21502</div></span><div><a value="+18885455008" style="color:rgb(17,85,204)" href="tel:888.545.5008" target="_blank">888.545.5008</a><span style="color:rgb(34,34,34)"> or </span><a value="+13017225008" style="color:rgb(17,85,204)" href="tel:301.722.5008+ext+144" target="_blank">301.722.5008 ext 144</a></div><span><div style="text-align:left">fax <a value="+13017222183" style="color:rgb(17,85,204)">301.722.2183</a></div></span><div><a href="mailto:brandon@exclamationlabs.com" style="color:rgb(17,85,204)" target="_blank">brandon@exclamationlabs.com</a></div><span><div style="text-align:left"><a href="mailto:brandon@exclamationlabs.com" style="color:rgb(17,85,204);font-size:13px" target="_blank">www.exclamationlabs.com</a></div></span></div></div></div></div></div></div></div></div></div></div></div>