diff --git a/cli/src/main/java/org/onosproject/cli/net/DevicePortStatsCommand.java b/cli/src/main/java/org/onosproject/cli/net/DevicePortStatsCommand.java index eb07071494..18413a73f9 100644 --- a/cli/src/main/java/org/onosproject/cli/net/DevicePortStatsCommand.java +++ b/cli/src/main/java/org/onosproject/cli/net/DevicePortStatsCommand.java @@ -67,7 +67,7 @@ public class DevicePortStatsCommand extends AbstractShellCommand { PortNumber portNumber = null; private static final String FORMAT = - " port=%s, pktRx=%s, pktTx=%s, bytesRx=%s, bytesTx=%s, pktRxDrp=%s, pktTxDrp=%s, Dur=%s"; + " port=%s, pktRx=%s, pktTx=%s, bytesRx=%s, bytesTx=%s, pktRxDrp=%s, pktTxDrp=%s, Dur=%s%s"; @Override protected void execute() { @@ -121,7 +121,8 @@ public class DevicePortStatsCommand extends AbstractShellCommand { continue; } print(FORMAT, stat.portNumber(), stat.packetsReceived(), stat.packetsSent(), stat.bytesReceived(), - stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec()); + stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec(), + annotations(stat.annotations())); } } diff --git a/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java b/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java index 6e0ab42756..e46def2b61 100644 --- a/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java +++ b/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java @@ -15,13 +15,15 @@ */ package org.onosproject.net.device; +import org.onosproject.net.AbstractAnnotated; +import org.onosproject.net.Annotations; import org.onosproject.net.DeviceId; import org.onosproject.net.PortNumber; /** * Default implementation of immutable port statistics. */ -public final class DefaultPortStatistics implements PortStatistics { +public final class DefaultPortStatistics extends AbstractAnnotated implements PortStatistics { private final DeviceId deviceId; private final PortNumber portNumber; @@ -47,7 +49,9 @@ public final class DefaultPortStatistics implements PortStatistics { long packetsRxErrors, long packetsTxErrors, long durationSec, - long durationNano) { + long durationNano, + Annotations annotations) { + super(annotations); this.deviceId = deviceId; this.portNumber = portNumber; this.packetsReceived = packetsReceived; @@ -168,7 +172,8 @@ public final class DefaultPortStatistics implements PortStatistics { "pktRxErr: " + this.packetsRxErrors + ", " + "pktTxErr: " + this.packetsTxErrors + ", " + "pktRxDrp: " + this.packetsRxDropped + ", " + - "pktTxDrp: " + this.packetsTxDropped; + "pktTxDrp: " + this.packetsTxDropped + ", " + + "annotations: " + annotations(); } public static final class Builder { @@ -185,6 +190,7 @@ public final class DefaultPortStatistics implements PortStatistics { long packetsTxErrors; long durationSec; long durationNano; + Annotations annotations; private Builder() { @@ -348,6 +354,18 @@ public final class DefaultPortStatistics implements PortStatistics { return this; } + /** + * Sets the annotations. + * + * @param anns annotations + * @return builder object + */ + public Builder setAnnotations(Annotations anns) { + annotations = anns; + + return this; + } + /** * Creates a PortStatistics object. * @@ -366,7 +384,8 @@ public final class DefaultPortStatistics implements PortStatistics { packetsRxErrors, packetsTxErrors, durationSec, - durationNano); + durationNano, + annotations); } } diff --git a/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java b/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java index 3b9f19ac94..f78768e1d0 100644 --- a/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java +++ b/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java @@ -15,12 +15,16 @@ */ package org.onosproject.net.device; +import org.onosproject.net.Annotated; +import org.onosproject.net.Annotations; import org.onosproject.net.PortNumber; +import static org.onosproject.net.DefaultAnnotations.EMPTY; + /** * Statistics of a port. */ -public interface PortStatistics { +public interface PortStatistics extends Annotated { /** * Returns the port number. @@ -108,6 +112,11 @@ public interface PortStatistics { */ long durationNano(); + @Override + default Annotations annotations() { + return EMPTY; + } + /** * Returns true if all the port stats are zero, excluding TxErrors and RxErrors. * diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java index 91d667a635..4f58bb19e5 100644 --- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java +++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java @@ -96,6 +96,7 @@ import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportSignalType; import org.projectfloodlight.openflow.protocol.OFPortReason; import org.projectfloodlight.openflow.protocol.OFPortState; import org.projectfloodlight.openflow.protocol.OFPortStatsEntry; +import org.projectfloodlight.openflow.protocol.OFPortStatsPropOptical; import org.projectfloodlight.openflow.protocol.OFPortStatsReply; import org.projectfloodlight.openflow.protocol.OFPortStatus; import org.projectfloodlight.openflow.protocol.OFStatsReply; @@ -103,6 +104,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; import org.projectfloodlight.openflow.protocol.OFStatsType; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.ver14.OFOpticalPortFeaturesSerializerVer14; +import org.projectfloodlight.openflow.protocol.ver14.OFPortStatsOpticalFlagsSerializerVer14; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.PortSpeed; import org.slf4j.Logger; @@ -164,12 +166,6 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr */ public static final String AK_GRID_HZ = "grid"; - /** - * Annotation key for transmit tune feature. - * Value is expected to be "enabled" or "disabled" - */ - public static final String AK_TX_TUNE_FEATURE = "txTuneFeature"; - /** * Annotation key for minimum frequency in Hz. * Value is expected to be an integer. @@ -188,12 +184,6 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr */ public static final String AK_TX_GRID_HZ = "txGrid"; - /** - * Annotation key for receive tune feature. - * Value is expected to be "enabled" or "disabled" - */ - public static final String AK_RX_TUNE_FEATURE = "rxTuneFeature"; - /** * Annotation key for minimum frequency in Hz. * Value is expected to be an integer. @@ -212,12 +202,6 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr */ public static final String AK_RX_GRID_HZ = "rxGrid"; - /** - * Annotation key for transmit power feature. - * Value is expected to be "enabled" or "disabled" - */ - public static final String AK_TX_PWR_FEATURE = "txPwrFeature"; - /** * Annotation key for minimum transmit power in dBm*10. * Value is expected to be an integer. @@ -230,6 +214,110 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr */ public static final String AK_TX_PWR_MAX = "txPowerMax"; + + + // Port Stats annotations + + /** + * Annotation key for transmit frequency in Hz. + * Value is expected be an integer. + */ + public static final String AK_TX_FREQ_HZ = "txFrequency"; + + /** + * Annotation key for transmit offset in Hz. + * Value is expected be an integer. + */ + public static final String AK_TX_OFFSET_HZ = "txOffset"; + + /** + * Annotation key for transmit grid spacing in Hz. + * Value is expected be an integer. + */ + public static final String AK_TX_GRID_SPAN_HZ = "txGridSpan"; + + /** + * Annotation key for receive frequency in Hz. + * Value is expected be an integer. + */ + public static final String AK_RX_FREQ_HZ = "rxFrequency"; + + /** + * Annotation key for receive offset in Hz. + * Value is expected be an integer. + */ + public static final String AK_RX_OFFSET_HZ = "rxOffset"; + + /** + * Annotation key for receive grid spacing in Hz. + * Value is expected be an integer. + */ + public static final String AK_RX_GRID_SPAN_HZ = "rxGridSpan"; + + /** + * Annotation key for transmit power in dBm*10. + * Value is expected to be an integer. + */ + public static final String AK_TX_PWR = "txPower"; + + /** + * Annotation key for receive power feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_RX_PWR_FEATURE = "rxPwrFeature"; + + /** + * Annotation key for receive power in dBm*10. + * Value is expected to be an integer. + */ + public static final String AK_RX_PWR = "rxPower"; + + /** + * Annotation key for transmit bias feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_TX_BIAS_FEATURE = "txBiasFeature"; + + /** + * Annotation key for transmit bias current in mA*10. + * Value is expected to be an integer. + */ + public static final String AK_BIAS_CURRENT = "biasCurrent"; + + /** + * Annotation key for transmit temperature feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_TX_TEMP_FEATURE = "txTempFeature"; + + /** + * Annotation key for transmit laser temperature in C*10. + * Value is expected to be an integer. + */ + public static final String AK_TEMPERATURE = "temperature"; + + + // Common feature annotations + + /** + * Annotation key for transmit tune feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_TX_TUNE_FEATURE = "txTuneFeature"; + + /** + * Annotation key for receive tune feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_RX_TUNE_FEATURE = "rxTuneFeature"; + + /** + * Annotation key for transmit power feature. + * Value is expected to be "enabled" or "disabled" + */ + public static final String AK_TX_PWR_FEATURE = "txPwrFeature"; + + //TODO consider renaming KBPS and MBPS (as they are used to convert by division) private static final long KBPS = 1_000; private static final long MBPS = 1_000 * 1_000; @@ -420,6 +508,11 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr providerService.updatePortStatistics(deviceId, stats); } + + private static String mhzToAnnotation(long freqMhz) { + return Long.toString(Frequency.ofMHz(freqMhz).asHz()); + } + private Collection buildPortStatistics(DeviceId deviceId, List entries) { HashSet stats = Sets.newHashSet(); @@ -429,6 +522,52 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr if (entry == null || entry.getPortNo() == null || entry.getPortNo().getPortNumber() < 0) { continue; } + DefaultAnnotations.Builder annotations = DefaultAnnotations.builder(); + Optional optical = entry.getProperties().stream() + .filter(OFPortStatsPropOptical.class::isInstance) + .map(OFPortStatsPropOptical.class::cast) + .findAny(); + if (optical.isPresent()) { + long flags = optical.get().getFlags(); + + int txTune = OFPortStatsOpticalFlagsSerializerVer14.TX_TUNE_VAL; + long txFreq = optical.get().getTxFreqLmda(); + long txOffset = optical.get().getTxOffset(); + long txGridSpan = optical.get().getTxGridSpan(); + annotations.set(AK_TX_TUNE_FEATURE, ((flags & txTune) != 0) ? "enabled" : "disabled"); + annotations.set(AK_TX_FREQ_HZ, mhzToAnnotation(txFreq)); + annotations.set(AK_TX_OFFSET_HZ, mhzToAnnotation(txOffset)); + annotations.set(AK_TX_GRID_SPAN_HZ, mhzToAnnotation(txGridSpan)); + + int rxTune = OFPortStatsOpticalFlagsSerializerVer14.RX_TUNE_VAL; + long rxFreq = optical.get().getRxFreqLmda(); + long rxOffset = optical.get().getRxOffset(); + long rxGridSpan = optical.get().getRxGridSpan(); + annotations.set(AK_RX_TUNE_FEATURE, ((flags & rxTune) != 0) ? "enabled" : "disabled"); + annotations.set(AK_RX_FREQ_HZ, mhzToAnnotation(rxFreq)); + annotations.set(AK_RX_OFFSET_HZ, mhzToAnnotation(rxOffset)); + annotations.set(AK_RX_GRID_SPAN_HZ, mhzToAnnotation(rxGridSpan)); + + int txPwrVal = OFPortStatsOpticalFlagsSerializerVer14.TX_PWR_VAL; + int txPwr = optical.get().getTxPwr(); + annotations.set(AK_TX_PWR_FEATURE, ((flags & txPwrVal) != 0) ? "enabled" : "disabled"); + annotations.set(AK_TX_PWR, Integer.toString(txPwr)); + + int rxPwrVal = OFPortStatsOpticalFlagsSerializerVer14.RX_PWR_VAL; + int rxPwr = optical.get().getRxPwr(); + annotations.set(AK_RX_PWR_FEATURE, ((flags & rxPwrVal) != 0) ? "enabled" : "disabled"); + annotations.set(AK_RX_PWR, Integer.toString(rxPwr)); + + int txBias = OFPortStatsOpticalFlagsSerializerVer14.TX_BIAS_VAL; + int biasCurrent = optical.get().getBiasCurrent(); + annotations.set(AK_TX_BIAS_FEATURE, ((flags & txBias) != 0) ? "enabled" : "disabled"); + annotations.set(AK_BIAS_CURRENT, Integer.toString(biasCurrent)); + + int txTemp = OFPortStatsOpticalFlagsSerializerVer14.TX_TEMP_VAL; + int temperature = optical.get().getTemperature(); + annotations.set(AK_TX_TEMP_FEATURE, ((flags & txTemp) != 0) ? "enabled" : "disabled"); + annotations.set(AK_TEMPERATURE, Integer.toString(temperature)); + } DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder(); DefaultPortStatistics stat = builder.setDeviceId(deviceId) .setPort(entry.getPortNo().getPortNumber()) @@ -442,6 +581,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr .setPacketsTxErrors(entry.getTxErrors().getValue()) .setDurationSec(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationSec()) .setDurationNano(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationNsec()) + .setAnnotations(annotations.build()) .build(); stats.add(stat); @@ -842,8 +982,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr } private String mhzToAnnotation(long freqMhz) { - // annotations is in Hz - return Long.toString(freqMhz * 1_000_000); + return OpenFlowDeviceProvider.mhzToAnnotation(freqMhz); } private String lambdaToAnnotationHz(long lambda) {