Repository: telstra/open-kilda
Issue: Flow partial update clears 'inner_vlan_id' if not set

1. Create flow with non-zero values in 'inner_vlan_id' fields
<details>
  <summary>curl</summary>
  
```
curl --location --request POST 'http://localhost:8080/api/v2/flows' \\
--header 'Accept: application/json;charset=UTF-8' \\
--header 'Content-Type: application/json' \\
--header 'Authorization: Basic a2lsZGE6a2lsZGE=' \\
--header 'correlation_id: rtretiak_test1614949868' \\
--data-raw '{
    "flow_id": "rtrtk_test",
    "source": {
        "switch_id": "1",
        "port_number": 13,
        "vlan_id": 111,
        "inner_vlan_id": 123
    },
    "destination": {
        "switch_id": "2",
        "port_number": 14,
        "vlan_id": 111,
        "inner_vlan_id": 123
    },
    "maximum_bandwidth": 100,
    "ignore_bandwidth": false,
    "allocate_protected_path": false,
    "encapsulation_type": "transit_vlan",
    "description": "autotest flow with weight loss, unexplained"
}'
```
</details>

2. Update flow using partial update API (`PATCH {{northbound.endpoint}}/api/v2/flows/:flowId`) without mentioning 'inner_vlan_id' fields. For example, update only source port number
<details>
  <summary>curl</summary>
  
```
curl --location --request PATCH 'http://localhost:8080/api/v2/flows/rtrtk_test' \\
--header 'Accept: application/json;charset=UTF-8' \\
--header 'Content-Type: application/json' \\
--header 'correlation_id: rtrtk1614950136' \\
--header 'Authorization: Basic a2lsZGE6a2lsZGE=' \\
--data-raw '{
  "source":{  
      "port_number": 14
   }
}'
```
</details>

**Expected:** Only source port number is updated
**Actual:** 'inner_vlan_id' both on src and dst is set to 0. Port number is updated as expected


Changed files:
src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/RequestedFlowMapper.java
src-java/nbworker-topology/nbworker-storm-topology/src/test/java/org/openkilda/wfm/share/mappers/RequestedFlowMapperTest.java

diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/RequestedFlowMapper.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/RequestedFlowMapper.java
index a14c2169a..0b4cfa089 100644
--- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/RequestedFlowMapper.java
+++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/RequestedFlowMapper.java
@@ -34,9 +34,9 @@ public abstract class RequestedFlowMapper {
      */
     @Mapping(target = "flowId", source = "flowId")
     @Mapping(target = "source", expression = "java(new FlowEndpoint(flow.getSrcSwitchId(), "
-            + "flow.getSrcPort(), flow.getSrcVlan()))")
+            + "flow.getSrcPort(), flow.getSrcVlan(), flow.getSrcInnerVlan()))")
     @Mapping(target = "destination", expression = "java(new FlowEndpoint(flow.getDestSwitchId(), "
-            + "flow.getDestPort(), flow.getDestVlan()))")
+            + "flow.getDestPort(), flow.getDestVlan(), flow.getDestInnerVlan()))")
     @Mapping(target = "encapsulationType", source = "encapsulationType")
     @Mapping(target = "pathComputationStrategy",
             expression = "java(java.util.Optional.ofNullable(flow.getPathComputationStrategy())"
diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/test/java/org/openkilda/wfm/share/mappers/RequestedFlowMapperTest.java b/src-java/nbworker-topology/nbworker-storm-topology/src/test/java/org/openkilda/wfm/share/mappers/RequestedFlowMapperTest.java
index 185d74aa5..077ccd99d 100644
--- a/src-java/nbworker-topology/nbworker-storm-topology/src/test/java/org/openkilda/wfm/share/mappers/RequestedFlowMapperTest.java
+++ b/src-java/nbworker-topology/nbworker-storm-topology/src/test/java/org/openkilda/wfm/share/mappers/RequestedFlowMapperTest.java
@@ -37,7 +37,9 @@ public class RequestedFlowMapperTest {
     public static final Integer DST_PORT = 2;
     public static final int SRC_VLAN = 3;
     public static final int DST_VLAN = 4;
-    public static final Integer PRIORITY = 5;
+    public static final int SRC_INNER_VLAN = 5;
+    public static final int DST_INNER_VLAN = 6;
+    public static final Integer PRIORITY = 7;
     public static final String DESCRIPTION = "description";
     public static final int BANDWIDTH = 1000;
     public static final Long MAX_LATENCY = 200L;
@@ -48,9 +50,11 @@ public class RequestedFlowMapperTest {
             .srcSwitch(Switch.builder().switchId(SRC_SWITCH_ID).build())
             .srcPort(SRC_PORT)
             .srcVlan(SRC_VLAN)
+            .srcInnerVlan(SRC_INNER_VLAN)
             .destSwitch(Switch.builder().switchId(DST_SWITCH_ID).build())
             .destPort(DST_PORT)
             .destVlan(DST_VLAN)
+            .destInnerVlan(DST_INNER_VLAN)
             .priority(PRIORITY)
             .description(DESCRIPTION)
             .bandwidth(BANDWIDTH)
@@ -74,9 +78,11 @@ public class RequestedFlowMapperTest {
         assertEquals(SRC_SWITCH_ID, flowRequest.getSource().getSwitchId());
         assertEquals(SRC_PORT, flowRequest.getSource().getPortNumber());
         assertEquals(SRC_VLAN, flowRequest.getSource().getOuterVlanId());
+        assertEquals(SRC_INNER_VLAN, flowRequest.getSource().getInnerVlanId());
         assertEquals(DST_SWITCH_ID, flowRequest.getDestination().getSwitchId());
         assertEquals(DST_PORT, flowRequest.getDestination().getPortNumber());
         assertEquals(DST_VLAN, flowRequest.getDestination().getOuterVlanId());
+        assertEquals(DST_INNER_VLAN, flowRequest.getDestination().getInnerVlanId());
         assertEquals(PRIORITY, flowRequest.getPriority());
         assertEquals(DESCRIPTION, flowRequest.getDescription());
         assertEquals(BANDWIDTH, flowRequest.getBandwidth());