Add NETCONF notification for ONU activation and Kafka client to receive events, update dependencies
Change-Id: I5f768fa8077ef7c64e00a534744ca47492344935
diff --git a/internal/core/translation.go b/internal/core/translation.go
index 634272c..ef6582d 100644
--- a/internal/core/translation.go
+++ b/internal/core/translation.go
@@ -18,15 +18,15 @@
import (
"fmt"
+ "time"
"github.com/opencord/voltha-protos/v5/go/common"
"github.com/opencord/voltha-protos/v5/go/voltha"
)
const (
- DeviceAggregationModel = "bbf-device-aggregation"
- DevicesPath = "/" + DeviceAggregationModel + ":devices"
- HardwarePath = "data/ietf-hardware:hardware"
+ DeviceAggregationModule = "bbf-device-aggregation"
+ DevicesPath = "/" + DeviceAggregationModule + ":devices"
//Device types
DeviceTypeOlt = "bbf-device-types:olt"
@@ -42,6 +42,13 @@
ietfOperStateDisabled = "disabled"
ietfOperStateEnabled = "enabled"
ietfOperStateTesting = "testing"
+ ietfOperStateUp = "up"
+ ietfOperStateDown = "down"
+
+ //Keys of useful values in device events
+ eventContextKeyPonId = "pon-id"
+ eventContextKeyOnuSn = "serial-number"
+ eventContextKeyOltSn = "olt-serial-number"
)
type YangItem struct {
@@ -56,7 +63,7 @@
//getDevicePath returns the yang path to the root of the device's hardware module in its data mountpoint
func getDeviceHardwarePath(id string) string {
- return fmt.Sprintf("%s/device[name='%s']/%s/component[name='%s']", DevicesPath, id, HardwarePath, id)
+ return fmt.Sprintf("%s/device[name='%s']/data/ietf-hardware:hardware/component[name='%s']", DevicesPath, id, id)
}
//ietfHardwareAdminState returns the string that represents the ietf-hardware admin state
@@ -101,8 +108,30 @@
return ietfOperStateUnknown
}
+//ietfHardwareOperState returns the string that represents the ietf-interfaces oper state
+//enum value corresponding to the one of VOLTHA
+func ietfInterfacesOperState(volthaOperState voltha.OperStatus_Types) string {
+ //TODO: verify this mapping is correct
+ switch volthaOperState {
+ case common.OperStatus_UNKNOWN:
+ return ietfOperStateUnknown
+ case common.OperStatus_TESTING:
+ return ietfOperStateTesting
+ case common.OperStatus_ACTIVE:
+ return ietfOperStateUp
+ case common.OperStatus_DISCOVERED:
+ case common.OperStatus_ACTIVATING:
+ case common.OperStatus_FAILED:
+ case common.OperStatus_RECONCILING:
+ case common.OperStatus_RECONCILING_FAILED:
+ return ietfOperStateDown
+ }
+
+ return ietfOperStateUnknown
+}
+
//translateDevice returns a slice of yang items that represent a voltha device
-func translateDevice(device voltha.Device) []YangItem {
+func translateDevice(device *voltha.Device) []YangItem {
devicePath := getDevicePath(device.Id)
hardwarePath := getDeviceHardwarePath(device.Id)
@@ -110,70 +139,148 @@
//Device type
if device.Root {
+ //OLT
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/type", devicePath),
+ Path: devicePath + "/type",
Value: DeviceTypeOlt,
})
} else {
+ //ONU
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/type", devicePath),
+ Path: devicePath + "/type",
Value: DeviceTypeOnu,
})
}
//Vendor name
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/mfg-name", hardwarePath),
+ Path: hardwarePath + "/mfg-name",
Value: device.Vendor,
})
//Model
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/model-name", hardwarePath),
+ Path: hardwarePath + "/model-name",
Value: device.Model,
})
//Hardware version
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/hardware-rev", hardwarePath),
+ Path: hardwarePath + "/hardware-rev",
Value: device.HardwareVersion,
})
//Firmware version
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/firmware-rev", hardwarePath),
+ Path: hardwarePath + "/firmware-rev",
Value: device.FirmwareVersion,
})
//Serial number
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/serial-num", hardwarePath),
+ Path: hardwarePath + "/serial-num",
Value: device.SerialNumber,
})
//Administrative state
//Translates VOLTHA admin state enum to ietf-hardware enum
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/state/admin-state", hardwarePath),
+ Path: hardwarePath + "/state/admin-state",
Value: ietfHardwareAdminState(device.AdminState),
})
//Operative state
result = append(result, YangItem{
- Path: fmt.Sprintf("%s/state/oper-state", hardwarePath),
+ Path: hardwarePath + "/state/oper-state",
Value: ietfHardwareOperState(device.OperStatus),
})
return result
}
-//translateDevices returns a slice of yang items that represent a list of voltha devices
-func translateDevices(devices voltha.Devices) []YangItem {
+//translateOnuPorts returns a slice of yang items that represent the UNIs of an ONU
+func translateOnuPorts(deviceId string, ports *voltha.Ports) ([]YangItem, error) {
+ interfacesPath := getDevicePath(deviceId) + "/data/ietf-interfaces:interfaces"
result := []YangItem{}
- for _, device := range devices.Items {
- result = append(result, translateDevice(*device)...)
+ for _, port := range ports.Items {
+ if port.Type == voltha.Port_ETHERNET_UNI {
+ if port.OfpPort == nil {
+ return nil, fmt.Errorf("no-ofp-port-in-uni: %s %d", deviceId, port.PortNo)
+ }
+
+ interfacePath := fmt.Sprintf("%s/interface[name='%s']", interfacesPath, port.OfpPort.Name)
+
+ result = append(result, []YangItem{
+ {
+ Path: interfacePath + "/type",
+ Value: "bbf-xpon-if-type:onu-v-vrefpoint",
+ },
+ {
+ Path: interfacePath + "/oper-status",
+ Value: ietfInterfacesOperState(port.OperStatus),
+ },
+ }...)
+ }
}
- return result
+ return result, nil
+}
+
+//TranslateOnuActivatedEvent returns a slice of yang items and the name of the channel termination to populate
+//an ONU discovery notification with data from ONU_ACTIVATED_RAISE_EVENT coming from the Kafka bus
+func TranslateOnuActivatedEvent(eventHeader *voltha.EventHeader, deviceEvent *voltha.DeviceEvent) (notification []YangItem, channelTermination []YangItem, err error) {
+
+ //TODO: the use of this notification, which requires the creation of a dummy channel termination node,
+ //is temporary, and will be substituted with a more fitting one as soon as it will be defined
+
+ //Check if the needed information is present
+ ponId, ok := deviceEvent.Context[eventContextKeyPonId]
+ if !ok {
+ return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyPonId)
+ }
+ oltId, ok := deviceEvent.Context[eventContextKeyOltSn]
+ if !ok {
+ return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyPonId)
+ }
+ ponName := oltId + "-pon-" + ponId
+
+ onuSn, ok := deviceEvent.Context[eventContextKeyOnuSn]
+ if !ok {
+ return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyOnuSn)
+ }
+
+ notificationPath := "/bbf-xpon-onu-states:onu-state-change"
+
+ notification = []YangItem{
+ {
+ Path: notificationPath + "/detected-serial-number",
+ Value: onuSn,
+ },
+ {
+ Path: notificationPath + "/channel-termination-ref",
+ Value: ponName,
+ },
+ {
+ Path: notificationPath + "/onu-state-last-change",
+ Value: eventHeader.RaisedTs.AsTime().Format(time.RFC3339),
+ },
+ {
+ Path: notificationPath + "/onu-state",
+ Value: "bbf-xpon-onu-types:onu-present",
+ },
+ {
+ Path: notificationPath + "/detected-registration-id",
+ Value: deviceEvent.ResourceId,
+ },
+ }
+
+ channelTermination = []YangItem{
+ {
+ Path: fmt.Sprintf("/ietf-interfaces:interfaces/interface[name='%s']/type", ponName),
+ Value: "bbf-if-type:vlan-sub-interface",
+ },
+ }
+
+ return notification, channelTermination, nil
}