[VOL-2260] Guard Openolt against Wrong Tech Profile configuration

Added checks to prevent crashing of Openolt container in case of
invalid values of SchedulingPolicy, Direction, AdditionalBW and
DiscardPolicy attributes in Technology Profile json.

Change-Id: I27afc753c86f925d7eb12a5bd2bbdb8f8aa88569
diff --git a/vendor/github.com/opencord/voltha-lib-go/v2/pkg/db/common.go b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/db/common.go
new file mode 100644
index 0000000..0851ede
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/db/common.go
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package db
+
+import (
+	"github.com/opencord/voltha-lib-go/v2/pkg/log"
+)
+
+const (
+	logLevel = log.FatalLevel
+)
+
+// Unit test initialization. This init() function handles all unit tests in
+// the current directory.
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	_, err := log.AddPackage(log.JSON, logLevel, log.Fields{"pkg": "db"})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile.go b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile.go
index 12cda8d..95ac08b 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile.go
@@ -334,22 +334,26 @@
 	if kvresult != nil {
 		/* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
 		if value, err := kvstore.ToByte(kvresult.Value); err == nil {
-			if err = json.Unmarshal(value, &kvtechprofile); err == nil {
-				log.Debugw("Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
-				return &kvtechprofile
+			if err = json.Unmarshal(value, &kvtechprofile); err != nil {
+				log.Errorw("Error unmarshaling techprofile fetched from KV store", log.Fields{"techProfiletblID": techProfiletblID, "error": err, "techprofile_json": value})
+				return nil
 			}
+
+			log.Debugw("Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
+			return &kvtechprofile
 		}
 	}
 	return nil
 }
-func (t *TechProfileMgr) CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) *TechProfile {
+
+func (t *TechProfileMgr) CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) (*TechProfile, error) {
 	var tpInstance *TechProfile
 	log.Infow("creating-tp-instance", log.Fields{"tableid": techProfiletblID, "uni": uniPortName, "intId": intfId})
 
 	// Make sure the uniPortName is as per format pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
 	if !uniPortNameFormat.Match([]byte(uniPortName)) {
 		log.Errorw("uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
-		return nil
+		return nil, errors.New("uni-port-name-not-confirming-to-format")
 	}
 
 	tp := t.getTPFromKVStore(techProfiletblID)
@@ -367,15 +371,15 @@
 	tpInstancePath := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)
 	if tpInstance = t.allocateTPInstance(uniPortName, tp, intfId, tpInstancePath); tpInstance == nil {
 		log.Error("tp-intance-allocation-failed")
-		return nil
+		return nil, errors.New("tp-intance-allocation-failed")
 	}
 	if err := t.addTechProfInstanceToKVStore(techProfiletblID, uniPortName, tpInstance); err != nil {
-		log.Errorw("error-adding-tp-to-kv-store ", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
-		return nil
+		log.Errorw("error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
+		return nil, errors.New("error-adding-tp-to-kv-store")
 	}
 	log.Infow("tp-added-to-kv-store-successfully",
 		log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
-	return tpInstance
+	return tpInstance, nil
 }
 
 func (t *TechProfileMgr) DeleteTechProfileInstance(techProfiletblID uint32, uniPortName string) error {
@@ -605,46 +609,51 @@
 	return result
 }
 
-func (t *TechProfileMgr) GetUsScheduler(tpInstance *TechProfile) *tp_pb.SchedulerConfig {
+func (t *TechProfileMgr) GetUsScheduler(tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error) {
 	dir := tp_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.UsScheduler.Direction))
 	if dir == -1 {
-		log.Fatal("Error in getting Proto for direction for upstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for direction %s for upstream scheduler", tpInstance.UsScheduler.Direction)
+		return nil, fmt.Errorf("unable to get proto id for direction %s for upstream scheduler", tpInstance.UsScheduler.Direction)
 	}
+
 	bw := tp_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.UsScheduler.AdditionalBw))
 	if bw == -1 {
-		log.Fatal("Error in getting Proto for bandwidth for upstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for bandwidth %s for upstream scheduler", tpInstance.UsScheduler.AdditionalBw)
+		return nil, fmt.Errorf("unable to get proto id for bandwidth %s for upstream scheduler", tpInstance.UsScheduler.AdditionalBw)
 	}
+
 	policy := tp_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.UsScheduler.QSchedPolicy))
 	if policy == -1 {
-		log.Fatal("Error in getting Proto for scheduling policy for upstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for scheduling policy %s for upstream scheduler", tpInstance.UsScheduler.QSchedPolicy)
+		return nil, fmt.Errorf("unable to get proto id for scheduling policy %s for upstream scheduler", tpInstance.UsScheduler.QSchedPolicy)
 	}
+
 	return &tp_pb.SchedulerConfig{
 		Direction:    dir,
 		AdditionalBw: bw,
 		Priority:     tpInstance.UsScheduler.Priority,
 		Weight:       tpInstance.UsScheduler.Weight,
-		SchedPolicy:  policy}
+		SchedPolicy:  policy}, nil
 }
 
-func (t *TechProfileMgr) GetDsScheduler(tpInstance *TechProfile) *tp_pb.SchedulerConfig {
+func (t *TechProfileMgr) GetDsScheduler(tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error) {
 
 	dir := tp_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.DsScheduler.Direction))
 	if dir == -1 {
-		log.Fatal("Error in getting Proto for direction for downstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for direction %s for downstream scheduler", tpInstance.DsScheduler.Direction)
+		return nil, fmt.Errorf("unable to get proto id for direction %s for downstream scheduler", tpInstance.DsScheduler.Direction)
 	}
+
 	bw := tp_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.DsScheduler.AdditionalBw))
 	if bw == -1 {
-		log.Fatal("Error in getting Proto for bandwidth for downstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for bandwidth %s for downstream scheduler", tpInstance.DsScheduler.AdditionalBw)
+		return nil, fmt.Errorf("unable to get proto id for bandwidth %s for downstream scheduler", tpInstance.DsScheduler.AdditionalBw)
 	}
+
 	policy := tp_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.DsScheduler.QSchedPolicy))
 	if policy == -1 {
-		log.Fatal("Error in getting Proto for scheduling policy for downstream scheduler")
-		return nil
+		log.Errorf("Error in getting proto id for scheduling policy %s for downstream scheduler", tpInstance.DsScheduler.QSchedPolicy)
+		return nil, fmt.Errorf("unable to get proto id for scheduling policy %s for downstream scheduler", tpInstance.DsScheduler.QSchedPolicy)
 	}
 
 	return &tp_pb.SchedulerConfig{
@@ -652,7 +661,7 @@
 		AdditionalBw: bw,
 		Priority:     tpInstance.DsScheduler.Priority,
 		Weight:       tpInstance.DsScheduler.Weight,
-		SchedPolicy:  policy}
+		SchedPolicy:  policy}, nil
 }
 
 func (t *TechProfileMgr) GetTrafficScheduler(tpInstance *TechProfile, SchedCfg *tp_pb.SchedulerConfig,
@@ -667,7 +676,7 @@
 	return tSched
 }
 
-func (tpm *TechProfileMgr) GetTrafficQueues(tp *TechProfile, Dir tp_pb.Direction) []*tp_pb.TrafficQueue {
+func (tpm *TechProfileMgr) GetTrafficQueues(tp *TechProfile, Dir tp_pb.Direction) ([]*tp_pb.TrafficQueue, error) {
 
 	var encryp bool
 	if Dir == tp_pb.Direction_UPSTREAM {
@@ -680,19 +689,32 @@
 			} else {
 				encryp = false
 			}
+
+			schedPolicy := tpm.GetprotoBufParamValue("sched_policy", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy)
+			if schedPolicy == -1 {
+				log.Errorf("Error in getting Proto Id for scheduling policy %s for Upstream Gem Port %d", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy, Count)
+				return nil, fmt.Errorf("upstream gem port traffic queue creation failed due to unrecognized scheduling policy %s", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy)
+			}
+
+			discardPolicy := tpm.GetprotoBufParamValue("discard_policy", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy)
+			if discardPolicy == -1 {
+				log.Errorf("Error in getting Proto Id for discard policy %s for Upstream Gem Port %d", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy, Count)
+				return nil, fmt.Errorf("upstream gem port traffic queue creation failed due to unrecognized discard policy %s", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy)
+			}
+
 			GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
 				Direction:     tp_pb.Direction(tpm.GetprotoBufParamValue("direction", tp.UsScheduler.Direction)),
 				GemportId:     tp.UpstreamGemPortAttributeList[Count].GemportID,
 				PbitMap:       tp.UpstreamGemPortAttributeList[Count].PbitMap,
 				AesEncryption: encryp,
-				SchedPolicy:   tp_pb.SchedulingPolicy(tpm.GetprotoBufParamValue("sched_policy", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy)),
+				SchedPolicy:   tp_pb.SchedulingPolicy(schedPolicy),
 				Priority:      tp.UpstreamGemPortAttributeList[Count].PriorityQueue,
 				Weight:        tp.UpstreamGemPortAttributeList[Count].Weight,
-				DiscardPolicy: tp_pb.DiscardPolicy(tpm.GetprotoBufParamValue("discard_policy", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy)),
+				DiscardPolicy: tp_pb.DiscardPolicy(discardPolicy),
 			})
 		}
 		log.Debugw("Upstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
-		return GemPorts
+		return GemPorts, nil
 	} else if Dir == tp_pb.Direction_DOWNSTREAM {
 		//downstream GEM ports
 		NumGemPorts := len(tp.DownstreamGemPortAttributeList)
@@ -703,25 +725,40 @@
 			} else {
 				encryp = false
 			}
+
+			schedPolicy := tpm.GetprotoBufParamValue("sched_policy", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)
+			if schedPolicy == -1 {
+				log.Errorf("Error in getting Proto Id for scheduling policy %s for Downstream Gem Port %d", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy, Count)
+				return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unrecognized scheduling policy %s", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)
+			}
+
+			discardPolicy := tpm.GetprotoBufParamValue("discard_policy", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)
+			if discardPolicy == -1 {
+				log.Errorf("Error in getting Proto Id for discard policy %s for Downstream Gem Port %d", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy, Count)
+				return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unrecognized discard policy %s", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)
+			}
+
 			GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
 				Direction:     tp_pb.Direction(tpm.GetprotoBufParamValue("direction", tp.DsScheduler.Direction)),
 				GemportId:     tp.DownstreamGemPortAttributeList[Count].GemportID,
 				PbitMap:       tp.DownstreamGemPortAttributeList[Count].PbitMap,
 				AesEncryption: encryp,
-				SchedPolicy:   tp_pb.SchedulingPolicy(tpm.GetprotoBufParamValue("sched_policy", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)),
+				SchedPolicy:   tp_pb.SchedulingPolicy(schedPolicy),
 				Priority:      tp.DownstreamGemPortAttributeList[Count].PriorityQueue,
 				Weight:        tp.DownstreamGemPortAttributeList[Count].Weight,
-				DiscardPolicy: tp_pb.DiscardPolicy(tpm.GetprotoBufParamValue("discard_policy", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)),
+				DiscardPolicy: tp_pb.DiscardPolicy(discardPolicy),
 			})
 		}
 		log.Debugw("Downstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
-		return GemPorts
+		return GemPorts, nil
 	}
-	return nil
+
+	log.Errorf("Unsupported direction %s used for generating Traffic Queue list", Dir)
+	return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unsupported direction %s", Dir)
 }
 
 func (tpm *TechProfileMgr) GetUsTrafficScheduler(tp *TechProfile) *tp_pb.TrafficScheduler {
-	UsScheduler := tpm.GetUsScheduler(tp)
+	UsScheduler, _ := tpm.GetUsScheduler(tp)
 
 	return &tp_pb.TrafficScheduler{Direction: UsScheduler.Direction,
 		AllocId:   tp.UsScheduler.AllocID,
diff --git a/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile_if.go b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile_if.go
index a77ea45..797edc8 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile_if.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v2/pkg/techprofile/tech_profile_if.go
@@ -25,14 +25,14 @@
 	SetKVClient() *db.Backend
 	GetTechProfileInstanceKVPath(techProfiletblID uint32, uniPortName string) string
 	GetTPInstanceFromKVStore(techProfiletblID uint32, path string) (*TechProfile, error)
-	CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) *TechProfile
+	CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) (*TechProfile, error)
 	DeleteTechProfileInstance(techProfiletblID uint32, uniPortName string) error
 	GetprotoBufParamValue(paramType string, paramKey string) int32
-	GetUsScheduler(tpInstance *TechProfile) *tp_pb.SchedulerConfig
-	GetDsScheduler(tpInstance *TechProfile) *tp_pb.SchedulerConfig
+	GetUsScheduler(tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error)
+	GetDsScheduler(tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error)
 	GetTrafficScheduler(tpInstance *TechProfile, SchedCfg *tp_pb.SchedulerConfig,
 		ShapingCfg *tp_pb.TrafficShapingInfo) *tp_pb.TrafficScheduler
-	GetTrafficQueues(tp *TechProfile, Dir tp_pb.Direction) []*tp_pb.TrafficQueue
+	GetTrafficQueues(tp *TechProfile, Dir tp_pb.Direction) ([]*tp_pb.TrafficQueue, error)
 	GetGemportIDForPbit(tp *TechProfile, Dir tp_pb.Direction, pbit uint32) uint32
 	FindAllTpInstances(techProfiletblID uint32, ponIntf uint32, onuID uint32) []TechProfile
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 8fe9dde..174601f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -63,7 +63,7 @@
 github.com/mitchellh/go-homedir
 # github.com/mitchellh/mapstructure v1.1.2
 github.com/mitchellh/mapstructure
-# github.com/opencord/voltha-lib-go/v2 v2.2.20
+# github.com/opencord/voltha-lib-go/v2 v2.2.22
 github.com/opencord/voltha-lib-go/v2/pkg/adapters
 github.com/opencord/voltha-lib-go/v2/pkg/adapters/adapterif
 github.com/opencord/voltha-lib-go/v2/pkg/adapters/common