Search in sources :

Example 1 with OutPort

use of org.openkilda.atdd.staging.model.topology.TopologyDefinition.OutPort in project open-kilda by telstra.

the class FlowCrudSteps method buildFlow.

private FlowPayload buildFlow(String flowId, Switch srcSwitch, Switch destSwitch) {
    // Take the switch vlan ranges as the base
    RangeSet<Integer> srcRangeSet = TreeRangeSet.create();
    srcSwitch.getOutPorts().forEach(port -> srcRangeSet.addAll(port.getVlanRange()));
    RangeSet<Integer> destRangeSet = TreeRangeSet.create();
    destSwitch.getOutPorts().forEach(port -> destRangeSet.addAll(port.getVlanRange()));
    // Exclude already allocated vlans
    srcRangeSet.removeAll(allocatedVlans);
    destRangeSet.removeAll(allocatedVlans);
    if (srcRangeSet.isEmpty() || destRangeSet.isEmpty()) {
        LOGGER.warn("Unable to define a flow between {} and {} as no vlan available.", srcSwitch, destSwitch);
        return null;
    }
    // Calculate intersection of the ranges
    RangeSet<Integer> interRangeSet = TreeRangeSet.create(srcRangeSet);
    interRangeSet.removeAll(destRangeSet.complement());
    // Same vlan for source and destination
    final Optional<Integer> sameVlan = interRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
    int srcVlan;
    int destVlan;
    if (sameVlan.isPresent()) {
        srcVlan = sameVlan.get();
        destVlan = sameVlan.get();
    } else {
        // Cross vlan flow
        Optional<Integer> srcVlanOpt = srcRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
        if (!srcVlanOpt.isPresent()) {
            LOGGER.warn("Unable to allocate a vlan for the switch {}.", srcSwitch);
            return null;
        }
        srcVlan = srcVlanOpt.get();
        Optional<Integer> destVlanOpt = destRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
        if (!destVlanOpt.isPresent()) {
            LOGGER.warn("Unable to allocate a vlan for the switch {}.", destSwitch);
            return null;
        }
        destVlan = destVlanOpt.get();
    }
    boolean sameSwitchFlow = srcSwitch.getDpId().equals(destSwitch.getDpId());
    Optional<OutPort> srcPort = srcSwitch.getOutPorts().stream().filter(p -> p.getVlanRange().contains(srcVlan)).findFirst();
    int srcPortId = srcPort.orElseThrow(() -> new IllegalStateException("Unable to allocate a port in found vlan.")).getPort();
    Optional<OutPort> destPort = destSwitch.getOutPorts().stream().filter(p -> p.getVlanRange().contains(destVlan)).filter(p -> !sameSwitchFlow || p.getPort() != srcPortId).findFirst();
    if (!destPort.isPresent()) {
        if (sameSwitchFlow) {
            LOGGER.warn("Unable to define a same switch flow for {} as no ports available.", srcSwitch);
            return null;
        } else {
            throw new IllegalStateException("Unable to allocate a port in found vlan.");
        }
    }
    // Record used vlan to archive uniqueness
    allocatedVlans.add(Range.singleton(srcVlan));
    allocatedVlans.add(Range.singleton(destVlan));
    FlowEndpointPayload srcEndpoint = new FlowEndpointPayload(srcSwitch.getDpId(), srcPortId, srcVlan);
    FlowEndpointPayload destEndpoint = new FlowEndpointPayload(destSwitch.getDpId(), destPort.get().getPort(), destVlan);
    return new FlowPayload(flowId, srcEndpoint, destEndpoint, 1, false, flowId, null);
}
Also used : RangeSet(com.google.common.collect.RangeSet) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) FlowPayload(org.openkilda.messaging.payload.flow.FlowPayload) Assert.assertThat(org.junit.Assert.assertThat) Given(cucumber.api.java.en.Given) NorthboundService(org.openkilda.atdd.staging.service.northbound.NorthboundService) FloodlightService(org.openkilda.atdd.staging.service.floodlight.FloodlightService) Then(cucumber.api.java.en.Then) SwitchInfoData(org.openkilda.messaging.info.event.SwitchInfoData) Matchers.reflectEquals(com.nitorcreations.Matchers.reflectEquals) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) ImmutablePair(org.openkilda.messaging.model.ImmutablePair) Collections.emptyList(java.util.Collections.emptyList) Range(com.google.common.collect.Range) TopologyChecker(org.openkilda.atdd.staging.steps.helpers.TopologyChecker) FlowEndpointPayload(org.openkilda.messaging.payload.flow.FlowEndpointPayload) RetryPolicy(net.jodah.failsafe.RetryPolicy) UUID(java.util.UUID) String.format(java.lang.String.format) Objects(java.util.Objects) List(java.util.List) TopologyEngineService(org.openkilda.atdd.staging.service.topology.TopologyEngineService) Assert.assertFalse(org.junit.Assert.assertFalse) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Optional(java.util.Optional) Matchers.is(org.hamcrest.Matchers.is) IslInfoData(org.openkilda.messaging.info.event.IslInfoData) ContiguousSet(com.google.common.collect.ContiguousSet) Switch(org.openkilda.atdd.staging.model.topology.TopologyDefinition.Switch) TreeRangeSet(com.google.common.collect.TreeRangeSet) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) Matchers.hasProperty(org.hamcrest.Matchers.hasProperty) FlowIdStatusPayload(org.openkilda.messaging.payload.flow.FlowIdStatusPayload) DiscreteDomain(com.google.common.collect.DiscreteDomain) And(cucumber.api.java.en.And) Flow(org.openkilda.messaging.model.Flow) Logger(org.slf4j.Logger) Assert.assertNotNull(org.junit.Assert.assertNotNull) Assert.assertTrue(org.junit.Assert.assertTrue) Failsafe(net.jodah.failsafe.Failsafe) TimeUnit(java.util.concurrent.TimeUnit) Collectors.toList(java.util.stream.Collectors.toList) Assert.assertNull(org.junit.Assert.assertNull) OutPort(org.openkilda.atdd.staging.model.topology.TopologyDefinition.OutPort) En(cucumber.api.java8.En) FlowState(org.openkilda.messaging.payload.flow.FlowState) VisibleForTesting(com.google.common.annotations.VisibleForTesting) When(cucumber.api.java.en.When) TopologyDefinition(org.openkilda.atdd.staging.model.topology.TopologyDefinition) FlowPayload(org.openkilda.messaging.payload.flow.FlowPayload) OutPort(org.openkilda.atdd.staging.model.topology.TopologyDefinition.OutPort) FlowEndpointPayload(org.openkilda.messaging.payload.flow.FlowEndpointPayload)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ContiguousSet (com.google.common.collect.ContiguousSet)1 DiscreteDomain (com.google.common.collect.DiscreteDomain)1 Range (com.google.common.collect.Range)1 RangeSet (com.google.common.collect.RangeSet)1 TreeRangeSet (com.google.common.collect.TreeRangeSet)1 Matchers.reflectEquals (com.nitorcreations.Matchers.reflectEquals)1 And (cucumber.api.java.en.And)1 Given (cucumber.api.java.en.Given)1 Then (cucumber.api.java.en.Then)1 When (cucumber.api.java.en.When)1 En (cucumber.api.java8.En)1 String.format (java.lang.String.format)1 Collections.emptyList (java.util.Collections.emptyList)1 List (java.util.List)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1 TimeUnit (java.util.concurrent.TimeUnit)1 Collectors.toList (java.util.stream.Collectors.toList)1