Repository: telstra/open-kilda
Issue: HA-flow protected path is equal to main path

**Steps to reproduce:**
1. Create ha flow with protected path via `POST /v2/ha-flows` with enabled protected path
2. check that main ha-flow path and protected path does not intersect 
You can do it by `GET /v2/ha-flows/{ha_flow_id}/paths` when issue https://github.com/telstra/open-kilda/issues/5148 will be ready or you can check it directly in orient DB

**Expected result:**
Paths do not intersect (excluding first and last switch)

**Actual result:**
paths are equal 

Changed files:
src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/create/actions/ResourcesAllocationAction.java
src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaFlowPathRepository.java
src-java/kilda-persistence-orientdb/src/main/java/org/openkilda/persistence/orientdb/repositories/OrientDbFlowPathRepository.java
src-java/base-topology/base-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilder.java
src-java/base-topology/base-storm-topology/src/test/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilderTest.java

diff --git a/src-java/base-topology/base-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilder.java b/src-java/base-topology/base-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilder.java
index 85b95d3f2..3fd3d4eec 100644
--- a/src-java/base-topology/base-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilder.java
+++ b/src-java/base-topology/base-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilder.java
@@ -89,22 +89,31 @@ public class FlowPathBuilder {
      * @param flowPath the flow path to evaluate.
      */
     public boolean arePathsOverlapped(Path path, FlowPath flowPath) {
-        Set<Segment> pathSegments = path.getSegments().stream()
-                .map(segment -> segment.toBuilder().latency(0).build())
-                .collect(Collectors.toSet());
-        Set<Segment> flowSegments = flowPath.getSegments().stream()
-                .map(segment -> Segment.builder()
-                        .srcSwitchId(segment.getSrcSwitchId())
-                        .srcPort(segment.getSrcPort())
-                        .destSwitchId(segment.getDestSwitchId())
-                        .destPort(segment.getDestPort())
-                        .latency(0)
-                        .build())
-                .collect(Collectors.toSet());
+        Set<Segment> pathSegments = buildSegmentSet(path);
+        Set<Segment> flowSegments = buildSegmentSet(flowPath);
 
         return !Sets.intersection(pathSegments, flowSegments).isEmpty();
     }
 
+    /**
+     * Check whether the ha-path and ha-flow path overlap.
+     *
+     * @param haPath the ha-path to evaluate.
+     * @param haFlowPath the ha-flow path to evaluate.
+     */
+    public boolean arePathsOverlapped(HaPath haPath, HaFlowPath haFlowPath) {
+        for (Path subPath : haPath.getSubPaths()) {
+            Set<Segment> haPathSegments = buildSegmentSet(subPath);
+            for (FlowPath haFlowSubPath : haFlowPath.getSubPaths()) {
+                Set<Segment> haFlowSegments = buildSegmentSet(haFlowSubPath);
+                if (!Sets.intersection(haPathSegments, haFlowSegments).isEmpty()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * Build a flow path entity for the flow using provided path and resources.
      *
@@ -304,6 +313,28 @@ public class FlowPathBuilder {
         return result;
     }
 
+    private static Set<Segment> buildSegmentSet(FlowPath flowPath) {
+        return flowPath.getSegments().stream()
+                .map(segment -> Segment.builder()
+                        .srcSwitchId(segment.getSrcSwitchId())
+                        .srcPort(segment.getSrcPort())
+                        .destSwitchId(segment.getDestSwitchId())
+                        .destPort(segment.getDestPort())
+                        .build())
+                .collect(Collectors.toSet());
+    }
+
+    private static Set<Segment> buildSegmentSet(Path path) {
+        return path.getSegments().stream()
+                .map(segment -> Segment.builder()
+                        .srcSwitchId(segment.getSrcSwitchId())
+                        .srcPort(segment.getSrcPort())
+                        .destSwitchId(segment.getDestSwitchId())
+                        .destPort(segment.getDestPort())
+                        .build())
+                .collect(Collectors.toSet());
+    }
+
     private LazyMap<SwitchId, SwitchProperties> getSwitchProperties(PathId pathId) {
         return LazyMap.lazyMap(new HashMap<>(), switchId ->
                 switchPropertiesRepository.findBySwitchId(switchId)
diff --git a/src-java/base-topology/base-storm-topology/src/test/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilderTest.java b/src-java/base-topology/base-storm-topology/src/test/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilderTest.java
index 384290cc2..be2a9df46 100644
--- a/src-java/base-topology/base-storm-topology/src/test/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilderTest.java
+++ b/src-java/base-topology/base-storm-topology/src/test/java/org/openkilda/wfm/topology/flowhs/service/FlowPathBuilderTest.java
@@ -16,12 +16,10 @@
 package org.openkilda.wfm.topology.flowhs.service;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static junit.framework.TestCase.assertTrue;
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.hasSize;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -29,6 +27,8 @@ import static org.mockito.Mockito.when;
 import org.openkilda.model.Flow;
 import org.openkilda.model.FlowPath;
 import org.openkilda.model.FlowPathDirection;
+import org.openkilda.model.HaFlowPath;
+import org.openkilda.model.HaSubFlow;
 import org.openkilda.model.MeterId;
 import org.openkilda.model.PathId;
 import org.openkilda.model.PathSegment;
@@ -36,6 +36,7 @@ import org.openkilda.model.Switch;
 import org.openkilda.model.SwitchId;
 import org.openkilda.model.SwitchProperties;
 import org.openkilda.model.cookie.FlowSegmentCookie;
+import org.openkilda.pce.HaPath;
 import org.openkilda.pce.Path;
 import org.openkilda.pce.Path.Segment;
 import org.openkilda.persistence.repositories.KildaConfigurationRepository;
@@ -43,6 +44,7 @@ import org.openkilda.persistence.repositories.SwitchPropertiesRepository;
 import org.openkilda.persistence.repositories.SwitchRepository;
 import org.openkilda.wfm.share.flow.resources.FlowResources.PathResources;
 
+import com.google.common.collect.ImmutableList;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -50,6 +52,15 @@ import java.util.Collections;
 import java.util.Optional;
 
 public class FlowPathBuilderTest {
+    private static final SwitchId SWITCH_ID_1 = new SwitchId(1);
+    private static final SwitchId SWITCH_ID_2 = new SwitchId(2);
+    private static final SwitchId SWITCH_ID_3 = new SwitchId(3);
+    private static final Switch SWITCH_1 = Switch.builder().switchId(SWITCH_ID_1).build();
+    private static final Switch SWITCH_2 = Switch.builder().switchId(SWITCH_ID_2).build();
+    private static final Switch SWITCH_3 = Switch.builder().switchId(SWITCH_ID_3).build();
+    private static final PathId PATH_ID_1 = new PathId("test_path_id");
+    private static final String HA_SUB_FLOW = "ha_sub_flow";
+
     private FlowPathBuilder builder;
 
     @Before
@@ -68,7 +79,7 @@ public class FlowPathBuilderTest {
     }
 
     @Test
-    public void shouldDetectSameSwitchPaths() {
+    public void detectSameSwitchPaths() {
         SwitchId switchId = new SwitchId(1);
         Switch switchEntity = Switch.builder().switchId(switchId).build();
 
@@ -88,21 +99,16 @@ public class FlowPathBuilderTest {
     }
 
     @Test
-    public void shouldDetectNotSameSwitchPaths() {
-        SwitchId switchId1 = new SwitchId(1);
-
-        SwitchId switchId2 = new SwitchId(2);
-        Switch switch2 = Switch.builder().switchId(switchId2).build();
-
+    public void detectNotSameSwitchPaths() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId1)
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_1)
                 .segments(Collections.emptyList())
                 .build();
 
         FlowPath flowPath = FlowPath.builder()
-                .srcSwitch(switch2)
-                .destSwitch(switch2)
+                .srcSwitch(SWITCH_2)
+                .destSwitch(SWITCH_2)
                 .pathId(new PathId("test_path_id"))
                 .build();
 
@@ -110,126 +116,78 @@ public class FlowPathBuilderTest {
     }
 
     @Test
-    public void shouldDetectSame2SwitchPaths() {
-        SwitchId switchId1 = new SwitchId(1);
-        Switch switch1 = Switch.builder().switchId(switchId1).build();
-
-        SwitchId switchId2 = new SwitchId(2);
-        Switch switch2 = Switch.builder().switchId(switchId2).build();
-
+    public void detectSame2SwitchPaths() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId2)
-                .segments(Collections.singletonList(Segment.builder()
-                        .srcSwitchId(switchId1)
-                        .srcPort(1)
-                        .destSwitchId(switchId2)
-                        .destPort(2)
-                        .build()))
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_2)
+                .segments(singletonList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2)))
                 .build();
 
         PathId flowPathId = new PathId("test_path_id");
         FlowPath flowPath = FlowPath.builder()
-                .srcSwitch(switch1)
-                .destSwitch(switch2)
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
                 .pathId(flowPathId)
-                .segments(Collections.singletonList(PathSegment.builder()
-                        .pathId(flowPathId)
-                        .srcSwitch(switch1).srcPort(1).destSwitch(switch2).destPort(2).build()))
+                .segments(singletonList(buildPathSegment(flowPathId, SWITCH_1, 1, SWITCH_2, 2)))
                 .build();
 
         assertTrue(builder.isSamePath(path, flowPath));
     }
 
     @Test
-    public void shouldDetectDifferenceInPortsFor2SwitchPaths() {
-        SwitchId switchId1 = new SwitchId(1);
-        Switch switch1 = Switch.builder().switchId(switchId1).build();
-
-        SwitchId switchId2 = new SwitchId(2);
-        Switch switch2 = Switch.builder().switchId(switchId2).build();
-
+    public void detectDifferenceInPortsFor2SwitchPaths() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId2)
-                .segments(Collections.singletonList(Segment.builder()
-                        .srcSwitchId(switchId1)
-                        .srcPort(1)
-                        .destSwitchId(switchId2)
-                        .destPort(2)
-                        .build()))
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_2)
+                .segments(singletonList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2)))
                 .build();
 
         PathId flowPathId = new PathId("test_path_id");
         FlowPath flowPath = FlowPath.builder()
-                .srcSwitch(switch1)
-                .destSwitch(switch2)
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
                 .pathId(flowPathId)
-                .segments(Collections.singletonList(PathSegment.builder()
+                .segments(singletonList(PathSegment.builder()
                         .pathId(flowPathId)
-                        .srcSwitch(switch1).srcPort(2).destSwitch(switch2).destPort(3).build()))
+                        .srcSwitch(SWITCH_1).srcPort(2).destSwitch(SWITCH_2).destPort(3).build()))
                 .build();
 
         assertFalse(builder.isSamePath(path, flowPath));
     }
 
     @Test
-    public void shouldDetectSame3SwitchPaths() {
-        SwitchId switchId1 = new SwitchId(1);
-        Switch switch1 = Switch.builder().switchId(switchId1).build();
-
-        SwitchId switchId2 = new SwitchId(2);
-        Switch switch2 = Switch.builder().switchId(switchId2).build();
-
-        SwitchId switchId3 = new SwitchId(3);
-        Switch switch3 = Switch.builder().switchId(switchId3).build();
-
+    public void detectSame3SwitchPaths() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId2)
-                .segments(asList(Segment.builder()
-                        .srcSwitchId(switchId1)
-                        .srcPort(1)
-                        .destSwitchId(switchId3)
-                        .destPort(2)
-                        .build(), Segment.builder()
-                        .srcSwitchId(switchId3)
-                        .srcPort(1)
-                        .destSwitchId(switchId2)
-                        .destPort(2)
-                        .build()))
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_2)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_3, 2),
+                        buildSegment(SWITCH_ID_3, 1, SWITCH_ID_2, 2)))
                 .build();
 
         PathId flowPathId = new PathId("test_path_id");
         FlowPath flowPath = FlowPath.builder()
-                .srcSwitch(switch1)
-                .destSwitch(switch2)
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
                 .pathId(flowPathId)
                 .segments(asList(
                         PathSegment.builder().pathId(flowPathId)
-                                .srcSwitch(switch1).srcPort(1).destSwitch(switch3).destPort(2).build(),
+                                .srcSwitch(SWITCH_1).srcPort(1).destSwitch(SWITCH_3).destPort(2).build(),
                         PathSegment.builder().pathId(flowPathId)
-                                .srcSwitch(switch3).srcPort(1).destSwitch(switch2).destPort(2).build()))
+                                .srcSwitch(SWITCH_3).srcPort(1).destSwitch(SWITCH_2).destPort(2).build()))
                 .build();
 
         assertTrue(builder.isSamePath(path, flowPath));
     }
 
     @Test
-    public void shouldBuildFlowPathFor1SwitchPath() {
-        SwitchId switchId = new SwitchId(1);
-
+    public void buildFlowPathFor1SwitchPath() {
         Path path = Path.builder()
-                .srcSwitchId(switchId)
-                .destSwitchId(switchId)
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_1)
                 .segments(Collections.emptyList())
                 .build();
 
-        Flow flow = Flow.builder()
-                .flowId("test_flow")
-                .srcSwitch(Switch.builder().switchId(switchId).build())
-                .destSwitch(Switch.builder().switchId(switchId).build())
-                .build();
+        Flow flow = buildFlow(SWITCH_1, SWITCH_1);
         PathId pathId = new PathId("test_path_id");
         MeterId meterId = new MeterId(MeterId.MIN_FLOW_METER_ID);
         PathResources pathResources = PathResources.builder()
@@ -243,30 +201,18 @@ public class FlowPathBuilderTest {
         assertEquals(pathId, flowPath.getPathId());
         assertEquals(meterId, flowPath.getMeterId());
         assertEquals(cookie, flowPath.getCookie());
-        assertThat(flowPath.getSegments(), empty());
+        assertEquals(0, flowPath.getSegments().size());
     }
 
     @Test
-    public void shouldBuildFlowPathFor2SwitchPath() {
-        SwitchId switchId1 = new SwitchId(1);
-        SwitchId switchId2 = new SwitchId(2);
-
+    public void buildFlowPathFor2SwitchPath() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId2)
-                .segments(Collections.singletonList(Segment.builder()
-                        .srcSwitchId(switchId1)
-                        .srcPort(1)
-                        .destSwitchId(switchId2)
-                        .destPort(2)
-                        .build()))
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_2)
+                .segments(singletonList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 3)))
                 .build();
 
-        Flow flow = Flow.builder()
-                .flowId("test_flow")
-                .srcSwitch(Switch.builder().switchId(switchId1).build())
-                .destSwitch(Switch.builder().switchId(switchId2).build())
-                .build();
+        Flow flow = buildFlow(SWITCH_1, SWITCH_2);
         PathId pathId = new PathId("test_path_id");
         MeterId meterId = new MeterId(MeterId.MIN_FLOW_METER_ID);
         PathResources pathResources = PathResources.builder()
@@ -277,56 +223,155 @@ public class FlowPathBuilderTest {
 
         FlowPath flowPath = builder.buildFlowPath(flow, pathResources, path, cookie, false, flow.getFlowId());
 
-        assertEquals(switchId1, flowPath.getSrcSwitchId());
-        assertEquals(switchId2, flowPath.getDestSwitchId());
+        assertEquals(SWITCH_ID_1, flowPath.getSrcSwitchId());
+        assertEquals(SWITCH_ID_2, flowPath.getDestSwitchId());
         assertEquals(pathId, flowPath.getPathId());
         assertEquals(meterId, flowPath.getMeterId());
         assertEquals(cookie, flowPath.getCookie());
-        assertThat(flowPath.getSegments(), hasSize(1));
+        assertEquals(1, flowPath.getSegments().size());
     }
 
     @Test
-    public void shouldBuildFlowPathFor3SwitchPath() {
-        SwitchId switchId1 = new SwitchId(1);
-        SwitchId switchId2 = new SwitchId(2);
-        SwitchId switchId3 = new SwitchId(3);
-
+    public void buildFlowPathFor3SwitchPath() {
         Path path = Path.builder()
-                .srcSwitchId(switchId1)
-                .destSwitchId(switchId2)
-                .segments(asList(Segment.builder()
-                        .srcSwitchId(switchId1)
-                        .srcPort(1)
-                        .destSwitchId(switchId3)
-                        .destPort(2)
-                        .build(), Segment.builder()
-                        .srcSwitchId(switchId3)
-                        .srcPort(1)
-                        .destSwitchId(switchId2)
-                        .destPort(2)
-                        .build()))
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_2)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_3, 2), 
+                        buildSegment(SWITCH_ID_3, 1,  SWITCH_ID_2, 2)))
                 .build();
 
-        Flow flow = Flow.builder()
-                .flowId("test_flow")
-                .srcSwitch(Switch.builder().switchId(switchId1).build())
-                .destSwitch(Switch.builder().switchId(switchId2).build())
-                .build();
-        PathId pathId = new PathId("test_path_id");
+        Flow flow = buildFlow(SWITCH_1, SWITCH_2);
         MeterId meterId = new MeterId(MeterId.MIN_FLOW_METER_ID);
         PathResources pathResources = PathResources.builder()
-                .pathId(pathId)
+                .pathId(PATH_ID_1)
                 .meterId(meterId)
                 .build();
         FlowSegmentCookie cookie = new FlowSegmentCookie(FlowPathDirection.FORWARD, 1);
 
         FlowPath flowPath = builder.buildFlowPath(flow, pathResources, path, cookie, false, flow.getFlowId());
 
-        assertEquals(switchId1, flowPath.getSrcSwitchId());
-        assertEquals(switchId2, flowPath.getDestSwitchId());
-        assertEquals(pathId, flowPath.getPathId());
+        assertEquals(SWITCH_ID_1, flowPath.getSrcSwitchId());
+        assertEquals(SWITCH_ID_2, flowPath.getDestSwitchId());
+        assertEquals(PATH_ID_1, flowPath.getPathId());
         assertEquals(meterId, flowPath.getMeterId());
         assertEquals(cookie, flowPath.getCookie());
-        assertThat(flowPath.getSegments(), hasSize(2));
+        assertEquals(2, flowPath.getSegments().size());
+    }
+
+    @Test
+    public void flowPathsOverlapped() {
+        Path path = Path.builder()
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_3)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2),
+                        buildSegment(SWITCH_ID_2, 3, SWITCH_ID_2, 4)))
+                .build();
+
+        FlowPath flowPath = FlowPath.builder()
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
+                .pathId(PATH_ID_1)
+                .segments(ImmutableList.of(buildPathSegment(PATH_ID_1, SWITCH_1, 1, SWITCH_2, 2)))
+                .build();
+
+        assertTrue(builder.arePathsOverlapped(path, flowPath));
+    }
+
+    @Test
+    public void flowPathsNotOverlapped() {
+        Path path = Path.builder()
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_3)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2),
+                        buildSegment(SWITCH_ID_2, 3, SWITCH_ID_2, 4)))
+                .build();
+
+        FlowPath flowPath = FlowPath.builder()
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
+                .pathId(PATH_ID_1)
+                .segments(ImmutableList.of(buildPathSegment(PATH_ID_1, SWITCH_1, 7, SWITCH_2, 8)))
+                .build();
+
+        assertFalse(builder.arePathsOverlapped(path, flowPath));
+    }
+
+    @Test
+    public void haFlowPathsOverlapped() {
+        Path path = Path.builder()
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_3)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2),
+                        buildSegment(SWITCH_ID_2, 3, SWITCH_ID_2, 4)))
+                .build();
+
+        HaPath haPath = HaPath.builder().sharedSwitchId(SWITCH_ID_1).yPointSwitchId(SWITCH_ID_2)
+                .subPaths(singletonList(path)).build();
+        FlowPath subPath = FlowPath.builder()
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
+                .pathId(PATH_ID_1)
+                .segments(singletonList(buildPathSegment(PATH_ID_1, SWITCH_1, 1, SWITCH_2, 2)))
+                .build();
+        HaSubFlow haSubFlow = HaSubFlow.builder().haSubFlowId(HA_SUB_FLOW).endpointSwitch(SWITCH_2).build();
+        subPath.setHaSubFlow(haSubFlow);
+
+        HaFlowPath haFlowPath = HaFlowPath.builder().sharedSwitch(SWITCH_1).haPathId(PATH_ID_1).build();
+        haFlowPath.setSubPaths(singletonList(subPath));
+        assertTrue(builder.arePathsOverlapped(haPath, haFlowPath));
+    }
+
+    @Test
+    public void haFlowPathsNotOverlapped() {
+        Path path = Path.builder()
+                .srcSwitchId(SWITCH_ID_1)
+                .destSwitchId(SWITCH_ID_3)
+                .segments(asList(buildSegment(SWITCH_ID_1, 1, SWITCH_ID_2, 2),
+                        buildSegment(SWITCH_ID_2, 3, SWITCH_ID_2, 4)))
+                .build();
+
+        HaPath haPath = HaPath.builder().sharedSwitchId(SWITCH_ID_1).yPointSwitchId(SWITCH_ID_2)
+                .subPaths(singletonList(path)).build();
+        FlowPath subPath = FlowPath.builder()
+                .srcSwitch(SWITCH_1)
+                .destSwitch(SWITCH_2)
+                .pathId(PATH_ID_1)
+                .segments(singletonList(buildPathSegment(PATH_ID_1, SWITCH_1, 8, SWITCH_2, 9)))
+                .build();
+        HaSubFlow haSubFlow = HaSubFlow.builder().haSubFlowId(HA_SUB_FLOW).endpointSwitch(SWITCH_2).build();
+        subPath.setHaSubFlow(haSubFlow);
+
+        HaFlowPath haFlowPath = HaFlowPath.builder().sharedSwitch(SWITCH_1).haPathId(PATH_ID_1).build();
+        haFlowPath.setSubPaths(singletonList(subPath));
+
+        assertFalse(builder.arePathsOverlapped(haPath, haFlowPath));
+    }
+
+    private static Flow buildFlow(Switch srcSwitch, Switch dstSwitch) {
+        return Flow.builder()
+                .flowId("test_flow")
+                .srcSwitch(srcSwitch)
+                .destSwitch(dstSwitch)
+                .build();
+    }
+
+    private static PathSegment buildPathSegment(
+            PathId flowPathId, Switch srcSwitch, int srcPort, Switch dstSwitch, int dstPort) {
+        return PathSegment.builder()
+                .pathId(flowPathId)
+                .srcSwitch(srcSwitch)
+                .srcPort(srcPort)
+                .destSwitch(dstSwitch)
+                .destPort(dstPort)
+                .build();
+    }
+
+    private static Segment buildSegment(SwitchId srcSwitchId, int srcPort, SwitchId dstSwitchId, int dstPort) {
+        return Segment.builder()
+                .srcSwitchId(srcSwitchId)
+                .srcPort(srcPort)
+                .destSwitchId(dstSwitchId)
+                .destPort(dstPort)
+                .build();
     }
 }
diff --git a/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/create/actions/ResourcesAllocationAction.java b/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/create/actions/ResourcesAllocationAction.java
index 0d62bfbbd..6267af024 100644
--- a/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/create/actions/ResourcesAllocationAction.java
+++ b/src-java/flowhs-topology/flowhs-storm-topology/src/main/java/org/openkilda/wfm/topology/flowhs/fsm/haflow/create/actions/ResourcesAllocationAction.java
@@ -257,7 +257,14 @@ public class ResourcesAllocationAction extends
         GetHaPathsResult protectedPaths = pathComputer.getHaPath(tmpFlow, true);
         stateMachine.setBackUpProtectedPathComputationWayUsed(protectedPaths.isBackUpPathComputationWayUsed());
 
-        //TODO check protected overlapping?
+        boolean overlappingProtectedPathFound =
+                flowPathBuilder.arePathsOverlapped(protectedPaths.getForward(), tmpFlow.getForwardPath())
+                        || flowPathBuilder.arePathsOverlapped(protectedPaths.getReverse(), tmpFlow.getReversePath());
+        if (overlappingProtectedPathFound) {
+            log.info("Couldn't find non overlapping protected path. Result ha-flow state: {}", tmpFlow);
+            throw new UnroutableFlowException("Couldn't find non overlapping protected path", tmpFlow.getHaFlowId());
+        }
+
         log.debug("Creating the protected path {} for flow {}", protectedPaths, tmpFlow);
 
         transactionManager.doInTransaction(() -> {
diff --git a/src-java/kilda-persistence-orientdb/src/main/java/org/openkilda/persistence/orientdb/repositories/OrientDbFlowPathRepository.java b/src-java/kilda-persistence-orientdb/src/main/java/org/openkilda/persistence/orientdb/repositories/OrientDbFlowPathRepository.java
index 60762fc0b..5e5791e32 100644
--- a/src-java/kilda-persistence-orientdb/src/main/java/org/openkilda/persistence/orientdb/repositories/OrientDbFlowPathRepository.java
+++ b/src-java/kilda-persistence-orientdb/src/main/java/org/openkilda/persistence/orientdb/repositories/OrientDbFlowPathRepository.java
@@ -20,6 +20,8 @@ import static java.lang.String.format;
 import org.openkilda.model.PathId;
 import org.openkilda.persistence.ferma.frames.FlowFrame;
 import org.openkilda.persistence.ferma.frames.FlowPathFrame;
+import org.openkilda.persistence.ferma.frames.HaFlowFrame;
+import org.openkilda.persistence.ferma.frames.HaFlowPathFrame;
 import org.openkilda.persistence.ferma.frames.converters.PathIdConverter;
 import org.openkilda.persistence.ferma.repositories.FermaFlowPathRepository;
 import org.openkilda.persistence.orientdb.OrientDbPersistenceImplementation;
@@ -28,6 +30,8 @@ import org.openkilda.persistence.repositories.FlowPathRepository;
 import org.apache.tinkerpop.gremlin.orientdb.executor.OGremlinResultSet;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -43,12 +47,18 @@ public class OrientDbFlowPathRepository extends FermaFlowPathRepository {
 
     @Override
     public Collection<PathId> findPathIdsByFlowDiverseGroupId(String flowDiverseGroupId) {
-        return findPathIdsByFlowGroupId(FlowFrame.DIVERSE_GROUP_ID_PROPERTY, flowDiverseGroupId);
+        Set<PathId> pathIds = new HashSet<>(
+                findPathIdsByFlowGroupId(FlowFrame.DIVERSE_GROUP_ID_PROPERTY, flowDiverseGroupId));
+        pathIds.addAll(findPathIdsByHaFlowGroupId(HaFlowFrame.DIVERSE_GROUP_ID_PROPERTY, flowDiverseGroupId));
+        return pathIds;
     }
 
     @Override
     public Collection<PathId> findPathIdsByFlowAffinityGroupId(String flowAffinityGroupId) {
-        return findPathIdsByFlowGroupId(FlowFrame.AFFINITY_GROUP_ID_PROPERTY, flowAffinityGroupId);
+        Set<PathId> pathIds = new HashSet<>(
+                findPathIdsByFlowGroupId(FlowFrame.AFFINITY_GROUP_ID_PROPERTY, flowAffinityGroupId));
+        pathIds.addAll(findPathIdsByHaFlowGroupId(HaFlowFrame.AFFINITY_GROUP_ID_PROPERTY, flowAffinityGroupId));
+        return pathIds;
     }
 
     private Collection<PathId> findPathIdsByFlowGroupId(String groupIdProperty, String flowGroupId) {
@@ -63,6 +73,18 @@ public class OrientDbFlowPathRepository extends FermaFlowPathRepository {
         }
     }
 
+    private Collection<PathId> findPathIdsByHaFlowGroupId(String groupIdProperty, String flowGroupId) {
+        try (OGremlinResultSet results = graphSupplier.get().querySql(
+                format("SELECT %s FROM %s WHERE in('%s').in('%s').%s = ?",
+                        FlowPathFrame.PATH_ID_PROPERTY, FlowPathFrame.FRAME_LABEL,
+                        HaFlowPathFrame.OWNS_PATH_EDGE, HaFlowFrame.OWNS_PATHS_EDGE, groupIdProperty), flowGroupId)) {
+            return results.stream()
+                    .map(r -> r.getProperty(FlowPathFrame.PATH_ID_PROPERTY))
+                    .map(pathId -> PathIdConverter.INSTANCE.toEntityAttribute((String) pathId))
+                    .collect(Collectors.toList());
+        }
+    }
+
     /*TODO: this need to be reimplemented to work with PathSegmentFrame.SHARED_BANDWIDTH_GROUP_ID_PROPERTY
     @Override
     protected long getUsedBandwidthBetweenEndpoints(FramedGraph framedGraph,
diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaFlowPathRepository.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaFlowPathRepository.java
index 9f0d65a0e..fd35afd44 100644
--- a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaFlowPathRepository.java
+++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaFlowPathRepository.java
@@ -50,6 +50,7 @@ import org.apache.tinkerpop.gremlin.structure.Column;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -198,7 +199,7 @@ public class FermaFlowPathRepository extends FermaGenericRepository<FlowPath, Fl
 
     @Override
     public Collection<PathId> findPathIdsByFlowAffinityGroupId(String flowAffinityGroupId) {
-        List<PathId> pathIds = new ArrayList<>(findPathIdsByFlowGroupId(
+        Set<PathId> pathIds = new HashSet<>(findPathIdsByFlowGroupId(
                 FlowFrame.AFFINITY_GROUP_ID_PROPERTY, flowAffinityGroupId));
         pathIds.addAll(findPathIdsByHaFlowGroupId(HaFlowFrame.AFFINITY_GROUP_ID_PROPERTY, flowAffinityGroupId));
         return pathIds;