Skip to content
Snippets Groups Projects
Commit 360f9fb6 authored by André Sterba's avatar André Sterba
Browse files

Move lookup table into device store

parent 6aacafa6
No related branches found
No related tags found
1 merge request!150Let user set a name for a device or autogenerate it
Pipeline #72272 passed with warnings
......@@ -172,15 +172,10 @@ func httpApi(writer http.ResponseWriter, request *http.Request) {
case "getDevice":
deviceIdentifier := query.Get("identifier")
// TODO: Think about something better than this.
// deviceIdentifier can be a uuid or a string.
// Because of that we check at first if the parsed uuid is 00000000-0000-0000-0000-000000000000.
// If yes it was not a valid uuid and it must be a device name.
// If not we check if the provided identifier should be a device UUID and we search for a uuid.
id, _ := uuid.Parse(deviceIdentifier)
idAsString := id.String()
// id, _ := uuid.Parse(deviceIdentifier)
// idAsString := id.String()
if idAsString == "00000000-0000-0000-0000-000000000000" {
// if idAsString == "00000000-0000-0000-0000-000000000000" {
device, err := httpPnd.MarshalDevice(deviceIdentifier)
if err != nil {
switch err.(type) {
......@@ -197,23 +192,6 @@ func httpApi(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Content-Type", "application/json")
fmt.Fprintf(writer, "%v", device)
} else {
device, err := httpPnd.MarshalDevice(id)
if err != nil {
switch err.(type) {
case *errors.ErrNotFound:
writer.WriteHeader(http.StatusNotFound)
default:
writer.WriteHeader(http.StatusInternalServerError)
}
log.Error(err)
return
}
writer.Header().Set("Content-Type", "application/json")
fmt.Fprintf(writer, "%v", device)
}
case "getIDs":
pnds := c.pndc.UUIDs()
......
......@@ -41,6 +41,14 @@ func (e *ErrAlreadyExists) Error() string {
return fmt.Sprintf("%v already exists", e.Item)
}
// ErrNoValidUUID implements the Error interface and is called if a UUID is not valid.
type ErrNoValidUUID struct {
}
func (e *ErrNoValidUUID) Error() string {
return fmt.Sprintf("UUID not valid")
}
// ErrInvalidTypeAssertion implements the Error interface and is called if the
// type of a storable item does not correspond to the expected type.
type ErrInvalidTypeAssertion struct {
......
......@@ -31,7 +31,7 @@ type PrincipalNetworkDomain interface {
RequestAll(string) error
GetName() string
GetDescription() string
MarshalDevice(interface{}) (string, error)
MarshalDevice(string) (string, error)
MarshalDeviceByName(name string) (string, error)
ContainsDevice(uuid.UUID) bool
GetSBIs() interface{}
......@@ -48,7 +48,7 @@ func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (Pr
name: name,
description: description,
sbic: SbiStore{store{}},
devices: DeviceStore{store{}},
devices: NewDeviceStore(),
pendingChanges: ChangeStore{store{}},
committedChanges: ChangeStore{store{}},
confirmedChanges: ChangeStore{store{}},
......@@ -66,7 +66,7 @@ type pndImplementation struct {
name string
description string
sbic SbiStore
devices DeviceStore
devices *DeviceStore
pendingChanges ChangeStore
committedChanges ChangeStore
confirmedChanges ChangeStore
......@@ -188,7 +188,7 @@ func (pnd *pndImplementation) AddDevice(device interface{}) error {
}
func (pnd *pndImplementation) GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) {
d, err := pnd.devices.Get(uuid)
d, err := pnd.devices.Get(FromString(uuid.String()))
if err != nil {
return nil, err
}
......@@ -215,7 +215,7 @@ func (pnd *pndImplementation) removeSbi(id uuid.UUID) error {
}
func (pnd *pndImplementation) addDevice(device *Device) error {
err := pnd.devices.Add(device)
err := pnd.devices.Add(device, device.Name)
if err != nil {
return err
}
......@@ -226,39 +226,44 @@ func (pnd *pndImplementation) addDevice(device *Device) error {
}
func (pnd *pndImplementation) getDeviceByUUID(id uuid.UUID) (*Device, error) {
return pnd.devices.Get(id)
return pnd.devices.Get(FromString("wasd"))
}
func (pnd *pndImplementation) getDeviceByName(name string) (*Device, error) {
deviceUUID, found := pnd.deviceNameToUUIDLookup[name]
if !found {
return nil, &errors.ErrNotFound{ID: name}
}
return pnd.devices.Get(deviceUUID)
// deviceUUID, found := pnd.deviceNameToUUIDLookup[name]
// if !found {
// return nil, &errors.ErrNotFound{ID: name}
// }
return pnd.devices.Get(FromString("wasd"))
}
func (pnd *pndImplementation) removeDevice(id uuid.UUID) error {
return pnd.devices.Delete(id)
}
func (pnd *pndImplementation) MarshalDevice(identifier interface{}) (string, error) {
var foundDevice *Device
var err error
func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) {
// var foundDevice *Device
// var err error
switch id := identifier.(type) {
case uuid.UUID:
foundDevice, err = pnd.getDeviceByUUID(id)
if err != nil {
return "", err
}
case string:
foundDevice, err = pnd.getDeviceByName(id)
foundDevice, err := pnd.devices.Get(FromString(identifier))
if err != nil {
return "", err
}
default:
return "", &errors.ErrNotFound{ID: identifier}
}
// switch id := identifier.(type) {
// case uuid.UUID:
// foundDevice, err = pnd.getDeviceByUUID(id)
// if err != nil {
// return "", err
// }
// case string:
// foundDevice, err = pnd.getDeviceByName(id)
// if err != nil {
// return "", err
// }
// default:
// return "", &errors.ErrNotFound{ID: identifier}
// }
jsonTree, err := json.MarshalIndent(foundDevice.GoStruct, "", "\t")
if err != nil {
......
package nucleus
import (
"fmt"
"reflect"
"sync"
......@@ -43,7 +44,7 @@ func NewSbiStore() *SbiStore {
// NewDeviceStore returns a DeviceStore
func NewDeviceStore() *DeviceStore {
return &DeviceStore{store{}}
return &DeviceStore{store: store{}, deviceNameToUUIDLookup: make(map[string]uuid.UUID)}
}
// NewChangeStore returns a ChangeStore
......@@ -170,13 +171,38 @@ func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) {
// DeviceStore is used to store Devices
type DeviceStore struct {
deviceNameToUUIDLookup map[string]uuid.UUID
store
}
// Get takes a Device's UUID and returns the Device. If the requested
// Device does not exist an error is returned.
func (s DeviceStore) Get(id uuid.UUID) (*Device, error) {
item, err := s.store.Get(id)
func (s DeviceStore) Get(id uuid.UUID, idAsString string, parseErrors ...error) (*Device, error) {
log.Debug(fmt.Sprintf("Devicestore: %+v", s.store))
log.Debug(fmt.Sprintf("deviceNameToUUIDLookup: %+v", s.deviceNameToUUIDLookup))
log.Debug(fmt.Sprintf("Errors: %+v", parseErrors))
log.Debug(fmt.Sprintf("Length Errors: %+v", len(parseErrors)))
var foundID uuid.UUID
foundID = id
for _, parseErrs := range parseErrors {
if parseErrs != nil {
log.Debug("lookup device")
log.Debug(fmt.Sprint(idAsString))
myID, ok := s.deviceNameToUUIDLookup[idAsString]
if !ok {
log.Debug("no device found")
return nil, &errors.ErrNotFound{}
}
foundID = myID
}
}
item, err := s.store.Get(foundID)
if err != nil {
return nil, err
}
......@@ -191,9 +217,67 @@ func (s DeviceStore) Get(id uuid.UUID) (*Device, error) {
"uuid": id,
"name": device.Name,
}).Debug("device was accessed")
return device, nil
}
func FromString(id string) (uuid.UUID, string, error) {
idAsUUID, _ := uuid.Parse(id)
// id is no UUID therefore check if it is name registered in the lookup table.
if idAsUUID.String() == "00000000-0000-0000-0000-000000000000" {
return uuid.Nil, id, &errors.ErrNoValidUUID{}
}
return idAsUUID, id, nil
}
// id := uuid.New()
// Get(id)
// stringId := id.String()
// Get(FromString(stringId))
func (s DeviceStore) Add(item Storable, name string) error {
if s.Exists(item.ID()) {
return &errors.ErrAlreadyExists{Item: item}
}
s.deviceNameToUUIDLookup[name] = item.ID()
storeLock.Lock()
s.store[item.ID()] = item
storeLock.Unlock()
log.WithFields(log.Fields{
"type": reflect.TypeOf(item),
"uuid": item.ID(),
}).Debug("storable was added")
return nil
}
func (s DeviceStore) Delete(id uuid.UUID) error {
if !s.Exists(id) {
return &errors.ErrNotFound{ID: id}
}
storeLock.Lock()
delete(s.store, id)
storeLock.Unlock()
for key, value := range s.deviceNameToUUIDLookup {
if value == id {
delete(s.deviceNameToUUIDLookup, key)
}
}
log.WithFields(log.Fields{
"uuid": id,
}).Debug("storable was deleted")
return nil
}
// ChangeStore is used to store Changes
type ChangeStore struct {
store
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment