diff --git a/CHANGES.md b/CHANGES.md
index 1ae82773..17944728 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,4 +1,8 @@
# OSCARS Release Notes
+### 1.2.8
+> May 2024
+- Add port utilization report API
+
### 1.2.8
> May 2024
- Add edge port search
diff --git a/backend/pom.xml b/backend/pom.xml
index 7eed255f..bd5e312c 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -14,7 +14,7 @@
net.es.oscars
backend
backend
- 1.2.8
+ 1.2.9
OSCARS backend
diff --git a/backend/src/main/java/net/es/oscars/topo/beans/v2/Bandwidth.java b/backend/src/main/java/net/es/oscars/topo/beans/v2/Bandwidth.java
index 40d716b9..5b55d256 100644
--- a/backend/src/main/java/net/es/oscars/topo/beans/v2/Bandwidth.java
+++ b/backend/src/main/java/net/es/oscars/topo/beans/v2/Bandwidth.java
@@ -1,7 +1,11 @@
package net.es.oscars.topo.beans.v2;
+import com.fasterxml.jackson.annotation.JsonGetter;
import lombok.*;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
@Data
@Builder
@AllArgsConstructor
@@ -17,6 +21,18 @@ public class Bandwidth {
@NonNull
private Integer physical;
+ @JsonGetter
+ private Double utilization() {
+
+ if (physical == 0) {
+ return 0.0;
+ }
+ BigDecimal bd = BigDecimal.valueOf(1.0 - (available.doubleValue() / physical.doubleValue()));
+ bd = bd.setScale(3, RoundingMode.HALF_UP);
+ return bd.doubleValue();
+
+ }
+
public enum Unit {
MBPS, GBPS
}
diff --git a/backend/src/main/java/net/es/oscars/topo/beans/v2/EdgePort.java b/backend/src/main/java/net/es/oscars/topo/beans/v2/EdgePort.java
index 1bedc548..57f4b2f0 100644
--- a/backend/src/main/java/net/es/oscars/topo/beans/v2/EdgePort.java
+++ b/backend/src/main/java/net/es/oscars/topo/beans/v2/EdgePort.java
@@ -27,16 +27,37 @@ public String getUrn() {
@NonNull
private Bandwidth bandwidth;
- @JsonProperty("vlan-availability")
- private VlanAvailability vlanAvailability;
+ @NonNull
+ private Availability availability;
- @JsonProperty("vlan-usage")
- private Map> vlanUsage;
+ @NonNull
+ private Usage usage;
@JsonProperty("esdb-equipment-interface-id")
private Integer esdbEquipmentInterfaceId;
private ArrayList description;
+ @Data
+ @Builder
+ @AllArgsConstructor
+ @NoArgsConstructor
+ public static class Usage {
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ private Map> vlan;
+
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ private Map bandwidth;
+ }
+ @Data
+ @Builder
+ @AllArgsConstructor
+ @NoArgsConstructor
+ public static class Availability {
+ @JsonProperty("vlan")
+ private VlanAvailability vlan;
+
+ }
+
}
\ No newline at end of file
diff --git a/backend/src/main/java/net/es/oscars/web/rest/v2/TopoSearchController.java b/backend/src/main/java/net/es/oscars/web/rest/v2/TopoSearchController.java
index 671eac64..2b55da45 100644
--- a/backend/src/main/java/net/es/oscars/web/rest/v2/TopoSearchController.java
+++ b/backend/src/main/java/net/es/oscars/web/rest/v2/TopoSearchController.java
@@ -13,11 +13,14 @@
import net.es.oscars.topo.enums.Layer;
import net.es.oscars.topo.pop.ConsistencyException;
import net.es.oscars.topo.svc.TopologyStore;
+import net.es.oscars.web.beans.Interval;
import net.es.oscars.web.beans.v2.PortSearchRequest;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.*;
@RestController
@@ -144,6 +147,36 @@ public List edgePortSearch(@RequestBody PortSearchRequest psr)
return results;
}
+
+ @RequestMapping(value = "/api/reports/utilization", method = RequestMethod.GET)
+ @ResponseBody
+ @Transactional
+ public List utilizationReport()
+ throws ConsistencyException, StartupException {
+ startup.startupCheck();
+ List results = new ArrayList<>();
+
+ Topology topology = topologyStore.getTopology();
+ if (topology.getVersion() == null) {
+ throw new ConsistencyException("null current topology");
+ }
+ Interval interval = Interval.builder()
+ .beginning(Instant.now())
+ .ending(Instant.now().plus(24, ChronoUnit.HOURS))
+ .build();
+ Map available = resvService.available(interval, null);
+ Map>> vlanUsageMap = resvService.vlanUsage(interval, null);
+
+
+ for (Device d : topology.getDevices().values()) {
+ for (net.es.oscars.topo.beans.Port p : d.getPorts()) {
+ results.add(fromOldPort(p, available, vlanUsageMap));
+ }
+ }
+ return results;
+ }
+
+
private EdgePort fromOldPort(net.es.oscars.topo.beans.Port p,
Map available,
Map>> vlanUsageMap) throws ConsistencyException {
@@ -187,10 +220,10 @@ private EdgePort fromOldPort(net.es.oscars.topo.beans.Port p,
.device(parts[0])
.name(parts[1])
.bandwidth(bw)
- .vlanAvailability(vlanAvailability)
+ .availability(EdgePort.Availability.builder().vlan(vlanAvailability).build())
.description(p.getTags())
.esdbEquipmentInterfaceId(p.getEsdbEquipmentInterfaceId())
- .vlanUsage(vlanUsage)
+ .usage(EdgePort.Usage.builder().vlan(vlanUsage).build())
.build();
}