VOL-1558 Update vendored voltha-go and other items

Result of running dep ensure.  golang openolt now
builds.

Also update dockerfile to used specific alpine version

Change-Id: I1e5407e25bb0636a241a0650d1e44e5df567f44b
diff --git a/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
new file mode 100755
index 0000000..2a3cae6
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
@@ -0,0 +1,1113 @@
+/*
+ * 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 ponresourcemanager
+
+import (
+    "encoding/base64"
+    "encoding/json"
+    "errors"
+    "fmt"
+    "strconv"
+
+    bitmap "github.com/boljen/go-bitmap"
+    "github.com/opencord/voltha-go/common/log"
+    "github.com/opencord/voltha-go/db/kvstore"
+    "github.com/opencord/voltha-go/db/model"
+    tp "github.com/opencord/voltha-go/common/techprofile"
+)
+
+const (
+    //Constants to identify resource pool
+    UNI_ID     = "UNI_ID"
+    ONU_ID     = "ONU_ID"
+    ALLOC_ID   = "ALLOC_ID"
+    GEMPORT_ID = "GEMPORT_ID"
+    FLOW_ID    = "FLOW_ID"
+
+    //Constants for passing command line arugments
+    OLT_MODEL_ARG = "--olt_model"
+    PATH_PREFIX   = "service/voltha/resource_manager/{%s}"
+    /*The resource ranges for a given device model should be placed
+      at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
+      path on the KV store.
+      If Resource Range parameters are to be read from the external KV store,
+      they are expected to be stored in the following format.
+      Note: All parameters are MANDATORY for now.
+      constants used as keys to reference the resource range parameters from
+      and external KV store.
+    */
+    UNI_ID_START_IDX      = "uni_id_start"
+    UNI_ID_END_IDX        = "uni_id_end"
+    ONU_ID_START_IDX      = "onu_id_start"
+    ONU_ID_END_IDX        = "onu_id_end"
+    ONU_ID_SHARED_IDX     = "onu_id_shared"
+    ALLOC_ID_START_IDX    = "alloc_id_start"
+    ALLOC_ID_END_IDX      = "alloc_id_end"
+    ALLOC_ID_SHARED_IDX   = "alloc_id_shared"
+    GEMPORT_ID_START_IDX  = "gemport_id_start"
+    GEMPORT_ID_END_IDX    = "gemport_id_end"
+    GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
+    FLOW_ID_START_IDX     = "flow_id_start"
+    FLOW_ID_END_IDX       = "flow_id_end"
+    FLOW_ID_SHARED_IDX    = "flow_id_shared"
+    NUM_OF_PON_PORT       = "pon_ports"
+
+    /*
+       The KV store backend is initialized with a path prefix and we need to
+       provide only the suffix.
+    */
+    PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
+
+    //resource path suffix
+    //Path on the KV store for storing alloc id ranges and resource pool for a given interface
+    //Format: <device_id>/alloc_id_pool/<pon_intf_id>
+    ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
+    //Path on the KV store for storing gemport id ranges and resource pool for a given interface
+    //Format: <device_id>/gemport_id_pool/<pon_intf_id>
+    GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
+    //Path on the KV store for storing onu id ranges and resource pool for a given interface
+    //Format: <device_id>/onu_id_pool/<pon_intf_id>
+    ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
+    //Path on the KV store for storing flow id ranges and resource pool for a given interface
+    //Format: <device_id>/flow_id_pool/<pon_intf_id>
+    FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
+
+    //Path on the KV store for storing list of alloc IDs for a given ONU
+    //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
+    ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
+
+    //Path on the KV store for storing list of gemport IDs for a given ONU
+    //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
+    GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
+
+    //Path on the KV store for storing list of Flow IDs for a given ONU
+    //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
+    FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
+
+    //Flow Id info: Use to store more metadata associated with the flow_id
+    //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
+    FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
+
+    //Constants for internal usage.
+    PON_INTF_ID     = "pon_intf_id"
+    START_IDX       = "start_idx"
+    END_IDX         = "end_idx"
+    POOL            = "pool"
+    NUM_OF_PON_INTF = 16
+
+    KVSTORE_RETRY_TIMEOUT = 5
+)
+
+//type ResourceTypeIndex string
+//type ResourceType string
+
+type PONResourceManager struct {
+    //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
+    Technology string
+    DeviceType string
+    DeviceID   string
+    Backend    string // ETCD, or consul
+    Host       string // host ip of the KV store
+    Port       int    // port number for the KV store
+    OLTModel   string
+    KVStore    *model.Backend
+    TechProfileMgr *tp.TechProfileMgr
+
+    // Below attribute, pon_resource_ranges, should be initialized
+    // by reading from KV store.
+    PonResourceRanges  map[string]interface{}
+    SharedResourceMgrs map[string]*PONResourceManager
+    SharedIdxByType    map[string]string
+    IntfIDs            []uint32 // list of pon interface IDs
+}
+
+func newKVClient(storeType string, address string, timeout int) (kvstore.Client, error) {
+    log.Infow("kv-store-type", log.Fields{"store": storeType})
+    switch storeType {
+    case "consul":
+        return kvstore.NewConsulClient(address, timeout)
+    case "etcd":
+        return kvstore.NewEtcdClient(address, timeout)
+    }
+    return nil, errors.New("unsupported-kv-store")
+}
+
+func SetKVClient(Technology string, Backend string, Host string, Port int) *model.Backend {
+    addr := Host + ":" + strconv.Itoa(Port)
+    // 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
+    kvClient, err := newKVClient(Backend, addr, KVSTORE_RETRY_TIMEOUT)
+    if err != nil {
+        log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
+        return nil
+    }
+    kvbackend := &model.Backend{
+        Client:     kvClient,
+        StoreType:  Backend,
+        Host:       Host,
+        Port:       Port,
+        Timeout:    KVSTORE_RETRY_TIMEOUT,
+        PathPrefix: fmt.Sprintf(PATH_PREFIX, Technology)}
+
+    return kvbackend
+}
+
+// NewPONResourceManager creates a new PON resource manager.
+func NewPONResourceManager(Technology string, DeviceType string, DeviceID string, Backend string, Host string, Port int) (*PONResourceManager, error) {
+    var PONMgr PONResourceManager
+    PONMgr.Technology = Technology
+    PONMgr.DeviceType = DeviceType
+    PONMgr.DeviceID = DeviceID
+    PONMgr.Backend = Backend
+    PONMgr.Host = Host
+    PONMgr.Port = Port
+    PONMgr.KVStore = SetKVClient(Technology, Backend, Host, Port)
+    if PONMgr.KVStore == nil {
+        log.Error("KV Client initilization failed")
+        return nil, errors.New("Failed to init KV client")
+    }
+    // Initialize techprofile for this technology 
+    if PONMgr.TechProfileMgr,_ =  tp.NewTechProfile(&PONMgr);PONMgr.TechProfileMgr == nil{
+        log.Error("Techprofile initialization failed")
+        return nil,errors.New("Failed to init tech profile")
+    }
+    PONMgr.PonResourceRanges = make(map[string]interface{})
+    PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
+    PONMgr.SharedIdxByType = make(map[string]string)
+    PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
+    PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
+    PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
+    PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
+    PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
+    PONMgr.OLTModel = DeviceType
+    return &PONMgr, nil
+}
+
+/*
+  Initialize PON resource ranges with config fetched from kv store.
+  return boolean: True if PON resource ranges initialized else false
+  Try to initialize the PON Resource Ranges from KV store based on the
+  OLT model key, if available
+*/
+
+func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore() bool {
+    //Initialize PON resource ranges with config fetched from kv store.
+    //:return boolean: True if PON resource ranges initialized else false
+    // Try to initialize the PON Resource Ranges from KV store based on the
+    // OLT model key, if available
+    if PONRMgr.OLTModel == "" {
+        log.Error("Failed to get OLT model")
+        return false
+    }
+    Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
+    //get resource from kv store
+    Result, err := PONRMgr.KVStore.Get(Path)
+    if err != nil {
+        log.Debugf("Error in fetching resource %s from KV strore", Path)
+        return false
+    }
+    if Result == nil {
+        log.Debug("There may be no resources in the KV store in case of fresh bootup, return true")
+        return false
+    }
+    //update internal ranges from kv ranges. If there are missing
+    // values in the KV profile, continue to use the defaults
+    Value, err := ToByte(Result.Value)
+    if err != nil {
+        log.Error("Failed to convert kvpair to byte string")
+        return false
+    }
+    if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
+        log.Error("Failed to Unmarshal json byte")
+        return false
+    }
+    log.Debug("Init resource ranges from kvstore success")
+    return true
+}
+
+func (PONRMgr *PONResourceManager) UpdateRanges(StartIDx string, StartID uint32, EndIDx string, EndID uint32,
+    SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
+    /*
+       Update the ranges for all reosurce type in the intermnal maps
+       param: resource type start index
+       param: start ID
+       param: resource type end index
+       param: end ID
+       param: resource type shared index
+       param: shared pool id
+       param: global resource manager
+    */
+    log.Debugf("update ranges for %s, %d", StartIDx, StartID)
+
+    if StartID != 0 {
+        PONRMgr.PonResourceRanges[StartIDx] = StartID
+    }
+    if EndID != 0 {
+        PONRMgr.PonResourceRanges[EndIDx] = EndID
+    }
+    //if SharedPoolID != 0 {
+    PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
+    //}
+    if RMgr != nil {
+        PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
+    }
+}
+
+func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ONUIDStart uint32,
+                                                                ONUIDEnd uint32,
+                                                                ONUIDSharedPoolID uint32,
+                                                                AllocIDStart uint32,
+                                                                AllocIDEnd uint32,
+                                                                AllocIDSharedPoolID uint32,
+                                                                GEMPortIDStart uint32,
+                                                                GEMPortIDEnd uint32,
+                                                                GEMPortIDSharedPoolID uint32,
+                                                                FlowIDStart uint32,
+                                                                FlowIDEnd uint32,
+                                                                FlowIDSharedPoolID uint32,
+                                                                UNIIDStart uint32,
+                                                                UNIIDEnd uint32,
+                                                                NoOfPONPorts uint32,
+                                                                IntfIDs []uint32) bool {
+
+    /*Initialize default PON resource ranges
+
+      :param onu_id_start_idx: onu id start index
+      :param onu_id_end_idx: onu id end index
+      :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
+      :param alloc_id_start_idx: alloc id start index
+      :param alloc_id_end_idx: alloc id end index
+      :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
+      :param gemport_id_start_idx: gemport id start index
+      :param gemport_id_end_idx: gemport id end index
+      :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
+      :param flow_id_start_idx: flow id start index
+      :param flow_id_end_idx: flow id end index
+      :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
+      :param num_of_pon_ports: number of PON ports
+      :param intf_ids: interfaces serviced by this manager
+    */
+    PONRMgr.UpdateRanges(ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
+    PONRMgr.UpdateRanges(ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
+    PONRMgr.UpdateRanges(GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
+    PONRMgr.UpdateRanges(FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
+    PONRMgr.UpdateRanges(UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
+    log.Debug("Initialize default range values")
+    var i uint32
+    if IntfIDs == nil {
+        for i = 0; i < NoOfPONPorts; i++ {
+            PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
+        }
+    } else {
+        PONRMgr.IntfIDs = IntfIDs
+    }
+    return true
+}
+
+func (PONRMgr *PONResourceManager) InitDeviceResourcePool() error {
+
+    //Initialize resource pool for all PON ports.
+
+    log.Debug("Init resource ranges")
+
+    var err error
+    for _, Intf := range PONRMgr.IntfIDs {
+        SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
+        if SharedPoolID != 0 {
+            Intf = SharedPoolID
+        }
+        if err = PONRMgr.InitResourceIDPool(Intf, ONU_ID,
+            PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
+            PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
+            log.Error("Failed to init ONU ID resource pool")
+            return err 
+        }
+        if SharedPoolID != 0 {
+            break
+        }
+    }
+
+    for _, Intf := range PONRMgr.IntfIDs {
+        SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
+        if SharedPoolID != 0 {
+            Intf = SharedPoolID
+        }
+        if err = PONRMgr.InitResourceIDPool(Intf, ALLOC_ID,
+            PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
+            PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
+            log.Error("Failed to init ALLOC ID resource pool ")
+            return err 
+        }
+        if SharedPoolID != 0 {
+            break
+        }
+    }
+    for _, Intf := range PONRMgr.IntfIDs {
+        SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
+        if SharedPoolID != 0 {
+            Intf = SharedPoolID
+        }
+        if err = PONRMgr.InitResourceIDPool(Intf, GEMPORT_ID,
+            PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
+            PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
+            log.Error("Failed to init GEMPORT ID resource pool")
+            return err 
+        }
+        if SharedPoolID != 0 {
+            break
+        }
+    }
+
+    for _, Intf := range PONRMgr.IntfIDs {
+        SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
+        if SharedPoolID != 0 {
+            Intf = SharedPoolID
+        }
+        if err = PONRMgr.InitResourceIDPool(Intf, FLOW_ID,
+            PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
+            PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
+            log.Error("Failed to init FLOW ID resource pool")
+            return err 
+        }
+        if SharedPoolID != 0 {
+            break
+        }
+    }
+    return err 
+}
+
+func (PONRMgr *PONResourceManager) InitResourceIDPool(Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
+
+    /*Initialize Resource ID pool for a given Resource Type on a given PON Port
+
+      :param pon_intf_id: OLT PON interface id
+      :param resource_type: String to identify type of resource
+      :param start_idx: start index for onu id pool
+      :param end_idx: end index for onu id pool
+      :return boolean: True if resource id pool initialized else false
+    */
+
+    // delegate to the master instance if sharing enabled across instances
+    SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
+    if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
+        return SharedResourceMgr.InitResourceIDPool(Intf, ResourceType, StartID, EndID)
+    }
+
+    Path := PONRMgr.GetPath(Intf, ResourceType)
+    if Path == "" {
+        log.Errorf("Failed to get path for resource type %s", ResourceType)
+        return errors.New(fmt.Sprintf("Failed to get path for resource type %s", ResourceType))
+    }
+
+    //In case of adapter reboot and reconciliation resource in kv store
+    //checked for its presence if not kv store update happens
+    Res, err := PONRMgr.GetResource(Path)
+    if (err == nil) && (Res != nil) {
+        log.Debugf("Resource %s already present in store ", Path)
+        return nil
+    } else {
+        FormatResult, err := PONRMgr.FormatResource(Intf, StartID, EndID)
+        if err != nil {
+            log.Errorf("Failed to format resource")
+            return err
+        }
+        // Add resource as json in kv store.
+        err = PONRMgr.KVStore.Put(Path, FormatResult)
+        if err == nil {
+            log.Debug("Successfuly posted to kv store")
+            return err
+        }
+    }
+
+    log.Debug("Error initializing pool")
+
+    return err
+}
+
+func (PONRMgr *PONResourceManager) FormatResource(IntfID uint32, StartIDx uint32, EndIDx uint32) ([]byte, error) {
+    /*
+       Format resource as json.
+       :param pon_intf_id: OLT PON interface id
+       :param start_idx: start index for id pool
+       :param end_idx: end index for id pool
+       :return dictionary: resource formatted as map
+    */
+    // Format resource as json to be stored in backend store
+    Resource := make(map[string]interface{})
+    Resource[PON_INTF_ID] = IntfID
+    Resource[START_IDX] = StartIDx
+    Resource[END_IDX] = EndIDx
+    /*
+       Resource pool stored in backend store as binary string.
+       Tracking the resource allocation will be done by setting the bits \
+       in the byte array. The index set will be the resource number allocated.
+    */
+    var TSData *bitmap.Threadsafe
+    if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
+        log.Error("Failed to create a bitmap")
+        return nil, errors.New("Failed to create bitmap")
+    }
+    Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
+
+    Value, err := json.Marshal(Resource)
+    if err != nil {
+        log.Errorf("Failed to marshall resource")
+        return nil, err
+    }
+    return Value, err
+}
+func (PONRMgr *PONResourceManager) GetResource(Path string) (map[string]interface{}, error) {
+    /*
+       Get resource from kv store.
+
+       :param path: path to get resource
+       :return: resource if resource present in kv store else None
+    */
+    //get resource from kv store
+
+    var Value []byte
+    Result := make(map[string]interface{})
+    var Str string
+
+    Resource, err := PONRMgr.KVStore.Get(Path)
+    if (err != nil) || (Resource == nil) {
+        log.Debugf("Resource  unavailable at %s", Path)
+        return nil, err
+    }
+
+    Value, err = ToByte(Resource.Value)
+
+    // decode resource fetched from backend store to dictionary
+    err = json.Unmarshal(Value, &Result)
+    if err != nil {
+        log.Error("Failed to decode resource")
+        return Result, err
+    }
+    /*
+       resource pool in backend store stored as binary string whereas to
+       access the pool to generate/release IDs it need to be converted
+       as BitArray
+    */
+    Str, err = ToString(Result[POOL])
+    if err != nil {
+        log.Error("Failed to conver to kv pair to string")
+        return Result, err
+    }
+    Decode64, _ := base64.StdEncoding.DecodeString(Str)
+    Result[POOL], err = ToByte(Decode64)
+    if err != nil {
+        log.Error("Failed to convert resource pool to byte")
+        return Result, err
+    }
+
+    return Result, err
+}
+
+func (PONRMgr *PONResourceManager) GetPath(IntfID uint32, ResourceType string) string {
+    /*
+       Get path for given resource type.
+       :param pon_intf_id: OLT PON interface id
+       :param resource_type: String to identify type of resource
+       :return: path for given resource type
+    */
+
+    /*
+       Get the shared pool for the given resource type.
+       all the resource ranges and the shared resource maps are initialized during the init.
+    */
+    SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
+    if SharedPoolID != 0 {
+        IntfID = SharedPoolID
+    }
+    var Path string
+    if ResourceType == ONU_ID {
+        Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
+    } else if ResourceType == ALLOC_ID {
+        Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
+    } else if ResourceType == GEMPORT_ID {
+        Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
+    } else if ResourceType == FLOW_ID {
+        Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
+    } else {
+        log.Error("Invalid resource pool identifier")
+    }
+    return Path
+}
+
+func (PONRMgr *PONResourceManager) GetResourceID(IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
+    /*
+       Create alloc/gemport/onu/flow id for given OLT PON interface.
+       :param pon_intf_id: OLT PON interface id
+       :param resource_type: String to identify type of resource
+       :param num_of_id: required number of ids
+       :return list/uint32/None: list, uint32 or None if resource type is
+        alloc_id/gemport_id, onu_id or invalid type respectively
+    */
+    if NumIDs < 1 {
+        log.Error("Invalid number of resources requested")
+        return nil, errors.New(fmt.Sprintf("Invalid number of resources requested %d", NumIDs))
+    }
+    // delegate to the master instance if sharing enabled across instances
+
+    SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
+    if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
+        return SharedResourceMgr.GetResourceID(IntfID, ResourceType, NumIDs)
+    }
+
+    Path := PONRMgr.GetPath(IntfID, ResourceType)
+    if Path == "" {
+        log.Errorf("Failed to get path for resource type %s", ResourceType)
+        return nil, errors.New(fmt.Sprintf("Failed to get path for resource type %s", ResourceType))
+    }
+    log.Debugf("Get resource for type %s on path %s", ResourceType, Path)
+    var Result []uint32
+    var NextID uint32
+    Resource, err := PONRMgr.GetResource(Path)
+    if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
+        if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
+            log.Error("Failed to Generate ID")
+            return Result, err
+        }
+        Result = append(Result, NextID)
+    } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
+        if NumIDs == 1 {
+            if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
+                log.Error("Failed to Generate ID")
+                return Result, err
+            }
+            Result = append(Result, NextID)
+        } else {
+            for NumIDs > 0 {
+                if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
+                    log.Error("Failed to Generate ID")
+                    return Result, err
+                }
+                Result = append(Result, NextID)
+                NumIDs--
+            }
+        }
+    } else {
+        log.Error("get resource failed")
+        return Result, err
+    }
+
+    //Update resource in kv store
+    if PONRMgr.UpdateResource(Path, Resource) != nil {
+        log.Errorf("Failed to update resource %s", Path)
+        return nil, errors.New(fmt.Sprintf("Failed to update resource %s", Path))
+    }
+    return Result, nil
+}
+
+func checkValidResourceType(ResourceType string) bool {
+    KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
+
+    for _, v := range KnownResourceTypes {
+        if v == ResourceType {
+            return true
+        }
+    }
+    return false
+}
+
+func (PONRMgr *PONResourceManager) FreeResourceID(IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
+    /*
+       Release alloc/gemport/onu/flow id for given OLT PON interface.
+       :param pon_intf_id: OLT PON interface id
+       :param resource_type: String to identify type of resource
+       :param release_content: required number of ids
+       :return boolean: True if all IDs in given release_content release else False
+    */
+    if checkValidResourceType(ResourceType) == false {
+        log.Error("Invalid resource type")
+        return false
+    }
+    if ReleaseContent == nil {
+        log.Debug("Nothing to release")
+        return true
+    }
+    // delegate to the master instance if sharing enabled across instances
+    SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
+    if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
+        return SharedResourceMgr.FreeResourceID(IntfID, ResourceType, ReleaseContent)
+    }
+    Path := PONRMgr.GetPath(IntfID, ResourceType)
+    if Path == "" {
+        log.Error("Failed to get path")
+        return false
+    }
+    Resource, err := PONRMgr.GetResource(Path)
+    if err != nil {
+        log.Error("Failed to get resource")
+        return false
+    }
+    for _, Val := range ReleaseContent {
+        PONRMgr.ReleaseID(Resource, Val)
+    }
+    if PONRMgr.UpdateResource(Path, Resource) != nil {
+        log.Errorf("Free resource for %s failed", Path)
+        return false
+    }
+    return true
+}
+
+func (PONRMgr *PONResourceManager) UpdateResource(Path string, Resource map[string]interface{}) error {
+    /*
+       Update resource in resource kv store.
+       :param path: path to update resource
+       :param resource: resource need to be updated
+       :return boolean: True if resource updated in kv store else False
+    */
+    // TODO resource[POOL] = resource[POOL].bin
+    Value, err := json.Marshal(Resource)
+    if err != nil {
+        log.Error("failed to Marshal")
+        return err
+    }
+    err = PONRMgr.KVStore.Put(Path, Value)
+    if err != nil {
+        log.Error("failed to put data to kv store %s", Path)
+        return err
+    }
+    return nil
+}
+
+func (PONRMgr *PONResourceManager) ClearResourceIDPool(IntfID uint32, ResourceType string) bool {
+    /*
+       Clear Resource Pool for a given Resource Type on a given PON Port.
+       :return boolean: True if removed else False
+    */
+
+    // delegate to the master instance if sharing enabled across instances
+    SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
+    if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
+        return SharedResourceMgr.ClearResourceIDPool(IntfID, ResourceType)
+    }
+    Path := PONRMgr.GetPath(IntfID, ResourceType)
+    if Path == "" {
+        log.Error("Failed to get path")
+        return false
+    }
+
+    if err := PONRMgr.KVStore.Delete(Path); err != nil {
+        log.Errorf("Failed to delete resource %s", Path)
+        return false
+    }
+    log.Debugf("Cleared resource %s", Path)
+    return true
+}
+
+func (PONRMgr PONResourceManager) InitResourceMap(PONIntfONUID string) {
+    /*
+       Initialize resource map
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+    */
+    // initialize pon_intf_onu_id tuple to alloc_ids map
+    AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
+    var AllocIDs []byte
+    Result := PONRMgr.KVStore.Put(AllocIDPath, AllocIDs)
+    if Result != nil {
+        log.Error("Failed to update the KV store")
+        return
+    }
+    // initialize pon_intf_onu_id tuple to gemport_ids map
+    GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
+    var GEMPortIDs []byte
+    Result = PONRMgr.KVStore.Put(GEMPortIDPath, GEMPortIDs)
+    if Result != nil {
+        log.Error("Failed to update the KV store")
+        return
+    }
+}
+
+func (PONRMgr PONResourceManager) RemoveResourceMap(PONIntfONUID string) bool {
+    /*
+       Remove resource map
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+    */
+    // remove pon_intf_onu_id tuple to alloc_ids map
+    var err error
+    AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
+    if err = PONRMgr.KVStore.Delete(AllocIDPath); err != nil {
+        log.Errorf("Failed to remove resource %s", AllocIDPath)
+        return false
+    }
+    // remove pon_intf_onu_id tuple to gemport_ids map
+    GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
+    err = PONRMgr.KVStore.Delete(GEMPortIDPath)
+    if err != nil {
+        log.Errorf("Failed to remove resource %s", GEMPortIDPath)
+        return false
+    }
+
+    FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
+    if FlowIDs, err := PONRMgr.KVStore.List(FlowIDPath); err != nil {
+        for _, Flow := range FlowIDs {
+            FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow)
+            if err = PONRMgr.KVStore.Delete(FlowIDInfoPath); err != nil {
+                log.Errorf("Failed to remove resource %s", FlowIDInfoPath)
+                return false
+            }
+        }
+    }
+
+    if err = PONRMgr.KVStore.Delete(FlowIDPath); err != nil {
+        log.Errorf("Failed to remove resource %s", FlowIDPath)
+        return false
+    }
+
+    return true
+}
+
+func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(IntfONUID string) []uint32 {
+    /*
+       Get currently configured alloc ids for given pon_intf_onu_id
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :return list: List of alloc_ids if available, else None
+    */
+    Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+
+    var Data []uint32
+    Value, err := PONRMgr.KVStore.Get(Path)
+    if err == nil {
+        if Value != nil {
+            Val,err := ToByte(Value.Value)
+            if err != nil{
+                log.Errorw("Failed to convert into byte array",log.Fields{"error":err})
+                return Data
+            }
+            if err = json.Unmarshal(Val, &Data); err != nil {
+                log.Error("Failed to unmarshal",log.Fields{"error":err})
+                return Data
+            }
+        }
+    }
+    return Data
+}
+
+func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(IntfONUID string) []uint32 {
+    /*
+       Get currently configured gemport ids for given pon_intf_onu_id
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :return list: List of gemport IDs if available, else None
+    */
+
+    Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+    log.Debugf("Getting current gemports for %s", Path)
+    var Data []uint32
+    Value, err := PONRMgr.KVStore.Get(Path)
+    if err == nil {
+        if Value != nil {
+            Val, _ := ToByte(Value.Value)
+            if err = json.Unmarshal(Val, &Data); err != nil {
+                log.Errorw("Failed to unmarshal",log.Fields{"error":err})
+                return Data
+            }
+        }
+    } else {
+        log.Errorf("Failed to get data from kvstore for %s", Path)
+    }
+    return Data
+}
+
+func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(IntfONUID string) []uint32 {
+    /*
+       Get currently configured flow ids for given pon_intf_onu_id
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :return list: List of Flow IDs if available, else None
+    */
+
+    Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+
+    var Data []uint32
+    Value, err := PONRMgr.KVStore.Get(Path)
+    if err == nil {
+        if Value != nil {
+            Val, _ := ToByte(Value.Value)
+            if err = json.Unmarshal(Val, &Data); err != nil {
+                log.Error("Failed to unmarshal")
+                return Data
+            }
+        }
+    }
+    return Data
+}
+
+func (PONRMgr *PONResourceManager) GetFlowIDInfo(IntfONUID string, FlowID uint32, Data interface{})error{
+    /*
+       Get flow details configured for the ONU.
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param flow_id: Flow Id reference
+       :param Data: Result
+       :return error: nil if no error in getting from KV store
+    */
+
+    Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
+
+    Value, err := PONRMgr.KVStore.Get(Path)
+    if err == nil {
+        if Value != nil {
+            Val,err := ToByte(Value.Value)
+            if err != nil{
+                log.Errorw("Failed to convert flowinfo into byte array",log.Fields{"error":err})
+                return err
+            }
+            if err = json.Unmarshal(Val, Data); err != nil {
+                log.Errorw("Failed to unmarshal",log.Fields{"error":err})
+                return err
+            }
+        }
+    }
+    return err
+}
+
+func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(IntfONUID string, FlowID uint32) bool {
+    /*
+       Get flow_id details configured for the ONU.
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param flow_id: Flow Id reference
+    */
+    Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
+
+    if err := PONRMgr.KVStore.Delete(Path); err != nil {
+        log.Errorf("Falied to remove resource %s", Path)
+        return false
+    }
+    return true
+}
+
+func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(IntfONUID string, AllocIDs []uint32) error {
+    /*
+       Update currently configured alloc ids for given pon_intf_onu_id
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param alloc_ids: list of alloc ids
+    */
+    var Value []byte
+    var err error
+    Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+    Value, err = json.Marshal(AllocIDs)
+    if err != nil {
+        log.Error("failed to Marshal")
+        return err
+    }
+
+    if err = PONRMgr.KVStore.Put(Path, Value); err != nil {
+        log.Errorf("Failed to update resource %s", Path)
+        return err
+    }
+    return err
+}
+
+func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(IntfONUID string, GEMPortIDs []uint32) error {
+    /*
+       Update currently configured gemport ids for given pon_intf_onu_id
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param gemport_ids: list of gem port ids
+    */
+
+    var Value []byte
+    var err error
+    Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+    log.Debugf("Updating gemport ids for %s", Path)
+    Value, err = json.Marshal(GEMPortIDs)
+    if err != nil {
+        log.Error("failed to Marshal")
+        return err
+    }
+
+    if err = PONRMgr.KVStore.Put(Path, Value); err != nil {
+        log.Errorf("Failed to update resource %s", Path)
+        return err
+    }
+    return err
+}
+
+func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
+    /*
+       Check for a flow id in a given list of flow IDs.
+       :param FLowIDList: List of Flow IDs
+       :param FlowID: Flowd to check in the list
+       : return true and the index if present false otherwise.
+    */
+
+    for idx, _ := range FlowIDList {
+        if FlowID == FlowIDList[idx] {
+            return true, uint32(idx)
+        }
+    }
+    return false, 0
+}
+
+func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(IntfONUID string, FlowID uint32, Add bool) error {
+    /*
+       Update the flow_id list of the ONU (add or remove flow_id from the list)
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param flow_id: flow ID
+       :param add: Boolean flag to indicate whether the flow_id should be
+                   added or removed from the list. Defaults to adding the flow.
+    */
+    var Value []byte
+    var err error
+    var RetVal bool
+    var IDx uint32
+    Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
+    FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(IntfONUID)
+
+    if Add {
+        if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); RetVal == true {
+            return err
+        }
+        FlowIDs = append(FlowIDs, FlowID)
+    } else {
+        if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); RetVal == false {
+            return err
+        }
+        // delete the index and shift
+        FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
+    }
+    Value, err = json.Marshal(FlowIDs)
+    if err != nil {
+        log.Error("Failed to Marshal")
+        return err
+    }
+
+    if err = PONRMgr.KVStore.Put(Path, Value); err != nil {
+        log.Errorf("Failed to update resource %s", Path)
+        return err
+    }
+    return err
+}
+
+func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(IntfONUID string, FlowID uint32, FlowData interface {}) error {
+    /*
+       Update any metadata associated with the flow_id. The flow_data could be json
+       or any of other data structure. The resource manager doesnt care
+       :param pon_intf_onu_id: reference of PON interface id and onu id
+       :param flow_id: Flow ID
+       :param flow_data: Flow data blob
+    */
+    var Value []byte
+    var err error
+    Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
+    Value, err = json.Marshal(FlowData)
+    if err != nil {
+        log.Error("failed to Marshal")
+        return err
+    }
+
+    if err = PONRMgr.KVStore.Put(Path, Value); err != nil {
+        log.Errorf("Failed to update resource %s", Path)
+        return err
+    }
+    return err
+}
+
+func (PONRMgr *PONResourceManager) GenerateNextID(Resource map[string]interface{}) (uint32, error) {
+    /*
+       Generate unique id having OFFSET as start
+       :param resource: resource used to generate ID
+       :return uint32: generated id
+    */
+    ByteArray, err := ToByte(Resource[POOL])
+    if err != nil {
+        log.Error("Failed to convert resource to byte array")
+        return 0, err
+    }
+    Data := bitmap.TSFromData(ByteArray, false)
+    if Data == nil {
+        log.Error("Failed to get data from byte array")
+        return 0, errors.New("Failed to get data from byte array")
+    }
+
+    Len := Data.Len()
+    var Idx int
+    for Idx = 0; Idx < Len; Idx++ {
+        Val := Data.Get(Idx)
+        if Val == false {
+            break
+        }
+    }
+    Data.Set(Idx, true)
+    res := uint32(Resource[START_IDX].(float64))
+    Resource[POOL] = Data.Data(false)
+    log.Debugf("Generated ID for %d", (uint32(Idx) + res))
+    return (uint32(Idx) + res), err
+}
+
+func (PONRMgr *PONResourceManager) ReleaseID(Resource map[string]interface{}, Id uint32) bool {
+    /*
+       Release unique id having OFFSET as start index.
+       :param resource: resource used to release ID
+       :param unique_id: id need to be released
+    */
+    ByteArray, err := ToByte(Resource[POOL])
+    if err != nil {
+        log.Error("Failed to convert resource to byte array")
+        return false
+    }
+    Data := bitmap.TSFromData(ByteArray, false)
+    if Data == nil {
+        log.Error("Failed to get resource pool")
+        return false
+    }
+    var Idx uint32
+    Idx = Id - uint32(Resource[START_IDX].(float64))
+    Data.Set(int(Idx), false)
+    Resource[POOL] = Data.Data(false)
+
+    return true
+}
+
+func (PONRMgr *PONResourceManager) GetTechnology()string{
+    return PONRMgr.Technology
+}
+
+func (PONRMgr *PONResourceManager) GetResourceTypeAllocID()string{
+    return ALLOC_ID
+}
+
+func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID()string{
+    return GEMPORT_ID
+}
+
+
+
+// ToByte converts an interface value to a []byte.  The interface should either be of
+// a string type or []byte.  Otherwise, an error is returned.
+func ToByte(value interface{}) ([]byte, error) {
+    switch t := value.(type) {
+    case []byte:
+        return value.([]byte), nil
+    case string:
+        return []byte(value.(string)), nil
+    default:
+        return nil, fmt.Errorf("unexpected-type-%T", t)
+    }
+}
+
+// ToString converts an interface value to a string.  The interface should either be of
+// a string type or []byte.  Otherwise, an error is returned.
+func ToString(value interface{}) (string, error) {
+    switch t := value.(type) {
+    case []byte:
+        return string(value.([]byte)), nil
+    case string:
+        return value.(string), nil
+    default:
+        return "", fmt.Errorf("unexpected-type-%T", t)
+    }
+}