Skip to content
Snippets Groups Projects
store.go 2.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • package nucleus
    
    import (
    	"github.com/google/uuid"
    
    	log "github.com/sirupsen/logrus"
    	"reflect"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"sync"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    var storeLock sync.RWMutex
    
    
    // Storable provides an interface for the controller's storage architecture.
    
    type Storable interface {
    
    	ID() uuid.UUID
    
    }
    
    type store map[uuid.UUID]Storable
    
    func (s store) exists(id uuid.UUID) bool {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.RLock()
    	defer storeLock.RUnlock()
    
    	_, ok := s[id]
    	return ok
    }
    
    func (s store) add(item Storable) error {
    
    	if s.exists(item.ID()) {
    
    		return &ErrAlreadyExists{item: item}
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.Lock()
    
    	s[item.ID()] = item
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.Unlock()
    
    	log.WithFields(log.Fields{
    		"type": reflect.TypeOf(item),
    
    		"uuid": item.ID(),
    
    	}).Info("storable was added")
    
    	return nil
    }
    
    func (s store) get(id uuid.UUID) (Storable, error) {
    	if !s.exists(id) {
    		return nil, &ErrNotFound{id: id}
    	}
    
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Info("storable was accessed")
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.RLock()
    	defer storeLock.RUnlock()
    
    	return s[id], nil
    }
    
    func (s store) delete(id uuid.UUID) error {
    	if !s.exists(id) {
    		return &ErrNotFound{id: id}
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.Lock()
    
    	delete(s, id)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.Unlock()
    
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Info("storable has been deleted")
    
    	return nil
    }
    
    func (s store) UUIDs() []uuid.UUID {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	storeLock.RLock()
    	defer storeLock.RUnlock()
    
    	keys := make([]uuid.UUID, len(s))
    	i := 0
    	for k := range s {
    		keys[i] = k
    		i++
    	}
    	return keys
    }
    
    type sbiStore struct {
    	store
    }
    
    func (s sbiStore) get(id uuid.UUID) (SouthboundInterface, error) {
    	item, err := s.store.get(id)
    	if err != nil {
    		return nil, err
    	}
    	sbi, ok := item.(SouthboundInterface)
    	if !ok {
    		return nil, &ErrInvalidTypeAssertion{
    			v: sbi,
    			t: "SouthboundInterface",
    		}
    	}
    
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Info("southbound interface was accessed")
    
    	return sbi, nil
    }
    
    type pndStore struct {
    	store
    }
    
    func (s pndStore) get(id uuid.UUID) (PrincipalNetworkDomain, error) {
    	item, err := s.store.get(id)
    	if err != nil {
    		return nil, err
    	}
    	pnd, ok := item.(PrincipalNetworkDomain)
    	if !ok {
    		return nil, &ErrInvalidTypeAssertion{
    			v: pnd,
    			t: "PrincipalNetworkDomain",
    		}
    	}
    
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Info("principal network domain was accessed")
    
    	return pnd, nil
    }
    
    type deviceStore struct {
    	store
    }
    
    func (s deviceStore) get(id uuid.UUID) (*Device, error) {
    	item, err := s.store.get(id)
    	if err != nil {
    		return nil, err
    	}
    	device, ok := item.(*Device)
    	if !ok {
    		return nil, &ErrInvalidTypeAssertion{
    			v: device,
    			t: "Device",
    		}
    	}
    
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Info("device was accessed")
    
    	return device, nil
    }