Skip to content

Commit

Permalink
Fix "incomplete but having value" issue in tasks
Browse files Browse the repository at this point in the history
When e.g. refreshing a task, we unintentionally created a task prism
object with result marked as incomplete and having a value at the same
time.

A serialized form of such tasks (e.g. in trace files) was then
not parseable because of "Attempt to store multiple values in
single-valued property" exception.

Resolves MID-7583.
  • Loading branch information
mederly committed Jan 20, 2022
1 parent f1e657d commit b7ef122
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public class TestTracing extends AbstractEmptyModelIntegrationTest {
public static final ItemName NAME_EMBEDDED = new ItemName(CONTAINERS_NS, "embedded");
public static final ItemName TYPE_MY_CONTAINER = new ItemName(CONTAINERS_NS, "MyContainerType");

private static final TestResource<TaskType> ARCHETYPE_DUMMY = new TestResource<>(
TEST_DIR, "archetype-dummy.xml", "70f3f752-89fc-46e5-80f5-b15c2a4bd5e5");
private static final TestResource<TaskType> TASK_RECOMPUTE_ADMINISTRATOR_TRACED = new TestResource<>(
TEST_DIR, "task-recompute-administrator-traced.xml", "80b30eb9-55d3-40dc-a674-cc1c9e0400d6");

@Override
public void initSystem(Task initTask, OperationResult initResult)
throws Exception {
Expand All @@ -75,6 +80,7 @@ public void initSystem(Task initTask, OperationResult initResult)
repoAdd(USER_JIM, initResult);
repoAdd(ROLE_CLASS_LESS_VALUES, initResult);
repoAdd(FUNCTION_LIBRARY_HACKING, initResult);
repoAdd(ARCHETYPE_DUMMY, initResult);
}

@Override
Expand Down Expand Up @@ -163,6 +169,32 @@ public void test200ClassLessValues() throws Exception {
assertTraceCanBeParsed(result);
}

/**
* Tests basic tracing of a task.
*
* MID-7583.
*/
@Test
public void test300TracingTaskBasic() throws Exception {
given();
Task task = getTestTask();
OperationResult result = getTestOperationResult();

deleteReportDataObjects(result);

when();
addObject(TASK_RECOMPUTE_ADMINISTRATOR_TRACED, task, result);

then();
waitForTaskFinish(TASK_RECOMPUTE_ADMINISTRATOR_TRACED.oid, false);

assertTask(TASK_RECOMPUTE_ADMINISTRATOR_TRACED.oid, "after")
.assertClosed()
.assertSuccess();

assertTraceCanBeParsed(result);
}

private void deleteReportDataObjects(OperationResult result) throws ObjectNotFoundException, SchemaException {
SearchResultList<PrismObject<ReportDataType>> objects = repositoryService.searchObjects(
ReportDataType.class, null, null, result);
Expand Down
11 changes: 11 additions & 0 deletions model/model-intest/src/test/resources/tracing/archetype-dummy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!--
~ Copyright (C) 2010-2022 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
oid="70f3f752-89fc-46e5-80f5-b15c2a4bd5e5">
<name>dummy</name>
</archetype>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@
<systemConfiguration xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
oid="00000000-0000-0000-0000-000000000001">
<name>SystemConfiguration</name>
<internals>
<tracing>
<profile>
<name>functional-model-logging</name>
<displayName>Functional tracing (with model logging)</displayName>
<visible>true</visible>
<fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
<createRepoObject>true</createRepoObject>
<compressOutput>true</compressOutput>
<collectLogEntries>true</collectLogEntries>
<loggingOverride>
<levelOverride>
<logger>com.evolveum.midpoint.model</logger>
<level>TRACE</level>
</levelOverride>
</loggingOverride>
<tracingTypeProfile>
<level>normal</level>
</tracingTypeProfile>
</profile>
</tracing>
</internals>
<audit>
<eventRecording>
<escapeIllegalCharacters>true</escapeIllegalCharacters>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!--
~ Copyright (C) 2010-2022 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
oid="80b30eb9-55d3-40dc-a674-cc1c9e0400d6">
<name>task-recompute-administrator-traced</name>
<assignment>
<targetRef oid="70f3f752-89fc-46e5-80f5-b15c2a4bd5e5" type="ArchetypeType"/>
</assignment>
<ownerRef oid="00000000-0000-0000-0000-000000000002" type="UserType"/>
<executionState>runnable</executionState>
<activity>
<work>
<recomputation>
<objects>
<type>UserType</type>
<query>
<q:filter>
<q:inOid>
<q:value>00000000-0000-0000-0000-000000000002</q:value>
</q:inOid>
</q:filter>
</query>
</objects>
</recomputation>
</work>
<reporting>
<tracing>
<tracingProfile>
<ref>functional-model-logging</ref>
</tracingProfile>
</tracing>
</reporting>
</activity>
</task>
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ private void updateTaskPrismResult() {
synchronized (prismAccess) {
if (taskResult != null) {
taskPrism.asObjectable().setResult(taskResult.createOperationResultType());
taskPrism.findProperty(TaskType.F_RESULT).setIncomplete(false); // prism will do this automatically some day
taskPrism.asObjectable().setResultStatus(taskResult.getStatus().createStatusType());
} else {
taskPrism.asObjectable().setResult(null);
Expand Down Expand Up @@ -786,7 +787,12 @@ public void setResultTransient(OperationResult result) {
synchronized (prismAccess) {
taskResult = result;
taskResultIncomplete = false;
taskPrism.asObjectable().setResult(result != null ? result.createOperationResultType() : null);
if (result != null) {
taskPrism.asObjectable().setResult(result.createOperationResultType());
taskPrism.findProperty(TaskType.F_RESULT).setIncomplete(false); // prism will do this automatically some day
} else {
taskPrism.asObjectable().setResult(null);
}
taskPrism.asObjectable().setResultStatus(result != null ? result.getStatus().createStatusType() : null);
}
}
Expand Down

0 comments on commit b7ef122

Please sign in to comment.