Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 111-cli-expansion-stateful-behaviour-more-command-feedback
  • 120-integration-tests-fail
  • 138-making-gnmi-response-processing-more-error-tolerable
  • 140-refactor-pipelines
  • 156-a-setrequest-to-change-a-specific-path-of-an-ond-only-works-for-paths-with-string-values
  • 186-creating-a-device-based-on-plugin-or-csbi-is-not-possible
  • 195-requesting-changes-does-not-work-in-storemode-database
  • 223-database-pnd-store-is-missing-option-to-search-by-name
  • 225-adding-support-and-visualization-for-the-test-coverage2
  • 233-structs-like-loadeddevice-loadedsbi-loadedrole-loadeduser-are-never-passed-as-pointer
  • 242-improve-security-by-enabling-and-enforcing-more-linting-rules
  • 242-improve-security-by-enabling-and-enforcing-more-linting-rules-govet
  • 246-implement-our-own-version-to-send-gnmi-requests
  • 258-deal-with-read-only-fields-in-yang
  • 282-refactoring-of-the-current-test-setup
  • 289-quantum-safe-communication-between-rabbitmq-and-sdn-controller
  • 291-lab-vm-for-arm64-apple
  • 296-related-existing-work-about-change-logic-for-yang-models
  • 320-deadline-and-cancellation-for-grpc-calls
  • 336-add-error-handling-for-mne-watching-if-the-provided-paths-do-not-exist
  • 349-integration-test-for-lab01
  • 350-applying-a-sdn-configuration-should-also-update-the-internal-configuration-of-managed-network
  • 351-link-shadowing-of-global-variables
  • 383-re-organize-comands-in-cli
  • 392-remove-renovate
  • PSD_VGU_Logging
  • add-backup-script
  • add-dockerignore
  • add-script-with-docker-stats
  • add-sr-linux-yang-models
  • add-support-for-mtls-in-plugins
  • allow-slashes-in-branch-names
  • arm-build
  • bump-ygot-generator-to-0-0-5
  • check-unit-tests
  • ci-refactor-1337
  • cli-docs
  • create-health-check-api
  • custom-marshal-for-grpc-gateway
  • deployment-docker-compose
  • develop
  • docker-build-cache-experiments
  • fbi1478-master-patch-42436
  • fix-docker-registry-error
  • fix-linting-in-makefile
  • fix-viper
  • go-plugin-playground
  • gosdn-storage-cleanup
  • heiss_bachelor_thesis
  • hotfix-unique-list-error-from-a-device-get-request
  • integration-test-pipeline-fix
  • inventory-manager-netbox
  • istaester/add-git-hooks
  • istaester/architecture-figures
  • istaester/basic-persistance-layer
  • istaester/bump-ygot-version
  • istaester/cli-tests
  • istaester/db
  • istaester/handle-makefile-in-editorconfig
  • istaester/init-monorepo
  • istaester/plugin-registry
  • istaester/provide-pnd-service
  • istaester/tooling
  • istaester/update-readme
  • master
  • mb/plugin-registry
  • mk/benchmark-stores
  • mpsd-at-vgu
  • neil/cobra-tests
  • new-integration-test-setup-v1
  • profile
  • proto-getters
  • recursive-read-only-try-1337
  • registry-used-by-app
  • remove-stuff
  • renovate/babel-runtime-7.x-lockfile
  • renovate/buf.build-gen-go-bufbuild-protovalidate-protocolbuffers-go-1.x
  • renovate/dompurify-3.x-lockfile
  • renovate/eslint-9.x-lockfile
  • renovate/eslint-plugin-prettier-5.x-lockfile
  • renovate/eslint-plugin-react-7.x-lockfile
  • renovate/eslint-plugin-react-hooks-5.x-lockfile
  • renovate/eslint-plugin-react-refresh-0.x-lockfile
  • renovate/fortawesome-fontawesome-svg-core-6.x-lockfile
  • renovate/fortawesome-free-regular-svg-icons-6.x-lockfile
  • renovate/fortawesome-free-solid-svg-icons-6.x-lockfile
  • renovate/github.com-aristanetworks-goarista-digest
  • renovate/github.com-bufbuild-protovalidate-go-0.x
  • renovate/github.com-docker-docker-27.x
  • renovate/github.com-docker-docker-28.x
  • renovate/github.com-grpc-ecosystem-grpc-gateway-v2-2.x
  • renovate/github.com-hashicorp-go-plugin-1.x
  • renovate/github.com-lesismal-nbio-1.x
  • renovate/github.com-openconfig-gnmi-0.x
  • renovate/github.com-prometheus-client_golang-1.x
  • renovate/go.mongodb.org-mongo-driver-2.x
  • renovate/golangci-golangci-lint-1.x
  • renovate/google.golang.org-genproto-googleapis-api-digest
  • renovate/react-18.x-lockfile
  • renovate/react-bootstrap-2.x-lockfile
  • 0.1.0
101 results

Target

Select target project
  • danet/gosdn
1 result
Select Git revision
  • 111-cli-expansion-stateful-behaviour-more-command-feedback
  • 120-integration-tests-fail
  • 138-making-gnmi-response-processing-more-error-tolerable
  • 140-refactor-pipelines
  • 156-a-setrequest-to-change-a-specific-path-of-an-ond-only-works-for-paths-with-string-values
  • 186-creating-a-device-based-on-plugin-or-csbi-is-not-possible
  • 195-requesting-changes-does-not-work-in-storemode-database
  • 223-database-pnd-store-is-missing-option-to-search-by-name
  • 225-adding-support-and-visualization-for-the-test-coverage2
  • 233-structs-like-loadeddevice-loadedsbi-loadedrole-loadeduser-are-never-passed-as-pointer
  • 242-improve-security-by-enabling-and-enforcing-more-linting-rules
  • 242-improve-security-by-enabling-and-enforcing-more-linting-rules-govet
  • 246-implement-our-own-version-to-send-gnmi-requests
  • 258-deal-with-read-only-fields-in-yang
  • 282-refactoring-of-the-current-test-setup
  • 289-quantum-safe-communication-between-rabbitmq-and-sdn-controller
  • 291-lab-vm-for-arm64-apple
  • 296-related-existing-work-about-change-logic-for-yang-models
  • 320-deadline-and-cancellation-for-grpc-calls
  • 336-add-error-handling-for-mne-watching-if-the-provided-paths-do-not-exist
  • 349-integration-test-for-lab01
  • 350-applying-a-sdn-configuration-should-also-update-the-internal-configuration-of-managed-network
  • 351-link-shadowing-of-global-variables
  • 383-re-organize-comands-in-cli
  • 392-remove-renovate
  • PSD_VGU_Logging
  • add-backup-script
  • add-dockerignore
  • add-script-with-docker-stats
  • add-sr-linux-yang-models
  • add-support-for-mtls-in-plugins
  • allow-slashes-in-branch-names
  • arm-build
  • bump-ygot-generator-to-0-0-5
  • check-unit-tests
  • ci-refactor-1337
  • cli-docs
  • create-health-check-api
  • custom-marshal-for-grpc-gateway
  • deployment-docker-compose
  • develop
  • docker-build-cache-experiments
  • fbi1478-master-patch-42436
  • fix-docker-registry-error
  • fix-linting-in-makefile
  • fix-viper
  • go-plugin-playground
  • gosdn-storage-cleanup
  • heiss_bachelor_thesis
  • hotfix-unique-list-error-from-a-device-get-request
  • integration-test-pipeline-fix
  • inventory-manager-netbox
  • istaester/add-git-hooks
  • istaester/architecture-figures
  • istaester/basic-persistance-layer
  • istaester/bump-ygot-version
  • istaester/cli-tests
  • istaester/db
  • istaester/handle-makefile-in-editorconfig
  • istaester/init-monorepo
  • istaester/plugin-registry
  • istaester/provide-pnd-service
  • istaester/tooling
  • istaester/update-readme
  • master
  • mb/plugin-registry
  • mk/benchmark-stores
  • mpsd-at-vgu
  • neil/cobra-tests
  • new-integration-test-setup-v1
  • profile
  • proto-getters
  • recursive-read-only-try-1337
  • registry-used-by-app
  • remove-stuff
  • renovate/babel-runtime-7.x-lockfile
  • renovate/buf.build-gen-go-bufbuild-protovalidate-protocolbuffers-go-1.x
  • renovate/dompurify-3.x-lockfile
  • renovate/eslint-9.x-lockfile
  • renovate/eslint-plugin-prettier-5.x-lockfile
  • renovate/eslint-plugin-react-7.x-lockfile
  • renovate/eslint-plugin-react-hooks-5.x-lockfile
  • renovate/eslint-plugin-react-refresh-0.x-lockfile
  • renovate/fortawesome-fontawesome-svg-core-6.x-lockfile
  • renovate/fortawesome-free-regular-svg-icons-6.x-lockfile
  • renovate/fortawesome-free-solid-svg-icons-6.x-lockfile
  • renovate/github.com-aristanetworks-goarista-digest
  • renovate/github.com-bufbuild-protovalidate-go-0.x
  • renovate/github.com-docker-docker-27.x
  • renovate/github.com-docker-docker-28.x
  • renovate/github.com-grpc-ecosystem-grpc-gateway-v2-2.x
  • renovate/github.com-hashicorp-go-plugin-1.x
  • renovate/github.com-lesismal-nbio-1.x
  • renovate/github.com-openconfig-gnmi-0.x
  • renovate/github.com-prometheus-client_golang-1.x
  • renovate/go.mongodb.org-mongo-driver-2.x
  • renovate/golangci-golangci-lint-1.x
  • renovate/google.golang.org-genproto-googleapis-api-digest
  • renovate/react-18.x-lockfile
  • renovate/react-bootstrap-2.x-lockfile
  • 0.1.0
101 results
Show changes
Showing
with 421 additions and 365 deletions
package app
import (
"fmt"
"context"
"log"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// ManagementStore is a store for apps.
type ManagementStore interface {
Add(App) error
Update(App) error
Delete(App) error
Get(store.Query) (App, error)
GetAll() ([]App, error)
Add(context.Context, App) error
Update(context.Context, App) error
Delete(context.Context, App) error
Get(context.Context, store.Query) (App, error)
GetAll(context.Context) ([]App, error)
}
const storeName = "app-store.json"
// Store stores registered apps.
type Store struct {
storeName string
collection *mongo.Collection
}
// NewAppStore returns a AppStore.
func NewAppStore() ManagementStore {
// NewDatabaseAppStore returns a AppStore.
func NewDatabaseAppStore(db *mongo.Database) ManagementStore {
collection := db.Collection(storeName)
return &Store{
storeName: "app-store.json",
collection: collection,
}
}
// Get takes a app's UUID or name and returns the app.
func (s *Store) Get(query store.Query) (App, error) {
func (s *Store) Get(ctx context.Context, query store.Query) (App, error) {
var loadedApp App
if query.ID.String() != "" && query.ID != uuid.Nil {
loadedApp, err := s.getByID(query.ID)
loadedApp, err := s.getByID(ctx, query.ID)
if err != nil {
return loadedApp, err
}
......@@ -48,7 +52,7 @@ func (s *Store) Get(query store.Query) (App, error) {
return loadedApp, nil
}
loadedApp, err := s.getByName(query.Name)
loadedApp, err := s.getByName(ctx, query.Name)
if err != nil {
return loadedApp, err
}
......@@ -56,22 +60,8 @@ func (s *Store) Get(query store.Query) (App, error) {
return loadedApp, nil
}
func (s *Store) getByID(appID uuid.UUID) (loadedApp App, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedApp, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: appID.String()}})
func (s *Store) getByID(ctx context.Context, appID uuid.UUID) (loadedApp App, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: appID.String()}})
if result == nil {
return loadedApp, customerrs.CouldNotFindError{ID: appID}
}
......@@ -85,22 +75,8 @@ func (s *Store) getByID(appID uuid.UUID) (loadedApp App, err error) {
return loadedApp, nil
}
func (s *Store) getByName(appName string) (loadedApp App, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedApp, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: appName}})
func (s *Store) getByName(ctx context.Context, appName string) (loadedApp App, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: appName}})
if result == nil {
return loadedApp, customerrs.CouldNotFindError{Name: appName}
}
......@@ -115,23 +91,8 @@ func (s *Store) getByName(appName string) (loadedApp App, err error) {
}
// GetAll returns all stored apps.
func (s *Store) GetAll() (loadedApps []App, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return nil, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
cursor, err := collection.Find(ctx, bson.D{})
func (s *Store) GetAll(ctx context.Context) (loadedApps []App, err error) {
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
......@@ -147,22 +108,8 @@ func (s *Store) GetAll() (loadedApps []App, err error) {
}
// Add adds a app to the app store.
func (s *Store) Add(app App) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
_, err = client.Database(database.DatabaseName).
Collection(s.storeName).
InsertOne(ctx, app)
func (s *Store) Add(ctx context.Context, app App) (err error) {
_, err = s.collection.InsertOne(ctx, app)
if err != nil {
log.Printf("Could not create app: %v", err)
return customerrs.CouldNotCreateError{Identifier: app.GetID(), Type: app, Err: err}
......@@ -172,21 +119,9 @@ func (s *Store) Add(app App) (err error) {
}
// Update updates a existing app.
func (s *Store) Update(app App) (err error) {
func (s *Store) Update(ctx context.Context, app App) (err error) {
var updatedApp App
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
update := bson.D{primitive.E{Key: "$set", Value: app}}
upsert := false
......@@ -196,10 +131,8 @@ func (s *Store) Update(app App) (err error) {
ReturnDocument: &after,
}
err = client.Database(database.DatabaseName).
Collection(s.storeName).
FindOneAndUpdate(
ctx, bson.M{"_id": app.GetID().String()}, update, &opt).
err = s.collection.FindOneAndUpdate(
ctx, bson.M{"_id": app.GetID().String()}, update, &opt).
Decode(&updatedApp)
if err != nil {
log.Printf("Could not update app: %v", err)
......@@ -211,22 +144,8 @@ func (s *Store) Update(app App) (err error) {
}
// Delete deletes a app from the app store.
func (s *Store) Delete(app App) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
_, err = collection.DeleteOne(ctx, bson.D{primitive.E{Key: app.GetID().String()}})
func (s *Store) Delete(ctx context.Context, app App) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: app.GetID().String()}})
if err != nil {
return customerrs.CouldNotDeleteError{Identifier: app.GetID().String(), Type: app, Err: err}
}
......
package app
import (
"context"
"fmt"
"code.fbi.h-da.de/danet/gosdn/controller/store"
......@@ -27,11 +28,12 @@ func NewAppService(store ManagementStore) ManagementService {
// Register checks if the app already exists and if not creates a new one.
func (a *Service) Register(appName, token string) (*App, error) {
ctx := context.Background()
if token != "SecurePresharedToken" {
return nil, fmt.Errorf("token not valid")
}
exisitingApp, err := a.store.Get(store.Query{ID: uuid.Nil, Name: appName})
exisitingApp, err := a.store.Get(ctx, store.Query{ID: uuid.Nil, Name: appName})
if err != nil {
if exisitingApp.ID == uuid.Nil {
return a.createNewApp(appName)
......@@ -45,12 +47,13 @@ func (a *Service) Register(appName, token string) (*App, error) {
// Deregister deregisters an app.
func (a *Service) Deregister(appName string) error {
app, err := a.store.Get(store.Query{Name: appName})
ctx := context.Background()
app, err := a.store.Get(ctx, store.Query{Name: appName})
if err != nil {
return err
}
err = a.store.Delete(app)
err = a.store.Delete(ctx, app)
if err != nil {
return err
}
......@@ -59,6 +62,7 @@ func (a *Service) Deregister(appName string) error {
}
func (a *Service) createNewApp(appName string) (*App, error) {
ctx := context.Background()
app := App{
ID: uuid.New(),
Name: appName,
......@@ -66,7 +70,7 @@ func (a *Service) createNewApp(appName string) (*App, error) {
}
// generate app credentials
err := a.store.Add(app)
err := a.store.Add(ctx, app)
if err != nil {
return nil, err
}
......
......@@ -10,11 +10,11 @@ type App struct {
}
// GetID returns the uuid of an app.
func (a *App) GetID() uuid.UUID {
func (a App) GetID() uuid.UUID {
return a.ID
}
// GetCredentials returns the credentials of an app.
func (a *App) GetCredentials() string {
func (a App) GetCredentials() string {
return a.EventSystemCredentials
}
package app
import (
"code.fbi.h-da.de/danet/gosdn/controller/store"
topoStore "code.fbi.h-da.de/danet/gosdn/controller/topology/store"
"go.mongodb.org/mongo-driver/mongo"
)
// NewAppStore returns a Topologytore.
func NewAppStore(db *mongo.Database) ManagementStore {
storeMode := store.GetStoreMode()
switch storeMode {
case store.Database:
return NewDatabaseAppStore(db)
default:
return topoStore.NewGenericStore[App]()
}
}
......@@ -30,6 +30,7 @@ import (
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
"code.fbi.h-da.de/danet/gosdn/controller/app"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/config"
"code.fbi.h-da.de/danet/gosdn/controller/conflict"
......@@ -97,31 +98,42 @@ func initialize() error {
return err
}
nodeService := nodes.NewNodeService(nodes.NewDatabaseNodeStore(), eventService)
portService := ports.NewPortService(ports.NewDatabasePortStore(), eventService)
db := database.GetDatabaseConnection()
nodeService := nodes.NewNodeService(nodes.NewNodeStore(db), eventService)
portService := ports.NewPortService(ports.NewPortStore(db), eventService)
routeService := routingtables.NewRoutingTableService(
routingtables.NewDatabaseRoutingTableStore(),
routingtables.NewRoutingTableStore(db),
nodeService,
portService,
eventService,
)
pluginRegistryClient := setupPluginRegistryClient()
pluginService := nucleus.NewPluginService(nucleus.NewPluginStore(), eventService, nucleus.NewPluginThroughReattachConfig, pluginRegistryClient)
pluginService := nucleus.NewPluginService(
nucleus.NewPluginStore(db),
eventService,
nucleus.NewPluginThroughReattachConfig,
pluginRegistryClient,
)
pndStore := nucleus.NewPndStore(pluginService)
pndStore := nucleus.NewPndStore(db, pluginService)
changeStore := store.NewChangeStore()
c = &Core{
pndStore: pndStore,
pndService: nucleus.NewPndService(pndStore),
mneService: nucleus.NewNetworkElementService(nucleus.NewNetworkElementStore(), pluginService, eventService),
pndStore: pndStore,
pndService: nucleus.NewPndService(pndStore),
mneService: nucleus.NewNetworkElementService(
nucleus.NewNetworkElementStore(db, config.BasePndUUID),
pluginService,
eventService,
),
changeStore: *changeStore,
userService: rbacImpl.NewUserService(rbacImpl.NewUserStore(), eventService),
roleService: rbacImpl.NewRoleService(rbacImpl.NewRoleStore(), eventService),
userService: rbacImpl.NewUserService(rbacImpl.NewUserStore(db), eventService),
roleService: rbacImpl.NewRoleService(rbacImpl.NewRoleStore(db), eventService),
topologyService: topology.NewTopologyService(
topology.NewDatabaseTopologyStore(),
topology.NewTopologyStore(db),
nodeService,
portService,
eventService,
......@@ -131,7 +143,7 @@ func initialize() error {
routeService: routeService,
eventService: eventService,
pluginService: pluginService,
appService: app.NewAppService(app.NewAppStore()),
appService: app.NewAppService(app.NewAppStore(db)),
stopChan: make(chan os.Signal, 1),
pluginRegistryClient: pluginRegistryClient,
}
......@@ -250,7 +262,7 @@ func createPrincipalNetworkDomain() error {
"base",
"gosdn base pnd",
)
err = c.pndStore.Add(pnd)
err = c.pndStore.Add(context.Background(), pnd)
if err != nil {
return err
}
......
package networkdomain
import (
"context"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
......@@ -8,10 +10,10 @@ import (
// PndStore describes an interface for pnd store implementations.
type PndStore interface {
Add(NetworkDomain) error
Delete(NetworkDomain) error
Get(store.Query) (LoadedPnd, error)
GetAll() ([]LoadedPnd, error)
Add(context.Context, NetworkDomain) error
Delete(context.Context, NetworkDomain) error
Get(context.Context, store.Query) (LoadedPnd, error)
GetAll(context.Context) ([]LoadedPnd, error)
PendingChannels(id uuid.UUID, parseErrors ...error) (chan networkelement.Details, error)
AddPendingChannel(id uuid.UUID, ch chan networkelement.Details)
RemovePendingChannel(id uuid.UUID)
......
package networkelement
import (
"context"
"code.fbi.h-da.de/danet/gosdn/controller/store"
)
// Store describes an interface for network element store implementations.
type Store interface {
Add(NetworkElement) error
Update(NetworkElement) error
Delete(NetworkElement) error
Get(store.Query) (LoadedNetworkElement, error)
GetAll() ([]LoadedNetworkElement, error)
Add(context.Context, NetworkElement) error
Update(context.Context, NetworkElement) error
Delete(context.Context, NetworkElement) error
Get(context.Context, store.Query) (LoadedNetworkElement, error)
GetAll(context.Context) ([]LoadedNetworkElement, error)
}
package plugin
import (
"context"
"code.fbi.h-da.de/danet/gosdn/controller/store"
)
// Store describes an interface for plugin store implementations.
type Store interface {
Add(Plugin) error
Update(Plugin) error
Delete(Plugin) error
Get(store.Query) (LoadedPlugin, error)
GetAll() ([]LoadedPlugin, error)
Add(context.Context, Plugin) error
Update(context.Context, Plugin) error
Delete(context.Context, Plugin) error
Get(context.Context, store.Query) (LoadedPlugin, error)
GetAll(context.Context) ([]LoadedPlugin, error)
}
package rbac
import "code.fbi.h-da.de/danet/gosdn/controller/store"
import (
"context"
"code.fbi.h-da.de/danet/gosdn/controller/store"
)
// RoleStore describes an interface for role store implementations.
type RoleStore interface {
Add(r Role) error
Update(r Role) error
Delete(Role) error
Get(store.Query) (LoadedRole, error)
GetAll() ([]LoadedRole, error)
Add(context.Context, Role) error
Update(context.Context, Role) error
Delete(context.Context, Role) error
Get(context.Context, store.Query) (LoadedRole, error)
GetAll(context.Context) ([]LoadedRole, error)
}
package rbac
import (
"context"
"code.fbi.h-da.de/danet/gosdn/controller/store"
)
// UserStore describes an interface for user store implementations.
type UserStore interface {
Add(u User) error
Update(u User) error
Delete(User) error
Get(store.Query) (LoadedUser, error)
GetAll() ([]LoadedUser, error)
Add(context.Context, User) error
Update(context.Context, User) error
Delete(context.Context, User) error
Get(context.Context, store.Query) (LoadedUser, error)
GetAll(context.Context) ([]LoadedUser, error)
}
......@@ -97,7 +97,7 @@ func (n *NetworkElementServer) Update(ctx context.Context, request *mnepb.Update
}, nil
}
// GetMne gets a specific mne.
// Get gets a specific mne.
func (n *NetworkElementServer) Get(ctx context.Context, request *mnepb.GetRequest) (*mnepb.GetResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -127,6 +127,12 @@ func (n *NetworkElementServer) Get(ctx context.Context, request *mnepb.GetReques
return nil, status.Errorf(codes.Aborted, "%v", err)
}
mne.Model, err = networkElement.GetModelAsString()
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &mnepb.GetResponse{
Timestamp: time.Now().UnixNano(),
Pnd: &ppb.PrincipalNetworkDomain{
......@@ -138,7 +144,7 @@ func (n *NetworkElementServer) Get(ctx context.Context, request *mnepb.GetReques
}, nil
}
// GetFlattenedMne gets a specific mne.
// GetFlattened gets a specific mne.
func (n *NetworkElementServer) GetFlattened(ctx context.Context, request *mnepb.GetFlattenedRequest) (*mnepb.GetFlattenedResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -199,7 +205,7 @@ func (n *NetworkElementServer) getPnd(identifier string) (networkdomain.NetworkD
return pnd, nil
}
// GetMneList returns a list of existing mnes.
// GetAll returns a list of existing mnes.
func (n *NetworkElementServer) GetAll(ctx context.Context, request *mnepb.GetAllRequest) (*mnepb.GetAllResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -241,7 +247,7 @@ func (n *NetworkElementServer) GetAll(ctx context.Context, request *mnepb.GetAll
}, nil
}
// GetFlattenedMneList returns a list of existing mnes.
// GetAllFlattened returns a list of existing mnes.
func (n *NetworkElementServer) GetAllFlattened(ctx context.Context, request *mnepb.GetAllFlattenedRequest) (*mnepb.GetAllFlattenedResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -528,7 +534,7 @@ func stringArrayToUUIDs(sid []string) ([]uuid.UUID, error) {
return UUIDs, nil
}
// SetMneList adds the list of mnes to the storage.
// AddList adds the list of mnes to the storage.
func (n *NetworkElementServer) AddList(ctx context.Context, request *mnepb.AddListRequest) (*mnepb.AddListResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -554,7 +560,12 @@ func (n *NetworkElementServer) AddList(ctx context.Context, request *mnepb.AddLi
gNMISubscriptionPaths := n.get2dSlicePathsFrom1dPaths(r.GnmiSubscribePaths)
mneID, err := n.addMne(ctx, r.MneName, r.TransportOption, nil, pluginId, pndID, gNMISubscriptionPaths)
mneID, err := uuid.Parse(r.MneId)
if err != nil {
log.Errorf("Error parsing UUID: %v. For: %v, ", r.MneId, r.MneName)
}
mneID, err = n.addMne(ctx, r.MneName, r.TransportOption, nil, pluginId, pndID, gNMISubscriptionPaths, mneID)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
......@@ -834,7 +845,7 @@ func (n *NetworkElementServer) ChangeMNE(duid uuid.UUID, operation mnepb.ApiOper
return ch.ID(), nil
}
// DeleteMne deletes a mne.
// Delete deletes a mne.
func (n *NetworkElementServer) Delete(ctx context.Context, request *mnepb.DeleteRequest) (*mnepb.DeleteResponse, error) {
if err := n.protoValidator.Validate(request); err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......
......@@ -71,9 +71,14 @@ func (r RoleServer) CreateRoles(ctx context.Context, request *apb.CreateRolesReq
}
for _, rrole := range request.Roles {
role := rbac.NewRole(uuid.New(), rrole.Name, rrole.Description, rrole.Permissions)
roleID, err := uuid.Parse(rrole.Id)
if err != nil {
roleID = uuid.New()
}
role := rbac.NewRole(roleID, rrole.Name, rrole.Description, rrole.Permissions)
err := r.roleService.Add(role)
err = r.roleService.Add(role)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
......
......@@ -131,7 +131,7 @@ func getTestStoreWithLinks(t *testing.T, nodes []links.Link) topology.Store {
store := store.NewGenericStore[links.Link]()
for _, node := range nodes {
err := store.Add(node)
err := store.Add(context.TODO(), node)
if err != nil {
t.Fatalf("failed to prepare test store while adding node: %v", err)
}
......@@ -144,7 +144,7 @@ func getTestStoreWithNodes(t *testing.T, nodesToAdd []nodes.Node) nodes.Store {
store := store.NewGenericStore[nodes.Node]()
for _, node := range nodesToAdd {
err := store.Add(node)
err := store.Add(context.TODO(), node)
if err != nil {
t.Fatalf("failed to prepare test store while adding node: %v", err)
}
......@@ -157,7 +157,7 @@ func getTestStoreWithPorts(t *testing.T, portsToAdd []ports.Port) ports.Store {
store := store.NewGenericStore[ports.Port]()
for _, port := range portsToAdd {
err := store.Add(port)
err := store.Add(context.TODO(), port)
if err != nil {
t.Fatalf("failed to prepare test store while adding port: %v", err)
}
......
......@@ -92,7 +92,12 @@ func (u UserServer) CreateUsers(ctx context.Context, request *apb.CreateUsersReq
hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(user.Password), []byte(salt), 1, 64*1024, 4, 32))
user := rbac.NewUser(uuid.New(), user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{ResourceVersion: 0})
userID, err := uuid.Parse(user.Id)
if err != nil {
userID = uuid.New()
}
user := rbac.NewUser(userID, user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{ResourceVersion: 0})
err = u.userService.Add(user)
if err != nil {
log.Error(err)
......
......@@ -2,38 +2,63 @@ package database
import (
"context"
"fmt"
"log"
"time"
"code.fbi.h-da.de/danet/gosdn/controller/config"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const (
// Timeout operations after N seconds.
connectTimeout = 5
timeout = 5 * time.Second
// DatabaseName is the name of the mongoDB database used.
DatabaseName = "gosdn"
)
// GetMongoConnection Retrieves a client to the MongoDB.
func GetMongoConnection() (*mongo.Client, context.Context, context.CancelFunc, error) {
// Connect Retrieves a client to the MongoDB.
func Connect() (*mongo.Database, error) {
mongoConnection := config.DatabaseConnection
ctx, cancel := context.WithTimeout(context.Background(), connectTimeout*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoConnection))
if err != nil {
log.Printf("Failed to create client: %v", err)
return nil, ctx, cancel, err
return nil, err
}
// Force a connection to verify our connection string
err = client.Ping(ctx, nil)
if err != nil {
log.Printf("Failed to connect to database: %v\n", err)
return nil, ctx, cancel, err
return nil, err
}
return client, ctx, cancel, nil
db := client.Database(DatabaseName)
if db == nil {
return nil, fmt.Errorf("can not connect to database %s", DatabaseName)
}
return db, nil
}
func GetDatabaseConnection() *mongo.Database {
var db *mongo.Database
storeMode := store.GetStoreMode()
if storeMode == store.Database {
db, err := Connect()
if err != nil {
logrus.Infof("Could not connect to database")
}
return db
}
return db
}
package nucleus
import (
"context"
"fmt"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
......@@ -19,22 +20,25 @@ import (
// DatabaseNetworkElementStore is used to store Network Elements.
type DatabaseNetworkElementStore struct {
storeName string
collection *mongo.Collection
}
// NewDatabaseNetworkElementStore returns a NetworkElementStore.
func NewDatabaseNetworkElementStore(pndUUID uuid.UUID) networkelement.Store {
func NewDatabaseNetworkElementStore(pndUUID uuid.UUID, db *mongo.Database) networkelement.Store {
storeName := fmt.Sprintf("networkElement-store-%s.json", pndUUID.String())
collection := db.Collection(storeName)
return &DatabaseNetworkElementStore{
storeName: fmt.Sprintf("networkElement-store-%s.json", pndUUID.String()),
collection: collection,
}
}
// Get takes a NetworkElement's UUID or name and returns the NetworkElement.
func (s *DatabaseNetworkElementStore) Get(query store.Query) (networkelement.LoadedNetworkElement, error) {
func (s *DatabaseNetworkElementStore) Get(ctx context.Context, query store.Query) (networkelement.LoadedNetworkElement, error) {
var loadedNetworkElement networkelement.LoadedNetworkElement
if query.ID.String() != "" {
loadedNetworkElement, err := s.getByID(query.ID)
loadedNetworkElement, err := s.getByID(ctx, query.ID)
if err != nil {
return loadedNetworkElement, err
}
......@@ -42,7 +46,7 @@ func (s *DatabaseNetworkElementStore) Get(query store.Query) (networkelement.Loa
return loadedNetworkElement, nil
}
loadedNetworkElement, err := s.getByName(query.Name)
loadedNetworkElement, err := s.getByName(ctx, query.Name)
if err != nil {
return loadedNetworkElement, err
}
......@@ -50,21 +54,8 @@ func (s *DatabaseNetworkElementStore) Get(query store.Query) (networkelement.Loa
return loadedNetworkElement, nil
}
func (s *DatabaseNetworkElementStore) getByID(idOfNetworkElement uuid.UUID) (loadedNetworkElement networkelement.LoadedNetworkElement, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedNetworkElement, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfNetworkElement.String()}})
func (s *DatabaseNetworkElementStore) getByID(ctx context.Context, idOfNetworkElement uuid.UUID) (loadedNetworkElement networkelement.LoadedNetworkElement, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfNetworkElement.String()}})
if result == nil {
return loadedNetworkElement, customerrs.CouldNotFindError{ID: idOfNetworkElement}
}
......@@ -78,21 +69,8 @@ func (s *DatabaseNetworkElementStore) getByID(idOfNetworkElement uuid.UUID) (loa
return loadedNetworkElement, nil
}
func (s *DatabaseNetworkElementStore) getByName(nameOfNetworkElement string) (loadedNetworkElement networkelement.LoadedNetworkElement, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedNetworkElement, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: nameOfNetworkElement}})
func (s *DatabaseNetworkElementStore) getByName(ctx context.Context, nameOfNetworkElement string) (loadedNetworkElement networkelement.LoadedNetworkElement, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: nameOfNetworkElement}})
if result == nil {
return loadedNetworkElement, customerrs.CouldNotFindError{Name: nameOfNetworkElement}
}
......@@ -107,23 +85,8 @@ func (s *DatabaseNetworkElementStore) getByName(nameOfNetworkElement string) (lo
}
// GetAll returns all stored network elements.
func (s *DatabaseNetworkElementStore) GetAll() (loadedNetworkElements []networkelement.LoadedNetworkElement, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return nil, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
cursor, err := collection.Find(ctx, bson.D{})
func (s *DatabaseNetworkElementStore) GetAll(ctx context.Context) (loadedNetworkElements []networkelement.LoadedNetworkElement, err error) {
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
......@@ -145,22 +108,8 @@ func (s *DatabaseNetworkElementStore) GetAll() (loadedNetworkElements []networke
}
// Add adds a network element to the network element store.
func (s *DatabaseNetworkElementStore) Add(networkElementToAdd networkelement.NetworkElement) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
_, err = client.Database(database.DatabaseName).
Collection(s.storeName).
InsertOne(ctx, networkElementToAdd)
func (s *DatabaseNetworkElementStore) Add(ctx context.Context, networkElementToAdd networkelement.NetworkElement) (err error) {
_, err = s.collection.InsertOne(ctx, networkElementToAdd)
if err != nil {
log.Printf("Could not create NetworkElement: %v", err)
return customerrs.CouldNotCreateError{Identifier: networkElementToAdd.ID(), Type: networkElementToAdd, Err: err}
......@@ -170,56 +119,46 @@ func (s *DatabaseNetworkElementStore) Add(networkElementToAdd networkelement.Net
}
// Update updates a existing network element.
func (s *DatabaseNetworkElementStore) Update(networkElementToUpdate networkelement.NetworkElement) (err error) {
func (s *DatabaseNetworkElementStore) Update(ctx context.Context, networkElementToUpdate networkelement.NetworkElement) (err error) {
var updatedLoadedNetworkElement networkelement.LoadedNetworkElement
client, ctx, cancel, err := database.GetMongoConnection()
db, err := database.Connect()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
// 1. Start Transaction
wcMajority := writeconcern.Majority()
wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority)
userCollection := client.Database(database.DatabaseName).Collection(s.storeName, wcMajorityCollectionOpts)
session, err := client.StartSession()
wc := writeconcern.Majority()
txnOptions := options.Transaction().SetWriteConcern(wc)
// Starts a session on the client
session, err := db.Client().StartSession()
if err != nil {
return err
}
// Defers ending the session after the transaction is committed or ended
defer session.EndSession(ctx)
// 2. Fetch exisiting Entity
existingNetworkElement, err := s.getByID(networkElementToUpdate.ID())
if err != nil {
return err
}
// Transaction
callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
// 1. Fetch exisiting Entity
existingNetworkElement, err := s.getByID(ctx, networkElementToUpdate.ID())
if err != nil {
return nil, err
}
// 3. Check if Entity.Metadata.ResourceVersion == UpdatedEntity.Metadata.ResourceVersion
if networkElementToUpdate.GetMetadata().ResourceVersion != existingNetworkElement.Metadata.ResourceVersion {
// 3.1.1 End transaction
// 3.1.2 If no -> return error
// 2. Check if Entity.Metadata.ResourceVersion == UpdatedEntity.Metadata.ResourceVersion
if networkElementToUpdate.GetMetadata().ResourceVersion != existingNetworkElement.Metadata.ResourceVersion {
// 2.1 End transaction
// 2.2 If no -> return error
return fmt.Errorf(
"resource version %d of provided network element %s is older or newer than %d in the store",
networkElementToUpdate.GetMetadata().ResourceVersion,
networkElementToUpdate.ID().String(), existingNetworkElement.Metadata.ResourceVersion,
)
}
return nil, fmt.Errorf(
"resource version %d of provided network element %s is older or newer than %d in the store",
networkElementToUpdate.GetMetadata().ResourceVersion,
networkElementToUpdate.ID().String(), existingNetworkElement.Metadata.ResourceVersion,
)
}
// 3.2.1 If yes -> Update entity in callback
callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
// Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the
// transaction.
u, _ := networkElementToUpdate.(*CommonNetworkElement)
u.Metadata.ResourceVersion = u.Metadata.ResourceVersion + 1
......@@ -232,7 +171,7 @@ func (s *DatabaseNetworkElementStore) Update(networkElementToUpdate networkeleme
ReturnDocument: &after,
}
err = userCollection.
err = s.collection.
FindOneAndUpdate(
ctx, bson.M{"_id": networkElementToUpdate.ID().String()}, update, &opt).
Decode(&updatedLoadedNetworkElement)
......@@ -246,7 +185,7 @@ func (s *DatabaseNetworkElementStore) Update(networkElementToUpdate networkeleme
return "", nil
}
_, err = session.WithTransaction(ctx, callback)
_, err = session.WithTransaction(ctx, callback, txnOptions)
if err != nil {
return err
}
......@@ -255,23 +194,8 @@ func (s *DatabaseNetworkElementStore) Update(networkElementToUpdate networkeleme
}
// Delete deletes a network element from the network element store.
func (s *DatabaseNetworkElementStore) Delete(networkElementToDelete networkelement.NetworkElement) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.storeName)
_, err = collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: networkElementToDelete.ID().String()}})
func (s *DatabaseNetworkElementStore) Delete(ctx context.Context, networkElementToDelete networkelement.NetworkElement) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: networkElementToDelete.ID().String()}})
if err != nil {
return customerrs.CouldNotDeleteError{Identifier: networkElementToDelete.ID(), Type: networkElementToDelete, Err: err}
}
......
package nucleus
import (
"context"
"fmt"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/plugin"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
......@@ -15,28 +15,24 @@ import (
log "github.com/sirupsen/logrus"
)
const storeName = "plugins-store.json"
// DatabasePluginStore is used to store Plugins.
type DatabasePluginStore struct {
pluginStoreName string
collection *mongo.Collection
}
// Add adds a plugin.
func (s *DatabasePluginStore) Add(pluginToAdd plugin.Plugin) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
func NewDatabasePluginStore(db *mongo.Database) *DatabasePluginStore {
collection := db.Collection(storeName)
return &DatabasePluginStore{
collection: collection,
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
}
_, err = client.Database(database.DatabaseName).
Collection(s.pluginStoreName).
InsertOne(ctx, pluginToAdd)
// Add adds a plugin.
func (s *DatabasePluginStore) Add(ctx context.Context, pluginToAdd plugin.Plugin) (err error) {
_, err = s.collection.InsertOne(ctx, pluginToAdd)
if err != nil {
if mongo.IsDuplicateKeyError(err) {
return nil
......@@ -49,21 +45,9 @@ func (s *DatabasePluginStore) Add(pluginToAdd plugin.Plugin) (err error) {
}
// Update updates an existing plugin.
func (s *DatabasePluginStore) Update(pluginToUpdate plugin.Plugin) (err error) {
func (s *DatabasePluginStore) Update(ctx context.Context, pluginToUpdate plugin.Plugin) (err error) {
var updatedLoadedPlugin plugin.LoadedPlugin
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
update := bson.D{primitive.E{Key: "$set", Value: pluginToUpdate}}
upsert := false
......@@ -73,10 +57,8 @@ func (s *DatabasePluginStore) Update(pluginToUpdate plugin.Plugin) (err error) {
ReturnDocument: &after,
}
err = client.Database(database.DatabaseName).
Collection(s.pluginStoreName).
FindOneAndUpdate(
ctx, bson.M{"_id": pluginToUpdate.ID().String()}, update, &opt).
err = s.collection.FindOneAndUpdate(
ctx, bson.M{"_id": pluginToUpdate.ID().String()}, update, &opt).
Decode(&updatedLoadedPlugin)
if err != nil {
log.Printf("Could not update Plugin: %v", err)
......@@ -88,22 +70,8 @@ func (s *DatabasePluginStore) Update(pluginToUpdate plugin.Plugin) (err error) {
}
// Delete deletes an plugin.
func (s *DatabasePluginStore) Delete(pluginToDelete plugin.Plugin) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
_, err = client.Database(database.DatabaseName).
Collection(s.pluginStoreName).
DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: pluginToDelete.ID().String()}})
func (s *DatabasePluginStore) Delete(ctx context.Context, pluginToDelete plugin.Plugin) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: pluginToDelete.ID().String()}})
if err != nil {
return customerrs.CouldNotDeleteError{Identifier: pluginToDelete.ID(), Type: pluginToDelete, Err: err}
}
......@@ -113,24 +81,8 @@ func (s *DatabasePluginStore) Delete(pluginToDelete plugin.Plugin) (err error) {
// Get takes a SouthboundInterface's UUID or name and returns the SouthboundInterface. If the requested
// SouthboundInterface does not exist an error is returned.
func (s *DatabasePluginStore) Get(query store.Query) (loadedPlugin plugin.LoadedPlugin, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedPlugin, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
log.Debugf("Plugin-Search-ID: %+v\n", query.ID.String())
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pluginStoreName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.ID.String()}})
func (s *DatabasePluginStore) Get(ctx context.Context, query store.Query) (loadedPlugin plugin.LoadedPlugin, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.ID.String()}})
if result == nil {
return loadedPlugin, customerrs.CouldNotFindError{ID: query.ID}
}
......@@ -146,22 +98,8 @@ func (s *DatabasePluginStore) Get(query store.Query) (loadedPlugin plugin.Loaded
}
// GetAll returns all plugin.
func (s *DatabasePluginStore) GetAll() (loadedPlugins []plugin.LoadedPlugin, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return nil, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pluginStoreName)
cursor, err := collection.Find(ctx, bson.D{})
func (s *DatabasePluginStore) GetAll(ctx context.Context) (loadedPlugins []plugin.LoadedPlugin, err error) {
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
......
package nucleus
import (
"context"
"fmt"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
......@@ -8,28 +9,40 @@ import (
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/plugin"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
const pndStoreName = "pnd-store.json"
// DatabasePndStore is used to store PrincipalNetworkDomains.
type DatabasePndStore struct {
pndStoreName string
pendingChannels map[uuid.UUID]chan networkelement.Details
collection *mongo.Collection
pluginService plugin.Service
}
func NewDatabasePndStore(db *mongo.Database, pluginService plugin.Service) *DatabasePndStore {
collection := db.Collection(pndStoreName)
return &DatabasePndStore{
pendingChannels: make(map[uuid.UUID]chan networkelement.Details),
pluginService: pluginService,
collection: collection,
}
}
// Get takes a PrincipalNetworkDomain's UUID or name and returns the PrincipalNetworkDomain. If the requested
// PrincipalNetworkDomain does not exist an error is returned.
func (s *DatabasePndStore) Get(query store.Query) (newPnd networkdomain.LoadedPnd, err error) {
func (s *DatabasePndStore) Get(ctx context.Context, query store.Query) (newPnd networkdomain.LoadedPnd, err error) {
var loadedPND networkdomain.LoadedPnd
if query.ID != uuid.Nil {
loadedPND, err := s.getByID(query.ID)
loadedPND, err := s.getByID(ctx, query.ID)
if err != nil {
return loadedPND, err
}
......@@ -37,7 +50,7 @@ func (s *DatabasePndStore) Get(query store.Query) (newPnd networkdomain.LoadedPn
return loadedPND, nil
}
loadedPND, err = s.getByName(query.Name)
loadedPND, err = s.getByName(ctx, query.Name)
if err != nil {
return loadedPND, err
}
......@@ -57,22 +70,8 @@ func (s *DatabasePndStore) Get(query store.Query) (newPnd networkdomain.LoadedPn
return loadedPND, nil
}
func (s *DatabasePndStore) getByID(idOfPnd uuid.UUID) (loadedPnd networkdomain.LoadedPnd, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedPnd, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pndStoreName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfPnd.String()}})
func (s *DatabasePndStore) getByID(ctx context.Context, idOfPnd uuid.UUID) (loadedPnd networkdomain.LoadedPnd, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfPnd.String()}})
if result == nil {
return loadedPnd, customerrs.CouldNotFindError{ID: idOfPnd}
}
......@@ -86,22 +85,8 @@ func (s *DatabasePndStore) getByID(idOfPnd uuid.UUID) (loadedPnd networkdomain.L
return loadedPnd, nil
}
func (s *DatabasePndStore) getByName(nameOfPnd string) (loadedPnd networkdomain.LoadedPnd, err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return loadedPnd, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pndStoreName)
result := collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: nameOfPnd}})
func (s *DatabasePndStore) getByName(ctx context.Context, nameOfPnd string) (loadedPnd networkdomain.LoadedPnd, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "name", Value: nameOfPnd}})
if result == nil {
return loadedPnd, customerrs.CouldNotFindError{ID: nameOfPnd}
}
......@@ -116,25 +101,10 @@ func (s *DatabasePndStore) getByName(nameOfPnd string) (loadedPnd networkdomain.
}
// GetAll returns all stored pnds.
func (s *DatabasePndStore) GetAll() (pnds []networkdomain.LoadedPnd, err error) {
func (s *DatabasePndStore) GetAll(ctx context.Context) (pnds []networkdomain.LoadedPnd, err error) {
var loadedPnds []networkdomain.LoadedPnd
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return nil, err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pndStoreName)
cursor, err := collection.Find(ctx, bson.D{})
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
......@@ -177,22 +147,8 @@ func (s *DatabasePndStore) GetAll() (pnds []networkdomain.LoadedPnd, err error)
}
// Add adds a pnd to the pnd store.
func (s *DatabasePndStore) Add(pndToAdd networkdomain.NetworkDomain) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
_, err = client.Database(database.DatabaseName).
Collection(s.pndStoreName).
InsertOne(ctx, pndToAdd)
func (s *DatabasePndStore) Add(ctx context.Context, pndToAdd networkdomain.NetworkDomain) (err error) {
_, err = s.collection.InsertOne(ctx, pndToAdd)
if err != nil {
return customerrs.CouldNotCreateError{Identifier: pndToAdd.ID(), Type: pndToAdd, Err: err}
}
......@@ -202,21 +158,8 @@ func (s *DatabasePndStore) Add(pndToAdd networkdomain.NetworkDomain) (err error)
// Delete deletes a pnd.
// It also deletes all assosicated devices and sbis.
func (s *DatabasePndStore) Delete(pndToDelete networkdomain.NetworkDomain) (err error) {
client, ctx, cancel, err := database.GetMongoConnection()
if err != nil {
return err
}
defer cancel()
defer func() {
if ferr := client.Disconnect(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
db := client.Database(database.DatabaseName)
collection := db.Collection(s.pndStoreName)
_, err = collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: pndToDelete.ID().String()}})
func (s *DatabasePndStore) Delete(ctx context.Context, pndToDelete networkdomain.NetworkDomain) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: pndToDelete.ID().String()}})
if err != nil {
return customerrs.CouldNotDeleteError{Identifier: pndToDelete.ID(), Type: pndToDelete, Err: err}
}
......
package nucleus
import (
"context"
"encoding/json"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
......@@ -23,7 +24,7 @@ func NewMemoryNetworkElementStore() networkelement.Store {
}
// Add adds a item to the store.
func (t *MemoryNetworkElementStore) Add(item networkelement.NetworkElement) error {
func (t *MemoryNetworkElementStore) Add(ctx context.Context, item networkelement.NetworkElement) error {
var mne networkelement.LoadedNetworkElement
b, err := json.Marshal(item)
......@@ -47,7 +48,7 @@ func (t *MemoryNetworkElementStore) Add(item networkelement.NetworkElement) erro
}
// Update updates a existing network element.
func (t *MemoryNetworkElementStore) Update(item networkelement.NetworkElement) error {
func (t *MemoryNetworkElementStore) Update(ctx context.Context, item networkelement.NetworkElement) error {
_, ok := t.Store[item.ID().String()]
if !ok {
return customerrs.CouldNotFindError{ID: item.ID(), Name: item.Name()}
......@@ -71,14 +72,14 @@ func (t *MemoryNetworkElementStore) Update(item networkelement.NetworkElement) e
}
// Delete deletes a network element from the network element store.
func (t *MemoryNetworkElementStore) Delete(item networkelement.NetworkElement) error {
func (t *MemoryNetworkElementStore) Delete(ctx context.Context, item networkelement.NetworkElement) error {
delete(t.Store, item.ID().String())
return nil
}
// Get takes a network element's UUID or name and returns the network element.
func (t *MemoryNetworkElementStore) Get(query store.Query) (networkelement.LoadedNetworkElement, error) {
func (t *MemoryNetworkElementStore) Get(ctx context.Context, query store.Query) (networkelement.LoadedNetworkElement, error) {
// First search for direct hit on UUID.
item, ok := t.Store[query.ID.String()]
if !ok {
......@@ -100,7 +101,7 @@ func (t *MemoryNetworkElementStore) Get(query store.Query) (networkelement.Loade
}
// GetAll returns all stored network elements.
func (t *MemoryNetworkElementStore) GetAll() ([]networkelement.LoadedNetworkElement, error) {
func (t *MemoryNetworkElementStore) GetAll(ctx context.Context) ([]networkelement.LoadedNetworkElement, error) {
var allItems []networkelement.LoadedNetworkElement
for _, item := range t.Store {
......
package nucleus
import (
"context"
"encoding/json"
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
......@@ -23,7 +24,7 @@ func NewMemoryPluginStore() plugin.Store {
}
// Add adds a item to the store.
func (t *MemoryPluginStore) Add(item plugin.Plugin) error {
func (t *MemoryPluginStore) Add(ctx context.Context, item plugin.Plugin) error {
loadedPlugin, err := store.TransformObjectToLoadedObject[plugin.Plugin, plugin.LoadedPlugin](item)
if err != nil {
return err
......@@ -40,7 +41,7 @@ func (t *MemoryPluginStore) Add(item plugin.Plugin) error {
}
// Update updates a existing plugin.
func (t *MemoryPluginStore) Update(item plugin.Plugin) error {
func (t *MemoryPluginStore) Update(ctx context.Context, item plugin.Plugin) error {
_, ok := t.Store[item.ID().String()]
if ok {
return nil
......@@ -65,14 +66,14 @@ func (t *MemoryPluginStore) Update(item plugin.Plugin) error {
}
// Delete deletes a plugin from the store.
func (t *MemoryPluginStore) Delete(item plugin.Plugin) error {
func (t *MemoryPluginStore) Delete(ctx context.Context, item plugin.Plugin) error {
delete(t.Store, item.ID().String())
return nil
}
// Get takes a plugins's UUID or name and returns the plugin.
func (t *MemoryPluginStore) Get(query store.Query) (plugin.LoadedPlugin, error) {
func (t *MemoryPluginStore) Get(ctx context.Context, query store.Query) (plugin.LoadedPlugin, error) {
// First search for direct hit on UUID.
item, ok := t.Store[query.ID.String()]
if !ok {
......@@ -94,7 +95,7 @@ func (t *MemoryPluginStore) Get(query store.Query) (plugin.LoadedPlugin, error)
}
// GetAll returns all stored plugins.
func (t *MemoryPluginStore) GetAll() ([]plugin.LoadedPlugin, error) {
func (t *MemoryPluginStore) GetAll(ctx context.Context) ([]plugin.LoadedPlugin, error) {
var allItems []plugin.LoadedPlugin
for _, item := range t.Store {
......