Repository: telstra/open-kilda
Issue: HaFlow Create or Update: updateFlowMonitoring throws IllegalArgumentException

Steps to reproduce using the standard test topology:
- create an HA flow with a valid request parameters. For example, use the request below.

Expected result: HA flow is created, no errors in the log
Actual result: there is an error in the logs, however the flow was created successfully.

The same behavior happens when performing an update (PUT). You can use the same request below.


The error:
```
java.lang.IllegalArgumentException: HA-flow ha-flow-1 has no HA-sub flow ha-flow-1-a
```
with the stack trace that includes:
```json
{
  "file": "HaFlow.java",
  "method": "getHaSubFlowOrThrowException",
  "line": 374,
  "exact": false,
  "location": "stormjar.jar",
  "class": "org.openkilda.model.HaFlow",
  "version": "?"
},
{
  "file": "OnFinishedAction.java",
  "method": "updateFlowMonitoring",
  "line": 81,
  "exact": false,
  "location": "stormjar.jar",
  "class": "org.openkilda.wfm.topology.flowhs.fsm.haflow.update.actions.OnFinishedAction",
  "version": "?"
}
```

An example of the request to create an HA flow:
```json
{
    "ha_flow_id": "ha-flow-1",
    "status": "In progress",
    "shared_endpoint": {
        "switch_id": "00:00:00:00:00:00:00:02",
        "port_number": 23,
        "vlan_id": 0,
        "inner_vlan_id": 0
    },
    "maximum_bandwidth": 0,
    "path_computation_strategy": "COST",
    "encapsulation_type": "transit_vlan",
    "max_latency": 0,
    "max_latency_tier2": 0,
    "ignore_bandwidth": true,
    "periodic_pings": true,
    "pinned": false,
    "priority": 0,
    "strict_bandwidth": false,
    "description": "HA flow test description 2",
    "allocate_protected_path": false,
    "diverse_with_flows": [],
    "diverse_with_y_flows": [],
    "diverse_with_ha_flows": [],
    "sub_flows": [
        {
            "flow_id": "ha-flow-1-a",
            "endpoint": {
                "switch_id": "00:00:00:00:00:00:00:09",
                "port_number": 22,
                "vlan_id": 0,
                "inner_vlan_id": 0
            },
            "status": "In progress",
            "description": "the first end point",
            "time_create": "2023-06-09T12:08:36.616Z",
            "time_update": "2023-06-09T12:08:36.618Z"
        },
        {
            "flow_id": "ha-flow-1-b",
            "endpoint": {
                "switch_id": "00:00:00:00:00:00:00:07",
                "port_number": 21,
                "vlan_id": 0,
                "inner_vlan_id": 0
            },
            "status": "In progress",
            "description": "the second end point",
            "time_create": "2023-06-09T12:08:36.617Z",
            "time_update": "2023-06-09T12:08:36.618Z"
        }
    ],
    "time_create": "2023-06-09T12:08:36.614Z",
    "time_update": "2023-06-09T12:08:37.038Z"
}
```

Changed files:
src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/update/actions/OnFinishedAction.java
src-java/kilda-model/src/main/java/org/openkilda/model/HaSubFlow.java

diff --git a/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/update/actions/OnFinishedAction.java b/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/update/actions/OnFinishedAction.java
index 148ceaf61..b0d870c10 100644
--- a/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/update/actions/OnFinishedAction.java
+++ b/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/update/actions/OnFinishedAction.java
@@ -31,6 +31,8 @@ import org.openkilda.wfm.topology.flowhs.mapper.HaFlowMapper;
 
 import lombok.extern.slf4j.Slf4j;
 
+import java.util.stream.Collectors;
+
 @Slf4j
 public class OnFinishedAction extends HistoryRecordingAction<HaFlowUpdateFsm, State, Event, HaFlowUpdateContext> {
     public static final String DEGRADED_FAIL_REASON = "Not all paths meet the SLA";
@@ -67,12 +69,12 @@ public class OnFinishedAction extends HistoryRecordingAction<HaFlowUpdateFsm, St
 
     private void updateFlowMonitoring(HaFlowUpdateFsm stateMachine) {
         HaFlow original = stateMachine.getOriginalHaFlow();
-        HaFlow target = HaFlowMapper.INSTANCE.toHaFlow(stateMachine.getTargetHaFlow());
+        HaFlow target = mapToTargetHaFlow(stateMachine.getTargetHaFlow());
 
         for (HaSubFlow originalSubFlow : original.getHaSubFlows()) {
             HaSubFlow targetSubFlow = target.getHaSubFlowOrThrowException(originalSubFlow.getHaSubFlowId());
             boolean originalNotSingle = !originalSubFlow.isOneSwitch();
-            boolean targetNotSingle = !targetSubFlow.isOneSwitch();
+            boolean targetNotSingle = !targetSubFlow.isOneSwitch(target.getSharedSwitchId());
             boolean srcUpdated = isSrcUpdated(original, target);
             boolean dstUpdated = isDstUpdated(originalSubFlow, targetSubFlow);
 
@@ -86,7 +88,7 @@ public class OnFinishedAction extends HistoryRecordingAction<HaFlowUpdateFsm, St
             // setup new if it is not single
             //TODO: Review logic during https://github.com/telstra/open-kilda/issues/5208
             if (targetNotSingle && (srcUpdated || dstUpdated)) {
-                stateMachine.getCarrier().sendActivateFlowMonitoring(null);
+                //stateMachine.getCarrier().sendActivateFlowMonitoring(null);
             }
         }
     }
@@ -104,4 +106,12 @@ public class OnFinishedAction extends HistoryRecordingAction<HaFlowUpdateFsm, St
                 && originalSubFlow.getEndpointVlan() == targetSubFlow.getEndpointVlan()
                 && originalSubFlow.getEndpointInnerVlan() == targetSubFlow.getEndpointInnerVlan());
     }
+
+    private HaFlow mapToTargetHaFlow(HaFlowRequest targetHaFlowRequest) {
+        HaFlow target = HaFlowMapper.INSTANCE.toHaFlow(targetHaFlowRequest);
+        target.setHaSubFlows(targetHaFlowRequest.getSubFlows().stream()
+                .map(HaFlowMapper.INSTANCE::toSubFlow)
+                .collect(Collectors.toSet()));
+        return target;
+    }
 }
diff --git a/src-java/kilda-model/src/main/java/org/openkilda/model/HaSubFlow.java b/src-java/kilda-model/src/main/java/org/openkilda/model/HaSubFlow.java
index 9da43de47..11f29faf1 100644
--- a/src-java/kilda-model/src/main/java/org/openkilda/model/HaSubFlow.java
+++ b/src-java/kilda-model/src/main/java/org/openkilda/model/HaSubFlow.java
@@ -128,6 +128,10 @@ public class HaSubFlow implements CompositeDataEntity<HaSubFlowData> {
         return getEndpointSwitchId().equals(getHaFlow().getSharedSwitchId());
     }
 
+    public boolean isOneSwitch(SwitchId sharedSwitchId) {
+        return getEndpointSwitchId().equals(sharedSwitchId);
+    }
+
     /**
      * Defines persistable data of the sub-flow.
      */