Skip to content
Snippets Groups Projects
pndFilesystemStore.go 5.42 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	"context"
    
    Andre Sterba's avatar
    Andre Sterba committed
    	"os"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/plugin"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    	"github.com/google/uuid"
    	log "github.com/sirupsen/logrus"
    )
    
    // FilesystemPndStore provides a filesystem implementation for a pnd store.
    type FilesystemPndStore struct {
    
    	pendingChannels map[uuid.UUID]chan networkelement.Details
    	pluginService   plugin.Service
    	// csbiClient      cpb.CsbiServiceClient
    	pathToPndFile string
    	fileMutex     sync.Mutex
    
    }
    
    // NewFilesystemPndStore returns a filesystem implementation for a pnd store.
    
    func NewFilesystemPndStore(pluginService plugin.Service) FilesystemPndStore {
    
    	if err := store.EnsureFilesystemStorePathExists(store.PndFilename); err != nil {
    		log.Error(err)
    	}
    
    
    	return FilesystemPndStore{
    
    		pendingChannels: make(map[uuid.UUID]chan networkelement.Details),
    
    		pathToPndFile:   store.GetCompletePathToFileStore(store.PndFilename),
    
    		fileMutex:       sync.Mutex{},
    
    func (t *FilesystemPndStore) readAllPndsFromFile() ([]networkdomain.LoadedPnd, error) {
    	var loadedPnds []networkdomain.LoadedPnd
    
    Andre Sterba's avatar
    Andre Sterba committed
    	content, err := os.ReadFile(t.pathToPndFile)
    
    	if err != nil {
    		return nil, err
    	}
    
    	err = json.Unmarshal(content, &loadedPnds)
    	if err != nil {
    		return nil, err
    	}
    
    	pnds := make([]networkdomain.NetworkDomain, len(loadedPnds))
    
    
    	// csbiClient, err := t.getCsbiClient()
    	// if err != nil {
    	// 	return nil, err
    	// }
    
    	for i, loadedPND := range loadedPnds {
    
    		pndUUID, err := uuid.Parse(loadedPND.ID)
    		if err != nil {
    			return nil, err
    		}
    
    			loadedPND.Name,
    			loadedPND.Description,
    		)
    
    		pnds[i] = newPnd
    	}
    
    func (t *FilesystemPndStore) writeAllPndsToFile(pnds []networkdomain.LoadedPnd) error {
    
    	serializedData, err := json.Marshal(pnds)
    	if err != nil {
    		return err
    	}
    
    
    Andre Sterba's avatar
    Andre Sterba committed
    	err = os.WriteFile(t.pathToPndFile, serializedData, 0600)
    
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Add a pnd to the store.
    
    func (t *FilesystemPndStore) Add(ctx context.Context, pndToAdd networkdomain.NetworkDomain) error {
    
    	t.fileMutex.Lock()
    	defer t.fileMutex.Unlock()
    
    	pnds, err := t.readAllPndsFromFile()
    	if err != nil {
    		return err
    	}
    
    
    	var loadedPnd networkdomain.LoadedPnd
    	loadedPnd, err = store.TransformObjectToLoadedObject[networkdomain.NetworkDomain, networkdomain.LoadedPnd](pndToAdd)
    	if err != nil {
    		return err
    	}
    
    	pnds = append(pnds, loadedPnd)
    
    
    	err = t.writeAllPndsToFile(pnds)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Delete deletes a pnd from the store.
    
    func (t *FilesystemPndStore) Delete(ctx context.Context, pndToDelete networkdomain.NetworkDomain) error {
    
    	t.fileMutex.Lock()
    	defer t.fileMutex.Unlock()
    
    	pnds, err := t.readAllPndsFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, pnd := range pnds {
    
    		if pnd.ID == pndToDelete.ID().String() {
    
    			//remove item from slice
    			pnds[i] = pnds[len(pnds)-1]
    			pnds = pnds[:len(pnds)-1]
    
    			err = t.writeAllPndsToFile(pnds)
    			if err != nil {
    				return err
    			}
    
    			return nil
    		}
    	}
    
    
    	return &customerrs.CouldNotDeleteError{Identifier: pndToDelete.ID(), Type: pndToDelete, Err: err}
    
    }
    
    // Get provides a the query interface to find a stored pnd.
    
    func (t *FilesystemPndStore) Get(ctx context.Context, query store.Query) (networkdomain.LoadedPnd, error) {
    
    	t.fileMutex.Lock()
    	defer t.fileMutex.Unlock()
    
    
    	var loadedPND networkdomain.LoadedPnd
    
    
    	pnds, err := t.readAllPndsFromFile()
    	if err != nil {
    
    		if pnd.ID == query.ID.String() || pnd.Name == query.Name {
    
    	return loadedPND, &customerrs.CouldNotFindError{ID: query.ID, Name: query.Name}
    
    }
    
    // GetAll returns all pnds currently on the store.
    
    func (t *FilesystemPndStore) GetAll(ctx context.Context) ([]networkdomain.LoadedPnd, error) {
    
    	t.fileMutex.Lock()
    	defer t.fileMutex.Unlock()
    
    	pnds, err := t.readAllPndsFromFile()
    
    	return pnds, err
    }
    
    // PendingChannels holds channels used communicate with pending
    
    func (t *FilesystemPndStore) PendingChannels(id uuid.UUID, parseErrors ...error) (chan networkelement.Details, error) {
    
    	ch, ok := t.pendingChannels[id]
    	if !ok {
    
    // AddPendingChannel adds a pending channel to the map.
    
    func (t *FilesystemPndStore) AddPendingChannel(id uuid.UUID, ch chan networkelement.Details) {
    
    // RemovePendingChannel removes a pending channel from the map.
    
    func (t *FilesystemPndStore) RemovePendingChannel(id uuid.UUID) {
    	delete(t.pendingChannels, id)
    }
    
    
    // func (t *FilesystemPndStore) callback(id uuid.UUID, ch chan networkelement.Details) {
    // 	if ch != nil {
    // 		t.AddPendingChannel(id, ch)
    // 		log.Infof("pending channel %v added", id)
    // 	} else {
    // 		t.RemovePendingChannel(id)
    // 		log.Infof("pending channel %v removed", id)
    // 	}
    // }
    
    // func (t *FilesystemPndStore) getCsbiClient() (cpb.CsbiServiceClient, error) {
    // 	if t.csbiClient == nil {
    // 		orchestrator := viper.GetString("csbi-orchestrator")
    // 		conn, err := grpc.Dial(orchestrator, grpc.WithTransportCredentials(insecure.NewCredentials()))
    // 		if err != nil {
    // 			return nil, err
    // 		}
    
    // 		t.csbiClient = cpb.NewCsbiServiceClient(conn)
    // 	}
    
    // 	return t.csbiClient, nil
    // }