From f788e3ee331aa2b4f9e5b88e6c711e5b23d6e10b Mon Sep 17 00:00:00 2001 From: malithie Date: Wed, 22 Jan 2025 11:32:05 +0530 Subject: [PATCH 1/2] Support for rule evaluation in action execution. --- .../pom.xml | 6 ++ .../ActionExecutionLogConstants.java | 1 + .../impl/ActionExecutorServiceImpl.java | 77 ++++++++++++--- .../ActionExecutionServiceComponent.java | 58 +++++++----- ...ActionExecutionServiceComponentHolder.java | 13 +++ .../util/ActionExecutionDiagnosticLogger.java | 40 ++++++++ .../impl/ActionExecutorServiceImplTest.java | 94 ++++++++++++++++++- 7 files changed, 246 insertions(+), 43 deletions(-) diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/pom.xml b/components/action-mgt/org.wso2.carbon.identity.action.execution/pom.xml index 591db89bf47f..03ab9784ba97 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/pom.xml +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/pom.xml @@ -41,6 +41,10 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.action.management + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.rule.evaluation + org.wso2.carbon.identity.framework org.wso2.carbon.identity.central.log.mgt @@ -94,6 +98,8 @@ org.wso2.carbon.identity.action.management.*; version="${carbon.identity.package.import.version.range}", + org.wso2.carbon.identity.rule.evaluation.*; + version="${carbon.identity.package.import.version.range}", org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}", org.apache.commons.logging; version="${import.package.version.commons.logging}", org.apache.commons.collections; version="${commons-collections.wso2.osgi.version.range}", diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/ActionExecutionLogConstants.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/ActionExecutionLogConstants.java index 159e34ec288d..e5dd20537e6a 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/ActionExecutionLogConstants.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/ActionExecutionLogConstants.java @@ -33,6 +33,7 @@ private ActionExecutionLogConstants() {} public static class ActionIDs { public static final String EXECUTE_ACTION = "execute-action"; + public static final String EVALUATE_RULE = "evaluate-rule"; public static final String PROCESS_ACTION_REQUEST = "process-action-request"; public static final String SEND_ACTION_REQUEST = "send-action-request"; public static final String RECEIVE_ACTION_RESPONSE = "receive-action-response"; diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java index 517dfc02d8bf..c20b3810920f 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java @@ -61,6 +61,10 @@ import org.wso2.carbon.identity.action.management.model.Authentication; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; import org.wso2.carbon.identity.core.ThreadLocalAwareExecutors; +import org.wso2.carbon.identity.rule.evaluation.exception.RuleEvaluationException; +import org.wso2.carbon.identity.rule.evaluation.model.FlowContext; +import org.wso2.carbon.identity.rule.evaluation.model.FlowType; +import org.wso2.carbon.identity.rule.evaluation.model.RuleEvaluationResult; import java.util.ArrayList; import java.util.List; @@ -118,7 +122,7 @@ public ActionExecutionStatus execute(ActionType actionType, Map execute(ActionType actionType, Map execute(ActionType actionType, String actionId, Action action = getActionByActionId(actionType, actionId, tenantDomain); try { - return execute(action, eventContext); + return execute(action, eventContext, tenantDomain); } catch (ActionExecutionRuntimeException e) { LOG.debug("Skip executing action for action type: " + actionType.name(), e); // Skip executing actions when no action available is considered as action execution being successful. @@ -154,20 +158,28 @@ public ActionExecutionStatus execute(ActionType actionType, String actionId, } } - private ActionExecutionStatus execute(Action action, Map eventContext) + private ActionExecutionStatus execute(Action action, Map eventContext, String tenantDomain) throws ActionExecutionException { + if (action.getStatus() != Action.Status.ACTIVE) { + // If no active actions are detected, it is regarded as the action execution being successful. + return new SuccessStatus.Builder().setResponseContext(eventContext).build(); + } + + DIAGNOSTIC_LOGGER.logActionInitiation(action); + + if (!evaluateActionRule(action, eventContext, tenantDomain)) { + // If the action rule is not satisfied, it is regarded as the action execution being successful. + return new SuccessStatus.Builder().setResponseContext(eventContext).build(); + } + + DIAGNOSTIC_LOGGER.logActionExecution(action); + ActionType actionType = ActionType.valueOf(action.getType().getActionType()); ActionExecutionRequest actionRequest = buildActionExecutionRequest(actionType, eventContext); ActionExecutionResponseProcessor actionExecutionResponseProcessor = getResponseProcessor(actionType); - if (action.getStatus() == Action.Status.ACTIVE) { - DIAGNOSTIC_LOGGER.logActionInitiation(action); - return executeAction(action, actionRequest, eventContext, actionExecutionResponseProcessor); - } else { - // If no active actions are detected, it is regarded as the action execution being successful. - return new SuccessStatus.Builder().setResponseContext(eventContext).build(); - } + return executeAction(action, actionRequest, eventContext, actionExecutionResponseProcessor); } private Action getActionByActionId(ActionType actionType, String actionId, String tenantDomain) @@ -265,6 +277,30 @@ private ActionExecutionStatus executeAction(Action action, } } + private boolean evaluateActionRule(Action action, Map eventContext, String tenantDomain) + throws ActionExecutionException { + + if (action.getActionRule() != null && action.getActionRule().getId() != null) { + try { + RuleEvaluationResult ruleEvaluationResult = + ActionExecutionServiceComponentHolder.getInstance().getRuleEvaluationService() + .evaluate(action.getActionRule().getId(), + new FlowContext(FlowType.valueOf(action.getType().getActionType()), + eventContext), tenantDomain); + + logActionRuleEvaluation(action, ruleEvaluationResult); + + return ruleEvaluationResult.isRuleSatisfied(); + } catch (RuleEvaluationException e) { + throw new ActionExecutionException( + "Error occurred while evaluating the rule for action: " + action.getId(), e); + } + } + + logNoRuleConfiguredForAction(action); + return true; // If no action rule available, consider the rule as satisfied and execute action. + } + private ActionInvocationResponse executeActionAsynchronously(Action action, AuthMethods.AuthMethod authenticationMethod, String payload) throws ActionExecutionException { @@ -387,6 +423,19 @@ private ActionExecutionStatus processFailureResponse(Action action, failureResponse); } + private void logActionRuleEvaluation(Action action, RuleEvaluationResult ruleEvaluationResult) { + + DIAGNOSTIC_LOGGER.logActionRuleEvaluation(action, ruleEvaluationResult.isRuleSatisfied()); + LOG.debug("Rule of action: " + action.getId() + " evaluated to: " + + ruleEvaluationResult.isRuleSatisfied()); + } + + private void logNoRuleConfiguredForAction(Action action) { + + DIAGNOSTIC_LOGGER.logNoRuleConfiguredForAction(action); + LOG.debug("No rule configured for action " + action.getId() + ". Proceed executing the action."); + } + private void logSuccessResponse(Action action, ActionInvocationSuccessResponse successResponse) { DIAGNOSTIC_LOGGER.logSuccessResponse(action); diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponent.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponent.java index 94c1e40a3719..4a23e50380e7 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponent.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponent.java @@ -35,6 +35,7 @@ import org.wso2.carbon.identity.action.execution.impl.ActionExecutionResponseProcessorFactory; import org.wso2.carbon.identity.action.execution.impl.ActionExecutorServiceImpl; import org.wso2.carbon.identity.action.management.service.ActionManagementService; +import org.wso2.carbon.identity.rule.evaluation.service.RuleEvaluationService; /** * OSGI service component for the Action execution. @@ -81,18 +82,14 @@ protected void deactivate(ComponentContext context) { ) protected void setActionManagementService(ActionManagementService actionManagementService) { - if (LOG.isDebugEnabled()) { - LOG.debug("Registering a reference for ActionManagementService in the ActionExecutionServiceComponent."); - } + LOG.debug("Registering a reference for ActionManagementService in the ActionExecutionServiceComponent."); ActionExecutionServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); } protected void unsetActionManagementService(ActionManagementService actionManagementService) { - if (LOG.isDebugEnabled()) { - LOG.debug( - "Unregistering the reference for ActionManagementService in the ActionExecutionServiceComponent."); - } + LOG.debug( + "Unregistering the reference for ActionManagementService in the ActionExecutionServiceComponent."); if (ActionExecutionServiceComponentHolder.getInstance().getActionManagementService() .equals(actionManagementService)) { ActionExecutionServiceComponentHolder.getInstance().setActionManagementService(null); @@ -108,20 +105,16 @@ protected void unsetActionManagementService(ActionManagementService actionManage ) protected void setActionExecutionRequestBuilder(ActionExecutionRequestBuilder actionExecutionRequestBuilder) { - if (LOG.isDebugEnabled()) { - LOG.debug("Registering ActionExecutionRequestBuilder: " + - actionExecutionRequestBuilder.getClass().getName() + - " in the ActionExecutionServiceComponent."); - } + LOG.debug("Registering ActionExecutionRequestBuilder: " + + actionExecutionRequestBuilder.getClass().getName() + + " in the ActionExecutionServiceComponent."); ActionExecutionRequestBuilderFactory.registerActionExecutionRequestBuilder(actionExecutionRequestBuilder); } protected void unsetActionExecutionRequestBuilder(ActionExecutionRequestBuilder actionExecutionRequestBuilder) { - if (LOG.isDebugEnabled()) { - LOG.debug("Unregistering ActionExecutionRequestBuilder: " + - actionExecutionRequestBuilder.getClass().getName() + " in the ActionExecutionServiceComponent."); - } + LOG.debug("Unregistering ActionExecutionRequestBuilder: " + + actionExecutionRequestBuilder.getClass().getName() + " in the ActionExecutionServiceComponent."); ActionExecutionRequestBuilderFactory.unregisterActionExecutionRequestBuilder(actionExecutionRequestBuilder); } @@ -135,11 +128,9 @@ protected void unsetActionExecutionRequestBuilder(ActionExecutionRequestBuilder protected void setActionExecutionResponseProcessor( ActionExecutionResponseProcessor actionExecutionResponseProcessor) { - if (LOG.isDebugEnabled()) { - LOG.debug("Registering ActionExecutionResponseProcessor: " + - actionExecutionResponseProcessor.getClass().getName() + - " in the ActionExecutionServiceComponent."); - } + LOG.debug("Registering ActionExecutionResponseProcessor: " + + actionExecutionResponseProcessor.getClass().getName() + + " in the ActionExecutionServiceComponent."); ActionExecutionResponseProcessorFactory.registerActionExecutionResponseProcessor( actionExecutionResponseProcessor); } @@ -147,11 +138,28 @@ protected void setActionExecutionResponseProcessor( protected void unsetActionExecutionResponseProcessor( ActionExecutionResponseProcessor actionExecutionResponseProcessor) { - if (LOG.isDebugEnabled()) { - LOG.debug("Unregistering ActionExecutionResponseProcessor: " + - actionExecutionResponseProcessor.getClass().getName() + " in the ActionExecutionServiceComponent."); - } + LOG.debug("Unregistering ActionExecutionResponseProcessor: " + + actionExecutionResponseProcessor.getClass().getName() + " in the ActionExecutionServiceComponent."); ActionExecutionResponseProcessorFactory.unregisterActionExecutionResponseProcessor( actionExecutionResponseProcessor); } + + @Reference( + name = "rule.evaluation.service.component", + service = RuleEvaluationService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetRuleEvaluationService" + ) + protected void setRuleEvaluationService(RuleEvaluationService ruleEvaluationService) { + + LOG.debug("Registering a reference for RuleEvaluationService in the ActionExecutionServiceComponent."); + ActionExecutionServiceComponentHolder.getInstance().setRuleEvaluationService(ruleEvaluationService); + } + + protected void unsetRuleEvaluationService(RuleEvaluationService ruleEvaluationService) { + + LOG.debug("Unregistering reference for RuleEvaluationService in the ActionExecutionServiceComponent."); + ActionExecutionServiceComponentHolder.getInstance().setRuleEvaluationService(ruleEvaluationService); + } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponentHolder.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponentHolder.java index 8163a538354a..8aa8574bf3e1 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponentHolder.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/internal/ActionExecutionServiceComponentHolder.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.action.execution.internal; import org.wso2.carbon.identity.action.management.service.ActionManagementService; +import org.wso2.carbon.identity.rule.evaluation.service.RuleEvaluationService; /** * This class holds references for dependent services required for Action Execution Service to function. @@ -28,6 +29,7 @@ public class ActionExecutionServiceComponentHolder { private static final ActionExecutionServiceComponentHolder INSTANCE = new ActionExecutionServiceComponentHolder(); private ActionManagementService actionManagementService; + private RuleEvaluationService ruleEvaluationService; private ActionExecutionServiceComponentHolder() { @@ -47,4 +49,15 @@ public void setActionManagementService(ActionManagementService actionManagementS this.actionManagementService = actionManagementService; } + + public RuleEvaluationService getRuleEvaluationService() { + + return ruleEvaluationService; + } + + public void setRuleEvaluationService( + RuleEvaluationService ruleEvaluationService) { + + this.ruleEvaluationService = ruleEvaluationService; + } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/util/ActionExecutionDiagnosticLogger.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/util/ActionExecutionDiagnosticLogger.java index f62c10e7fd21..a3d49c1d9794 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/util/ActionExecutionDiagnosticLogger.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/util/ActionExecutionDiagnosticLogger.java @@ -46,6 +46,46 @@ public void logActionInitiation(Action action) { DiagnosticLog.ResultStatus.SUCCESS)); } + public void logActionExecution(Action action) { + + if (!LoggerUtils.isDiagnosticLogsEnabled()) { + return; + } + + triggerLogEvent( + initializeDiagnosticLogBuilder( + ActionExecutionLogConstants.ActionIDs.EXECUTE_ACTION, + action.getType().getDisplayName() + " action execution started.", + DiagnosticLog.ResultStatus.SUCCESS)); + } + + public void logActionRuleEvaluation(Action action, boolean ruleEvaluationResult) { + + if (!LoggerUtils.isDiagnosticLogsEnabled()) { + return; + } + + triggerLogEvent( + initializeDiagnosticLogBuilder( + ActionExecutionLogConstants.ActionIDs.EVALUATE_RULE, + "Rule of " + action.getType().getDisplayName() + " action evaluated to " + + ruleEvaluationResult, DiagnosticLog.ResultStatus.SUCCESS)); + } + + public void logNoRuleConfiguredForAction(Action action) { + + if (!LoggerUtils.isDiagnosticLogsEnabled()) { + return; + } + + triggerLogEvent( + initializeDiagnosticLogBuilder( + ActionExecutionLogConstants.ActionIDs.EVALUATE_RULE, + "No rule configured for action " + action.getType().getDisplayName() + + ". Proceed executing the action." + , DiagnosticLog.ResultStatus.SUCCESS)); + } + public void logActionRequest(Action action) { if (!LoggerUtils.isDiagnosticLogsEnabled()) { diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/test/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImplTest.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/test/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImplTest.java index 51552bb9af0e..fbc66f2bcc17 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/test/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImplTest.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/test/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImplTest.java @@ -65,10 +65,14 @@ import org.wso2.carbon.identity.action.execution.util.RequestFilter; import org.wso2.carbon.identity.action.management.exception.ActionMgtException; import org.wso2.carbon.identity.action.management.model.Action; +import org.wso2.carbon.identity.action.management.model.ActionRule; import org.wso2.carbon.identity.action.management.model.Authentication; import org.wso2.carbon.identity.action.management.model.EndpointConfig; import org.wso2.carbon.identity.action.management.service.ActionManagementService; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; +import org.wso2.carbon.identity.rule.evaluation.exception.RuleEvaluationException; +import org.wso2.carbon.identity.rule.evaluation.model.RuleEvaluationResult; +import org.wso2.carbon.identity.rule.evaluation.service.RuleEvaluationService; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -94,6 +98,8 @@ public class ActionExecutorServiceImplTest { @Mock private ActionManagementService actionManagementService; @Mock + private RuleEvaluationService ruleEvaluationService; + @Mock private ActionExecutionRequestBuilder actionExecutionRequestBuilder; @Mock private ActionExecutionResponseProcessor actionExecutionResponseProcessor; @@ -121,6 +127,7 @@ public void setUp() throws Exception { ActionExecutionServiceComponentHolder actionExecutionServiceComponentHolder = ActionExecutionServiceComponentHolder.getInstance(); actionExecutionServiceComponentHolder.setActionManagementService(actionManagementService); + actionExecutionServiceComponentHolder.setRuleEvaluationService(ruleEvaluationService); // Set apiClient field using reflection setField(actionExecutorService, "apiClient", apiClient); setFinalField(actionExecutorService, "DIAGNOSTIC_LOGGER", actionExecutionDiagnosticLogger); @@ -182,6 +189,23 @@ public void testActionExecuteSuccessWhenNoActiveActionAvailableForActionType() t assertEquals(actualStatus.getStatus(), expectedStatus.getStatus()); } + @Test + public void testActionExecuteSuccessWhenRuleConfiguredAndNotSatisfied() throws Exception { + + Action action = mock(Action.class); + when(action.getStatus()).thenReturn(Action.Status.ACTIVE); + when(action.getType()).thenReturn(Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN); + when(action.getActionRule()).thenReturn(ActionRule.create("ruleId", "tenantDomain")); + when(ruleEvaluationService.evaluate(any(), any(), any())).thenReturn(new RuleEvaluationResult("ruleId", false)); + + ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; + Map eventContext = Collections.emptyMap(); + + ActionExecutionStatus status = actionExecutorService.execute(actionType, eventContext, "tenantDomain"); + + assertEquals(status.getStatus(), ActionExecutionStatus.Status.SUCCESS); + } + @Test(expectedExceptions = ActionExecutionException.class, expectedExceptionsMessageRegExp = "Multiple actions found for action type: PRE_ISSUE_ACCESS_TOKEN. " + "Current implementation doesn't support multiple actions for a single action type.") @@ -233,6 +257,27 @@ public void testActionExecuteWithActionFailureWhenInvalidActionGiven() throws Ex actionExecutorService.execute(ActionType.PRE_ISSUE_ACCESS_TOKEN, any(), any()); } + @Test(expectedExceptions = ActionExecutionException.class, + expectedExceptionsMessageRegExp = "Error occurred while evaluating the rule for action: actionId") + public void testActionExecuteFailureWhenRuleEvaluationFails() throws Exception { + + Action action = mock(Action.class); + when(action.getId()).thenReturn("actionId"); + when(action.getStatus()).thenReturn(Action.Status.ACTIVE); + when(action.getType()).thenReturn(Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN); + when(action.getActionRule()).thenReturn(ActionRule.create("ruleId", "tenantDomain")); + when(actionManagementService.getActionsByActionType(any(), any())).thenReturn( + Collections.singletonList(action)); + when(ruleEvaluationService.evaluate(any(), any(), any())).thenThrow(new RuleEvaluationException("Error")); + + ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; + Map eventContext = Collections.emptyMap(); + + ActionExecutionStatus status = actionExecutorService.execute(actionType, eventContext, "tenantDomain"); + + assertEquals(status.getStatus(), ActionExecutionStatus.Status.SUCCESS); + } + @Test(expectedExceptions = ActionExecutionException.class, expectedExceptionsMessageRegExp = "Failed to build the request payload for action type: " + "PRE_ISSUE_ACCESS_TOKEN") @@ -387,7 +432,7 @@ public void testBuildActionExecutionRequest() throws Exception { } @Test - public void testExecuteSuccess() throws Exception { + public void testActionExecuteSuccessWhenNoRuleConfiguredInAction() throws Exception { ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; Map eventContext = Collections.emptyMap(); @@ -426,7 +471,50 @@ public void testExecuteSuccess() throws Exception { } @Test - public void testExecuteFailure() throws Exception { + public void testActionExecuteSuccessWhenRuleConfiguredInActionIsSatisfied() throws Exception { + + ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; + Map eventContext = Collections.emptyMap(); + + Action action = createAction(); + when(action.getActionRule()).thenReturn(ActionRule.create("ruleId", "tenantDomain")); + + when(actionManagementService.getActionsByActionType(any(), any())).thenReturn( + Collections.singletonList(action)); + + when(ruleEvaluationService.evaluate(any(), any(), any())).thenReturn(new RuleEvaluationResult("ruleId", true)); + + actionExecutionRequestBuilderFactory.when( + () -> ActionExecutionRequestBuilderFactory.getActionExecutionRequestBuilder(any())) + .thenReturn(actionExecutionRequestBuilder); + actionExecutionResponseProcessorFactory.when(() -> ActionExecutionResponseProcessorFactory + .getActionExecutionResponseProcessor(any())) + .thenReturn(actionExecutionResponseProcessor); + + when(actionExecutionRequestBuilder.getSupportedActionType()).thenReturn(actionType); + when(actionExecutionRequestBuilder.buildActionExecutionRequest(eventContext)).thenReturn( + mock(ActionExecutionRequest.class)); + + ActionInvocationResponse actionInvocationResponse = createSuccessActionInvocationResponse(); + when(apiClient.callAPI(any(), any(), any())).thenReturn(actionInvocationResponse); + + ActionExecutionStatus expectedStatus = new SuccessStatus.Builder().build(); + when(actionExecutionResponseProcessor.getSupportedActionType()).thenReturn(actionType); + when(actionExecutionResponseProcessor.processSuccessResponse(any(), any(), any())).thenReturn( + expectedStatus); + when(actionManagementService.getActionByActionId(any(), any(), any())).thenReturn(action); + + ActionExecutionStatus actualStatus = + actionExecutorService.execute(actionType, eventContext, "tenantDomain"); + assertEquals(actualStatus.getStatus(), expectedStatus.getStatus()); + + ActionExecutionStatus actionExecutionStatusWithActionIds = actionExecutorService.execute( + actionType, action.getId(), eventContext, "tenantDomain"); + assertEquals(actionExecutionStatusWithActionIds.getStatus(), expectedStatus.getStatus()); + } + + @Test + public void testActionExecuteFailure() throws Exception { ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; Map eventContext = Collections.emptyMap(); @@ -509,7 +597,6 @@ public void testExecuteIncomplete() throws Exception { "PRE_ISSUE_ACCESS_TOKEN action ID: actionId") public void testActionExecuteFailureForUnexpectedAPIResponse() throws Exception { - ActionType actionType = ActionType.PRE_ISSUE_ACCESS_TOKEN; Map eventContext = Collections.emptyMap(); @@ -611,7 +698,6 @@ private ActionInvocationResponse createIncompleteActionInvocationResponse() { return actionInvocationResponse; } - private ActionInvocationResponse createFailureActionInvocationResponse() { ActionInvocationFailureResponse failureResponse = mock(ActionInvocationFailureResponse.class); From 83c62ef36d70cefe80dd965a0fbcd3f4b6c67ed9 Mon Sep 17 00:00:00 2001 From: malithie Date: Wed, 22 Jan 2025 14:53:38 +0530 Subject: [PATCH 2/2] Apply minor refactoring. --- .../impl/ActionExecutorServiceImpl.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java index c20b3810920f..60a0311933b3 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.execution/src/main/java/org/wso2/carbon/identity/action/execution/impl/ActionExecutorServiceImpl.java @@ -280,25 +280,25 @@ private ActionExecutionStatus executeAction(Action action, private boolean evaluateActionRule(Action action, Map eventContext, String tenantDomain) throws ActionExecutionException { - if (action.getActionRule() != null && action.getActionRule().getId() != null) { - try { - RuleEvaluationResult ruleEvaluationResult = - ActionExecutionServiceComponentHolder.getInstance().getRuleEvaluationService() - .evaluate(action.getActionRule().getId(), - new FlowContext(FlowType.valueOf(action.getType().getActionType()), - eventContext), tenantDomain); - - logActionRuleEvaluation(action, ruleEvaluationResult); - - return ruleEvaluationResult.isRuleSatisfied(); - } catch (RuleEvaluationException e) { - throw new ActionExecutionException( - "Error occurred while evaluating the rule for action: " + action.getId(), e); - } + if (action.getActionRule() == null || action.getActionRule().getId() == null) { + logNoRuleConfiguredForAction(action); + return true; // If no action rule available, consider the rule as satisfied and execute action. } - logNoRuleConfiguredForAction(action); - return true; // If no action rule available, consider the rule as satisfied and execute action. + try { + RuleEvaluationResult ruleEvaluationResult = + ActionExecutionServiceComponentHolder.getInstance().getRuleEvaluationService() + .evaluate(action.getActionRule().getId(), + new FlowContext(FlowType.valueOf(action.getType().getActionType()), + eventContext), tenantDomain); + + logActionRuleEvaluation(action, ruleEvaluationResult); + + return ruleEvaluationResult.isRuleSatisfied(); + } catch (RuleEvaluationException e) { + throw new ActionExecutionException( + "Error occurred while evaluating the rule for action: " + action.getId(), e); + } } private ActionInvocationResponse executeActionAsynchronously(Action action,