[VOL-3666] Reading TP template from default locations, write the instance using the per-stack prefix

Change-Id: Iabdacad1e8c3be718479c840214c2f700c967cd7
diff --git a/VERSION b/VERSION
index 3704213..c4e41f9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.3-dev
+4.0.3
diff --git a/pkg/techprofile/config.go b/pkg/techprofile/config.go
index 07926c5..438ea4a 100644
--- a/pkg/techprofile/config.go
+++ b/pkg/techprofile/config.go
@@ -32,7 +32,11 @@
 
 	defaultKVStoreTimeout = 5 * time.Second //in seconds
 
-	// Tech profile path prefix in kv store
+	// Tech profile path prefix in kv store (for the TP template)
+	// NOTE that this hardcoded to service/voltha as the TP template is shared across stacks
+	defaultTpKvPathPrefix = "service/voltha/technology_profiles"
+
+	// Tech profile path prefix in kv store (for TP instances)
 	defaultKVPathPrefix = "%s/technology_profiles"
 
 	// Tech profile path in kv store
@@ -94,38 +98,41 @@
 
 // TechprofileFlags represents the set of configurations used
 type TechProfileFlags struct {
-	KVStoreAddress       string
-	KVStoreType          string
-	KVStoreTimeout       time.Duration
-	KVBackend            *db.Backend
-	TPKVPathPrefix       string
-	TPFileKVPath         string
-	TPInstanceKVPath     string
-	DefaultTPName        string
-	TPVersion            int
-	NumGemPorts          uint32
-	DefaultPbits         []string
-	LogLevel             int
-	DefaultTechProfileID uint32
-	DefaultNumGemPorts   uint32
+	KVStoreAddress        string
+	KVStoreType           string
+	KVStoreTimeout        time.Duration
+	KVBackend             *db.Backend // this is the backend used to store TP instances
+	DefaultTpKVBackend    *db.Backend // this is the backend used to read the TP profile
+	TPKVPathPrefix        string
+	defaultTpKvPathPrefix string
+	TPFileKVPath          string
+	TPInstanceKVPath      string
+	DefaultTPName         string
+	TPVersion             int
+	NumGemPorts           uint32
+	DefaultPbits          []string
+	LogLevel              int
+	DefaultTechProfileID  uint32
+	DefaultNumGemPorts    uint32
 }
 
 func NewTechProfileFlags(KVStoreType string, KVStoreAddress string, basePathKvStore string) *TechProfileFlags {
 	// initialize with default values
 	var techProfileFlags = TechProfileFlags{
-		KVBackend:            nil,
-		KVStoreAddress:       KVStoreAddress,
-		KVStoreType:          KVStoreType,
-		KVStoreTimeout:       defaultKVStoreTimeout,
-		DefaultTPName:        defaultTechProfileName,
-		TPKVPathPrefix:       fmt.Sprintf(defaultKVPathPrefix, basePathKvStore),
-		TPVersion:            defaultVersion,
-		TPFileKVPath:         defaultTechProfileKVPath,
-		TPInstanceKVPath:     defaultTPInstanceKVPath,
-		DefaultTechProfileID: DEFAULT_TECH_PROFILE_TABLE_ID,
-		DefaultNumGemPorts:   defaultGemportsCount,
-		DefaultPbits:         []string{defaultPbits},
-		LogLevel:             defaultLogLevel,
+		KVBackend:             nil,
+		KVStoreAddress:        KVStoreAddress,
+		KVStoreType:           KVStoreType,
+		KVStoreTimeout:        defaultKVStoreTimeout,
+		DefaultTPName:         defaultTechProfileName,
+		TPKVPathPrefix:        fmt.Sprintf(defaultKVPathPrefix, basePathKvStore),
+		defaultTpKvPathPrefix: defaultTpKvPathPrefix,
+		TPVersion:             defaultVersion,
+		TPFileKVPath:          defaultTechProfileKVPath,
+		TPInstanceKVPath:      defaultTPInstanceKVPath,
+		DefaultTechProfileID:  DEFAULT_TECH_PROFILE_TABLE_ID,
+		DefaultNumGemPorts:    defaultGemportsCount,
+		DefaultPbits:          []string{defaultPbits},
+		LogLevel:              defaultLogLevel,
 	}
 
 	return &techProfileFlags
diff --git a/pkg/techprofile/tech_profile.go b/pkg/techprofile/tech_profile.go
index c066542..e21de45 100644
--- a/pkg/techprofile/tech_profile.go
+++ b/pkg/techprofile/tech_profile.go
@@ -382,13 +382,13 @@
 	epon   = "EPON"
 )
 
-func (t *TechProfileMgr) SetKVClient(ctx context.Context) *db.Backend {
+func (t *TechProfileMgr) SetKVClient(ctx context.Context, pathPrefix string) *db.Backend {
 	kvClient, err := newKVClient(ctx, t.config.KVStoreType, t.config.KVStoreAddress, t.config.KVStoreTimeout)
 	if err != nil {
 		logger.Errorw(ctx, "failed-to-create-kv-client",
 			log.Fields{
 				"type": t.config.KVStoreType, "address": t.config.KVStoreAddress,
-				"timeout": t.config.KVStoreTimeout, "prefix": t.config.TPKVPathPrefix,
+				"timeout": t.config.KVStoreTimeout, "prefix": pathPrefix,
 				"error": err.Error(),
 			})
 		return nil
@@ -398,7 +398,7 @@
 		StoreType:  t.config.KVStoreType,
 		Address:    t.config.KVStoreAddress,
 		Timeout:    t.config.KVStoreTimeout,
-		PathPrefix: t.config.TPKVPathPrefix}
+		PathPrefix: pathPrefix}
 
 	/* TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
 		  issue between kv store and backend , core is not calling NewBackend directly
@@ -423,7 +423,8 @@
 	var techprofileObj TechProfileMgr
 	logger.Debug(ctx, "Initializing techprofile Manager")
 	techprofileObj.config = NewTechProfileFlags(KVStoreType, KVStoreAddress, basePathKvStore)
-	techprofileObj.config.KVBackend = techprofileObj.SetKVClient(ctx)
+	techprofileObj.config.KVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.TPKVPathPrefix)
+	techprofileObj.config.DefaultTpKVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.defaultTpKvPathPrefix)
 	if techprofileObj.config.KVBackend == nil {
 		logger.Error(ctx, "Failed to initialize KV backend\n")
 		return nil, errors.New("KV backend init failed")
@@ -510,7 +511,7 @@
 	var kvtechprofile DefaultTechProfile
 	key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
 	logger.Debugw(ctx, "Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
-	kvresult, err := t.config.KVBackend.Get(ctx, key)
+	kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
 	if err != nil {
 		logger.Errorw(ctx, "Error while fetching value from KV store", log.Fields{"key": key})
 		return nil
@@ -534,7 +535,7 @@
 	var kvtechprofile DefaultEponProfile
 	key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
 	logger.Debugw(ctx, "Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
-	kvresult, err := t.config.KVBackend.Get(ctx, key)
+	kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
 	if err != nil {
 		logger.Errorw(ctx, "Error while fetching value from KV store", log.Fields{"key": key})
 		return nil
diff --git a/pkg/techprofile/tech_profile_if.go b/pkg/techprofile/tech_profile_if.go
index 0c5e273..ee67d2c 100644
--- a/pkg/techprofile/tech_profile_if.go
+++ b/pkg/techprofile/tech_profile_if.go
@@ -24,7 +24,7 @@
 )
 
 type TechProfileIf interface {
-	SetKVClient(ctx context.Context) *db.Backend
+	SetKVClient(ctx context.Context, pathPrefix string) *db.Backend
 	GetTechProfileInstanceKVPath(ctx context.Context, techProfiletblID uint32, uniPortName string) string
 	GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (interface{}, error)
 	CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (interface{}, error)