From 28b0f2c9f8a6ebf20cd8ed07873be924b0df6778 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@stud.h-da.de>
Date: Fri, 29 Jan 2021 17:45:52 +0100
Subject: [PATCH] added functions to retrieve instances of sbis

---
 nucleus/controller.go  |  7 ++++---
 nucleus/device.go      |  1 -
 nucleus/json_Helper.go |  6 ++----
 nucleus/southbound.go  | 47 ++++++++++++++++++++++++++++++++----------
 4 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/nucleus/controller.go b/nucleus/controller.go
index 57742c2a8..3de206c57 100644
--- a/nucleus/controller.go
+++ b/nucleus/controller.go
@@ -79,9 +79,10 @@ func (c *Core) UnMarshallPNDs() error {
 // CreateSouthboundInterfaces initializes the controller with his SBIs
 func (c *Core) CreateSouthboundInterfaces() {
 	if len(c.southboundInterfaces) == 0 {
-		sbi := &AristaOC{}
-		sbi.SetDefaults()
-		c.southboundInterfaces[sbi.SbiIdentifier()] = sbi
+		arista := GetAristaOCInstance()
+		c.southboundInterfaces[arista.SbiIdentifier()] = arista
+		openconfig := GetOpenconfigInstance()
+		c.southboundInterfaces[openconfig.SbiIdentifier()] = openconfig
 	}
 }
 
diff --git a/nucleus/device.go b/nucleus/device.go
index 261f56263..05ac126e1 100644
--- a/nucleus/device.go
+++ b/nucleus/device.go
@@ -42,7 +42,6 @@ func (d *Device) UnmarshalJSON(b []byte) error {
 		},
 		Transport: nil,
 	}
-	device.SBI.SetDefaults()
 	device.Transport = device.SBI.GetTransport()
 	device.Device = device.SBI.Schema().Root
 
diff --git a/nucleus/json_Helper.go b/nucleus/json_Helper.go
index f3367cec8..364fe2eed 100644
--- a/nucleus/json_Helper.go
+++ b/nucleus/json_Helper.go
@@ -48,12 +48,10 @@ func getSouthboundInterfaceFromJSONMap(m map[string]interface{}) SouthboundInter
 
 	switch sbi := m["name"]; sbi {
 	case "arista":
-		newSBI = &AristaOC{}
-		newSBI.SetDefaults()
+		newSBI = GetAristaOCInstance()
 
 	case "openconfig":
-		newSBI = &OpenConfig{}
-		newSBI.SetDefaults()
+		newSBI = GetOpenconfigInstance()
 	}
 	return newSBI
 }
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index dfe83a07b..42357ea18 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -1,6 +1,8 @@
 package nucleus
 
 import (
+	"sync"
+
 	"code.fbi.h-da.de/cocsn/yang-models/generated/arista"
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 	log "github.com/golang/glog"
@@ -9,13 +11,16 @@ import (
 	"github.com/openconfig/ygot/ytypes"
 )
 
+var lock = &sync.Mutex{}
+var singleOpenConfig *OpenConfig
+var singleArista *AristaOC
+
 // SouthboundInterface provides an
 // interface for SBI implementations
 type SouthboundInterface interface {
 	// Deprecated
 	SbiIdentifier() string
 
-	SetDefaults()
 	SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error
 	Schema() *ytypes.Schema
 	SetTransport(t Transport)
@@ -31,10 +36,6 @@ type OpenConfig struct {
 	schema    *ytypes.Schema
 }
 
-func (oc *OpenConfig) SetDefaults() {
-	oc.Name = "openconfig"
-}
-
 func (oc *OpenConfig) SbiIdentifier() string {
 	return oc.Name
 }
@@ -64,18 +65,27 @@ func (oc *OpenConfig) SetTransport(t Transport) {
 	oc.Transport = t
 }
 
+func GetOpenconfigInstance() SouthboundInterface {
+	if singleOpenConfig == nil {
+		lock.Lock()
+		defer lock.Unlock()
+		if singleOpenConfig == nil {
+			log.Info("creating OpenConfig instance")
+			singleOpenConfig = &OpenConfig{}
+			singleOpenConfig.Name = "openconfig"
+			t := &Gnmi{SetNode: singleOpenConfig.SetNode()}
+			singleOpenConfig.Transport = t
+		}
+	}
+	return singleOpenConfig
+}
+
 type AristaOC struct {
 	Name      string    `json:"name"`
 	Transport Transport `json:"-"`
 	schema    *ytypes.Schema
 }
 
-func (oc *AristaOC) SetDefaults() {
-	oc.Name = "arista"
-	t := &Gnmi{SetNode: oc.SetNode()}
-	oc.Transport = t
-}
-
 func (oc *AristaOC) SbiIdentifier() string {
 	return oc.Name
 }
@@ -104,3 +114,18 @@ func (oc *AristaOC) GetTransport() Transport {
 func (oc *AristaOC) SetTransport(t Transport) {
 	oc.Transport = t
 }
+
+func GetAristaOCInstance() SouthboundInterface {
+	if singleArista == nil {
+		lock.Lock()
+		defer lock.Unlock()
+		if singleArista == nil {
+			log.Info("creating AristaOC instance")
+			singleArista = &AristaOC{}
+			singleArista.Name = "arista"
+			t := &Gnmi{SetNode: singleArista.SetNode()}
+			singleArista.Transport = t
+		}
+	}
+	return singleArista
+}
-- 
GitLab