Newer
Older
package topology
import (
Fabian Seidl
committed
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
query "code.fbi.h-da.de/danet/gosdn/controller/store"
"code.fbi.h-da.de/danet/gosdn/controller/topology/links"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// Store defines a Topology store interface.
type Store interface {
Add(context.Context, links.Link) error
Update(context.Context, links.Link) error
Delete(context.Context, links.Link) error
Get(context.Context, query.Query) (links.Link, error)
GetAll(context.Context) ([]links.Link, error)
// DatabaseTopologyStore is a database store for the topology.
type DatabaseTopologyStore struct {
// NewDatabaseTopologyStore returns a TopologyStore.
func NewDatabaseTopologyStore(db *mongo.Database) Store {
collection := db.Collection(storeName)
return &DatabaseTopologyStore{
}
}
// Get takes a link's UUID or name and returns the link.
func (s *DatabaseTopologyStore) Get(ctx context.Context, query query.Query) (links.Link, error) {
var loadedTopology links.Link
if query.ID.String() != "" {
loadedTopology, err := s.getByID(ctx, query.ID)
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotFindError{ID: query.ID, Name: query.Name}
}
return loadedTopology, nil
}
loadedTopology, err := s.getByName(ctx, query.Name)
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotFindError{ID: query.ID, Name: query.Name}
}
return loadedTopology, nil
}
func (s *DatabaseTopologyStore) getByID(ctx context.Context, idOfTopology uuid.UUID) (loadedTopology links.Link, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfTopology}})
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotFindError{ID: idOfTopology}
err = result.Decode(&loadedTopology)
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotMarshallError{Identifier: idOfTopology, Type: loadedTopology, Err: err}
}
return loadedTopology, nil
}
func (s *DatabaseTopologyStore) getByName(ctx context.Context, nameOfTopology string) (loadedTopology links.Link, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: nameOfTopology}})
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotFindError{Name: nameOfTopology}
err = result.Decode(&loadedTopology)
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotMarshallError{Identifier: nameOfTopology, Type: loadedTopology, Err: err}
}
return loadedTopology, nil
}
// GetAll returns all stored links.
func (s *DatabaseTopologyStore) GetAll(ctx context.Context) (loadedTopology []links.Link, err error) {
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return loadedTopology, err
}
defer func() {
if ferr := cursor.Close(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
err = cursor.All(ctx, &loadedTopology)
if err != nil {
Fabian Seidl
committed
return loadedTopology, customerrs.CouldNotMarshallError{Type: loadedTopology, Err: err}
}
return loadedTopology, nil
}
// Add adds a link to the link store.
func (s *DatabaseTopologyStore) Add(ctx context.Context, link links.Link) (err error) {
_, err = s.collection.
InsertOne(ctx, link)
if err != nil {
Fabian Seidl
committed
return customerrs.CouldNotCreateError{Identifier: link.ID, Type: link, Err: err}
}
return nil
}
// Update updates a existing link.
func (s *DatabaseTopologyStore) Update(ctx context.Context, linkToUpdate links.Link) (err error) {
var updatedLink links.Link
update := bson.D{primitive.E{Key: "$set", Value: linkToUpdate}}
upsert := false
after := options.After
opt := options.FindOneAndUpdateOptions{
Upsert: &upsert,
ReturnDocument: &after,
}
ctx, bson.M{"_id": linkToUpdate.ID}, update, &opt).
Decode(&updatedLink)
if err != nil {
Fabian Seidl
committed
return customerrs.CouldNotUpdateError{Identifier: linkToUpdate.ID, Type: linkToUpdate, Err: err}
}
return nil
}
// Delete deletes a link from the link store.
func (s *DatabaseTopologyStore) Delete(ctx context.Context, linkToDelete links.Link) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: linkToDelete.ID}})
if err != nil {
return err
}
return nil
}