diff --git a/database/database.go b/database/database.go
new file mode 100644
index 0000000..11040b0
--- /dev/null
+++ b/database/database.go
@@ -0,0 +1,1048 @@
+/*
+* Copyright 2022-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.
+*/
+// This implementation of database assumes that it is working for
+// Open ONU adapter. Thus, it assumes some base path for all the
+// database operations. For all database operations, the key passed is
+// added to the database base path.
+
+package database
+
+import (
+	"context"
+	"errors"
+	"net"
+	"strconv"
+	"time"
+	"fmt"
+
+	"voltha-go-controller/internal/pkg/of"
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+var ctx = context.TODO()
+
+// Database structure
+type Database struct {
+	storeType string
+	address   string
+	//timeout   uint32
+	kvc       kvstore.Client
+}
+
+// Initialize the database module. The database module runs as a singleton
+// object and is initialized when the adapter is created.
+func Initialize(storeType string, address string, timeout int) (*Database, error) {
+	var err error
+	var database Database
+	logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
+	database.address = address
+	database.storeType = storeType
+	switch storeType {
+	case "redis":
+		database.kvc, err = kvstore.NewRedisClient(address, time.Duration(timeout), false)
+		return &database, err
+	}
+	return &database, errors.New("unsupported-kv-store")
+}
+
+// Utility function that retrieves value for a key. It is assumed that
+// the information is always a string and the data retrieved is returned
+// as a string
+
+// Put to add value to database
+func (db *Database) Put(fullKeyPath, value string) error {
+	return db.kvc.Put(context.Background(), fullKeyPath, value)
+}
+
+// Get to retrieve value from database
+func (db *Database) Get(key string) (string, error) {
+	kv, err := db.kvc.Get(context.Background(), key)
+	if err != nil {
+		return "", err
+	}
+	if kv != nil {
+		return string(kv.Value.([]byte)), nil
+	}
+	return "", errors.New("Value not found")
+}
+
+// Del to delete value from database
+func (db *Database) Del(fullPath string) error {
+	if err := db.kvc.Delete(context.Background(), fullPath); err != nil {
+		logger.Errorf(ctx, "The path doesn't exist", log.Fields{"key": fullPath, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DeleteAll to delete all value from database
+func (db *Database) DeleteAll(fullPath string) error {
+	if err := db.kvc.DeleteWithPrefix(context.Background(), fullPath); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": fullPath, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DeleteAllUnderHashKey to delete all values under hash key
+func (db *Database) DeleteAllUnderHashKey(hashKeyPrefix string) error {
+	if err := db.kvc.Delete(context.Background(), hashKeyPrefix); err != nil {
+		logger.Errorf(ctx, "The key path doesn't exist", log.Fields{"key": hashKeyPrefix, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// List to list the values
+func (db *Database) List(key string) (map[string]*kvstore.KVPair, error) {
+	kv, err := db.kvc.List(context.Background(), key)
+	if err != nil {
+		return nil, err
+	}
+	if kv != nil {
+		return kv, nil
+	}
+	return nil, errors.New("Value not found")
+}
+
+// OLT specific database items
+
+// GetOlt to get olt info
+func (db *Database) GetOlt(deviceID string) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DevicePath), deviceID)
+	return db.Get(key)
+}
+
+// PutOlt to add olt info
+func (db *Database) PutOlt(deviceID string, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DevicePath), deviceID)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelOlt to delete olt info
+func (db *Database) DelOlt(deviceID string) error {
+	key := fmt.Sprintf(GetKeyPath(DevicePath), deviceID)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Flows specific database actions
+
+// PutFlow to add flow
+func (db *Database) PutFlow(deviceID string, flowID uint64, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID) + strconv.FormatUint(flowID, 10)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetFlow to get flow
+func (db *Database) GetFlow(deviceID string, flowID uint64) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID) + strconv.FormatUint(flowID, 10)
+	return db.Get(key)
+}
+
+// GetFlows to get multiple flows
+func (db *Database) GetFlows(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID)
+	return db.List(key)
+}
+
+// DelFlow to delete flow
+func (db *Database) DelFlow(deviceID string, flowID uint64) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID) + strconv.FormatUint(flowID, 10)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Group specific database actions
+
+// PutGroup to add group info
+func (db *Database) PutGroup(deviceID string, groupID uint32, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceGroupPath), deviceID) + strconv.FormatUint(uint64(groupID), 10)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetGroup to get group info
+func (db *Database) GetGroup(deviceID string, groupID uint32) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceGroupPath), deviceID) + strconv.FormatUint(uint64(groupID), 10)
+	return db.Get(key)
+}
+
+// GetGroups to get multiple group info
+func (db *Database) GetGroups(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceGroupPath), deviceID)
+	logger.Infow(ctx, "key", log.Fields{"Key": key})
+	return db.List(key)
+}
+
+// DelGroup to delete group info
+func (db *Database) DelGroup(deviceID string, groupID uint32) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceGroupPath), deviceID) + strconv.FormatUint(uint64(groupID), 10)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllGroup to delete all group info
+func (db *Database) DelAllGroup(deviceID string) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceGroupPath), deviceID)
+	if err := db.DeleteAllUnderHashKey(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	logger.Infow(ctx, "Deleting all the groups for device", log.Fields{"device": deviceID})
+	return nil
+}
+
+// DelAllPorts to delete all ports info
+func (db *Database) DelAllPorts(device string) error {
+	key := fmt.Sprintf(GetKeyPath(DevicePortPath), device)
+	if err := db.DeleteAllUnderHashKey(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	logger.Infow(ctx, "Deleting all the ports for device", log.Fields{"device": device})
+	return nil
+}
+
+// Ports specific database actions
+
+// PutPort to add port info
+func (db *Database) PutPort(deviceID string, portID uint32, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DevicePortPath), deviceID) + strconv.FormatUint(uint64(portID), 10)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetPort to get port info
+func (db *Database) GetPort(deviceID string, portID uint32) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DevicePortPath), deviceID) + strconv.FormatUint(uint64(portID), 10)
+	return db.Get(key)
+}
+
+// GetPorts to get multiple ports info
+func (db *Database) GetPorts(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(DevicePortPath), deviceID)
+	return db.List(key)
+}
+
+// DelPort to delete port info
+func (db *Database) DelPort(deviceID string, portID uint32) error {
+	key := fmt.Sprintf(GetKeyPath(DevicePortPath), deviceID) + strconv.FormatUint(uint64(portID), 10)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Device meter specific database actions
+
+// PutDeviceMeter to add device meter info
+func (db *Database) PutDeviceMeter(deviceID string, meterID uint32, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceMeterPath), deviceID) + strconv.FormatUint(uint64(meterID), 10)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetDeviceMeter to get device meter info
+func (db *Database) GetDeviceMeter(deviceID string, meterID uint32) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceMeterPath), deviceID) + strconv.FormatUint(uint64(meterID), 10)
+	return db.Get(key)
+}
+
+// GetDeviceMeters to get multiple device meter info
+func (db *Database) GetDeviceMeters(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceMeterPath), deviceID)
+	return db.List(key)
+}
+
+// DelDeviceMeter to delete device meter info
+func (db *Database) DelDeviceMeter(deviceID string, meterID uint32) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceMeterPath), deviceID) + strconv.FormatUint(uint64(meterID), 10)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Service specific database actions
+
+// GetServices to get multiple services info
+func (db *Database) GetServices() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(ServicePath)
+	return db.List(key)
+}
+
+// GetService to get service info
+func (db *Database) GetService(name string) (string, error) {
+	key := GetKeyPath(ServicePath) + name
+	return db.Get(key)
+}
+
+// PutService to add service info
+func (db *Database) PutService(name string, value string) error {
+	key := GetKeyPath(ServicePath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelService to delete service info
+func (db *Database) DelService(name string) error {
+	key := GetKeyPath(ServicePath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Virtual networks specific database actions
+
+// GetVnets to get multiple vnets info
+func (db *Database) GetVnets() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(VnetPath)
+	return db.List(key)
+}
+
+// GetVnet to get vnet info
+func (db *Database) GetVnet(name string) (string, error) {
+	key := GetKeyPath(VnetPath) + name
+	return db.Get(key)
+}
+
+// PutVnet to add vnet info
+func (db *Database) PutVnet(name string, value string) error {
+	key := GetKeyPath(VnetPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelVnet to delete vnet info
+func (db *Database) DelVnet(name string) error {
+	key := GetKeyPath(VnetPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Virtual networks on ports specific database actions
+
+// GetVpvs to get multiple vpvs info
+func (db *Database) GetVpvs() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(VpvPath)
+	return db.List(key)
+}
+
+// GetVpv to get vpv info
+func (db *Database) GetVpv(port string, SVlan uint16, CVlan uint16, UniVlan uint16) (string, error) {
+	name := port + fmt.Sprintf("-%v-%v-%v", SVlan, CVlan, UniVlan)
+	key := GetKeyPath(VpvPath) + name
+	return db.Get(key)
+}
+
+// PutVpv to add vpv info
+func (db *Database) PutVpv(port string, SVlan uint16, CVlan uint16, UniVlan uint16, value string) error {
+	name := port + fmt.Sprintf("-%v-%v-%v", SVlan, CVlan, UniVlan)
+	key := GetKeyPath(VpvPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelVpv to delete vpv info
+func (db *Database) DelVpv(port string, SVlan uint16, CVlan uint16, UniVlan uint16) error {
+	name := port + fmt.Sprintf("-%v-%v-%v", SVlan, CVlan, UniVlan)
+	key := GetKeyPath(VpvPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Virtual networks on ports specific database actions
+
+// GetMvlans to get multiple mvlans info
+func (db *Database) GetMvlans() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(MvlanPath)
+	return db.List(key)
+}
+
+// GetMvlan to get mvlan info
+func (db *Database) GetMvlan(mvlan uint16) (string, error) {
+	name := strconv.FormatInt(int64(mvlan), 10)
+	key := GetKeyPath(MvlanPath) + name
+	return db.Get(key)
+}
+
+// PutMvlan to add mvlan info
+func (db *Database) PutMvlan(mvlan uint16, value string) error {
+	name := strconv.FormatInt(int64(mvlan), 10)
+	key := GetKeyPath(MvlanPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelMvlan to delete mvlan info
+func (db *Database) DelMvlan(mvlan uint16) error {
+	name := strconv.FormatInt(int64(mvlan), 10)
+	key := GetKeyPath(MvlanPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// database specific actions on IGMP config
+
+// DelIGMPCfg to delete icmp config
+func (db *Database) DelIGMPCfg() error {
+	key := GetKeyPath(IgmpConfPath)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// database specific actions on IGMP Profile
+
+// GetIgmpProfiles to get multiple igmp profile info
+func (db *Database) GetIgmpProfiles() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpProfPath)
+	return db.List(key)
+}
+
+// GetIgmpProfile to get igmp profile info
+func (db *Database) GetIgmpProfile(name string) (string, error) {
+	key := GetKeyPath(IgmpProfPath) + name
+	return db.Get(key)
+}
+
+// PutIgmpProfile to put igmp profile info
+func (db *Database) PutIgmpProfile(name string, value string) error {
+	key := GetKeyPath(IgmpProfPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelIgmpProfile to delete igmp profile
+func (db *Database) DelIgmpProfile(name string) error {
+	key := GetKeyPath(IgmpProfPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// database specific actions on Mcast config Info
+
+// GetMcastConfigs to get multiple mcast config info
+func (db *Database) GetMcastConfigs() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(McastConfigPath)
+	return db.List(key)
+}
+
+// GetMcastConfig to get igmp profile info
+func (db *Database) GetMcastConfig(name string) (string, error) {
+	key := GetKeyPath(McastConfigPath) + name
+	return db.Get(key)
+}
+
+// PutMcastConfig to put igmp profile info
+func (db *Database) PutMcastConfig(name string, value string) error {
+	key := GetKeyPath(McastConfigPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelMcastConfig to delete igmp profile
+func (db *Database) DelMcastConfig(name string) error {
+	key := GetKeyPath(McastConfigPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// database specific actions on health
+
+// GetHealth to get health info
+func (db *Database) GetHealth() (string, error) {
+	key := GetKeyPath(HealthPath)
+	return db.Get(key)
+}
+
+// PutHealth to add health info
+func (db *Database) PutHealth(value string) error {
+	key := GetKeyPath(HealthPath)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelHealth to delete health info
+func (db *Database) DelHealth() error {
+	key := GetKeyPath(HealthPath)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// Meters
+
+// GetMeters to get multiple meters info
+func (db *Database) GetMeters() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(MeterPath)
+	return db.List(key)
+}
+
+// GetMeter to get meter info
+func (db *Database) GetMeter(name string) (string, error) {
+	key := GetKeyPath(MeterPath) + name
+	return db.Get(key)
+}
+
+// PutMeter to add meter info
+func (db *Database) PutMeter(name string, value string) error {
+	key := GetKeyPath(MeterPath) + name
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelMeter to delete meter info
+func (db *Database) DelMeter(name string) error {
+	key := GetKeyPath(MeterPath) + name
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllMeter to delete meter info
+func (db *Database) DelAllMeter(device string) error {
+	key := GetKeyPath(DevicePath) + device + "/" + MeterPath
+	if err := db.DeleteAllUnderHashKey(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	logger.Infow(ctx, "Deleting all the meters for device", log.Fields{"device": device})
+	return nil
+}
+
+// IGMP groups
+
+// GetIgmpGroups to get multiple igmp groups info
+func (db *Database) GetIgmpGroups() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpGroupPath)
+	return db.List(key)
+}
+
+// GetIgmpGroup to get igmp group info
+func (db *Database) GetIgmpGroup(id string) (string, error) {
+	key := GetKeyPath(IgmpGroupPath) + id
+	return db.Get(key)
+}
+
+// PutIgmpGroup to add igmp group info
+func (db *Database) PutIgmpGroup(id string, value string) error {
+	key := GetKeyPath(IgmpGroupPath) + id
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelIgmpGroup to delete igmp group info
+func (db *Database) DelIgmpGroup(id string) error {
+	key := GetKeyPath(IgmpGroupPath) + id
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// IGMP group devices
+
+// GetAllIgmpDevices to get multiple igmp devices info
+func (db *Database) GetAllIgmpDevices() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpDevicePath)
+	return db.List(key)
+}
+
+// GetPrevIgmpDevices to get previous igmp devices
+func (db *Database) GetPrevIgmpDevices(mvlan of.VlanType, gid string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpDevicePath) + mvlan.String() + "/" + gid + "/"
+	return db.List(key)
+}
+
+// GetIgmpDevices to get igmp devices
+func (db *Database) GetIgmpDevices(mvlan of.VlanType, gid string, gip net.IP) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpDevicePath) + mvlan.String() + "/" + gid + "/" + gip.String() + "/"
+	return db.List(key)
+}
+
+// GetIgmpDevice to get igmp device
+func (db *Database) GetIgmpDevice(mvlan of.VlanType, gid string, gip net.IP, device string) (string, error) {
+	key := GetKeyPath(IgmpDevicePath) + mvlan.String() + "/" + gid + "/" + gip.String() + "/" + device
+	return db.Get(key)
+}
+
+// PutIgmpDevice to add igmp device
+func (db *Database) PutIgmpDevice(mvlan of.VlanType, gid string, gip net.IP, device string, value string) error {
+	key := GetKeyPath(IgmpDevicePath) + mvlan.String() + "/" + gid + "/" + gip.String() + "/" + device
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelIgmpDevice to delete igmp device
+func (db *Database) DelIgmpDevice(mvlan of.VlanType, gid string, gip net.IP, device string) error {
+	key := GetKeyPath(IgmpDevicePath) + mvlan.String() + "/" + gid + "/" + gip.String() + "/" + device
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// IGMP group channels
+
+// GetAllIgmpChannels to get all igmp channels
+func (db *Database) GetAllIgmpChannels() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpChannelPath)
+	return db.List(key)
+}
+
+// GetPrevIgmpChannels to get previous igmp channels
+func (db *Database) GetPrevIgmpChannels(gName, device string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpChannelPath) + gName + "/" + device + "/"
+	return db.List(key)
+}
+
+// GetIgmpChannels to get multiple igmp channels
+func (db *Database) GetIgmpChannels(mvlan of.VlanType, gName, device string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpChannelPath) + mvlan.String() + "/" + gName + "/" + device + "/"
+	return db.List(key)
+}
+
+// GetIgmpChannel to get igmp channel
+func (db *Database) GetIgmpChannel(mvlan of.VlanType, gName string, device string, gip net.IP) (string, error) {
+	key := GetKeyPath(IgmpChannelPath) + mvlan.String() + "/" + gName + "/" + device + "/" + gip.String()
+	return db.Get(key)
+}
+
+// PutIgmpChannel to add igmp channel info
+func (db *Database) PutIgmpChannel(mvlan of.VlanType, gName string, device string, gip net.IP, value string) error {
+	key := GetKeyPath(IgmpChannelPath) + mvlan.String() + "/" + gName + "/" + device + "/" + gip.String()
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelIgmpChannel to delete igmp channel info
+func (db *Database) DelIgmpChannel(mvlan of.VlanType, gName string, device string, gip net.IP) error {
+	key := GetKeyPath(IgmpChannelPath) + mvlan.String() + "/" + gName + "/" + device + "/" + gip.String()
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// IGMP group receivers
+
+// GetAllIgmpRcvrs to get all igmp receivers info
+func (db *Database) GetAllIgmpRcvrs() (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpPortPath)
+	return db.List(key)
+}
+
+// GetPrevIgmpRcvrs to get previous igmp receivers info
+func (db *Database) GetPrevIgmpRcvrs(gip net.IP, device string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpPortPath) + gip.String() + "/" + device + "/"
+	return db.List(key)
+}
+
+// GetIgmpRcvrs to get multiple igmp receivers info
+func (db *Database) GetIgmpRcvrs(mvlan of.VlanType, gip net.IP, device string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(IgmpPortPath) + mvlan.String() + "/" + gip.String() + "/" + device + "/"
+	return db.List(key)
+}
+
+// GetIgmpRcvr to get igmp receiver info
+func (db *Database) GetIgmpRcvr(mvlan of.VlanType, gip net.IP, device string, rcvr string) (string, error) {
+	key := GetKeyPath(IgmpPortPath) + mvlan.String() + "/" + gip.String() + "/" + device + "/" + rcvr
+	return db.Get(key)
+}
+
+// PutIgmpRcvr to add igmp receiver info
+func (db *Database) PutIgmpRcvr(mvlan of.VlanType, gip net.IP, device string, rcvr string, value string) error {
+	key := GetKeyPath(IgmpPortPath) + mvlan.String() + "/" + gip.String() + "/" + device + "/" + rcvr
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelIgmpRcvr to delete igmp receiver info
+func (db *Database) DelIgmpRcvr(mvlan of.VlanType, gip net.IP, device string, rcvr string) error {
+	key := GetKeyPath(IgmpPortPath) + mvlan.String() + "/" + gip.String() + "/" + device + "/" + rcvr
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllIgmpRcvr to delete all igmp receiver info
+func (db *Database) DelAllIgmpRcvr(mvlan of.VlanType, gip net.IP, device string) error {
+	key := GetKeyPath(IgmpPortPath) + mvlan.String() + "/" + gip.String() + "/" + device + "/"
+	if err := db.DeleteAll(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllRoutesForDevice to delete all routes for device
+func (db *Database) DelAllRoutesForDevice(device string) error {
+	/* service/vgc/v1/devices/<deviceID>/flows/ */
+	logger.Infow(ctx, "Deleting all the flows for device", log.Fields{"device": device})
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), device)
+	if err := db.DeleteAllUnderHashKey(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// PutNbDevicePort to add device port info
+func (db *Database) PutNbDevicePort(device string, ponPortID uint32, value string) {
+	key := GetKeyPath(NbDevicePath) + device + "/pon-port/" + fmt.Sprintf("%v", ponPortID)
+
+	if err := db.kvc.Put(context.Background(), key, value); err != nil {
+		logger.Warnf(ctx, "Put Device Port failed", key)
+	}
+}
+
+// DelNbDevicePort to delete device port
+func (db *Database) DelNbDevicePort(device string, ponPortID uint32) {
+	key := GetKeyPath(NbDevicePath) + device + "/pon-port/" + fmt.Sprintf("%v", ponPortID)
+
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "Delete Device Port failed", key)
+	}
+}
+
+// GetAllNbPorts to get all ports info
+func (db *Database) GetAllNbPorts(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(NbDevicePath) + deviceID + "/pon-port/"
+	return db.List(key)
+}
+
+//Functions for migration database
+
+// GetMigrationInfo to get migration info
+func (db *Database) GetMigrationInfo() (string, error) {
+	key := GetKeyPath(MigrationInfoPath)
+	return db.Get(key)
+}
+
+// PutMigrationInfo to add migration info
+func (db *Database) PutMigrationInfo(value string) error {
+	key := GetKeyPath(MigrationInfoPath)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelMigrationInfo to delete migration info
+func (db *Database) DelMigrationInfo() error {
+	key := GetKeyPath(MigrationInfoPath)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+//PON counters
+
+// GetAllPonCounters to get all pon counters info
+func (db *Database) GetAllPonCounters(device string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(PonCounterPath) + device
+	return db.List(key)
+}
+
+// GetPonCounter to get pon counter info
+func (db *Database) GetPonCounter(device, ponID string) (string, error) {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID
+	return db.Get(key)
+}
+
+// PutPonCounter to add pon counter info
+func (db *Database) PutPonCounter(device, ponID, value string) error {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelPonCounter to delete pon counter info
+func (db *Database) DelPonCounter(device, ponID string) error {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+//PON Channel counters
+
+// GetAllPonChannelCounters to get all pon channel counters
+func (db *Database) GetAllPonChannelCounters(device, ponID string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID + "/" + ChannelCounterPath
+	return db.List(key)
+}
+
+// GetPonChannelCounter to get pon channel counter
+func (db *Database) GetPonChannelCounter(device, ponID, channel string) (string, error) {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID + "/" + ChannelCounterPath + channel
+	return db.Get(key)
+}
+
+// PutPonChannelCounter to add pon channel counter
+func (db *Database) PutPonChannelCounter(device, ponID, channel, value string) error {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID + "/" + ChannelCounterPath + channel
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelPonChannelCounter to delete pon channel counter
+func (db *Database) DelPonChannelCounter(device, ponID, channel string) error {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID + "/" + ChannelCounterPath + channel
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllPONCounters to delete all pon channel counters
+func (db *Database) DelAllPONCounters(device string) error {
+	key := GetKeyPath(PonCounterPath) + device + "/"
+	return db.DeleteAll(key)
+}
+
+// DelPONCounters to delete pon counters
+func (db *Database) DelPONCounters(device string, ponID string) {
+	key := GetKeyPath(PonCounterPath) + device + "/" + ponID + "/"
+	if err := db.DeleteAll(key); err != nil {
+		logger.Warnf(ctx, "Delete Pon counters failed", key)
+	}
+	//DeletePonCounter(device, ponID)
+}
+
+// PutOltIgmpCounters to add Olt Igmp counter info
+func (db *Database) PutOltIgmpCounters(device, value string) error {
+	key := GetKeyPath(OltIgmpCounterPath) + device
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetOltIgmpCounter to get Olt Igmp counter info
+func (db *Database) GetOltIgmpCounter(device string) (string, error) {
+	key := GetKeyPath(OltIgmpCounterPath) + device
+	return db.Get(key)
+}
+
+//Service Channel counters
+
+// GetAllServiceChannelCounters to get all service channel counters info
+func (db *Database) GetAllServiceChannelCounters(serviceName string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(ServiceCounterPath) + serviceName + "/" + ChannelCounterPath
+	return db.List(key)
+}
+
+// GetServiceChannelCounter to get service channel counter info
+func (db *Database) GetServiceChannelCounter(serviceName, channel string) (string, error) {
+	key := GetKeyPath(ServiceCounterPath) + serviceName + "/" + ChannelCounterPath + channel
+	return db.Get(key)
+}
+
+// PutServiceChannelCounter to add service channel counter
+func (db *Database) PutServiceChannelCounter(serviceName, channel, value string) error {
+	key := GetKeyPath(ServiceCounterPath) + serviceName + "/" + ChannelCounterPath + channel
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// DelServiceChannelCounter to delete service channel counter
+func (db *Database) DelServiceChannelCounter(serviceName, channel string) error {
+	key := GetKeyPath(ServiceCounterPath) + serviceName + "/" + ChannelCounterPath + channel
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllServiceChannelCounter to delete all service channel counter
+func (db *Database) DelAllServiceChannelCounter(serviceName string) error {
+	key := GetKeyPath(ServiceCounterPath) + serviceName + "/" + ChannelCounterPath
+	return db.DeleteAllUnderHashKey(key)
+}
+
+// OltExists to know if the ONU is added to the database
+func (db *Database) OltExists(deviceID string) bool {
+	if _, err := db.GetOlt(deviceID); err != nil {
+		return false
+	}
+	return true
+
+}
+
+// PutFlowHash to add flowhash for the device
+func (db *Database) PutFlowHash(deviceID string, value string) error {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID)
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetFlowHash gets the flow hash for the device
+func (db *Database) GetFlowHash(deviceID string) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(DeviceFlowPath), deviceID)
+	return db.Get(key)
+}
+
+// PutPortAlarmProfile to add port alarm profile
+func (db *Database) PutPortAlarmProfile(portAlarmProfileID string, value string) {
+	key := GetKeyPath(PortAlarmProfilePath) + fmt.Sprintf("%v", portAlarmProfileID)
+	if err := db.kvc.Put(context.Background(), key, value); err != nil {
+		logger.Warnf(ctx, "Put PortAlarmProfile failed", key)
+	}
+}
+
+// DelPortAlarmProfile to delete port alarm profile
+func (db *Database) DelPortAlarmProfile(portAlarmProfileID string) {
+	key := GetKeyPath(PortAlarmProfilePath) + fmt.Sprintf("%v", portAlarmProfileID)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "Delete PortAlarmProfile failed", key)
+	}
+}
+
+// GetPortAlarmProfile to get port alarm profile
+func (db *Database) GetPortAlarmProfile(portAlarmProfileID string) (map[string]*kvstore.KVPair, error) {
+	key := GetKeyPath(PortAlarmProfilePath) + fmt.Sprintf("%v", portAlarmProfileID)
+	return db.List(key)
+}
+
+// PutPortAlarmData to add port alarm data
+func (db *Database) PutPortAlarmData(deviceID string, portID uint32, value string) {
+	key := fmt.Sprintf(GetKeyPath(PortAlarmDataPath), deviceID) + fmt.Sprintf("%v", portID)
+	if err := db.kvc.Put(context.Background(), key, value); err != nil {
+		logger.Warnf(ctx, "Put PortAlarmData failed", key)
+	}
+}
+
+// DelPortAlarmData to delete port alarm data
+func (db *Database) DelPortAlarmData(deviceID string, portID uint32) {
+	key := fmt.Sprintf(GetKeyPath(PortAlarmDataPath), deviceID) + fmt.Sprintf("%v", portID)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "Delete PortAlarmData failed", key)
+	}
+}
+
+// GetPortAlarmData to get port alarm data
+func (db *Database) GetPortAlarmData(deviceID string, portID uint32) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(PortAlarmDataPath), deviceID) + fmt.Sprintf("%v", portID)
+	return db.Get(key)
+}
+
+// GetAllPortAlarmData to get port alarm data for all ports
+func (db *Database) GetAllPortAlarmData(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(PortAlarmDataPath), deviceID)
+	return db.List(key)
+}
+
+// PutSubAlarmData to add subscriber alarm data
+func (db *Database) PutSubAlarmData(deviceID string, portName string, value string) {
+	key := fmt.Sprintf(GetKeyPath(SubAlarmDataPath), deviceID) + fmt.Sprintf("%v", portName)
+	if err := db.kvc.Put(context.Background(), key, value); err != nil {
+		logger.Warnf(ctx, "Put Subscriber AlarmData failed", key)
+	}
+}
+
+// DelSubAlarmData to delete subscriber alarm data
+func (db *Database) DelSubAlarmData(deviceID string, portName string) {
+	key := fmt.Sprintf(GetKeyPath(SubAlarmDataPath), deviceID) + fmt.Sprintf("%v", portName)
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Warnf(ctx, "Delete Subscriber AlarmData failed", key)
+	}
+}
+
+// GetSubAlarmData to get subscriber alarm data
+func (db *Database) GetSubAlarmData(deviceID string, portName string) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(SubAlarmDataPath), deviceID) + fmt.Sprintf("%v", portName)
+	return db.Get(key)
+}
+
+// GetAllSubAlarmData to get sub alarm data for all subscribers
+func (db *Database) GetAllSubAlarmData(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(SubAlarmDataPath), deviceID)
+	return db.List(key)
+}
+
+// Migrate Service req specific database actions
+
+// PutMigrateServicesReq to add MigrateServicesReq info
+func (db *Database) PutMigrateServicesReq(deviceID string, vnet string, value string) error {
+	key := fmt.Sprintf(GetKeyPath(ServicesMigrateReqPath), deviceID) + vnet
+	return db.kvc.Put(context.Background(), key, value)
+}
+
+// GetMigrateServicesReq to get MigrateServicesReq info
+func (db *Database) GetMigrateServicesReq(deviceID string, vnet string) (string, error) {
+	key := fmt.Sprintf(GetKeyPath(ServicesMigrateReqPath), deviceID) + vnet
+	return db.Get(key)
+}
+
+// GetAllMigrateServicesReq to get multiple MigrateServicesReq info
+func (db *Database) GetAllMigrateServicesReq(deviceID string) (map[string]*kvstore.KVPair, error) {
+	key := fmt.Sprintf(GetKeyPath(ServicesMigrateReqPath), deviceID)
+	return db.List(key)
+}
+
+// DelMigrateServicesReq to delete MigrateServicesReq info
+func (db *Database) DelMigrateServicesReq(deviceID string, vnet string) error {
+	key := fmt.Sprintf(GetKeyPath(ServicesMigrateReqPath), deviceID) + vnet
+	if err := db.kvc.Delete(context.Background(), key); err != nil {
+		logger.Errorf(ctx, "The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	return nil
+}
+
+// DelAllMigrateServicesReq to delete all MigrateServicesReq info
+func (db *Database) DelAllMigrateServicesReq(deviceID string) error {
+	key := fmt.Sprintf(GetKeyPath(ServicesMigrateReqPath), deviceID)
+	if err := db.DeleteAllUnderHashKey(key); err != nil {
+		logger.Warnf(ctx, "Delete All failed: The key doesn't exist", log.Fields{"key": key, "Error": err})
+		return err
+	}
+	logger.Infow(ctx, "Deleting all the Update Vnet Requests for device", log.Fields{"device": deviceID})
+	return nil
+}
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
