Skip to content

Commit edbe117

Browse files
author
Michal Zelencik
committed
Smart Integration: Add support for configurable number of mapping retries
Introduce smartIntegrationMappingSuggestionRetryCount parameter to control how many mapping retries should be executed during mapping suggestions. - Default value is 0 (no retry) Task #11155 Signed-off-by: Michal Zelencik <michal.zelencik@evolveum.com>
1 parent 4464f04 commit edbe117

File tree

7 files changed

+144
-54
lines changed

7 files changed

+144
-54
lines changed

config/initial-objects/system-configuration/000-system-configuration.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@
180180
<operationExecutionRecording>
181181
<skipWhenSuccess>true</skipWhenSuccess>
182182
</operationExecutionRecording>
183+
<smartIntegrationMappingSuggestionRetryCount>0</smartIntegrationMappingSuggestionRetryCount>
184+
<smartIntegrationStatisticsTtl>P1D</smartIntegrationStatisticsTtl>
183185
</internals>
184186
<adminGuiConfiguration>
185187
<homePage id="21">

infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13877,6 +13877,18 @@
1387713877
</xsd:appinfo>
1387813878
</xsd:annotation>
1387913879
</xsd:element>
13880+
<xsd:element name="smartIntegrationMappingSuggestionRetryCount" type="xsd:int" minOccurs="0">
13881+
<xsd:annotation>
13882+
<xsd:documentation>
13883+
Number of retry attempts for AI mapping suggestion when validation fails.
13884+
Default is 0 (no retry). Set to 1 or higher to enable retry mechanism.
13885+
</xsd:documentation>
13886+
<xsd:appinfo>
13887+
<a:since>4.11</a:since>
13888+
<a:displayName>InternalsConfigurationType.smartIntegrationMappingSuggestionRetryCount</a:displayName>
13889+
</xsd:appinfo>
13890+
</xsd:annotation>
13891+
</xsd:element>
1388013892
</xsd:sequence>
1388113893
<xsd:attribute name="id" type="xsd:long"/>
1388213894
</xsd:complexType>

model/smart-impl/src/main/java/com/evolveum/midpoint/smart/impl/MappingSuggestionOperationFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public MappingsSuggestionOperation create(ServiceClient client, String resourceO
4949
ResourceObjectTypeIdentification typeIdentification, CurrentActivityState<?> activityState,
5050
boolean isInbound, boolean useAiService,
5151
@Nullable ShadowObjectClassStatisticsType objectTypeStatistics,
52+
int retryCount,
5253
Task task, OperationResult parentResult)
5354
throws SchemaException, ExpressionEvaluationException, SecurityViolationException, CommunicationException,
5455
ConfigurationException, ObjectNotFoundException {
@@ -62,6 +63,7 @@ public MappingsSuggestionOperation create(ServiceClient client, String resourceO
6263
this.categoricalAttributeRegistry,
6364
isInbound,
6465
useAiService,
65-
objectTypeStatistics);
66+
objectTypeStatistics,
67+
retryCount);
6668
}
6769
}

model/smart-impl/src/main/java/com/evolveum/midpoint/smart/impl/MappingsSuggestionOperation.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class MappingsSuggestionOperation {
8181
private final boolean isInbound;
8282
private final boolean useAiService;
8383
@Nullable private final ShadowObjectClassStatisticsType objectTypeStatistics;
84+
private final int retryCount;
8485

8586
private MappingsSuggestionOperation(
8687
TypeOperationContext ctx,
@@ -92,7 +93,8 @@ private MappingsSuggestionOperation(
9293
CategoricalAttributeRegistry categoricalAttributeRegistry,
9394
boolean isInbound,
9495
boolean useAiService,
95-
@Nullable ShadowObjectClassStatisticsType objectTypeStatistics) {
96+
@Nullable ShadowObjectClassStatisticsType objectTypeStatistics,
97+
int retryCount) {
9698
this.ctx = ctx;
9799
this.qualityAssessor = qualityAssessor;
98100
this.scriptValidator = scriptValidator;
@@ -103,6 +105,7 @@ private MappingsSuggestionOperation(
103105
this.isInbound = isInbound;
104106
this.useAiService = useAiService;
105107
this.objectTypeStatistics = objectTypeStatistics;
108+
this.retryCount = retryCount;
106109
}
107110

108111
static MappingsSuggestionOperation init(
@@ -115,7 +118,8 @@ static MappingsSuggestionOperation init(
115118
CategoricalAttributeRegistry categoricalAttributeRegistry,
116119
boolean isInbound,
117120
boolean useAiService,
118-
@Nullable ShadowObjectClassStatisticsType objectTypeStatistics)
121+
@Nullable ShadowObjectClassStatisticsType objectTypeStatistics,
122+
int retryCount)
119123
throws SchemaException, ExpressionEvaluationException, SecurityViolationException, CommunicationException,
120124
ConfigurationException, ObjectNotFoundException {
121125
return new MappingsSuggestionOperation(
@@ -128,7 +132,8 @@ static MappingsSuggestionOperation init(
128132
categoricalAttributeRegistry,
129133
isInbound,
130134
useAiService,
131-
objectTypeStatistics);
135+
objectTypeStatistics,
136+
retryCount);
132137
}
133138

134139
private MappingDirection resolveDirection() {
@@ -641,7 +646,7 @@ private ExpressionType evaluateAiMappingWithRetry(
641646
String errorLog = null;
642647
String retryScript = null;
643648

644-
for (int attempt = 1; attempt <= 2; attempt++) {
649+
for (int attempt = 0; attempt <= retryCount; attempt++) {
645650
var mappingResponse = askMicroserviceAsync(matchPair, valuePairsForLLM, errorLog, retryScript);
646651
retryScript = mappingResponse != null ? mappingResponse.getTransformationScript() : null;
647652
var aiExpression = buildScriptExpression(mappingResponse);
@@ -653,11 +658,11 @@ private ExpressionType evaluateAiMappingWithRetry(
653658
}
654659
break;
655660
} catch (ExpressionEvaluationException | SecurityViolationException e) {
656-
if (attempt == 1) {
661+
if (attempt < retryCount) {
657662
errorLog = e.getMessage();
658-
LOGGER.warn("Validation issues found on attempt 1; retrying.");
663+
LOGGER.warn("Validation issues found on attempt {}; retrying.", attempt);
659664
} else {
660-
LOGGER.warn("Validation issues persist after retry; giving up.");
665+
LOGGER.warn("Validation issues found in mapping script; giving up.");
661666
throw e;
662667
}
663668
}

model/smart-impl/src/main/java/com/evolveum/midpoint/smart/impl/SmartIntegrationServiceImpl.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.evolveum.midpoint.prism.query.ObjectQuery;
3333
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
3434
import com.evolveum.midpoint.repo.api.RepositoryService;
35+
import com.evolveum.midpoint.repo.common.SystemObjectCache;
3536
import com.evolveum.midpoint.repo.common.activity.ActivityInterruptedException;
3637
import com.evolveum.midpoint.repo.common.activity.run.state.CurrentActivityState;
3738
import com.evolveum.midpoint.schema.GetOperationOptions;
@@ -112,13 +113,15 @@ public class SmartIntegrationServiceImpl implements SmartIntegrationService {
112113
private final ObjectTypesSuggestionOperationFactory objectTypesSuggestionOperationFactory;
113114
private final StatisticsService statisticsService;
114115
private final SchemaMatchService schemaMatchService;
116+
private final SystemObjectCache systemObjectCache;
115117

116118
public SmartIntegrationServiceImpl(ModelService modelService,
117119
TaskService taskService, ModelInteractionServiceImpl modelInteractionService, TaskManager taskManager,
118120
@Qualifier("cacheRepositoryService") RepositoryService repositoryService,
119121
ServiceClientFactory clientFactory, MappingSuggestionOperationFactory mappingSuggestionOperationFactory,
120122
ObjectTypesSuggestionOperationFactory objectTypesSuggestionOperationFactory,
121-
StatisticsService statisticsService, SchemaMatchService schemaMatchService) {
123+
StatisticsService statisticsService, SchemaMatchService schemaMatchService,
124+
SystemObjectCache systemObjectCache) {
122125
this.modelService = modelService;
123126
this.taskService = taskService;
124127
this.modelInteractionService = modelInteractionService;
@@ -129,6 +132,7 @@ public SmartIntegrationServiceImpl(ModelService modelService,
129132
this.objectTypesSuggestionOperationFactory = objectTypesSuggestionOperationFactory;
130133
this.statisticsService = statisticsService;
131134
this.schemaMatchService = schemaMatchService;
135+
this.systemObjectCache = systemObjectCache;
132136
}
133137

134138
@Override
@@ -661,8 +665,9 @@ public MappingsSuggestionType suggestMappings(
661665
.addArbitraryObjectAsParam("typeIdentification", typeIdentification)
662666
.build();
663667
try (var serviceClient = this.clientFactory.getServiceClient(result)) {
668+
int retryCount = getConfiguredRetryCount(result);
664669
var mappings = this.mappingSuggestionOperationFactory.create(serviceClient, resourceOid,
665-
typeIdentification, activityState, isInbound, useAiService, objectTypeStatistics, task, result)
670+
typeIdentification, activityState, isInbound, useAiService, objectTypeStatistics, retryCount, task, result)
666671
.suggestMappings(result, schemaMatch, targetPathsToIgnore);
667672
LOGGER.debug("Suggested mappings:\n{}", mappings.debugDumpLazily(1));
668673
return mappings;
@@ -674,6 +679,26 @@ public MappingsSuggestionType suggestMappings(
674679
}
675680
}
676681

682+
/**
683+
* Retrieves the configured retry count for AI mapping suggestions from system configuration.
684+
* Falls back to default of 0 (no retry) if not configured.
685+
*/
686+
private int getConfiguredRetryCount(OperationResult result) {
687+
try {
688+
SystemConfigurationType systemConfig = systemObjectCache.getSystemConfigurationBean(result);
689+
if (systemConfig != null && systemConfig.getInternals() != null) {
690+
Integer configuredRetryCount = systemConfig.getInternals().getSmartIntegrationMappingSuggestionRetryCount();
691+
if (configuredRetryCount != null && configuredRetryCount >= 0) {
692+
LOGGER.debug("Using configured retry count for mapping suggestions: {}", configuredRetryCount);
693+
return configuredRetryCount;
694+
}
695+
}
696+
} catch (SchemaException e) {
697+
LOGGER.warn("Failed to retrieve configured retry count, using default: {}", e.getMessage());
698+
}
699+
return 0;
700+
}
701+
677702
@Override
678703
public String submitSuggestCorrelationOperation(
679704
String resourceOid, ResourceObjectTypeIdentification typeIdentification,

0 commit comments

Comments
 (0)