Repository: wso2/carbon-identity-framework
Pull request #6669: Introduce listeners to registration engine
Author: login: ThaminduR
Created: 2025-04-08T06:06:44Z | Merged: 2025-04-08T17:21:03Z

### Proposed changes in this pull request

Introduce listeners to registration engine. This introduces listener implementation to following points.

- preInitiate
- postInitiate
- preContinue
- postContinue

Further, input validation is refactored to a listener.


Diff:
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/pom.xml b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/pom.xml
index 9b328cc3f972..e3bed3f15ff6 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/pom.xml
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/pom.xml
@@ -155,7 +155,8 @@
                             org.wso2.carbon.identity.user.registration.engine,
                             org.wso2.carbon.identity.user.registration.engine.cache,
                             org.wso2.carbon.identity.user.registration.engine.model,
-                            org.wso2.carbon.identity.user.registration.engine.services,
+                            org.wso2.carbon.identity.user.registration.engine.listener,
+                            org.wso2.carbon.identity.user.registration.engine.validation,
                             org.wso2.carbon.identity.user.registration.engine.exception,
                             org.wso2.carbon.identity.user.registration.engine.graph;
                             version="${carbon.identity.package.export.version}"
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/UserRegistrationFlowService.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/UserRegistrationFlowService.java
index c37f29f7c7cc..c6571e308015 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/UserRegistrationFlowService.java
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/UserRegistrationFlowService.java
@@ -21,9 +21,10 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.internal.RegistrationFlowEngineDataHolder;
+import org.wso2.carbon.identity.user.registration.engine.listener.FlowExecutionListener;
 import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
 import org.wso2.carbon.identity.user.registration.engine.model.RegistrationStep;
-import org.wso2.carbon.identity.user.registration.engine.services.InputValidationService;
 import org.wso2.carbon.identity.user.registration.engine.util.RegistrationFlowEngine;
 import org.wso2.carbon.identity.user.registration.engine.util.RegistrationFlowEngineUtils;
 
@@ -59,8 +60,19 @@ public RegistrationStep initiateDefaultRegistrationFlow(String tenantDomain) thr
 
         try {
             RegistrationContext context = RegistrationFlowEngineUtils.initiateContext(tenantDomain);
+            for (FlowExecutionListener listener :
+                    RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()) {
+                if (listener.isEnabled() && !listener.doPreInitiate(context)) {
+                    return null;
+                }
+            }
             RegistrationStep step = RegistrationFlowEngine.getInstance().execute(context);
-            InputValidationService.getInstance().handleStepInputs(step.getData(), context);
+            for (FlowExecutionListener listener :
+                    RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()) {
+                if (listener.isEnabled() && !listener.doPostInitiate(step, context)) {
+                    return null;
+                }
+            }
             RegistrationFlowEngineUtils.addRegContextToCache(context);
             return step;
         } catch (RegistrationEngineException e) {
@@ -83,15 +95,25 @@ public RegistrationStep continueFlow(String flowId, String actionId, Map<String,
         try {
             RegistrationContext context = RegistrationFlowEngineUtils.retrieveRegContextFromCache(flowId);
             context.getUserInputData().putAll(inputs);
-            InputValidationService.getInstance().validateInputs(actionId, context);
             context.setCurrentActionId(actionId);
+            for (FlowExecutionListener listener :
+                    RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()) {
+                if (listener.isEnabled() && !listener.doPreContinue(context)) {
+                    return null;
+                }
+            }
             RegistrationStep step = RegistrationFlowEngine.getInstance().execute(context);
+            for (FlowExecutionListener listener :
+                    RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()) {
+                if (listener.isEnabled() && !listener.doPostContinue(step, context)) {
+                    return null;
+                }
+            }
             if (STATUS_COMPLETE.equals(step.getFlowStatus())) {
                 RegistrationFlowEngineUtils.removeRegContextFromCache(flowId);
             } else {
                 RegistrationFlowEngineUtils.addRegContextToCache(context);
             }
-            InputValidationService.getInstance().handleStepInputs(step.getData(), context);
             return step;
         } catch (RegistrationEngineException e) {
             RegistrationFlowEngineUtils.removeRegContextFromCache(flowId);
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineDataHolder.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineDataHolder.java
index 564fcda59b48..24c2abcb4e5a 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineDataHolder.java
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineDataHolder.java
@@ -21,11 +21,10 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementServiceImpl;
 import org.wso2.carbon.identity.input.validation.mgt.services.InputValidationManagementService;
 import org.wso2.carbon.identity.user.registration.engine.graph.Executor;
+import org.wso2.carbon.identity.user.registration.engine.listener.FlowExecutionListener;
 import org.wso2.carbon.identity.user.registration.mgt.RegistrationFlowMgtService;
-import org.wso2.carbon.identity.user.registration.engine.graph.Node;
 import org.wso2.carbon.user.core.service.RealmService;
 
 import java.util.ArrayList;
@@ -40,6 +39,7 @@ public class RegistrationFlowEngineDataHolder {
     private RegistrationFlowMgtService registrationFlowMgtService;
     private RealmService realmService;
     private InputValidationManagementService inputValidationManagementService;
+    private List<FlowExecutionListener> flowExecutionListeners = new ArrayList<>();
     private static final RegistrationFlowEngineDataHolder instance = new RegistrationFlowEngineDataHolder();
 
     private RegistrationFlowEngineDataHolder() {
@@ -120,4 +120,24 @@ public void setInputValidationManagementService(InputValidationManagementService
 
         this.inputValidationManagementService = inputValidationManagementService;
     }
+
+    /**
+     * Get the list of registration execution listeners.
+     *
+     * @return  List of registration execution listeners.
+     */
+    public List<FlowExecutionListener> getRegistrationExecutionListeners() {
+
+        return flowExecutionListeners;
+    }
+
+    /**
+     * Set the list of registration execution listeners.
+     *
+     * @param flowExecutionListeners    List of registration execution listeners.
+     */
+    public void addRegistrationExecutionListeners(FlowExecutionListener flowExecutionListeners) {
+
+        this.flowExecutionListeners.add(flowExecutionListeners);
+    }
 }
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java
index cdd6b636ccc4..6354d8d5486d 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java
@@ -28,14 +28,17 @@
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
-import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementServiceImpl;
 import org.wso2.carbon.identity.input.validation.mgt.services.InputValidationManagementService;
 import org.wso2.carbon.identity.user.registration.engine.UserRegistrationFlowService;
 import org.wso2.carbon.identity.user.registration.engine.graph.Executor;
 import org.wso2.carbon.identity.user.registration.engine.graph.UserOnboardingExecutor;
+import org.wso2.carbon.identity.user.registration.engine.listener.FlowExecutionListener;
+import org.wso2.carbon.identity.user.registration.engine.validation.InputValidationListener;
 import org.wso2.carbon.identity.user.registration.mgt.RegistrationFlowMgtService;
 import org.wso2.carbon.user.core.service.RealmService;
 
+import java.util.Comparator;
+
 /**
  * OSGi declarative services component which handles registration flow engine service.
  */
@@ -54,6 +57,8 @@ protected void activate(ComponentContext context) {
             bundleContext.registerService(UserRegistrationFlowService.class.getName(),
                     UserRegistrationFlowService.getInstance(), null);
             bundleContext.registerService(Executor.class.getName(), new UserOnboardingExecutor(), null);
+            bundleContext.registerService(FlowExecutionListener.class.getName(), new InputValidationListener(),
+                    null);
             LOG.debug("Registration Flow Engine service successfully activated.");
         } catch (Throwable e) {
             LOG.error("Error while initiating Registration Flow Engine service", e);
@@ -144,4 +149,44 @@ protected void unsetInputValidationManagementService(InputValidationManagementSe
         LOG.debug("Unsetting the Input Validation Mgt Service in the Registration Flow Engine component.");
         RegistrationFlowEngineDataHolder.getInstance().setInputValidationManagementService(null);
     }
+
+    @Reference(
+            name = "FlowExecutionListener",
+            service = FlowExecutionListener.class,
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC,
+            unbind = "unsetRegistrationExecutionListener")
+    protected void setRegistrationExecutionListener(FlowExecutionListener flowExecutionListener) {
+
+        LOG.debug("Setting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .add(flowExecutionListener);
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners().sort(listenerComparator);
+    }
+
+    protected void unsetRegistrationExecutionListener(FlowExecutionListener flowExecutionListener) {
+
+        LOG.debug("Unsetting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .remove(flowExecutionListener);
+    }
+
+    private static final Comparator<FlowExecutionListener> listenerComparator =
+            new Comparator<FlowExecutionListener>() {
+
+                @Override
+                public int compare(FlowExecutionListener flowExecutionListener1,
+                                   FlowExecutionListener flowExecutionListener2) {
+
+                    if (flowExecutionListener1.getExecutionOrderId() >
+                            flowExecutionListener2.getExecutionOrderId()) {
+                        return 1;
+                    } else if (flowExecutionListener1.getExecutionOrderId() <
+                            flowExecutionListener2.getExecutionOrderId()) {
+                        return -1;
+                    } else {
+                        return 0;
+                    }
+                }
+            };
 }
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/AbstractFlowExecutionListener.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/AbstractFlowExecutionListener.java
new file mode 100644
index 000000000000..fbaa555d040f
--- /dev/null
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/AbstractFlowExecutionListener.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.listener;
+
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationStep;
+
+/**
+ * Abstract class for registration execution listeners.
+ */
+public class AbstractFlowExecutionListener implements FlowExecutionListener {
+
+    @Override
+    public int getExecutionOrderId() {
+
+        return -1;
+    }
+
+    @Override
+    public int getDefaultOrderId() {
+
+        return -1;
+    }
+
+    @Override
+    public boolean isEnabled() {
+
+        return false;
+    }
+
+    @Override
+    public boolean doPreInitiate(RegistrationContext registrationContext) throws RegistrationEngineException {
+
+        return true;
+    }
+
+    @Override
+    public boolean doPostInitiate(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException {
+
+        return true;
+    }
+
+    @Override
+    public boolean doPreContinue(RegistrationContext registrationContext) throws RegistrationEngineException {
+
+        return true;
+    }
+
+    @Override
+    public boolean doPostContinue(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException {
+
+        return true;
+    }
+}
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/FlowExecutionListener.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/FlowExecutionListener.java
new file mode 100644
index 000000000000..5402df2bac62
--- /dev/null
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/FlowExecutionListener.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.listener;
+
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationStep;
+
+/**
+ * Interface for registration execution listeners.
+ * <p>
+ * Registration execution listeners are used to perform actions at different stages of the registration flow.
+ */
+public interface FlowExecutionListener {
+
+    /**
+     * Returns the order ID of the listener.
+     *
+     * @return Order ID.
+     */
+    int getExecutionOrderId();
+
+    /**
+     * Returns the default order ID of the listener.
+     *
+     * @return Default order ID.
+     */
+    int getDefaultOrderId();
+
+    /**
+     * Returns whether the listener is enabled or not.
+     *
+     * @return true if enabled, false otherwise.
+     */
+    boolean isEnabled();
+
+    /**
+     * Pre-initiate method to be called before the registration flow is initiated.
+     *
+     * @param registrationContext Registration context.
+     * @return true if the pre-initiate was successful, false otherwise.
+     * @throws RegistrationEngineException if an error occurs during pre-initiate.
+     */
+    boolean doPreInitiate(RegistrationContext registrationContext) throws RegistrationEngineException;
+
+    /**
+     * Post-initiate method to be called after the registration flow is initiated.
+     *
+     * @param step                Registration step.
+     * @param registrationContext Registration context.
+     * @return true if the post-initiate was successful, false otherwise.
+     * @throws RegistrationEngineException if an error occurs during post-initiate.
+     */
+    boolean doPostInitiate(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException;
+
+    /**
+     * Pre-continue method to be called before the registration flow continues.
+     *
+     * @param registrationContext Registration context.
+     * @return true if the pre-continue was successful, false otherwise.
+     * @throws RegistrationEngineException if an error occurs during pre-continue.
+     */
+    boolean doPreContinue(RegistrationContext registrationContext) throws RegistrationEngineException;
+
+    /**
+     * Post-continue method to be called after the registration flow continues.
+     *
+     * @param step                Registration step.
+     * @param registrationContext Registration context.
+     * @return true if the post-continue was successful, false otherwise.
+     * @throws RegistrationEngineException if an error occurs during post-continue.
+     */
+    boolean doPostContinue(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException;
+}
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationListener.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationListener.java
new file mode 100644
index 000000000000..b41773733174
--- /dev/null
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationListener.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.validation;
+
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.listener.AbstractFlowExecutionListener;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationStep;
+
+/**
+ * Listener to handle input validation.
+ */
+public class InputValidationListener extends AbstractFlowExecutionListener {
+
+    @Override
+    public int getDefaultOrderId() {
+
+        return 1;
+    }
+
+    @Override
+    public int getExecutionOrderId() {
+
+        return 2;
+    }
+
+    @Override
+    public boolean isEnabled() {
+
+        return true;
+    }
+
+    @Override
+    public boolean doPostInitiate(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException {
+
+        InputValidationService.getInstance().handleStepInputs(step.getData(), registrationContext);
+        return true;
+    }
+
+    @Override
+    public boolean doPreContinue(RegistrationContext registrationContext)
+            throws RegistrationEngineException {
+
+        InputValidationService.getInstance().validateInputs(registrationContext);
+        InputValidationService.getInstance().handleUserInputs(registrationContext);
+        return true;
+    }
+
+    @Override
+    public boolean doPostContinue(RegistrationStep step, RegistrationContext registrationContext)
+            throws RegistrationEngineException {
+
+        InputValidationService.getInstance().handleStepInputs(step.getData(), registrationContext);
+        InputValidationService.getInstance().clearUserInputs(registrationContext);
+        return true;
+    }
+}
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/services/InputValidationService.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationService.java
similarity index 94%
rename from components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/services/InputValidationService.java
rename to components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationService.java
index 601511b24849..e41f6b025a72 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/services/InputValidationService.java
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationService.java
@@ -16,7 +16,7 @@
  * under the License.
  */
 
-package org.wso2.carbon.identity.user.registration.engine.services;
+package org.wso2.carbon.identity.user.registration.engine.validation;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -86,9 +86,10 @@ public static InputValidationService getInstance() {
      * @param context Registration context.
      * @throws RegistrationEngineException Registration framework exception.
      */
-    public void validateInputs(String actionId, RegistrationContext context) throws RegistrationEngineException {
+    public void validateInputs(RegistrationContext context) throws RegistrationEngineException {
 
         // Check if the actionId is empty and set it to default action.
+        String actionId = context.getCurrentActionId();
         actionId = StringUtils.EMPTY.equals(actionId) ? DEFAULT_ACTION : actionId;
         if (context.getCurrentStepInputs() == null || context.getCurrentStepInputs().isEmpty()) {
             return;
@@ -126,7 +127,6 @@ public void validateInputs(String actionId, RegistrationContext context) throws
     public void handleStepInputs(DataDTO dataDTO, RegistrationContext context)
             throws RegistrationEngineServerException {
 
-        processCurrentUserInputs(context);
         if (dataDTO == null) {
             return;
         }
@@ -141,7 +141,7 @@ public void handleStepInputs(DataDTO dataDTO, RegistrationContext context)
      *
      * @param context Registration context.
      */
-    private static void processCurrentUserInputs(RegistrationContext context) {
+    public void handleUserInputs(RegistrationContext context) {
 
         context.getUserInputData().forEach(
                 (key, value) -> {
@@ -150,7 +150,23 @@ private static void processCurrentUserInputs(RegistrationContext context) {
                     }
                 }
         );
-        context.getUserInputData().clear();
+        context.getRegisteringUser().getClaims().forEach(
+                (key, value) -> {
+                    context.getUserInputData().remove(key);
+                }
+        );
+    }
+
+    /**
+     * Clears the user inputs from the registration context.
+     *
+     * @param context Registration context.
+     */
+    public void clearUserInputs(RegistrationContext context) {
+
+        if (context != null) {
+            context.getUserInputData().clear();
+        }
     }
 
     /**
@@ -206,7 +222,9 @@ private void processStepInputs(DataDTO dataDTO, RegistrationContext context) {
             }
         }
 
-        if (dataDTO.getRequiredParams() != null && !dataDTO.getRequiredParams().isEmpty()) {
+        // If the dataDTO has required params, add them to the current step inputs and required inputs.
+        if ((dataDTO.getComponents() == null || dataDTO.getComponents().isEmpty()) &&
+                dataDTO.getRequiredParams() != null && !dataDTO.getRequiredParams().isEmpty()) {
             context.getCurrentRequiredInputs().put(DEFAULT_ACTION, new HashSet<>(dataDTO.getRequiredParams()));
             context.getCurrentStepInputs().put(DEFAULT_ACTION, new HashSet<>(dataDTO.getRequiredParams()));
         }
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/util/RegistrationFlowEngineTest.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/util/RegistrationFlowEngineTest.java
index 7f9ca5264d09..dc414e938627 100644
--- a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/util/RegistrationFlowEngineTest.java
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/util/RegistrationFlowEngineTest.java
@@ -24,6 +24,8 @@
 
 import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineServerException;
 import org.wso2.carbon.identity.user.registration.engine.graph.TaskExecutionNode;
+import org.wso2.carbon.identity.user.registration.engine.listener.FlowExecutionListener;
+import org.wso2.carbon.identity.user.registration.engine.validation.InputValidationListener;
 import org.wso2.carbon.identity.user.registration.engine.model.*;
 import org.wso2.carbon.identity.user.registration.mgt.model.*;
 import static org.junit.Assert.assertNotNull;
@@ -50,11 +52,13 @@ public class RegistrationFlowEngineTest {
 
     private RegistrationContext context;
     private RegistrationGraphConfig defaultGraph;
+    private List<FlowExecutionListener> listeners = new ArrayList<>();
 
     @BeforeClass
     public void setup() {
 
         defaultGraph = buildRegistrationGraphWithDecision();
+        listeners.add(new InputValidationListener());
     }
 
     @Test
diff --git a/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationServiceTest.java b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationServiceTest.java
new file mode 100644
index 000000000000..31000944b3ca
--- /dev/null
+++ b/components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/test/java/org/wso2/carbon/identity/user/registration/engine/validation/InputValidationServiceTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.validation;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineClientException;
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineServerException;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
+import org.wso2.carbon.identity.user.registration.mgt.Constants;
+import org.wso2.carbon.identity.user.registration.mgt.model.ActionDTO;
+import org.wso2.carbon.identity.user.registration.mgt.model.ComponentDTO;
+import org.wso2.carbon.identity.user.registration.mgt.model.DataDTO;
+import org.wso2.carbon.identity.user.registration.mgt.model.RegistrationGraphConfig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.wso2.carbon.identity.user.registration.engine.Constants.CLAIM_URI_PREFIX;
+import static org.wso2.carbon.identity.user.registration.engine.Constants.DEFAULT_ACTION;
+
+public class InputValidationServiceTest {
+
+    public static final String ACTION_1 = "action1";
+    private RegistrationContext registrationContext;
+    private InputValidationService inputValidationService;
+    private RegistrationGraphConfig defaultGraph;
+
+    @BeforeMethod
+    public void setUp() {
+
+        defaultGraph = new RegistrationGraphConfig();
+        inputValidationService = InputValidationService.getInstance();
+    }
+
+    @AfterMethod
+    public void tearDown() {
+
+    }
+
+    @Test(expectedExceptions = RegistrationEngineClientException.class)
+    public void testValidateInputsMissingInputs() throws RegistrationEngineException {
+
+        registrationContext = initiateRegistrationContext();
+        registrationContext.setRegGraph(defaultGraph);
+        Map<String, Set<String>> inputData = new HashMap<>();
+        Set<String> value = new HashSet<>();
+        value.add("input1");
+        inputData.put(ACTION_1, value);
+        registrationContext.setCurrentRequiredInputs(inputData);
+        registrationContext.setCurrentStepInputs(inputData);
+
+        Map<String, String> userInputData = new HashMap<>();
+        userInputData.put("input2", "value2");
+        registrationContext.getUserInputData().putAll(userInputData);
+        registrationContext.setCurrentActionId(ACTION_1);
+        inputValidationService.validateInputs(registrationContext);
+    }
+
+    @Test(expectedExceptions = RegistrationEngineClientException.class)
+    public void testValidateInputsExtraInputs() throws RegistrationEngineException {
+
+        registrationContext = initiateRegistrationContext();
+        registrationContext.setRegGraph(defaultGraph);
+        Map<String, Set<String>> inputData = new HashMap<>();
+        Set<String> value = new HashSet<>();
+        value.add("input1");
+        inputData.put(ACTION_1, value);
+        registrationContext.setCurrentRequiredInputs(inputData);
+        registrationContext.setCurrentStepInputs(inputData);
+
+        Map<String, String> userInputData = new HashMap<>();
+        userInputData.put("input1", "value1");
+        userInputData.put("input2", "value2");
+        registrationContext.getUserInputData().putAll(userInputData);
+        registrationContext.setCurrentActionId(ACTION_1);
+        inputValidationService.validateInputs(registrationContext);
+    }
+
+    @Test
+    public void testHandleStepInputsViewStep() throws RegistrationEngineServerException {
+
+        registrationContext = initiateRegistrationContext();
+        registrationContext.setRegGraph(defaultGraph);
+        List<ComponentDTO> formComponents = new ArrayList<>();
+        ComponentDTO input1 = new ComponentDTO.Builder()
+                .type(Constants.ComponentTypes.INPUT)
+                .configs(Collections.singletonMap("identifier", "input1"))
+                .build();
+        Map<String, Object> configs = new HashMap<>();
+        configs.put("identifier", "input2");
+        configs.put("required", true);
+        ComponentDTO input2 = new ComponentDTO.Builder().type(Constants.ComponentTypes.INPUT).configs(configs).build();
+        ComponentDTO button1 = new ComponentDTO.Builder()
+                .type(Constants.ComponentTypes.BUTTON)
+                .id("action1")
+                .action(new ActionDTO.Builder().type(Constants.ActionTypes.EXECUTOR).nextId("action2").build())
+                .build();
+        formComponents.add(input1);
+        formComponents.add(input2);
+        formComponents.add(button1);
+        ComponentDTO formDTO = new ComponentDTO.Builder()
+                .type(Constants.ComponentTypes.FORM)
+                .components(formComponents)
+                .build();
+        ComponentDTO redirectionDTO = new ComponentDTO.Builder()
+                .type(Constants.ComponentTypes.BUTTON)
+                .id("action2")
+                .action(new ActionDTO.Builder().type(Constants.ActionTypes.EXECUTOR).nextId("action3").build())
+                .build();
+        List<ComponentDTO> components = new ArrayList<>();
+        components.add(formDTO);
+        components.add(redirectionDTO);
+        DataDTO dataDTO = new DataDTO.Builder()
+                .components(components)
+                .requiredParams(Collections.singletonList("input3"))
+                .build();
+        inputValidationService.handleStepInputs(dataDTO, registrationContext);
+        Assert.assertEquals(registrationContext.getCurrentStepInputs().size(), 2);
+        Assert.assertEquals(registrationContext.getCurrentStepInputs().get("action1").size(), 2);
+        Assert.assertTrue(registrationContext.getCurrentStepInputs().get("action1").contains("input1"));
+        Assert.assertTrue(registrationContext.getCurrentStepInputs().get("action1").contains("input2"));
+        Assert.assertEquals(registrationContext.getCurrentRequiredInputs().get("action1").size(), 1);
+        Assert.assertTrue(registrationContext.getCurrentRequiredInputs().get("action1").contains("input2"));
+    }
+
+    @Test
+    public void testHandleStepInputsRedirectionStep() throws RegistrationEngineServerException {
+
+        registrationContext = initiateRegistrationContext();
+        registrationContext.setRegGraph(defaultGraph);
+        DataDTO dataDTO = new DataDTO.Builder()
+                .requiredParams(Collections.singletonList("input1"))
+                .build();
+        inputValidationService.handleStepInputs(dataDTO, registrationContext);
+        Assert.assertEquals(registrationContext.getCurrentStepInputs().size(), 1);
+        Assert.assertEquals(registrationContext.getCurrentStepInputs().get(DEFAULT_ACTION).size(), 1);
+        Assert.assertTrue(registrationContext.getCurrentStepInputs().get(DEFAULT_ACTION).contains("input1"));
+    }
+
+    @Test
+    public void testHandleUserInputs() throws RegistrationEngineServerException {
+
+        registrationContext = initiateRegistrationContext();
+        registrationContext.setRegGraph(defaultGraph);
+        Map<String, String> userInputData = new HashMap<>();
+        userInputData.put(CLAIM_URI_PREFIX + "input1", "value1");
+        userInputData.put("input2", "value2");
+        registrationContext.getUserInputData().putAll(userInputData);
+        inputValidationService.handleUserInputs(registrationContext);
+        Assert.assertEquals(registrationContext.getRegisteringUser().getClaims().size(), 1);
+        Assert.assertEquals(registrationContext.getUserInputData().size(), 1);
+        Assert.assertEquals(registrationContext.getRegisteringUser().getClaims().get(CLAIM_URI_PREFIX + "input1"),
+                "value1");
+        Assert.assertEquals(registrationContext.getUserInputData().get("input2"), "value2");
+    }
+
+    private RegistrationContext initiateRegistrationContext() {
+
+        RegistrationContext context = new RegistrationContext();
+        context.setTenantDomain("test.com");
+        context.setContextIdentifier("flow123");
+        return context;
+    }
+}


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: 

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.


<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**components/registration-framework/org.wso2/carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java:60**
* Manually registering the InputValidationListener alongside dynamic registration via DS may lead to duplicate listener invocations. Consider consolidating the registration mechanism to avoid potential conflicts.
```
bundleContext.registerService(RegistrationExecutionListener.class.getName(), new InputValidationListener(), null);
```
**components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineDataHolder.java:139**
* [nitpick] The method name 'addRegistrationExecutionListeners' suggests adding multiple listeners, but it only adds a single listener instance. Renaming it to 'addRegistrationExecutionListener' would clarify its intent.
```
public void addRegistrationExecutionListeners(RegistrationExecutionListener registrationExecutionListeners) {
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T06:07:12Z
user: login: pamodaaw
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T06:18:17Z
user: login: ThaminduR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T06:21:44Z
user: login: pamodaaw
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T11:55:22Z
user: login: SujanSanjula96
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T15:53:26Z

Review comments:
diff_hunk: @@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.services;
+
+public class RecaptchaValidationService {
+
+    public void validateRecaptchaResponse(String captchaResponse) {
path: components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/services/RecaptchaValidationService.java
user: login: Copilot
body: The validateRecaptchaResponse method is currently empty, which might lead to unexpected behavior when reCAPTCHA validation is expected. Either implement the necessary logic or add a comment explaining why it is left as a stub.
created_at: 2025-04-08T06:07:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -144,4 +149,44 @@ protected void unsetInputValidationManagementService(InputValidationManagementSe
         LOG.debug("Unsetting the Input Validation Mgt Service in the Registration Flow Engine component.");
         RegistrationFlowEngineDataHolder.getInstance().setInputValidationManagementService(null);
     }
+
+    @Reference(
+            name = "RegistrationExecutionListener",
+            service = RegistrationExecutionListener.class,
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC,
+            unbind = "unsetRegistrationExecutionListener")
+    protected void setRegistrationExecutionListener(RegistrationExecutionListener registrationExecutionListener) {
+
+        LOG.debug("Setting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .add(registrationExecutionListener);
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners().sort(listenerComparator);
+    }
+
+    protected void unsetRegistrationExecutionListener(RegistrationExecutionListener registrationExecutionListener) {
+
+        LOG.debug("Unsetting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .remove(registrationExecutionListener);
+    }
+
+    private static final Comparator<RegistrationExecutionListener> listenerComparator =
path: components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java
user: login: pamodaaw
body: Why we need this?
created_at: 2025-04-08T06:18:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -144,4 +149,44 @@ protected void unsetInputValidationManagementService(InputValidationManagementSe
         LOG.debug("Unsetting the Input Validation Mgt Service in the Registration Flow Engine component.");
         RegistrationFlowEngineDataHolder.getInstance().setInputValidationManagementService(null);
     }
+
+    @Reference(
+            name = "RegistrationExecutionListener",
+            service = RegistrationExecutionListener.class,
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC,
+            unbind = "unsetRegistrationExecutionListener")
+    protected void setRegistrationExecutionListener(RegistrationExecutionListener registrationExecutionListener) {
+
+        LOG.debug("Setting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .add(registrationExecutionListener);
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners().sort(listenerComparator);
+    }
+
+    protected void unsetRegistrationExecutionListener(RegistrationExecutionListener registrationExecutionListener) {
+
+        LOG.debug("Unsetting the Registration Execution Listener in the Registration Flow Engine component.");
+        RegistrationFlowEngineDataHolder.getInstance().getRegistrationExecutionListeners()
+                .remove(registrationExecutionListener);
+    }
+
+    private static final Comparator<RegistrationExecutionListener> listenerComparator =
path: components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/internal/RegistrationFlowEngineServiceComponent.java
user: login: ThaminduR
body: To sort the listeners according to the execution order id
created_at: 2025-04-08T06:21:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you 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 org.wso2.carbon.identity.user.registration.engine.listener;
+
+import org.wso2.carbon.identity.user.registration.engine.exception.RegistrationEngineException;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationContext;
+import org.wso2.carbon.identity.user.registration.engine.model.RegistrationStep;
+
+/**
+ * Interface for registration execution listeners.
+ * <p>
+ * Registration execution listeners are used to perform actions at different stages of the registration flow.
+ */
+public interface FlowExecutionListener {
+
+    int getExecutionOrderId();
path: components/registration-framework/org.wso2.carbon.identity.user.registration.engine/src/main/java/org/wso2/carbon/identity/user/registration/engine/listener/FlowExecutionListener.java
user: login: pamodaaw
body: Add method comments. Check all the methods of the interface
created_at: 2025-04-08T11:55:22Z
author_association: CONTRIBUTOR

PR comments:
user: login: jenkins-is-staging
created_at: 2025-04-08T06:20:50Z
body: PR builder started 
Link: https://github.com/wso2/product-is/actions/runs/14326544713
author_association: NONE
user: login: codecov[bot]
created_at: 2025-04-08T06:50:58Z
body: ## [Codecov](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) Report
Attention: Patch coverage is `13.23529%` with `59 lines` in your changes missing coverage. Please review.
> Project coverage is 48.02%. Comparing base [(`96c0b0f`)](https://app.codecov.io/gh/wso2/carbon-identity-framework/commit/96c0b0fba5d164354dcea4ed3155bee4f7844c11?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) to head [(`3165e55`)](https://app.codecov.io/gh/wso2/carbon-identity-framework/commit/3165e55bbcabacb915a8f2ba3911979867f87d01?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2).
> Report is 12 commits behind head on master.

| [Files with missing lines](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) | Patch % | Lines |
|---|---|---|
| [...ternal/RegistrationFlowEngineServiceComponent.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2Finternal%2FRegistrationFlowEngineServiceComponent.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL2ludGVybmFsL1JlZ2lzdHJhdGlvbkZsb3dFbmdpbmVTZXJ2aWNlQ29tcG9uZW50LmphdmE=) | 0.00% | [19 Missing :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |
| [...gistration/engine/UserRegistrationFlowService.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2FUserRegistrationFlowService.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL1VzZXJSZWdpc3RyYXRpb25GbG93U2VydmljZS5qYXZh) | 0.00% | [12 Missing and 4 partials :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |
| [...ion/engine/validation/InputValidationListener.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2Fvalidation%2FInputValidationListener.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL3ZhbGlkYXRpb24vSW5wdXRWYWxpZGF0aW9uTGlzdGVuZXIuamF2YQ==) | 8.33% | [11 Missing :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |
| [...engine/listener/AbstractFlowExecutionListener.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2Flistener%2FAbstractFlowExecutionListener.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL2xpc3RlbmVyL0Fic3RyYWN0Rmxvd0V4ZWN1dGlvbkxpc3RlbmVyLmphdmE=) | 12.50% | [7 Missing :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |
| [...tion/engine/validation/InputValidationService.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2Fvalidation%2FInputValidationService.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL3ZhbGlkYXRpb24vSW5wdXRWYWxpZGF0aW9uU2VydmljZS5qYXZh) | 55.55% | [2 Missing and 2 partials :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |
| [...ine/internal/RegistrationFlowEngineDataHolder.java](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&filepath=components%2Fregistration-framework%2Forg.wso2.carbon.identity.user.registration.engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fwso2%2Fcarbon%2Fidentity%2Fuser%2Fregistration%2Fengine%2Finternal%2FRegistrationFlowEngineDataHolder.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#diff-Y29tcG9uZW50cy9yZWdpc3RyYXRpb24tZnJhbWV3b3JrL29yZy53c28yLmNhcmJvbi5pZGVudGl0eS51c2VyLnJlZ2lzdHJhdGlvbi5lbmdpbmUvc3JjL21haW4vamF2YS9vcmcvd3NvMi9jYXJib24vaWRlbnRpdHkvdXNlci9yZWdpc3RyYXRpb24vZW5naW5lL2ludGVybmFsL1JlZ2lzdHJhdGlvbkZsb3dFbmdpbmVEYXRhSG9sZGVyLmphdmE=) | 50.00% | [2 Missing :warning: ](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) |

:x: Your patch status has failed because the patch coverage (13.23%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the [target](https://docs.codecov.com/docs/commit-status#target) coverage.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #6669      +/-   ##
============================================
- Coverage     48.09%   48.02%   -0.07%     
- Complexity    16156    16220      +64     
============================================
  Files          1831     1834       +3     
  Lines        108612   109178     +566     
  Branches      20453    20608     +155     
============================================
+ Hits          52233    52434     +201     
- Misses        49216    49542     +326     
- Partials       7163     7202      +39     
```

| [Flag](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) | Coverage Δ | |
|---|---|---|
| [unit](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2) | `32.01% <13.23%> (+0.04%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/wso2/carbon-identity-framework/pull/6669?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wso2).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: jenkins-is-staging
created_at: 2025-04-08T08:15:32Z
body: PR builder completed 
Link: https://github.com/wso2/product-is/actions/runs/14326544713 
Status: **failure**
author_association: NONE
user: login: jenkins-is-staging
created_at: 2025-04-08T11:48:26Z
body: PR builder started 
Link: https://github.com/wso2/product-is/actions/runs/14332720286
author_association: NONE
user: login: jenkins-is-staging
created_at: 2025-04-08T13:40:25Z
body: PR builder completed 
Link: https://github.com/wso2/product-is/actions/runs/14332720286 
Status: **failure**
author_association: NONE
user: login: jenkins-is-staging
created_at: 2025-04-08T15:25:38Z
body: PR builder started 
Link: https://github.com/wso2/product-is/actions/runs/14337461230
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-04-08T15:27:42Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=wso2_carbon-identity-framework&pullRequest=6669) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [8 New issues](https://sonarcloud.io/project/issues?id=wso2_carbon-identity-framework&pullRequest=6669&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=wso2_carbon-identity-framework&pullRequest=6669&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=wso2_carbon-identity-framework&pullRequest=6669&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=wso2_carbon-identity-framework&pullRequest=6669&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=wso2_carbon-identity-framework&pullRequest=6669&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=wso2_carbon-identity-framework&pullRequest=6669)


author_association: NONE
user: login: jenkins-is-staging
created_at: 2025-04-08T17:20:09Z
body: PR builder completed 
Link: https://github.com/wso2/product-is/actions/runs/14337461230 
Status: **failure**
author_association: NONE
user: login: ThaminduR
created_at: 2025-04-08T17:20:54Z
body: Failures are known intermittent ones
author_association: CONTRIBUTOR