Skip to content
Snippets Groups Projects
networkElementFilesystemStore.go 4.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	"context"
    
    	"encoding/json"
    	"os"
    	"sync"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    	log "github.com/sirupsen/logrus"
    )
    
    // FilesystemNetworkElementStore is the filesystem implementation of the network element store.
    type FilesystemNetworkElementStore struct {
    	fileMutex                sync.Mutex
    	pathToNetworkElementFile string
    }
    
    // NewFilesystemNetworkElementStore returns a filesystem implementation for a pnd store.
    
    func NewFilesystemNetworkElementStore() networkelement.Store {
    	if err := store.EnsureFilesystemStorePathExists(store.NetworkElementFilenameSuffix); err != nil {
    
    		log.Error(err)
    	}
    	return &FilesystemNetworkElementStore{
    
    		pathToNetworkElementFile: store.GetCompletePathToFileStore(store.NetworkElementFilenameSuffix),
    
    		fileMutex:                sync.Mutex{},
    	}
    }
    
    func (s *FilesystemNetworkElementStore) readAllNetworkElementsFromFile() ([]networkelement.LoadedNetworkElement, error) {
    	var loadedNetworkElements []networkelement.LoadedNetworkElement
    
    	content, err := os.ReadFile(s.pathToNetworkElementFile)
    	if err != nil {
    		return nil, err
    	}
    
    	err = json.Unmarshal(content, &loadedNetworkElements)
    	if err != nil {
    		return nil, err
    	}
    
    	return loadedNetworkElements, nil
    }
    
    func (s *FilesystemNetworkElementStore) writeAllNetworkElementsToFile(mnes []networkelement.LoadedNetworkElement) error {
    	serializedData, err := json.Marshal(mnes)
    	if err != nil {
    		return err
    	}
    
    	err = os.WriteFile(s.pathToNetworkElementFile, serializedData, 0600)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Get takes a network element's UUID or name and returns the network element.
    
    func (s *FilesystemNetworkElementStore) Get(ctx context.Context, query store.Query) (networkelement.LoadedNetworkElement, error) {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	var lMNE networkelement.LoadedNetworkElement
    
    	mnes, err := s.readAllNetworkElementsFromFile()
    	if err != nil {
    		return lMNE, err
    	}
    
    	for _, mne := range mnes {
    		if mne.ID == query.ID.String() || mne.Name == query.Name {
    			return mne, nil
    		}
    	}
    
    	return lMNE, &customerrs.CouldNotFindError{ID: query.ID, Name: query.Name}
    }
    
    // GetAll returns all stored network elements.
    
    func (s *FilesystemNetworkElementStore) GetAll(ctx context.Context) ([]networkelement.LoadedNetworkElement, error) {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	mnes, err := s.readAllNetworkElementsFromFile()
    
    	return mnes, err
    }
    
    // Add adds a network element to the network element store.
    
    func (s *FilesystemNetworkElementStore) Add(ctx context.Context, networkElementToAdd networkelement.NetworkElement) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	mnes, err := s.readAllNetworkElementsFromFile()
    	if err != nil {
    		return err
    	}
    
    	var loadedNetworkElement networkelement.LoadedNetworkElement
    	loadedNetworkElement, err = store.TransformObjectToLoadedObject[networkelement.NetworkElement, networkelement.LoadedNetworkElement](networkElementToAdd)
    	if err != nil {
    		return err
    	}
    
    	mnes = append(mnes, loadedNetworkElement)
    
    	err = s.writeAllNetworkElementsToFile(mnes)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Update updates a existing network element.
    
    func (s *FilesystemNetworkElementStore) Update(ctx context.Context, networkElementToUpdate networkelement.NetworkElement) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	loadedNetworkElementToUpdate, err := store.TransformObjectToLoadedObject[networkelement.NetworkElement, networkelement.LoadedNetworkElement](networkElementToUpdate)
    	if err != nil {
    		return err
    	}
    
    	mnes, err := s.readAllNetworkElementsFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, mne := range mnes {
    		if mne.ID == networkElementToUpdate.ID().String() {
    			mnes[i] = loadedNetworkElementToUpdate
    			err = s.writeAllNetworkElementsToFile(mnes)
    			if err != nil {
    				return err
    			}
    			return nil
    		}
    	}
    
    	return &customerrs.CouldNotUpdateError{Identifier: networkElementToUpdate.ID(), Type: networkElementToUpdate, Err: err}
    }
    
    // Delete deletes a network element from the network element store.
    
    func (s *FilesystemNetworkElementStore) Delete(ctx context.Context, networkElementToDelete networkelement.NetworkElement) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	mnes, err := s.readAllNetworkElementsFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, mne := range mnes {
    		if mne.ID == networkElementToDelete.ID().String() {
    			//remove item from slice
    			mnes[i] = mnes[len(mnes)-1]
    			mnes = mnes[:len(mnes)-1]
    
    			err = s.writeAllNetworkElementsToFile(mnes)
    			if err != nil {
    				return err
    			}
    
    			return nil
    		}
    	}
    
    	return &customerrs.CouldNotDeleteError{Identifier: networkElementToDelete.ID(), Type: networkElementToDelete, Err: err}
    }