Skip to content

Commit

Permalink
Improve edge port search (#481)
Browse files Browse the repository at this point in the history
* update vlan usage

* do not return backbone-only ports in edge port search
  • Loading branch information
haniotak authored May 15, 2024
1 parent f4e044c commit 0577592
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ public Validity validate(SimpleConnection in, ConnectionMode mode)
fv.setValid(false);
valid = false;
}
log.debug(f.getPort() + " vlan " + vlan + " contained in " + IntRange.asString(availVlanRanges) + " ? " + atLeastOneContains);
log.debug(f.getPort() + " vlan " + vlan + " contained in " + IntRange.asString(availVlanRanges, "-") + " ? " + atLeastOneContains);
}
} else {
fv.setValid(false);
Expand Down
6 changes: 3 additions & 3 deletions backend/src/main/java/net/es/oscars/resv/svc/ResvLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static Map<String, PortBwVlan> portBwVlans(Map<String, TopoUrn> urnMap,

if (topoUrn.getCapabilities().contains(Layer.ETHERNET)) {
intRanges = availableVlanMap.get(urn);
vlanExpr = IntRange.asString(intRanges);
vlanExpr = IntRange.asString(intRanges, ":");
}

PortBwVlan pbw = PortBwVlan.builder()
Expand Down Expand Up @@ -167,11 +167,11 @@ public static Map<String, Integer> decideIdentifier(Map<String, Set<IntRange>> r
Map<String, Set<IntRange>> search = new HashMap<>();
for (String r : requested.keySet()) {
search.put(r+"-req", requested.get(r));
log.info("req: "+r+" : "+IntRange.asString(requested.get(r)));
log.info("req: "+r+" : "+IntRange.asString(requested.get(r), "-"));
}
for (String a : available.keySet()) {
search.put(a+"-avail", available.get(a));
log.info("avail: "+a+" : "+IntRange.asString(available.get(a)));
log.info("avail: "+a+" : "+IntRange.asString(available.get(a), "-"));
}

Integer least = IntRange.leastInAll(search);
Expand Down
32 changes: 21 additions & 11 deletions backend/src/main/java/net/es/oscars/topo/beans/IntRange.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@EqualsAndHashCode

@Slf4j
public class IntRange {
public class IntRange implements Comparable<IntRange> {
private Integer floor;
private Integer ceiling;

Expand All @@ -29,7 +29,7 @@ public boolean contains(Integer i) {
public Set<IntRange> subtract(Integer i) throws NoSuchElementException {
HashSet<IntRange> result = new HashSet<>();
if (!this.contains(i)) {
throw new NoSuchElementException("range " + this.toString() + " does not contain " + i);
throw new NoSuchElementException("range " + this + " does not contain " + i);
}
// remove last one: return an empty set
if (this.getFloor().equals(this.getCeiling())) {
Expand Down Expand Up @@ -64,13 +64,12 @@ public Set<Integer> asSet() {

public static Set<IntRange> fromSet(Set<Integer> ints) {
Set<IntRange> result = new HashSet<>();
List<Integer> sortedInts = new ArrayList<>();
sortedInts.addAll(ints);
List<Integer> sortedInts = new ArrayList<>(ints);
Collections.sort(sortedInts);

IntRange range = IntRange.builder().floor(-1).ceiling(-1).build();

for (Integer idx = 0; idx < sortedInts.size(); idx++) {
for (int idx = 0; idx < sortedInts.size(); idx++) {
Integer number = sortedInts.get(idx);
if (range.getCeiling() == -1) {
range.setFloor(number);
Expand Down Expand Up @@ -153,24 +152,31 @@ public static Set<Integer> singleSetFromExpr(String rangeExpr){
}


public static String asString(Collection<IntRange> ranges) {
public static String asString(Collection<IntRange> ranges, String separator) {
ranges = mergeIntRanges(ranges);
List<IntRange> listOfRanges = new ArrayList<>();
listOfRanges.addAll(ranges);
listOfRanges.sort(Comparator.comparing(IntRange::getFloor));
List<IntRange> listOfRanges = new ArrayList<>(ranges);

List<String> parts = new ArrayList<>();
listOfRanges.forEach(r -> {
listOfRanges.stream().sorted().forEach(r -> {
if (r.getCeiling().equals(r.getFloor())) {
parts.add(r.getCeiling() + "");
} else {
parts.add(r.getFloor() + ":" + r.getCeiling());
parts.add(r.getFloor() + separator + r.getCeiling());

}
});
return StringUtils.join(parts, ',');
}
public static String asIntervalNotation(Collection<IntRange> ranges) {
ranges = mergeIntRanges(ranges);
List<IntRange> listOfRanges = new ArrayList<>(ranges);

List<String> parts = new ArrayList<>();
listOfRanges.stream().sorted().forEach(r -> {
parts.add("["+r.getFloor() + " .. " + r.getCeiling()+"]");
});
return StringUtils.join(parts, ',');
}

public static List<IntRange> mergeIntRanges(Collection<IntRange> input) {

Expand Down Expand Up @@ -273,4 +279,8 @@ public static Integer leastInAll(Map<String, Set<IntRange>> rangeMapOfSets) {

}

@Override
public int compareTo(@NonNull IntRange o) {
return this.getFloor().compareTo(o.getFloor());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Port {
public class EdgePort {
@JsonGetter("urn")
public String getUrn() {
return device+":"+name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.es.oscars.topo.beans.IntRange;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

Expand All @@ -21,18 +22,24 @@ public class VlanAvailability {

@JsonGetter("expression")
private String asExpression() {
return IntRange.asString(ranges);
return IntRange.asString(ranges, "-");
}
// @JsonGetter("intervals")
// private String asIntervals() {
// return IntRange.asIntervalNotation(ranges);
// }

@JsonGetter("tuples")
private List<List<Integer>> asTuples() {
List<List<Integer>> result = new ArrayList<>();
for (IntRange range : ranges) {
List<Integer> tuple = new ArrayList<>();
tuple.add(range.getFloor());
tuple.add(range.getCeiling());
result.add(tuple);
}

ranges.stream()
.sorted()
.forEach(range -> result.add(new ArrayList<>() {{
add(range.getFloor());
add(range.getCeiling());
}}));

return result;
}
}
3 changes: 2 additions & 1 deletion backend/src/main/java/net/es/oscars/topo/enums/Layer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ public enum Layer {
ETHERNET,
INTERNAL,
MPLS,
LOGICAL;
LOGICAL,
EDGE;


}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import net.es.oscars.topo.beans.PortBwVlan;
import net.es.oscars.topo.beans.Topology;
import net.es.oscars.topo.beans.v2.Bandwidth;
import net.es.oscars.topo.beans.v2.Port;
import net.es.oscars.topo.beans.v2.EdgePort;
import net.es.oscars.topo.beans.v2.VlanAvailability;
import net.es.oscars.topo.enums.Layer;
import net.es.oscars.topo.pop.ConsistencyException;
Expand All @@ -26,6 +26,7 @@ public class TopoSearchController {
private final TopologyStore topologyStore;
private final Startup startup;
private final ResvService resvService;

public TopoSearchController(TopologyStore topologyStore, Startup startup, ResvService resvService) {
this.topologyStore = topologyStore;
this.startup = startup;
Expand All @@ -35,7 +36,7 @@ public TopoSearchController(TopologyStore topologyStore, Startup startup, ResvSe
@ExceptionHandler(ConsistencyException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public void handleException(ConsistencyException ex) {
log.warn("consistency error "+ex.getMessage() );
log.warn("consistency error " + ex.getMessage());
}

@ExceptionHandler(StartupException.class)
Expand All @@ -55,10 +56,11 @@ public SearchException(String msg) {
super(msg);
}
}

@RequestMapping(value = "/api/topo/edge-port-search", method = RequestMethod.POST)
@ResponseBody
@Transactional
public List<Port> edgePortSearch(@RequestBody PortSearchRequest psr)
public List<EdgePort> edgePortSearch(@RequestBody PortSearchRequest psr)
throws ConsistencyException, StartupException, SearchException {
startup.startupCheck();

Expand All @@ -72,75 +74,108 @@ public List<Port> edgePortSearch(@RequestBody PortSearchRequest psr)
if (topology.getVersion() == null) {
throw new ConsistencyException("null current topology");
}

Map<String, PortBwVlan> available = resvService.available(psr.getInterval(), psr.getConnectionId());
Map<String, Map<Integer, Set<String>>> vlanUsage = resvService.vlanUsage(psr.getInterval(), psr.getConnectionId());
Map<String, Map<Integer, Set<String>>> vlanUsageMap = resvService.vlanUsage(psr.getInterval(), psr.getConnectionId());


String term = psr.getTerm().toUpperCase();

List<Port> results = new ArrayList<>();
List<EdgePort> results = new ArrayList<>();

for (Device d : topology.getDevices().values()) {
for (net.es.oscars.topo.beans.Port p : d.getPorts() ) {
if (p.getCapabilities().contains(Layer.ETHERNET)) {

boolean isResult = false;
if (p.getUrn().toUpperCase().contains(term)) {
isResult = true;
} else {
for (String tag : p.getTags()) {
if (tag.toUpperCase().contains(term)) {
isResult = true;
break;
}
for (net.es.oscars.topo.beans.Port p : d.getPorts()) {

boolean isEdge = true;
if (!p.getCapabilities().contains(Layer.ETHERNET)) {
isEdge = false;
} else if (p.getCapabilities().contains(Layer.EDGE)) {
// this is really what we should be getting from topology service
isEdge = true;
}

// TODO: take this out once Layer.EDGE is everywhere
if (isEdge) {
for (String tag : p.getTags()) {
if (tag.contains(":bbl-")) {
isEdge = false;
break;
}
}
if (isResult) {
String[] parts = p.getUrn().split(":");
if (parts.length != 2) {
throw new ConsistencyException("Invalid port URN format");
}
if (!available.containsKey(p.getUrn())) {
throw new ConsistencyException("cannot get available bw and vlans for "+p.getUrn());
}
PortBwVlan pbw = available.get(p.getUrn());
}

VlanAvailability vlanAvailability = VlanAvailability.builder()
.ranges(pbw.getVlanRanges())
.build();
if (!isEdge) {
continue;
}

// get the least of ingress / egress available
int bwPhysical = p.getReservableIngressBw();
if (p.getReservableEgressBw() < bwPhysical) {
bwPhysical = p.getReservableEgressBw();
}
int bwAvailable = pbw.getIngressBandwidth();
if (pbw.getEgressBandwidth() < bwAvailable) {
bwAvailable = pbw.getEgressBandwidth();
}
boolean isResult = false;

Bandwidth bw = Bandwidth.builder()
.unit(Bandwidth.Unit.MBPS)
.available(bwAvailable)
.physical(bwPhysical)
.build();

results.add(Port.builder()
.device(parts[0])
.name(parts[1])
.bandwidth(bw)
.vlanAvailability(vlanAvailability)
.description(p.getTags())
.esdbEquipmentInterfaceId(p.getEsdbEquipmentInterfaceId())
.vlanUsage(vlanUsage.get(p.getUrn()))
.build());
if (p.getUrn().toUpperCase().contains(term)) {
isResult = true;
} else {
for (String tag : p.getTags()) {
if (tag.toUpperCase().contains(term)) {
isResult = true;
break;
}
}
}
if (isResult) {
results.add(fromOldPort(p, available, vlanUsageMap));
}
}
}

return results;
}

private EdgePort fromOldPort(net.es.oscars.topo.beans.Port p,
Map<String, PortBwVlan> available,
Map<String, Map<Integer, Set<String>>> vlanUsageMap) throws ConsistencyException {

String[] parts = p.getUrn().split(":");
if (parts.length != 2) {
throw new ConsistencyException("Invalid port URN format");
}

if (!available.containsKey(p.getUrn())) {
throw new ConsistencyException("cannot get available bw and vlans for " + p.getUrn());
}
PortBwVlan pbw = available.get(p.getUrn());

VlanAvailability vlanAvailability = VlanAvailability.builder()
.ranges(pbw.getVlanRanges())
.build();

// get the least of ingress / egress available
int bwPhysical = p.getReservableIngressBw();
if (p.getReservableEgressBw() < bwPhysical) {
bwPhysical = p.getReservableEgressBw();
}
int bwAvailable = pbw.getIngressBandwidth();
if (pbw.getEgressBandwidth() < bwAvailable) {
bwAvailable = pbw.getEgressBandwidth();
}

Bandwidth bw = Bandwidth.builder()
.unit(Bandwidth.Unit.MBPS)
.available(bwAvailable)
.physical(bwPhysical)
.build();

Map<Integer, Set<String>> vlanUsage = new HashMap<>();
if (vlanUsageMap.containsKey(p.getUrn())) {
vlanUsage = vlanUsageMap.get(p.getUrn());
}

return EdgePort.builder()
.device(parts[0])
.name(parts[1])
.bandwidth(bw)
.vlanAvailability(vlanAvailability)
.description(p.getTags())
.esdbEquipmentInterfaceId(p.getEsdbEquipmentInterfaceId())
.vlanUsage(vlanUsage)
.build();
}

}

0 comments on commit 0577592

Please sign in to comment.