diff --git a/pkg/config/config.go b/pkg/config/config.go
new file mode 100644
index 0000000..d395bb2
--- /dev/null
+++ b/pkg/config/config.go
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2020-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 config Common Logger initialization
+package config
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+)
+
+// Constants defined for environment variables
+const (
+	envLogLevel            = "LOG_LEVEL"
+	envMsgbusEndPoint      = "MSGBUS_END_POINT"
+	envMsgbusRetryInterval = "MSGBUS_RETRY_INTERVAL"
+	envDbEndPoint          = "DB_END_POINT"
+	envDbTimeout           = "DB_TIMEOUT"
+	envGrpcEndPoint        = "GRPC_END_POINT"
+	envGrpcRetryInterval   = "GRPC_RETRY_INTERVAL"
+	envGrpcBackoffMaxDelay = "GRPC_BACKOFF_MAX_DELAY"
+	envGrpcMaxRetryCount   = "GRPC_MAX_RETRY_COUNT"
+	envSecureConnection    = "SECURE_GRPC"
+)
+
+// Default values defined if not provided through environment variables
+const (
+	defaultLogLevel            = LogLevelDebug
+	defaultMsgbusEndPoint      = "127.0.0.1:9092"
+	defaultMsgbusRetryInterval = 10 * time.Second
+	defaultDbEndPoint          = "127.0.0.1:2379"
+	defaultDbTimeout           = 5 * time.Second
+	defaultGrpcEndPoint        = "0.0.0.0:9292"
+	defaultGrpcRetryInterval   = 10 * time.Second
+	defaultGrpcBackoffMaxDelay = 30 * time.Second
+	defaultGrpcMaxRetryCount   = 5
+	defaultGrpcHostName        = "DMI"
+	defaultSecureConnection    = false
+)
+
+// Constants defined for certiifcates
+const (
+	pathRootCaCrt = "/etc/Root_CA.crt"
+	pathServerCrt = "/etc/grpc_server.crt"
+	pathServerKey = "/etc/grpc_server.key"
+)
+
+// DB versions
+const (
+	DBVer1 = "v1"
+)
+
+// Constants defined for Db
+const (
+	KVStore  = "etcd"
+	DBPrefix = "/OpenDevMgr/"
+	CurDBVer = DBVer1
+)
+
+// Constants defined for Msgbus Topic to receive messages
+const (
+	OpenDevMgrEventsTopic   = "dm.events"
+	OpenDevMgrMetricsTopic  = "dm.metrics"
+	OpenDevMgrEventsMsgType = "OPEN-DEV-MGR-EVENTS-MSG"
+)
+
+// Log Level Constants
+const (
+	LogLevelDebug = "DEBUG"
+	LogLevelInfo  = "INFO"
+	LogLevelWarn  = "WARN"
+	LogLevelError = "ERROR"
+)
+
+type correlationIdType int8
+
+// Constants defined for context management
+const (
+	RequestIdKey correlationIdType = iota
+	SessionIdKey
+)
+
+// ContextId constant used to print context id in logs
+const (
+	ContextId = "context-id"
+)
+
+var coreFlags *CoreFlags
+
+// NewCoreFlags creates a new CoreFlag object for you
+func NewCoreFlags() *CoreFlags {
+	if coreFlags != nil {
+		return coreFlags
+	}
+	coreFlags = new(CoreFlags)
+	coreFlags.LogLevel = defaultLogLevel
+	coreFlags.MsgbusEndPoint = defaultMsgbusEndPoint
+	coreFlags.MsgbusRetryInterval = defaultMsgbusRetryInterval
+	coreFlags.DbEndPoint = defaultDbEndPoint
+	coreFlags.DbTimeout = defaultDbTimeout
+	coreFlags.SecureConnection = defaultSecureConnection
+	coreFlags.GrpcFlags.GrpcEndPoint = defaultGrpcEndPoint
+	coreFlags.GrpcFlags.GrpcRetryInterval = defaultGrpcRetryInterval
+	coreFlags.GrpcFlags.GrpcBackoffMaxDelay = defaultGrpcBackoffMaxDelay
+	coreFlags.GrpcFlags.GrpcMaxRetryCount = defaultGrpcMaxRetryCount
+	coreFlags.GrpcFlags.GrpcHostName = defaultGrpcHostName
+	coreFlags.CertsPath.RootCaCrt = pathRootCaCrt
+	coreFlags.CertsPath.ServerCrt = pathServerCrt
+	coreFlags.CertsPath.ServerKey = pathServerKey
+	return coreFlags
+}
+
+// GetCoreFlags returns the entire config values
+func GetCoreFlags() *CoreFlags {
+	if coreFlags != nil {
+		return coreFlags
+	}
+	return nil
+}
+
+// GetGrpcFlags returns the grpc config values
+func GetGrpcFlags() *GrpcFlags {
+	if coreFlags != nil {
+		return &coreFlags.GrpcFlags
+	}
+	return nil
+}
+
+// GrpcFlags is struct defined to store grpc parameters
+type GrpcFlags struct {
+	GrpcEndPoint        string
+	GrpcRetryInterval   time.Duration
+	GrpcBackoffMaxDelay time.Duration
+	GrpcMaxRetryCount   int
+	GrpcHostName        string
+}
+
+// CertsPath is struct defined to store certificates path
+type CertsPath struct {
+	RootCaCrt string
+	ServerCrt string
+	ServerKey string
+}
+
+// CoreFlags is a structure defined to store all configurations
+type CoreFlags struct {
+	LogLevel            string
+	MsgbusEndPoint      string
+	MsgbusRetryInterval time.Duration
+	DbEndPoint          string
+	DbTimeout           time.Duration
+	SecureConnection    bool
+	GrpcFlags
+	CertsPath
+}
+
+// ParseEnv method retrieves environment variables passed and replaces with
+// corresponding default variables stored in the CoreFlags object
+func (cf *CoreFlags) ParseEnv() {
+
+	if env := os.Getenv(envLogLevel); env != "" {
+		cf.LogLevel = env
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envLogLevel, cf.LogLevel)
+
+	if env := os.Getenv(envMsgbusEndPoint); env != "" {
+		cf.MsgbusEndPoint = env
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envMsgbusEndPoint, cf.MsgbusEndPoint)
+
+	if env := os.Getenv(envMsgbusRetryInterval); env != "" {
+		interval, err := strconv.Atoi(env)
+		if err == nil {
+			cf.MsgbusRetryInterval = time.Duration(interval) * time.Second
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envMsgbusRetryInterval)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envMsgbusRetryInterval, cf.MsgbusRetryInterval)
+
+	if env := os.Getenv(envDbEndPoint); env != "" {
+		cf.DbEndPoint = env
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envDbEndPoint, cf.DbEndPoint)
+
+	if env := os.Getenv(envDbTimeout); env != "" {
+		interval, err := strconv.Atoi(env)
+		if err == nil {
+			cf.DbTimeout = time.Duration(interval) * time.Second
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envDbTimeout)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envDbTimeout, cf.DbTimeout)
+
+	if env := os.Getenv(envGrpcEndPoint); env != "" {
+		cf.GrpcFlags.GrpcEndPoint = env
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envGrpcEndPoint, cf.GrpcFlags.GrpcEndPoint)
+
+	if env := os.Getenv(envGrpcRetryInterval); env != "" {
+		interval, err := strconv.Atoi(env)
+		if err == nil {
+			cf.GrpcFlags.GrpcRetryInterval = time.Duration(interval) * time.Second
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envGrpcRetryInterval)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envGrpcRetryInterval, cf.GrpcFlags.GrpcRetryInterval)
+
+	if env := os.Getenv(envGrpcBackoffMaxDelay); env != "" {
+		interval, err := strconv.Atoi(env)
+		if err == nil {
+			cf.GrpcFlags.GrpcBackoffMaxDelay = time.Duration(interval) * time.Second
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envGrpcBackoffMaxDelay)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %s\n", envGrpcBackoffMaxDelay, cf.GrpcFlags.GrpcBackoffMaxDelay)
+
+	if env := os.Getenv(envGrpcMaxRetryCount); env != "" {
+		maxRetry, err := strconv.Atoi(env)
+		if err == nil {
+			cf.GrpcFlags.GrpcMaxRetryCount = maxRetry
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envGrpcMaxRetryCount)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %v\n", envGrpcMaxRetryCount, cf.GrpcFlags.GrpcMaxRetryCount)
+
+	if env := os.Getenv(envSecureConnection); env != "" {
+		secureCon, err := strconv.ParseBool(env)
+		if err == nil {
+			cf.SecureConnection = secureCon
+		} else {
+			fmt.Printf("Invalid value '%s' passed for '%s'. Taking the default value.\n", env, envSecureConnection)
+		}
+	}
+	fmt.Printf("Environment variable '%s' setting to : %v\n", envSecureConnection, cf.SecureConnection)
+
+}
diff --git a/pkg/config/core.go b/pkg/config/core.go
new file mode 100644
index 0000000..f828138
--- /dev/null
+++ b/pkg/config/core.go
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020-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 config Common Logger initialization
+package config
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/google/uuid"
+)
+
+var ctxGlobal context.Context
+
+// Core represent read,write core attributes
+type Core struct {
+	Ctx     context.Context
+	Cancel  context.CancelFunc
+	Stopped chan struct{}
+}
+
+// NewCoreConfig will give the new core configuration
+func NewCoreConfig() *Core {
+	ctx, cancelCtx := context.WithCancel(context.Background())
+	core := &Core{Ctx: ctx, Cancel: cancelCtx, Stopped: make(chan struct{})}
+	ctxGlobal = ctx
+	return core
+}
+
+// GetContext returns global context
+func GetContext() context.Context {
+	return ctxGlobal
+}
+
+func retConstructedContxt(ctx context.Context, msg string) context.Context {
+	id, _ := uuid.NewRandom()
+	var reqID string
+	if msg != "" {
+		reqID = fmt.Sprintf("%s-%v", msg, id)
+	} else {
+		reqID = fmt.Sprintf("%v", id)
+	}
+	ctx2 := context.WithValue(ctx, RequestIdKey, reqID)
+	return ctx2
+}
+
+// GetNewContextFromGlobalContxt returns context from global context
+func GetNewContextFromGlobalContxt(msg string) context.Context {
+	return retConstructedContxt(ctxGlobal, msg)
+}
+
+// GetNewContextFromContxt returns new context from passed context
+func GetNewContextFromContxt(ctx context.Context, msg string) context.Context {
+	return retConstructedContxt(ctx, msg)
+}
diff --git a/pkg/config/logger.go b/pkg/config/logger.go
new file mode 100644
index 0000000..d6f4ffa
--- /dev/null
+++ b/pkg/config/logger.go
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-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 config Common log initialization
+package config
+
+import (
+	log "github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// logger represents the log object
+var logger log.CLogger
+
+// Initlog initialise log package
+func Initlog() log.CLogger {
+	if logger != nil {
+		return logger
+	}
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+
+	coreFlags := NewCoreFlags()
+
+	var logLevel log.LogLevel
+
+	switch coreFlags.LogLevel {
+	case LogLevelDebug:
+		logLevel = log.DebugLevel
+	case LogLevelInfo:
+		logLevel = log.InfoLevel
+	case LogLevelWarn:
+		logLevel = log.WarnLevel
+	case LogLevelError:
+		logLevel = log.ErrorLevel
+	default:
+		logLevel = log.ErrorLevel
+	}
+
+	logger, err = log.RegisterPackage(log.JSON, logLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+	return logger
+}
diff --git a/pkg/db/connection.go b/pkg/db/connection.go
new file mode 100644
index 0000000..52cf88b
--- /dev/null
+++ b/pkg/db/connection.go
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2020-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 holds utils for datastore implementation
+package db
+
+import (
+	"context"
+	"errors"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/db"
+	"github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/probe"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+
+	"github.com/opencord/opendevice-manager/pkg/config"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+var kvClient *KvStoreClient
+
+// KvStoreClient holds the KVStore info
+type KvStoreClient struct {
+	client kvstore.Client
+}
+
+// logger represents the log object
+var logger log.CLogger
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+}
+
+// NewKVClient function initialises and connects to KVStore
+func NewKVClient(ctx context.Context, storeType, address string, timeout time.Duration) (kvstore.Client, error) {
+	ctx1, cancel := context.WithTimeout(ctx, timeout)
+	logger.Infow(ctx, "kv-store-type", log.Fields{"store": config.KVStore})
+	switch storeType {
+	case "etcd":
+		etcdClient, err := kvstore.NewEtcdClient(ctx1, address, timeout, log.FatalLevel)
+		defer cancel()
+		if !etcdClient.IsConnectionUp(ctx1) {
+			logger.Errorw(ctx, "etcd-server-unreachable", log.Fields{"address": address})
+			return nil, errors.New("etcd client unreachable")
+		}
+		kvClient = new(KvStoreClient)
+		kvClient.client = etcdClient
+		return etcdClient, err
+	}
+	return nil, errors.New("unsupported-kv-store")
+}
+
+// StopKVClient function disconnects connects from KVStore
+func StopKVClient(ctx context.Context, kvClient kvstore.Client) {
+
+	// Release all reservations
+	if err := kvClient.ReleaseAllReservations(ctx); err != nil {
+		logger.Infow(ctx, "fail-to-release-all-reservations", log.Fields{"error": err})
+	}
+	// Close the DB connection
+	kvClient.Close(ctx)
+}
+
+// WaitUntilKVStoreReachableOrMaxTries will wait until it can connect to a KV store or until maxtries has been reached
+func WaitUntilKVStoreReachableOrMaxTries(ctx context.Context, kvClient kvstore.Client, maxRetries int, retryInterval time.Duration) error {
+	logger.Infow(ctx, "verifying-KV-store-connectivity", log.Fields{"retries": maxRetries, "retryInterval": retryInterval})
+	count := 0
+	for {
+		if !kvClient.IsConnectionUp(ctx) {
+			logger.Info(ctx, "KV-store-unreachable")
+			if maxRetries != -1 {
+				if count >= maxRetries {
+					return status.Error(codes.Unavailable, "kv store unreachable")
+				}
+			}
+			count++
+
+			//	Take a nap before retrying
+			select {
+			case <-ctx.Done():
+				//ctx canceled
+				return ctx.Err()
+			case <-time.After(retryInterval):
+			}
+			logger.Infow(ctx, "retry-KV-store-connectivity", log.Fields{"retryCount": count, "maxRetries": maxRetries, "retryInterval": retryInterval})
+		} else {
+			break
+		}
+	}
+	probe.UpdateStatusFromContext(ctx, "kv-store", probe.ServiceStatusRunning)
+	logger.Info(ctx, "KV-store-reachable")
+	return nil
+}
+
+/*
+ * Thread to monitor kvstore Liveness (connection status)
+ *
+ * This function constantly monitors Liveness State of kvstore as reported
+ * periodically by backend and updates the Status of kv-store service registered
+ * with rw_core probe.
+ *
+ * If no liveness event has been seen within a timeout, then the thread will
+ * perform a "liveness" check attempt, which will in turn trigger a liveness event on
+ * the liveness channel, true or false depending on whether the attempt succeeded.
+ *
+ * The gRPC server in turn monitors the state of the readiness probe and will
+ * start issuing UNAVAILABLE response while the probe is not ready.
+ */
+// MonitorKVStoreLiveness abc
+func MonitorKVStoreLiveness(ctx context.Context, backend *db.Backend, liveProbeInterval, notLiveProbeInterval time.Duration) {
+	logger.Info(ctx, "start-monitoring-kvstore-liveness")
+
+	// Instruct backend to create Liveness channel for transporting state updates
+	livenessChannel := backend.EnableLivenessChannel(ctx)
+
+	logger.Debug(ctx, "enabled-kvstore-liveness-channel")
+
+	// Default state for kvstore is alive for rw_core
+	timeout := liveProbeInterval
+loop:
+	for {
+		timeoutTimer := time.NewTimer(timeout)
+		select {
+
+		case liveness := <-livenessChannel:
+			logger.Debugw(ctx, "received-liveness-change-notification", log.Fields{"liveness": liveness})
+
+			if !liveness {
+				probe.UpdateStatusFromContext(ctx, "kv-store", probe.ServiceStatusNotReady)
+				logger.Info(ctx, "kvstore-set-server-notready")
+
+				timeout = notLiveProbeInterval
+
+			} else {
+				probe.UpdateStatusFromContext(ctx, "kv-store", probe.ServiceStatusRunning)
+				logger.Info(ctx, "kvstore-set-server-ready")
+
+				timeout = liveProbeInterval
+			}
+
+			if !timeoutTimer.Stop() {
+				<-timeoutTimer.C
+			}
+
+		case <-ctx.Done():
+			break loop
+
+		case <-timeoutTimer.C:
+			logger.Info(ctx, "kvstore-perform-liveness-check-on-timeout")
+
+			// Trigger Liveness check if no liveness update received within the timeout period.
+			// The Liveness check will push Live state to same channel which this routine is
+			// reading and processing. This, do it asynchronously to avoid blocking for
+			// backend response and avoid any possibility of deadlock
+			go backend.PerformLivenessCheck(ctx)
+		}
+	}
+}
diff --git a/pkg/db/operations.go b/pkg/db/operations.go
new file mode 100644
index 0000000..ea63050
--- /dev/null
+++ b/pkg/db/operations.go
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2020-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 holds utils for datastore implementation
+package db
+
+import (
+	"context"
+	"errors"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// Read function reads key value pair from db/kvstore
+func Read(ctx context.Context, key string) (string, error) {
+	if kvClient != nil {
+		logger.Debugw(ctx, "Reading-key-value-pair-from-kv-store", log.Fields{"key": key})
+		kvPair, err := kvClient.client.Get(ctx, key)
+		if err != nil {
+			return "", err
+		}
+		if kvPair == nil {
+			return "", errors.New("key not found")
+		}
+		return string(kvPair.Value.([]byte)), nil
+
+	}
+	logger.Errorw(ctx, "Reading-key-value-pair-in kv-store-failed-because-kvstore-not-initialised", log.Fields{"key": key})
+	return "", errors.New("kvstore not initialised")
+}
+
+// ReadAll function reads all key value pair from db/kvstore
+func ReadAll(ctx context.Context, keyPrefix string) (map[string]string, error) {
+	keyValues := make(map[string]string)
+	if kvClient != nil {
+		logger.Debugw(ctx, "Reading-all-key-value-pairs-from-kv-store", log.Fields{"key-prefix": keyPrefix})
+		kvPairs, err := kvClient.client.List(ctx, keyPrefix)
+		if err != nil {
+			return keyValues, err
+		}
+		if kvPairs == nil {
+			return keyValues, errors.New("key not found")
+		}
+
+		for key, kvPair := range kvPairs {
+			keyValues[key] = string(kvPair.Value.([]byte))
+		}
+		return keyValues, nil
+	}
+	logger.Errorw(ctx, "Reading-all-key-value-pair-in-kv-store-failed-because-kvstore-not-initialised", log.Fields{"key-prefix": keyPrefix})
+	return keyValues, errors.New("kvstore not initialised")
+}
+
+// Del function deletes key value pair from db/kvstore
+func Del(ctx context.Context, key string) error {
+	if kvClient != nil {
+		logger.Debugw(ctx, "Deleting-key-value-pair-from-kv-store", log.Fields{"key": key})
+		return kvClient.client.Delete(ctx, key)
+	}
+	logger.Errorw(ctx, "Deleting-key-value-pair-in-kv-store-failed-because-kvstore-not-initialised", log.Fields{"key": key})
+	return errors.New("kvstore not initialised")
+}
+
+// DelAll function deletes all key value pair from db/kvstore with provided key prefix
+func DelAll(ctx context.Context, keyPrefix string) error {
+	if kvClient != nil {
+		logger.Debugw(ctx, "Deleting-all-key-value-pair-from-kv-store-with-prefix", log.Fields{"key-prefix": keyPrefix})
+		return kvClient.client.DeleteWithPrefix(ctx, keyPrefix)
+	}
+	logger.Errorw(ctx, "Deleting-all-key-value-pair-in-kv-store-with-prefix-failed-because-kvstore-not-initialised", log.Fields{"key-prefix": keyPrefix})
+	return errors.New("kvstore not initialised")
+}
+
+// Put function stores key value pair in db/kvstore
+func Put(ctx context.Context, key string, val string) error {
+	if kvClient != nil {
+		logger.Debugw(ctx, "Storing-key-value-pair-in-kv-store", log.Fields{"key": key, "value": val})
+		return kvClient.client.Put(ctx, key, val)
+	}
+	logger.Errorw(ctx, "Storing-key-value-pair-in-kv-store-failed-because-kvstore-not-initialised", log.Fields{"key": key, "value": val})
+	return errors.New("kvstore not initialised")
+}
diff --git a/pkg/models/device/db.go b/pkg/models/device/db.go
new file mode 100644
index 0000000..a98213e
--- /dev/null
+++ b/pkg/models/device/db.go
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2020-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 modifiablecomponent stores ModifiableComponent methods and functions
+package device
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+
+	"github.com/opencord/opendevice-manager/pkg/db"
+
+	copy "github.com/jinzhu/copier"
+)
+
+// DBGetByName func reads device record by name
+func DBGetByName(ctx context.Context, name string) (*DeviceRecord, error) {
+	if name == "" {
+		logger.Errorw(ctx, "DBGetByName-failed-missing-device-name", log.Fields{})
+		return nil, errors.New("name field is empty")
+	}
+
+	logger.Debugw(ctx, "DBGetByName-invoked", log.Fields{"name": name})
+	defer logger.Debugw(ctx, "DBGetByName-completed", log.Fields{"name": name})
+
+	if val, ok := cache.nameToRec.Load(name); ok {
+		return val.(*DeviceRecord), nil
+	}
+
+	key := fmt.Sprintf(DbPathNameToRecord, name)
+	entry, err := db.Read(ctx, key)
+	if err != nil {
+		logger.Errorw(ctx, "DBGetByName-failed-read-db", log.Fields{"error": err, "key": key})
+		return nil, err
+	}
+
+	rec := new(DeviceRecord)
+	if err = json.Unmarshal([]byte(entry), rec); err != nil {
+		logger.Errorw(ctx, "Failed-to-unmarshal-at-DBGetByName", log.Fields{"reason": err, "entry": entry})
+		return nil, err
+	}
+
+	cache.nameToRec.Store(name, rec)
+
+	return rec, nil
+}
+
+// DBGetByUuid func reads device record by Uuid
+func DBGetByUuid(ctx context.Context, uuid string) (*DeviceRecord, error) {
+
+	if uuid == "" {
+		logger.Errorw(ctx, "DBGetByUuid-failed-missing-device-uuid", log.Fields{})
+		return nil, errors.New("uuid field is empty")
+	}
+
+	logger.Debugw(ctx, "DBGetByUuid-invoked", log.Fields{"uuid": uuid})
+	defer logger.Debugw(ctx, "DBGetByUuid-completed", log.Fields{"uuid": uuid})
+
+	var name string
+	var err error
+
+	if val, ok := cache.uuidToName.Load(uuid); ok {
+		name = val.(string)
+	} else {
+
+		key := fmt.Sprintf(DbPathUuidToName, uuid)
+		name, err = db.Read(ctx, key)
+		if err != nil {
+			logger.Errorw(ctx, "DBGetByUuid-failed-read-db", log.Fields{"error": err, "key": key})
+			return nil, err
+		}
+	}
+
+	cache.uuidToName.Store(uuid, name)
+
+	return DBGetByName(ctx, name)
+}
+
+// DBGetAll func returns all device records
+func DBGetAll(ctx context.Context) ([]*DeviceRecord, error) {
+	key := fmt.Sprintf(DbPathNameToRecord, "")
+	kvPairs, err := db.ReadAll(ctx, key)
+	if err != nil {
+		logger.Errorw(ctx, "DBGetAll-failed-read-db", log.Fields{"error": err, "key": key})
+		return nil, err
+	}
+
+	var listDevs []*DeviceRecord
+
+	for _, entry := range kvPairs {
+		rec := new(DeviceRecord)
+		if err = json.Unmarshal([]byte(entry), rec); err != nil {
+			logger.Errorw(ctx, "Failed-to-unmarshal-at-DBGetByName", log.Fields{"reason": err, "entry": entry})
+		} else {
+			listDevs = append(listDevs, rec)
+		}
+	}
+
+	logger.Infow(ctx, "DBGetAll-success", log.Fields{"entry": listDevs})
+
+	return listDevs, nil
+}
+
+// DBAddByName inserts Device Info record to DB with Name as Key
+func (rec *DeviceRecord) DBAddByName(ctx context.Context) error {
+	if rec.Name == "" {
+		logger.Errorw(ctx, "DBAddByName-failed-missing-device-name", log.Fields{"rec": rec})
+		return errors.New("missing name")
+	}
+	key := fmt.Sprintf(DbPathNameToRecord, rec.Name)
+	b, _ := json.Marshal(rec)
+	entry := string(b)
+	err := db.Put(ctx, key, entry)
+	cache.nameToRec.Store(rec.Name, rec)
+	logger.Infow(ctx, "Inserting-device-info-to-Db-in-DBAddByName-method", log.Fields{"rec": rec, "error": err})
+	return err
+}
+
+// DBAddUuidLookup creates a lookup of name from uuid
+func (rec *DeviceRecord) DBAddUuidLookup(ctx context.Context) error {
+	if rec.Uuid == "" || rec.Name == "" {
+		logger.Errorw(ctx, "DBAddUuidLookup-failed-missing-device-name-or-uuid", log.Fields{"rec": rec})
+		return errors.New("missing name")
+	}
+	key := fmt.Sprintf(DbPathUuidToName, rec.Uuid)
+	err := db.Put(ctx, key, rec.Name)
+	cache.uuidToName.Store(rec.Uuid, rec.Name)
+	logger.Infow(ctx, "DBAddUuidLookup-success", log.Fields{"rec": rec, "error": err})
+	return err
+}
+
+// DBDelRecord deletes all entries for Device Info
+func (rec *DeviceRecord) DBDelRecord(ctx context.Context) error {
+
+	var err error
+
+	if rec.Name != "" {
+		key := fmt.Sprintf(DbPathNameToRecord, rec.Name)
+		logger.Infow(ctx, "deleting-device-info-record-using-name", log.Fields{"name": rec.Name, "key": key})
+		err = db.Del(ctx, key)
+		cache.nameToRec.Delete(rec.Name)
+	}
+
+	if err == nil && rec.Uuid != "" {
+		key := fmt.Sprintf(DbPathUuidToName, rec.Uuid)
+		logger.Infow(ctx, "deleting-device-info-record-using-uuid", log.Fields{"uuid": rec.Uuid, "key": key})
+		err = db.Del(ctx, key)
+		cache.uuidToName.Delete(rec.Uuid)
+	}
+
+	return err
+}
+
+// DBSaveHwInfo stores hardware copies info from response and stores in db
+func (rec *DeviceRecord) DBSaveHwInfo(ctx context.Context, hw *dmi.Hardware) error {
+	defer logger.Infow(ctx, "saving-hw-info-to-device-record-completed", log.Fields{"rec": rec})
+	rec.LastBooted = hw.LastBooted
+	rec.LastChange = hw.LastChange
+	name := rec.Name
+	uuid := rec.Uuid
+	if err := copy.Copy(&rec, &hw.Root); err != nil {
+		logger.Errorw(ctx, "copy-failed-at-DBSaveHwInfo", log.Fields{"rec": rec, "error": err, "hw": hw})
+		return err
+	}
+	rec.Children = []string{}
+	for _, child := range hw.Root.Children {
+		rec.Children = append(rec.Children, child.Uuid.Uuid)
+	}
+	rec.Name = name
+	rec.Uuid = uuid
+	return rec.DBAddByName(ctx)
+}
diff --git a/pkg/models/device/models.go b/pkg/models/device/models.go
new file mode 100644
index 0000000..ab9611d
--- /dev/null
+++ b/pkg/models/device/models.go
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2020-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 device stores methods and functions related to device
+package device
+
+import (
+	"context"
+	"sync"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/jinzhu/copier"
+	"github.com/opencord/opendevice-manager/pkg/config"
+
+	v1 "github.com/opencord/opendevice-manager/pkg/models/device/v1"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// Constants defined are the DB Path meant for storing device info records
+const (
+	DbPathUuidToName   = config.DBPrefix + config.CurDBVer + "/DevRec/DevUuid/%s"
+	DbPathNameToRecord = config.DBPrefix + config.CurDBVer + "/DevRec/DevName/%s"
+)
+
+// deviceCache stores device informations in buffer
+type deviceCache struct {
+	nameToRec  *sync.Map // nameToRecord maintains cache for mapping from name to main record
+	uuidToName *sync.Map // uuidToName maintains cache for mapping from uuid to name
+}
+
+var cache *deviceCache
+
+// logger represents the log object
+var logger log.CLogger
+
+// initCache initialises device cache
+func initCache() {
+	cache = new(deviceCache)
+	cache.nameToRec = new(sync.Map)
+	cache.uuidToName = new(sync.Map)
+}
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+	initCache()
+}
+
+// ClearCacheEntry clearsentry from device cache
+func ClearCacheEntry(ctx context.Context, name, uuid string) {
+	if name != "" {
+		logger.Debugw(ctx, "Clearing-name-key-from-device-cache", log.Fields{"name": name})
+		cache.nameToRec.Delete(name)
+	}
+	if uuid != "" {
+		logger.Debugw(ctx, "Clearing-uuid-key-from-device-cache", log.Fields{"uuid": uuid})
+		cache.uuidToName.Delete(name)
+	}
+}
+
+// DeviceRecord refers to the structure defined for storing OLT info
+type DeviceRecord v1.DeviceRecordV1_0
+
+// NewDeviceRecord return record for aliased ModifiableComponent
+func NewDeviceRecord(ctx context.Context, req *dmi.ModifiableComponent) (*DeviceRecord, error) {
+	rec := new(DeviceRecord)
+	err := copier.Copy(&rec, &req)
+	if err != nil {
+		logger.Errorw(ctx, "Failed-at-creating-object-for-new-device-info", log.Fields{"error": err, "req": req})
+		return nil, err
+	}
+	rec.Uri = req.Uri.Uri
+	rec.State = new(dmi.ComponentState)
+	rec.State.AdminState = req.AdminState
+	logger.Infow(ctx, "Successful-at-creating-object-for-new-device-info", log.Fields{"new-object": rec})
+	return rec, nil
+}
diff --git a/pkg/models/device/util.go b/pkg/models/device/util.go
new file mode 100644
index 0000000..8930cab
--- /dev/null
+++ b/pkg/models/device/util.go
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2020-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 modifiablecomponent stores ModifiableComponent methods and functions
+package device
+
+import (
+	"context"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// GetLoggableEntitiesFromDevRec represnets the fetch the log level with entity from device record
+func (rec *DeviceRecord) GetLoggableEntitiesFromDevRec(ctx context.Context, entities []string) ([]*dmi.EntitiesLogLevel, bool) {
+
+	var traceLevel, debugLevel, infoLevel, warnLevel, errorLevel []string
+
+	if len(entities) > 0 {
+		// getLogLevel request for given entities
+		for _, entity := range entities {
+			if logLevel, ok := rec.Logging.LoggableEntities[entity]; ok {
+				switch logLevel {
+				case dmi.LogLevel_TRACE:
+					traceLevel = append(traceLevel, entity)
+				case dmi.LogLevel_DEBUG:
+					debugLevel = append(debugLevel, entity)
+				case dmi.LogLevel_INFO:
+					infoLevel = append(infoLevel, entity)
+				case dmi.LogLevel_WARN:
+					warnLevel = append(warnLevel, entity)
+				case dmi.LogLevel_ERROR:
+					errorLevel = append(errorLevel, entity)
+				}
+			} else {
+				logger.Warnw(ctx, "entity-was-not-found-in-device-record", log.Fields{"device-name": rec.Name, "entity": entity})
+				return nil, false
+			}
+
+		}
+	} else if len(rec.Logging.LoggableEntities) == 0 {
+		// if LoggableEntities length is zero means loglevel is applicable for entire hardware
+		logger.Debug(ctx, "all-entities-have-common-loglevel", log.Fields{"device-name": rec.Name, "log-level": rec.Logging.LogLevel})
+		return []*dmi.EntitiesLogLevel{{LogLevel: rec.Logging.LogLevel}}, true
+	} else {
+		// get globle log level or get loggble entities will  invoke here
+		logger.Debug(ctx, "all-entities-have-diffrent-loglevel", log.Fields{"device-name": rec.Name})
+		for entity, logLevel := range rec.Logging.LoggableEntities {
+			switch logLevel {
+			case dmi.LogLevel_TRACE:
+				traceLevel = append(traceLevel, entity)
+			case dmi.LogLevel_DEBUG:
+				debugLevel = append(debugLevel, entity)
+			case dmi.LogLevel_INFO:
+				infoLevel = append(infoLevel, entity)
+			case dmi.LogLevel_WARN:
+				warnLevel = append(warnLevel, entity)
+			case dmi.LogLevel_ERROR:
+				errorLevel = append(errorLevel, entity)
+			}
+		}
+	}
+
+	entitiesLogLevel := []*dmi.EntitiesLogLevel{
+		{LogLevel: dmi.LogLevel_TRACE, Entities: traceLevel},
+		{LogLevel: dmi.LogLevel_DEBUG, Entities: debugLevel},
+		{LogLevel: dmi.LogLevel_INFO, Entities: infoLevel},
+		{LogLevel: dmi.LogLevel_WARN, Entities: warnLevel},
+		{LogLevel: dmi.LogLevel_ERROR, Entities: errorLevel},
+	}
+	logger.Debug(ctx, "entities-with-log-level", log.Fields{"entities": entitiesLogLevel})
+
+	return entitiesLogLevel, true
+}
+
+// SaveLoggableEntities func is is used to save the log level with entity in device record
+func (rec *DeviceRecord) SaveLoggableEntities(ctx context.Context, listEntities []*dmi.EntitiesLogLevel) {
+
+	if rec.Logging.LoggableEntities == nil {
+
+		logger.Debug(ctx, "allocating-memory-for-loggable-entitie", log.Fields{"device-name": rec.Name})
+		rec.Logging.LoggableEntities = make(map[string]dmi.LogLevel)
+	}
+
+	if len(listEntities) == 1 && listEntities[0].Entities == nil {
+
+		logger.Debug(ctx, "set-global-log-level", log.Fields{"device-name": rec.Name})
+		rec.Logging.LogLevel = listEntities[0].LogLevel
+
+	} else {
+
+		logger.Debug(ctx, "setting-entity-log-level", log.Fields{"device-name": rec.Name, "list-of-entities": listEntities})
+		for _, entities := range listEntities {
+			logLevel := entities.LogLevel
+			for _, entity := range entities.Entities {
+				rec.Logging.LoggableEntities[entity] = logLevel
+			}
+		}
+	}
+}
diff --git a/pkg/models/device/v1/models.go b/pkg/models/device/v1/models.go
new file mode 100644
index 0000000..cf0a1ad
--- /dev/null
+++ b/pkg/models/device/v1/models.go
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020-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 contains version v1 of Device Info
+package v1
+
+import (
+	"github.com/golang/protobuf/ptypes/timestamp"
+	"github.com/opencord/device-management-interface/go/dmi"
+)
+
+type DeviceRecordV1_0 struct {
+	Uuid         string               `json:"uuid,omitempty"`
+	Name         string               `json:"name,omitempty"`
+	Make         string               `json:"make,omitempty"`
+	Class        dmi.ComponentType    `json:"class,omitempty"`
+	Parent       *dmi.Component       `json:"parent,omitempty"`
+	ParentRelPos int32                `json:"parent_rel_pos,omitempty"`
+	Alias        string               `json:"alias,omitempty"`
+	AssetId      string               `json:"asset_id,omitempty"`
+	Uri          string               `json:"uri,omitempty"`
+	HardwareRev  string               `json:"hardware_rev,omitempty"`
+	FirmwareRev  string               `json:"firmware_rev,omitempty"`
+	SoftwareRev  string               `json:"software_rev,omitempty"`
+	SerialNum    string               `json:"serial_num,omitempty"`
+	ModelName    string               `json:"model_name,omitempty"`
+	MfgName      string               `json:"mfg_name,omitempty"`
+	MfgDate      *timestamp.Timestamp `json:"mfg_date,omitempty"`
+	State        *dmi.ComponentState  `json:"state,omitempty"`
+	Inventories  map[string]string    `json:"inventories,omitempty"`
+	Children     []string             `json:"children,omitempty"` // Children stores uuid of all direct child
+	Logging      LoggingInfo          `json:"logging,omitempty"`
+	LastChange   *timestamp.Timestamp `json:"last_change,omitempty"`
+	LastBooted   *timestamp.Timestamp `json:"last_booted,omitempty"` // Timestamp at which the hardware last booted
+}
+
+type LoggingInfo struct {
+	EndPoint         string                  `json:"end_point,omitempty"`
+	Protocol         string                  `json:"protocol,omitempty"`
+	LogLevel         dmi.LogLevel            `json:"log_level,omitempty"`
+	LoggableEntities map[string]dmi.LogLevel `json:"loggable_entities,omitempty"`
+}
diff --git a/pkg/models/hwcomponents/db.go b/pkg/models/hwcomponents/db.go
new file mode 100644
index 0000000..7d59d3f
--- /dev/null
+++ b/pkg/models/hwcomponents/db.go
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2020-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 hwcomponents stores methods and functions related to hardware
+package hwcomponents
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+
+	copy "github.com/jinzhu/copier"
+	dmi "github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/opencord/opendevice-manager/pkg/db"
+	log "github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// DBAddByName inserts Device Info record to DB with Name as Key
+func (rec *HwCompRecord) DBAddByUuid(ctx context.Context, deviceUuid string) error {
+	if rec.Uuid == "" || deviceUuid == "" {
+		logger.Errorw(ctx, "DBAddByUuid-failed-missing-uuid", log.Fields{"rec": rec, "dev-uuid": deviceUuid})
+		return errors.New("missing uuid")
+	}
+	key := fmt.Sprintf(DbPathUuidToRecord, deviceUuid, rec.Uuid)
+	b, _ := json.Marshal(rec)
+	entry := string(b)
+	err := db.Put(ctx, key, entry)
+	cache.store(deviceUuid, rec)
+	logger.Infow(ctx, "Inserting-hw-comp-info-to-Db-in-DBAddByUuid-method", log.Fields{"rec": rec, "error": err})
+	return err
+}
+
+// DBAddByName inserts Device Info record to DB with Name as Key
+func DBAddNameToUuidlookup(ctx context.Context, deviceUuid string, nameToUuidMap map[string]string) error {
+	if deviceUuid == "" || len(nameToUuidMap) == 0 {
+		logger.Errorw(ctx, "DBAddNameToUuidlookup-failed-missing-uuid-or-map", log.Fields{"map": nameToUuidMap, "dev-uuid": deviceUuid})
+		return errors.New("missing info")
+	}
+	key := fmt.Sprintf(DbPathNameToUuid, deviceUuid)
+	b, _ := json.Marshal(nameToUuidMap)
+	entry := string(b)
+	err := db.Put(ctx, key, entry)
+	logger.Infow(ctx, "DBAddNameToUuidlookup-method-complete", log.Fields{"map": nameToUuidMap, "error": err})
+	return err
+}
+
+// DBSaveHwCompsFromPhysicalInventory iterates through each children and store hwcomponents in db
+func DBSaveHwCompsFromPhysicalInventory(ctx context.Context, deviceUuid string, nameToUuidMap map[string]string, children []*dmi.Component) {
+	if len(children) == 0 {
+		return
+	}
+	for _, child := range children {
+		hwRec := new(HwCompRecord)
+		if err := copy.Copy(&hwRec, &child); hwRec.Name == "" {
+			logger.Errorw(ctx, "Failed-at-copying-hw-comp-from-inventory-list", log.Fields{"error": err, "child": child, "hw-comp": hwRec})
+			continue
+		}
+		if child.Uri != nil {
+			hwRec.Uri = child.Uri.Uri
+		}
+		if child.Uuid != nil {
+			hwRec.Uuid = child.Uuid.Uuid
+		}
+		for _, grandChild := range child.Children {
+			hwRec.Children = append(hwRec.Children, grandChild.Uuid.Uuid)
+		}
+		hwRec.DBAddByUuid(ctx, deviceUuid)
+		nameToUuidMap[hwRec.Name] = hwRec.Uuid
+		DBSaveHwCompsFromPhysicalInventory(ctx, deviceUuid, nameToUuidMap, child.Children)
+		logger.Infow(ctx, "Successful-at-creating-object-for-new-hw-info", log.Fields{"new-object": child})
+	}
+}
+
+// DBDelRecord deletes all entries for Device Info
+func DBDelAllHwComponents(ctx context.Context, deviceUuid string) error {
+
+	var err error
+
+	if deviceUuid == "" {
+		logger.Errorw(ctx, "deleting-all-hw-components-failed", log.Fields{"reason": "missing-device-uuid"})
+		return errors.New("missing device uuid")
+	}
+
+	key := fmt.Sprintf(DbPrefix, deviceUuid)
+	err = db.DelAll(ctx, key)
+	cache.delDevice(deviceUuid)
+	logger.Infow(ctx, "deleting-all-hw-components-completed", log.Fields{"key": key})
+
+	return err
+}
+
+// DBGetRecByUuid func reads hw comp record by uuid
+func DBGetRecByUuid(ctx context.Context, deviceUuid, hwCompUuid string) (*HwCompRecord, error) {
+	if deviceUuid == "" || hwCompUuid == "" {
+		logger.Errorw(ctx, "DBGetHwCompRec-failed-missing-uuid", log.Fields{"device-uuid": deviceUuid, "hw-comp-uuid": hwCompUuid})
+		return nil, errors.New("uuid field is empty")
+	}
+
+	if rec := cache.get(deviceUuid, hwCompUuid); rec != nil {
+		return rec, nil
+	}
+
+	key := fmt.Sprintf(DbPathUuidToRecord, deviceUuid, hwCompUuid)
+	entry, err := db.Read(ctx, key)
+	if err != nil {
+		logger.Errorw(ctx, "DBGetRecByUuid-failed-read-db", log.Fields{"error": err, "key": key})
+		return nil, err
+	}
+
+	rec := new(HwCompRecord)
+	if err = json.Unmarshal([]byte(entry), rec); err != nil {
+		logger.Errorw(ctx, "Failed-to-unmarshal-at-DBGetRecByUuid", log.Fields{"reason": err, "entry": entry})
+		return nil, err
+	}
+
+	cache.store(deviceUuid, rec)
+
+	logger.Debugw(ctx, "DBGetHwCompRec-completed", log.Fields{"device-uuid": deviceUuid, "hw-comp-uuid": hwCompUuid, "rec": rec})
+	return rec, nil
+}
+
+// DBGetRecByName func reads hw comp record by name
+func DBGetRecByName(ctx context.Context, deviceUuid, hwName string) (*HwCompRecord, error) {
+	if deviceUuid == "" || hwName == "" {
+		logger.Errorw(ctx, "DBGetRecByName-failed-missing-uuid", log.Fields{"device-uuid": deviceUuid, "hw-comp-name": hwName})
+		return nil, errors.New("name field is empty")
+	}
+	key := fmt.Sprintf(DbPathNameToUuid, deviceUuid)
+	entry, err := db.Read(ctx, key)
+	if err != nil {
+		logger.Errorw(ctx, "DBGetRecByName-failed-read-db", log.Fields{"error": err, "key": key})
+		return nil, err
+	}
+
+	nameToUuidMap := make(map[string]string)
+	if err = json.Unmarshal([]byte(entry), &nameToUuidMap); nameToUuidMap == nil || err != nil {
+		logger.Errorw(ctx, "Failed-to-unmarshal-at-DBGetRecByName", log.Fields{"reason": err, "entry": entry})
+		return nil, err
+	}
+
+	if hwUuid, ok := nameToUuidMap[hwName]; ok {
+		rec, err2 := DBGetRecByUuid(ctx, deviceUuid, hwUuid)
+		logger.Debugw(ctx, "DBGetRecByName-completed", log.Fields{"device-uuid": deviceUuid, "hw-comp-name": hwName, "rec": rec, "error": err2})
+	}
+
+	return nil, errors.New("name not found")
+}
diff --git a/pkg/models/hwcomponents/models.go b/pkg/models/hwcomponents/models.go
new file mode 100644
index 0000000..9906b53
--- /dev/null
+++ b/pkg/models/hwcomponents/models.go
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2020-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 hwcomponents stores methods and functions related to hardware
+package hwcomponents
+
+import (
+	"sync"
+
+	config "github.com/opencord/opendevice-manager/pkg/config"
+	v1 "github.com/opencord/opendevice-manager/pkg/models/hwcomponents/v1"
+	log "github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// Constants defined are the DB Path meant for storing hw component info records
+const (
+	DbPrefix = config.DBPrefix + config.CurDBVer + "/HwCompRec/%s"
+	// Key : /OpenDevMgr/v1/HwCompRec/{Device-Uuid}/Components
+	// Val : Map => {"hw-comp-name-1":"hw-comp-uuid-1", "hw-comp-name-2":"hw-comp-uuid-2"}
+	DbPathNameToUuid = DbPrefix + "/Components"
+	// Key : /OpenDevMgr/v1/HwCompRec/{Device-Uuid}/Uuid/{Hw-Comp-Uuid}
+	// Val : HwCompRecord{}
+	DbPathUuidToRecord = DbPrefix + "/Uuid/%s"
+)
+
+// compCache stores component information in buffer
+type compCache struct {
+	uuidToRec map[string]map[string]*HwCompRecord // nameToRecord maintains cache for mapping from name to main record
+	mutex     sync.Mutex
+}
+
+var cache *compCache
+
+// logger represents the log object
+var logger log.CLogger
+
+// initCache initialises device cache
+func initCache() {
+	cache = new(compCache)
+	cache.uuidToRec = make(map[string]map[string]*HwCompRecord)
+	cache.mutex = sync.Mutex{}
+}
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+	initCache()
+}
+
+type HwCompRecord v1.HwCompRecordV1_0
+
+func (*compCache) store(devUuid string, rec *HwCompRecord) {
+	cache.mutex.Lock()
+	defer cache.mutex.Unlock()
+
+	var uuidToRecMap map[string]*HwCompRecord
+
+	if val, ok := cache.uuidToRec[devUuid]; !ok {
+		uuidToRecMap = make(map[string]*HwCompRecord)
+	} else {
+		uuidToRecMap = val
+	}
+
+	uuidToRecMap[rec.Uuid] = rec
+	cache.uuidToRec[devUuid] = uuidToRecMap
+}
+
+func (*compCache) get(devUuid, compUuid string) *HwCompRecord {
+	cache.mutex.Lock()
+	defer cache.mutex.Unlock()
+
+	var uuidToRecMap map[string]*HwCompRecord
+
+	if val, ok := cache.uuidToRec[devUuid]; !ok {
+		return nil
+	} else {
+		uuidToRecMap = val
+	}
+
+	if rec, ok := uuidToRecMap[compUuid]; ok {
+		return rec
+	}
+
+	return nil
+}
+
+func (*compCache) delDevice(devUuid string) *HwCompRecord {
+	cache.mutex.Lock()
+	defer cache.mutex.Unlock()
+	delete(cache.uuidToRec, devUuid)
+	return nil
+}
diff --git a/pkg/models/hwcomponents/v1/models.go b/pkg/models/hwcomponents/v1/models.go
new file mode 100644
index 0000000..b7734a8
--- /dev/null
+++ b/pkg/models/hwcomponents/v1/models.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020-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 v1 stores models for hw components
+package v1
+
+import (
+	dmi "github.com/opencord/device-management-interface/go/dmi"
+
+	timestamp "github.com/golang/protobuf/ptypes/timestamp"
+)
+
+type HwCompRecordV1_0 struct {
+	Name         string                     `json:"name,omitempty"`
+	Class        dmi.ComponentType          `json:"class,omitempty"`
+	Description  string                     `json:"description,omitempty"`
+	Parent       string                     `json:"parent,omitempty"`
+	ParentRelPos int32                      `json:"parent_rel_pos,omitempty"`
+	Children     []string                   `json:"children,omitempty"` // Children stores uuid of all direct child
+	SerialNum    string                     `json:"serial_num,omitempty"`
+	MfgName      string                     `json:"mfg_name,omitempty"`
+	ModelName    string                     `json:"model_name,omitempty"`
+	Alias        string                     `json:"alias,omitempty"`
+	AssetId      string                     `json:"asset_id,omitempty"`
+	IsFru        bool                       `json:"is_fru,omitempty"`
+	MfgDate      *timestamp.Timestamp       `json:"mfg_date,omitempty"`
+	Uri          string                     `json:"uri,omitempty"`
+	Uuid         string                     `json:"uuid,omitempty"`
+	State        *dmi.ComponentState        `json:"state,omitempty"`
+	SensorData   []*dmi.ComponentSensorData `json:"sensor_data,omitempty"`
+	Specific     string                     `json:"specific,omitempty"`
+}
diff --git a/pkg/msgbus/connection.go b/pkg/msgbus/connection.go
new file mode 100644
index 0000000..38c6cc1
--- /dev/null
+++ b/pkg/msgbus/connection.go
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2020-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 msgbus holds messagebus related util functions
+package msgbus
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"time"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/Shopify/sarama"
+	"github.com/opencord/opendevice-manager/pkg/config"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+var kafkaProducer sarama.SyncProducer
+
+// logger represents the log object
+var logger log.CLogger
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+}
+
+// InitMsgbusProducer initialises producer for kafka msgbus
+func InitMsgbusProducer(ctx context.Context) error {
+	cf := config.NewCoreFlags()
+	saramaConfig := sarama.NewConfig()
+	saramaConfig.Producer.Retry.Max = 6
+	saramaConfig.Producer.Retry.Backoff = time.Millisecond * 30
+	saramaConfig.Producer.Return.Successes = true
+	saramaConfig.Producer.Return.Errors = true
+
+	// The level of acknowledgement reliability needed from the broker.
+	saramaConfig.Producer.RequiredAcks = sarama.WaitForAll
+	brokers := []string{cf.MsgbusEndPoint}
+	producer, err := sarama.NewSyncProducer(brokers, saramaConfig)
+
+	if err != nil {
+		logger.Errorw(ctx, "Failed-creating-kafka-producer", log.Fields{"error": err, "sarama-config": saramaConfig})
+		return err
+	}
+
+	kafkaProducer = producer
+	logger.Infow(ctx, "creating-kafka-producer-successful", log.Fields{"sarama-config": saramaConfig})
+	return nil
+}
+
+// SendEvent sends events over kafka bus
+func SendEvent(ctx context.Context, event *dmi.Event) error {
+	e, err := json.Marshal(event)
+	if err != nil {
+		logger.Errorw(ctx, "marshal-event-failed", log.Fields{"event": event})
+		return err
+	}
+	logger.Infow(ctx, "sending-event", log.Fields{"event": event})
+	return sendMsg(ctx, string(e), config.OpenDevMgrEventsTopic, event.EventId.String())
+}
+
+// SendMetric sends metrics over kafka bus
+func SendMetric(ctx context.Context, metric *dmi.Metric) error {
+	e, err := json.Marshal(metric)
+	if err != nil {
+		logger.Errorw(ctx, "marshal-metrics-failed", log.Fields{"metrics": metric})
+		return err
+	}
+	logger.Infow(ctx, "sending-metric", log.Fields{"metrics": metric})
+	return sendMsg(ctx, string(e), config.OpenDevMgrMetricsTopic, metric.MetricId.String())
+}
+
+// SendMsg function will help to publish the message to msgbus/kafka
+func sendMsg(ctx context.Context, msg, topic, key string) error {
+	if kafkaProducer != nil {
+		logger.Debugw(ctx, "sending-message", log.Fields{"msg": msg})
+		msg := &sarama.ProducerMessage{
+			Topic: topic,
+			Key:   sarama.StringEncoder(key),
+			Value: sarama.StringEncoder(msg),
+		}
+
+		partition, offset, err := kafkaProducer.SendMessage(msg)
+		logger.Debugw(ctx, "kafka-msg-sent-info", log.Fields{"msg": msg, "partition": partition, "offset": offset, "error": err})
+		return err
+	}
+	logger.Errorw(ctx, "kafka-producer-not-found", log.Fields{"msg": msg, "topic": topic, "key": key})
+	return errors.New("kafka producer not found")
+}
+
+// Close close the msgbus connection
+func Close(ctx context.Context) {
+	if kafkaProducer != nil {
+		reason := "pod exited"
+		logger.Warnw(ctx, "Exiting-msg-bus", log.Fields{"reason": reason})
+		kafkaProducer.Close()
+	}
+}
diff --git a/pkg/msgbus/examples.go b/pkg/msgbus/examples.go
new file mode 100644
index 0000000..3e8e20c
--- /dev/null
+++ b/pkg/msgbus/examples.go
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020-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 msgbus holds messagebus related util functions
+package msgbus
+
+import (
+	"context"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+)
+
+// SendSampleMetric sends a sample metric
+func SendSampleMetric(ctx context.Context) {
+	m := new(dmi.Metric)
+	m.MetricId = dmi.MetricNames_METRIC_CPU_TEMP
+	m.MetricMetadata = new(dmi.MetricMetaData)
+	m.MetricMetadata.ComponentName = "CPU-COMPONENT"
+	m.MetricMetadata.ComponentUuid = new(dmi.Uuid)
+	m.MetricMetadata.ComponentUuid.Uuid = "uuid-123"
+	m.MetricMetadata.DeviceUuid = new(dmi.Uuid)
+	m.MetricMetadata.DeviceUuid.Uuid = "dev-uuid-123"
+	go SendMetric(ctx, m)
+}
+
+// SendSampleEvent sends a sample event
+func SendSampleEvent(ctx context.Context) {
+	e := new(dmi.Event)
+	e.EventId = dmi.EventIds_EVENT_FAN_FAILURE
+	e.EventMetadata = new(dmi.EventMetaData)
+	e.EventMetadata.ComponentName = "CPU-COMPONENT"
+	e.EventMetadata.ComponentUuid = new(dmi.Uuid)
+	e.EventMetadata.ComponentUuid.Uuid = "uuid-123"
+	go SendEvent(ctx, e)
+}
diff --git a/pkg/nbi/common.go b/pkg/nbi/common.go
new file mode 100644
index 0000000..4f80e8c
--- /dev/null
+++ b/pkg/nbi/common.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+	"net"
+	"os"
+
+	"github.com/opencord/opendevice-manager/pkg/config"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+	g "google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/reflection"
+)
+
+// logger represents the log object
+var logger log.CLogger
+
+// grpcServer refers to object which holds grpc serevr
+var grpcServer *g.Server
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+	initConnectMap()
+}
+
+func registerServers(grpcServer *g.Server) {
+	hwMgmtSvc := new(NativeHwManagementService)
+	dmi.RegisterNativeHWManagementServiceServer(grpcServer, hwMgmtSvc)
+	reflection.Register(grpcServer)
+}
+
+// StartGrpcServer starts the grpc server for listening to NEM requests
+func StartGrpcServer(ctx context.Context) {
+	coreFlags := config.GetCoreFlags()
+	lis, err := net.Listen("tcp", coreFlags.GrpcEndPoint)
+	if err != nil {
+		logger.Error(ctx, "Failed-to-listen-on-Grpc-Port", log.Fields{"grpc-flags": coreFlags.GrpcFlags, "error": err})
+		os.Exit(1)
+	}
+
+	if coreFlags.SecureConnection {
+		creds, err := credentials.NewServerTLSFromFile(coreFlags.ServerCrt, coreFlags.ServerKey)
+		if err != nil {
+			logger.Error(ctx, "could-not-process-the-credentials", log.Fields{"error": err})
+		}
+		grpcServer = g.NewServer(g.Creds(creds))
+	} else {
+		grpcServer = g.NewServer()
+	}
+
+	registerServers(grpcServer)
+
+	logger.Infow(ctx, "Grpc-server-starting", log.Fields{"grpc-server-info": grpcServer, "grpc-env-info": coreFlags.GrpcFlags, "is-secure-conn": coreFlags.SecureConnection})
+
+	// Starting the server
+	if err := grpcServer.Serve(lis); err != nil {
+		logger.Errorw(ctx, "Failed-to-start-Grpc-Server", log.Fields{"server": coreFlags.GrpcFlags, "error": err})
+		os.Exit(1)
+	}
+
+	logger.Infow(ctx, "grpc-server-stopped-successfully", log.Fields{"grpc-server-info": grpcServer, "grpc-env-info": coreFlags.GrpcFlags})
+
+}
+
+// StopGrpcServer tear down the gRPC connection from opendevice manager to NEM
+func StopGrpcServer(ctx context.Context) {
+	if grpcServer != nil {
+		grpcServer.GracefulStop()
+	}
+	logger.Infow(ctx, "grpc-server-teardown-success", log.Fields{"grpc-server-info": grpcServer})
+}
diff --git a/pkg/nbi/connection.go b/pkg/nbi/connection.go
new file mode 100644
index 0000000..ae94999
--- /dev/null
+++ b/pkg/nbi/connection.go
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+	"sync"
+
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	"github.com/opencord/opendevice-manager/pkg/sbi"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// connectMap store all device connections established
+type connectMap struct {
+	nameToAdapter map[string]sbi.Adapter // key is name and value is adapter
+	mutex         *sync.RWMutex          // mutex is used to lock when accessing
+}
+
+var connections *connectMap
+
+// initConnectMap initialises map for storing connections
+func initConnectMap() {
+	connections = new(connectMap)
+	connections.nameToAdapter = make(map[string]sbi.Adapter)
+	connections.mutex = &sync.RWMutex{}
+}
+
+// DeInitConnectMap clears all stored connections
+func DeInitConnectMap(ctx context.Context) {
+	connections.nameToAdapter = nil
+	connections.mutex = nil
+	connections = nil
+}
+
+// getConnection retrieves connection object from map using name
+func (conn *connectMap) getConnection(ctx context.Context, devRec *dev.DeviceRecord) (sbi.Adapter, error) {
+	conn.mutex.Lock()
+	defer conn.mutex.Unlock()
+	if val, ok := conn.nameToAdapter[devRec.Name]; ok {
+		return val, nil
+	}
+
+	// Get the right adapter
+	adapter := sbi.GetHwMgmtSvcClient(devRec)
+	if err := adapter.Connect(ctx); err != nil {
+		return nil, err
+	}
+
+	conn.nameToAdapter[devRec.Name] = adapter
+	logger.Infow(ctx, "getConnection-completed", log.Fields{"name": devRec.Name, "adapter": adapter})
+
+	return adapter, nil
+}
+
+// // storeConn stores connection object in map using uuid and name
+// func (conn *connectMap) storeConnWithName(ctx context.Context, name string, adapter sbi.Adapter) {
+// 	conn.mutex.Lock()
+// 	defer conn.mutex.Unlock()
+// 	conn.nameToAdapter[name] = adapter
+// 	logger.Infow(ctx, "storeConnWithName-completed", log.Fields{"name": name, "adapter": adapter})
+// }
+
+// delConn deletes connection object from map using uuid and name
+func (conn *connectMap) delConn(ctx context.Context, name string) {
+	conn.mutex.Lock()
+	defer conn.mutex.Unlock()
+
+	if name != "" {
+		delete(conn.nameToAdapter, name)
+	}
+	logger.Infow(ctx, "delConn-completed", log.Fields{"name": name})
+}
diff --git a/pkg/nbi/hw_mgmt_svc_api.go b/pkg/nbi/hw_mgmt_svc_api.go
new file mode 100644
index 0000000..0bfd82f
--- /dev/null
+++ b/pkg/nbi/hw_mgmt_svc_api.go
@@ -0,0 +1,388 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"github.com/jinzhu/copier"
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/opendevice-manager/pkg/config"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
+
+	empty "github.com/golang/protobuf/ptypes/empty"
+)
+
+// StartManagingDevice refers to the RPC method invoked for start Managing Device.
+// Initializes context for a device and sets up required states
+func (c *NativeHwManagementService) StartManagingDevice(req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) error {
+	ctx := config.GetNewContextFromGlobalContxt("StartManagingDevice")
+
+	logger.Infow(ctx, "StartManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "StartManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
+
+	if errorResp, ok := validateStartManagingDeviceReq(ctx, req); !ok {
+		streamResp.Send(errorResp)
+		return errors.New("failed at validateStartManagingDeviceReq")
+	}
+
+	devRec, err := dev.NewDeviceRecord(ctx, req)
+
+	if err != nil {
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
+		return err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+
+	if adapter == nil {
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
+		return err
+	}
+
+	devRec.DBAddByName(ctx)
+
+	err, connMade := adapter.StartManagingDevice(ctx, devRec, req, streamResp)
+
+	if !connMade {
+		devRec.DBDelRecord(ctx)
+		adapter.Disconnect(ctx)
+		connections.delConn(ctx, devRec.Name)
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_UNDEFINED_REASON, err))
+	}
+
+	return err
+}
+
+// StopManagingDevice - Stops management of a device and clean up any context and caches for that device
+// This rpc can be called at any time, even before the StartManagingDevice operation
+// has completed, and should be able to cleanup.
+func (c *NativeHwManagementService) StopManagingDevice(ctx context.Context, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
+
+	var devRec *dev.DeviceRecord
+	resp := new(dmi.StopManagingDeviceResponse)
+	var err error
+
+	ctx = config.GetNewContextFromContxt(ctx, "StopManagingDevice")
+
+	logger.Infow(ctx, "StopManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "StopManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
+
+	if recTmp, err := dev.DBGetByName(ctx, req.Name); recTmp == nil {
+		return errRespStopManagingDevice(ctx, req, dmi.StopManagingDeviceResponse_UNKNOWN_DEVICE, err), err
+	} else {
+		devRec = recTmp
+	}
+
+	defer devRec.DBDelRecord(ctx)
+	defer hw.DBDelAllHwComponents(ctx, devRec.Uuid)
+
+	adapter, err := connections.getConnection(ctx, devRec)
+
+	if adapter != nil {
+		resp, err = adapter.StopManagingDevice(ctx, devRec, req)
+		adapter.Disconnect(ctx)
+		connections.delConn(ctx, devRec.Name)
+	}
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-StopManagingDevice", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// GetManagedDevices - Returns an object containing a list of devices managed by this entity
+func (c *NativeHwManagementService) GetManagedDevices(ctx context.Context, req *empty.Empty) (*dmi.ManagedDevicesResponse, error) {
+	ctx = config.GetNewContextFromContxt(ctx, "GetManagedDevices")
+	resp := new(dmi.ManagedDevicesResponse)
+
+	logger.Infow(ctx, "GetManagedDevices-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetManagedDevices-on-grpc-server-completed", log.Fields{"req": req})
+
+	listDevRecs, err := dev.DBGetAll(ctx)
+	for _, devRec := range listDevRecs {
+		modComp := new(dmi.ModifiableComponent)
+		err2 := copier.Copy(&modComp, &devRec)
+		if err2 != nil {
+			logger.Errorw(ctx, "Copy-failed-at-GetManagedDevices", log.Fields{"req": req, "rec": devRec, "error": err})
+		} else {
+			modComp.Uri.Uri = devRec.Uri
+			resp.Devices = append(resp.Devices, modComp)
+		}
+	}
+	logger.Infow(ctx, "GetManagedDevices-completed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp, err
+}
+
+// GetPhysicalInventory - Place Holder for implementation in future
+func (c *NativeHwManagementService) GetPhysicalInventory(req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
+
+	ctx := config.GetNewContextFromGlobalContxt("GetPhysicalInventory")
+
+	logger.Infow(ctx, "GetPhysicalInventory-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetPhysicalInventory-on-grpc-server-completed", log.Fields{"req": req})
+
+	var devRec *dev.DeviceRecord
+
+	if recTmp, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); recTmp == nil {
+		streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_UNKNOWN_DEVICE, err))
+		return err
+	} else {
+		devRec = recTmp
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_DEVICE_UNREACHABLE, err))
+		return err
+	}
+
+	err = adapter.GetPhysicalInventory(ctx, devRec, req, streamResp)
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetPhysicalInventory", log.Fields{"req": req, "error": err})
+	}
+
+	return err
+}
+
+// GetHWComponentInfo - refers to the RPC method invoked for get the details of a particular HW component
+func (c *NativeHwManagementService) GetHWComponentInfo(req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
+	ctx := config.GetNewContextFromGlobalContxt("GetHWComponentInfo")
+
+	logger.Infow(ctx, "GetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if devRec == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
+		return err
+	}
+
+	hwCompRec, err := hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid)
+	if hwCompRec == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
+		return err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_DEVICE_UNREACHABLE, err))
+		return err
+	}
+
+	err = adapter.GetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req, streamResp)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetHWComponentInfo", log.Fields{"req": req, "error": err})
+	}
+	return err
+}
+
+// SetHWComponentInfo is the nb api exposed for receiving SetHWComponentInfo from NEM
+func (c *NativeHwManagementService) SetHWComponentInfo(ctx context.Context, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
+	ctx = config.GetNewContextFromContxt(ctx, "SetHWComponentInfo")
+
+	logger.Infow(ctx, "SetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
+
+	var devRec *dev.DeviceRecord
+	var hwCompRec *hw.HwCompRecord
+	var err error
+
+	if devRec, err = dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); devRec == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if hwCompRec, err = hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid); hwCompRec == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	resp, err := adapter.SetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req)
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// SetLoggingEndpoint - refers to the RPC method invoked for set the location to which logs need to be shipped
+func (c *NativeHwManagementService) SetLoggingEndpoint(ctx context.Context, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	ctx = config.GetNewContextFromGlobalContxt("SetLoggingEndpoint")
+
+	logger.Infow(ctx, "SetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
+
+	// Check device is there or not by Uuid
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err2 := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_DEVICE_UNREACHABLE, err2), err2
+	}
+
+	resp, err := adapter.SetLoggingEndpoint(ctx, devRec, req)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-SetLoggingEndpoint", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// GetLoggingEndpoint - refers to the RPC method invoked for get the location to which logs need to be shipped
+func (c *NativeHwManagementService) GetLoggingEndpoint(ctx context.Context, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
+	ctx = config.GetNewContextFromGlobalContxt("GetLoggingEndpoint")
+
+	logger.Infow(ctx, "GetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
+
+	// Check device is there or not by Uuid
+	devRec, err := dev.DBGetByUuid(ctx, req.Uuid.Uuid)
+	if err != nil {
+		return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	resp, err := adapter.GetLoggingEndpoint(ctx, devRec, req)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetLoggingEndpoint", log.Fields{"req": req, "error": err})
+	}
+	return resp, err
+}
+
+// SetMsgBusEndpoint - Place Holder for implementation in future
+func (c *NativeHwManagementService) SetMsgBusEndpoint(ctx context.Context, req *dmi.SetMsgBusEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	errMsg := "SetMsgBusEndpoint not yet implemented"
+	fmt.Println(errMsg)
+	return nil, errors.New(errMsg)
+}
+
+// GetMsgBusEndpoint - Place Holder for implementation in future
+func (c *NativeHwManagementService) GetMsgBusEndpoint(ctx context.Context, req *empty.Empty) (*dmi.GetMsgBusEndpointResponse, error) {
+	errMsg := "GetMsgBusEndpoint not yet implemented"
+	fmt.Println(errMsg)
+	return nil, errors.New(errMsg)
+}
+
+// GetLoggableEntities refers to the grpc northbound interface exposed for getting loggable entities from device
+func (c *NativeHwManagementService) GetLoggableEntities(ctx context.Context, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "GetLoggableEntities")
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "GetLoggableEntities-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLoggableEntities-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if devRec.Logging.LoggableEntities != nil {
+		resp.Status = dmi.Status_OK_STATUS
+		resp.LogLevels, _ = devRec.GetLoggableEntitiesFromDevRec(ctx, nil)
+		return resp, nil
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.GetLoggableEntities(ctx, devRec, req)
+}
+
+// SetLogLevel refers to the grpc northbound interface exposed for setting log level for entities
+func (c *NativeHwManagementService) SetLogLevel(ctx context.Context, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "SetLogLevel")
+	resp := new(dmi.SetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "SetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
+
+	// validate request
+	if ok, err := isValidSetLogLevel(ctx, req.Loglevels); ok {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_LOG_ENTITY, err), err
+	}
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.SetLogLevel(ctx, devRec, req)
+}
+
+// GetLogLevel refers to the grpc northbound interface exposed for getting log level of entities
+func (c *NativeHwManagementService) GetLogLevel(ctx context.Context, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "GetLogLevel")
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "GetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if devRec.Logging.LoggableEntities != nil {
+
+		if output, ok := devRec.GetLoggableEntitiesFromDevRec(ctx, req.Entities); ok {
+			resp.Status = dmi.Status_OK_STATUS
+			resp.LogLevels = output
+			return resp, nil
+		}
+
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.GetLogLevel(ctx, devRec, req)
+}
diff --git a/pkg/nbi/hw_mgmt_svc_err_resp.go b/pkg/nbi/hw_mgmt_svc_err_resp.go
new file mode 100644
index 0000000..ab0c517
--- /dev/null
+++ b/pkg/nbi/hw_mgmt_svc_err_resp.go
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+// errRespStartManagingDevice represents the func to construct error response for rpc StartManagingDevice
+func errRespStartManagingDevice(ctx context.Context, req *dmi.ModifiableComponent, reason dmi.StartManagingDeviceResponse_Reason, err error) *dmi.StartManagingDeviceResponse {
+	resp := new(dmi.StartManagingDeviceResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "StartManagingDevice-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespStopManagingDevice represents the func to construct error response for rpc StopManagingDevice
+func errRespStopManagingDevice(ctx context.Context, req *dmi.StopManagingDeviceRequest, reason dmi.StopManagingDeviceResponse_Reason, err error) *dmi.StopManagingDeviceResponse {
+	resp := new(dmi.StopManagingDeviceResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "StopManagingDevice-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespGetPhysicatInventory represents the func to construct error response for rpc GetPhysicatInventory
+func errRespGetPhysicatInventory(ctx context.Context, req *dmi.PhysicalInventoryRequest, reason dmi.PhysicalInventoryResponse_Reason, err error) *dmi.PhysicalInventoryResponse {
+	resp := new(dmi.PhysicalInventoryResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "GetPhysicatInventory-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespGetHWComponentInfo represents the func to construct error response for rpc GetHWComponentInfo
+func errRespGetHWComponentInfo(ctx context.Context, req *dmi.HWComponentInfoGetRequest, reason dmi.HWComponentInfoGetResponse_Reason, err error) *dmi.HWComponentInfoGetResponse {
+	resp := new(dmi.HWComponentInfoGetResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "GetHWComponentInfo-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespSetHWComponentInfo represents the func to construct error response for rpc SetHWComponentInfo
+func errRespSetHWComponentInfo(ctx context.Context, req *dmi.HWComponentInfoSetRequest, reason dmi.HWComponentInfoSetResponse_Reason, err error) *dmi.HWComponentInfoSetResponse {
+	resp := new(dmi.HWComponentInfoSetResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "SetHWComponentInfo-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespSetLoggingEndpoint represents the func to construct error response for rpc SetLoggingEndpoint
+func errRespSetLoggingEndpoint(ctx context.Context, req *dmi.SetLoggingEndpointRequest, reason dmi.SetRemoteEndpointResponse_Reason, err error) *dmi.SetRemoteEndpointResponse {
+	resp := new(dmi.SetRemoteEndpointResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "SetLoggingEndpoint-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespGetLoggingEndpoint represents the func to construct error response for rpc GetLoggingEndpoint
+func errRespGetLoggingEndpoint(ctx context.Context, req *dmi.HardwareID, reason dmi.GetLoggingEndpointResponse_Reason, err error) *dmi.GetLoggingEndpointResponse {
+	resp := new(dmi.GetLoggingEndpointResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "GetLoggingEndpoint-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespGetLoggableEntities represents the func to construct error response for rpc GetLoggableEntities
+func errRespGetLoggableEntities(ctx context.Context, req *dmi.GetLoggableEntitiesRequest, reason dmi.GetLogLevelResponse_Reason, err error) *dmi.GetLogLevelResponse {
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "GetLoggableEntities-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespSetLogLevel represents the func to construct error response for rpc SetLogLevel
+func errRespSetLogLevel(ctx context.Context, req *dmi.SetLogLevelRequest, reason dmi.SetLogLevelResponse_Reason, err error) *dmi.SetLogLevelResponse {
+	resp := new(dmi.SetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "SetLogLevel-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
+
+// errRespGetLogLevel represents the func to construct error response for rpc GetLogLevel
+func errRespGetLogLevel(ctx context.Context, req *dmi.GetLogLevelRequest, reason dmi.GetLogLevelResponse_Reason, err error) *dmi.GetLogLevelResponse {
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = reason
+	resp.ReasonDetail = err.Error()
+	logger.Errorw(ctx, "GetLogLevel-on-grpc-server-failed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp
+}
diff --git a/pkg/nbi/server_structs.go b/pkg/nbi/server_structs.go
new file mode 100644
index 0000000..8811397
--- /dev/null
+++ b/pkg/nbi/server_structs.go
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+// NativeHwManagementService refers to the struct defined for Service NativeHwManagementService
+type NativeHwManagementService struct {
+}
diff --git a/pkg/nbi/util.go b/pkg/nbi/util.go
new file mode 100644
index 0000000..d8af7cc
--- /dev/null
+++ b/pkg/nbi/util.go
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2020-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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+	"errors"
+	"net"
+	"strconv"
+	"strings"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+/* validateUri() verifies if the ip and port are valid and already registered then return the truth value of the desired state specified by the following 2 switches,
+   wantRegistered: 'true' if the fact of an ip is registered is the desired state
+   includePort: 'true' further checks if <ip>:<port#> does exist in the devicemap in case an ip is found registered
+*/
+func validateUri(ctx context.Context, uri string) (ok bool, err error) {
+	ok = false
+	if !strings.Contains(uri, ":") {
+		logger.Errorw(ctx, "Invalid-uri", log.Fields{"uri-received": uri, "expected-uri": "ip:port"})
+		err = errors.New("incorrect IP address format (<ip>:<port #>)")
+		return
+	}
+	splits := strings.Split(uri, ":")
+	ip, port := splits[0], splits[1]
+	if net.ParseIP(ip) == nil {
+		// also check to see if it's a valid hostname
+		if _, err2 := net.LookupIP(ip); err2 != nil {
+			logger.Errorw(ctx, "Invalid-ip", log.Fields{"uri-received": uri, "ip": ip})
+			err = errors.New("invalid IP address " + ip)
+			return
+		}
+	}
+	if _, err2 := strconv.Atoi(port); err2 != nil {
+		logger.Errorw(ctx, "Invalid-port", log.Fields{"uri-received": uri, "port": port})
+		err = errors.New("Port number " + port + " needs to be an integer")
+		return
+	}
+	ok = true
+	return
+}
+
+// validateStartManagingDeviceReq validates the 'StartManagingDevice' request is proper or not
+func validateStartManagingDeviceReq(ctx context.Context, req *dmi.ModifiableComponent) (resp *dmi.StartManagingDeviceResponse, ok bool) {
+	resp = new(dmi.StartManagingDeviceResponse)
+	resp.DeviceUuid = new(dmi.Uuid)
+	resp.Status = dmi.Status_ERROR_STATUS
+	if ok1, err := validateUri(ctx, req.Uri.Uri); !ok1 {
+		logger.Errorw(ctx, "validation-failed-for-StartManagingDevice-request", log.Fields{"error": err, "req": req})
+		resp.Reason = dmi.StartManagingDeviceResponse_INVALID_PARAMS
+		resp.ReasonDetail = err.Error()
+		return
+	}
+
+	if rec, _ := dev.DBGetByName(ctx, req.Name); rec != nil {
+		logger.Errorw(ctx, "validation-failed-for-StartManagingDevice-request-record-already-exists", log.Fields{"req": req, "rec": rec})
+		resp.Reason = dmi.StartManagingDeviceResponse_DEVICE_ALREADY_MANAGED
+		resp.ReasonDetail = "device already exists and managed with uuid " + rec.Uuid + " and uri " + rec.Uri
+		return
+	}
+
+	ok = true
+
+	return
+}
+
+// isValidSetLogLevel check is valid set loglevel request
+func isValidSetLogLevel(ctx context.Context, listEntities []*dmi.EntitiesLogLevel) (bool, error) {
+
+	if len(listEntities) == 0 {
+		// atleast one entities is required for set loglevel
+		logger.Errorw(ctx, "found-empty-entities", log.Fields{"entities": listEntities})
+		return false, errors.New("found empty entities")
+	}
+
+	if len(listEntities) > 1 {
+		// if set Entities more than 1, atleast 1 entity in nested struct
+		for _, entities := range listEntities {
+			if len(entities.Entities) == 0 {
+				logger.Errorw(ctx, "entities-has-empty-entries", log.Fields{"entities": entities})
+				return false, errors.New("set-empty-entries-not-allowed")
+			}
+		}
+	}
+
+	logger.Debug(ctx, "valid-set-log-request")
+	return true, nil
+}
diff --git a/pkg/sbi/adapter.go b/pkg/sbi/adapter.go
new file mode 100644
index 0000000..58f7549
--- /dev/null
+++ b/pkg/sbi/adapter.go
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-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 sbi holds interfaces for adapter operations
+package sbi
+
+import (
+	"context"
+
+	dmi "github.com/opencord/device-management-interface/go/dmi"
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
+	grpc "github.com/opencord/opendevice-manager/pkg/sbi/grpc"
+)
+
+// GetHwMgmtSvcClient returns the adapter
+func GetHwMgmtSvcClient(devRec *dev.DeviceRecord) Adapter {
+	switch devRec.Make {
+	case "ROLT":
+		return grpc.NewClient(devRec.Uri)
+	}
+	return grpc.NewClient(devRec.Uri)
+}
+
+// Adapter interface contains all methods for rpc calls
+type Adapter interface {
+	Connect(ctx context.Context) error
+	Disconnect(ctx context.Context) error
+	AdapterHwMgmtSvc
+}
+
+// AdapterHwMgmtSvc refers to the interface used for defining RPCs for HW management Service
+type AdapterHwMgmtSvc interface {
+	StartManagingDevice(context.Context, *dev.DeviceRecord, *dmi.ModifiableComponent, dmi.NativeHWManagementService_StartManagingDeviceServer) (error, bool)
+	StopManagingDevice(context.Context, *dev.DeviceRecord, *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error)
+	GetPhysicalInventory(context.Context, *dev.DeviceRecord, *dmi.PhysicalInventoryRequest, dmi.NativeHWManagementService_GetPhysicalInventoryServer) error
+	SetHWComponentInfo(context.Context, string, *hw.HwCompRecord, *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error)
+	GetHWComponentInfo(context.Context, string, *hw.HwCompRecord, *dmi.HWComponentInfoGetRequest, dmi.NativeHWManagementService_GetHWComponentInfoServer) error
+	SetLoggingEndpoint(context.Context, *dev.DeviceRecord, *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error)
+	GetLoggingEndpoint(context.Context, *dev.DeviceRecord, *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error)
+	GetLoggableEntities(context.Context, *dev.DeviceRecord, *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error)
+	SetLogLevel(context.Context, *dev.DeviceRecord, *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error)
+	GetLogLevel(context.Context, *dev.DeviceRecord, *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error)
+}
diff --git a/pkg/sbi/grpc/connection.go b/pkg/sbi/grpc/connection.go
new file mode 100644
index 0000000..3b65c29
--- /dev/null
+++ b/pkg/sbi/grpc/connection.go
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020-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 grpc holds utils for grpc client implementation
+package grpc
+
+import (
+	"context"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/opendevice-manager/pkg/config"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+	"google.golang.org/grpc/credentials"
+
+	g "google.golang.org/grpc"
+)
+
+// logger represents the log object
+var logger log.CLogger
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+}
+
+// Client holds the parameters for grpc
+type Client struct {
+	uri             string
+	conn            *g.ClientConn
+	hwMgmtSvcClient dmi.NativeHWManagementServiceClient
+}
+
+// NewClient returns a new Grpc Client
+func NewClient(uri string) *Client {
+	c := new(Client)
+	c.uri = uri
+	return c
+}
+
+func (c *Client) getDialOpts(ctx context.Context) []g.DialOption {
+
+	coreFlags := config.NewCoreFlags()
+	var opts []g.DialOption
+
+	if coreFlags.SecureConnection {
+		logger.Info(ctx, "Trying-to-establish-secure-connection")
+
+		creds, err := credentials.NewClientTLSFromFile(coreFlags.CertsPath.RootCaCrt, "")
+		if err != nil {
+			logger.Fatalf(ctx, "could-not-process-the-credentials", log.Fields{"err": err})
+		}
+
+		err = creds.OverrideServerName(coreFlags.GrpcHostName)
+		if err != nil {
+			logger.Fatalf(ctx, "Overriding-server-name-failed-at-getDialOpts()", log.Fields{"err": err})
+		}
+
+		opts = append(opts, g.WithTransportCredentials(creds))
+	} else {
+		logger.Info(ctx, "Trying-to-establish-insecure-connection")
+		opts = append(opts, g.WithInsecure())
+	}
+
+	opts = append(opts, g.WithTimeout(coreFlags.GrpcRetryInterval))
+	backoffConfig := g.BackoffConfig{MaxDelay: coreFlags.GrpcBackoffMaxDelay}
+	opts = append(opts, g.WithBackoffConfig(backoffConfig))
+
+	return opts
+}
+
+// Connect will establish a connection
+func (c *Client) Connect(ctx context.Context) error {
+	logger.Info(ctx, "Invoked-connectGrpcServer")
+	// log.Info("Invoked-connectGrpcServer", log.Opts{"peer-ID": peerID})
+	opts := c.getDialOpts(ctx)
+	// Establishing the server connection
+	conn, err := g.Dial(c.uri, opts...)
+	if err != nil {
+		logger.Error(ctx, "Grpc-client-connection-failed", log.Fields{"error": err})
+		return err
+	}
+	c.conn = conn
+	logger.Info(ctx, "Connection-established", log.Fields{"conn": conn})
+	// Constructing a client object
+	c.hwMgmtSvcClient = dmi.NewNativeHWManagementServiceClient(conn)
+	return nil
+}
+
+// Disconnect will remove the connection
+func (c *Client) Disconnect(ctx context.Context) error {
+	logger.Infow(ctx, "Invoked-Disconnect", log.Fields{"client": c})
+	return c.conn.Close()
+}
diff --git a/pkg/sbi/grpc/hw_mgmt_svc.go b/pkg/sbi/grpc/hw_mgmt_svc.go
new file mode 100644
index 0000000..f2bd64a
--- /dev/null
+++ b/pkg/sbi/grpc/hw_mgmt_svc.go
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2020-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 grpc holds utils for grpc Client implementation
+package grpc
+
+import (
+	"context"
+	"errors"
+	"io"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+
+	copy "github.com/jinzhu/copier"
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
+)
+
+// StartManagingDevice is the adapter implementation for start managing device in grpc adapter layer
+func (c *Client) StartManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) (error, bool) {
+
+	var connMade bool
+
+	resp := new(dmi.StartManagingDeviceResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.StartManagingDeviceResponse_INTERNAL_ERROR
+
+	logger.Info(ctx, "Invoked-StartManagingDevice-at-grpc-adapter", log.Fields{"req": req})
+
+	stream, err := c.hwMgmtSvcClient.StartManagingDevice(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-StartManagingDevice")
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return errors.New("RPC Failed for StartManagingDevice"), connMade
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-StartManagingDevice-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-StartManagingDevice-while-receiving-server-response", log.Fields{"error": err, "req": req})
+			return err, connMade
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+			connMade = true
+			devRec.Uuid = respFromDev.DeviceUuid.Uuid
+			// Store in DB
+			devRec.DBAddByName(ctx)
+			devRec.DBAddUuidLookup(ctx)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err, connMade
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil, connMade
+
+}
+
+// StopManagingDevice is the adapter implementation for stop managing device in grpc adapter layer
+func (c *Client) StopManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
+
+	logger.Info(ctx, "Invoked-StopManagingDevice-at-grpc-adapter", log.Fields{"req": req})
+
+	return c.hwMgmtSvcClient.StopManagingDevice(ctx, req)
+
+}
+
+// SetLoggingEndpoint is the adapter implementation for set the location to which logs need to be shipped in grpc adapter layer
+func (c *Client) SetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	logger.Info(ctx, "Invoked-SetLoggingEndpoint", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetLoggingEndpoint(ctx, req)
+	if err != nil {
+		logger.Error(ctx, "error-at-SetLoggingEndpoint")
+		return resp, err
+	}
+	err = errors.New(resp.ReasonDetail)
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.Logging.EndPoint = req.LoggingEndpoint
+		devRec.Logging.Protocol = req.LoggingProtocol
+		// Store in DB
+		devRec.DBAddByName(ctx)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	}
+	return resp, err
+}
+
+// GetLoggingEndpoint is the adapter implementation for get the location to which logs need to be shipped in grpc adapter layer
+func (c *Client) GetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
+	logger.Info(ctx, "Invoked-GetLoggingEndpoint", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLoggingEndpoint(ctx, req)
+	if err != nil {
+		logger.Error(ctx, "error-at-GetLoggingEndpoint")
+		return resp, err
+	}
+	err = errors.New(resp.ReasonDetail)
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.Logging.EndPoint = resp.LoggingEndpoint
+		devRec.Logging.Protocol = resp.LoggingProtocol
+		// Store in DB
+		devRec.DBAddByName(ctx)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	}
+	return resp, err
+}
+
+// GetPhysicalInventory is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetPhysicalInventory(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
+
+	logger.Info(ctx, "Invoked-GetPhysicalInventory-at-grpc-adapter", log.Fields{"req": req})
+
+	resp := new(dmi.PhysicalInventoryResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.PhysicalInventoryResponse_INTERNAL_ERROR
+
+	stream, err := c.hwMgmtSvcClient.GetPhysicalInventory(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-GetPhysicalInventory", log.Fields{"error": err})
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return err
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-GetPhysicalInventory-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-GetPhysicalInventory-while-receiving-server-response", log.Fields{"error": err, "request": req})
+			return err
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+
+			// Store in DB
+			devRec.DBSaveHwInfo(ctx, respFromDev.Inventory)
+			nameToUuidMap := make(map[string]string)
+			hw.DBSaveHwCompsFromPhysicalInventory(ctx, devRec.Uuid, nameToUuidMap, respFromDev.Inventory.Root.Children)
+			hw.DBAddNameToUuidlookup(ctx, devRec.Uuid, nameToUuidMap)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
+
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err
+
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil
+}
+
+// GetLoggableEntities is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetLoggableEntities(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-GetLoggableEntities-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLoggableEntities(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-GetLoggableEntities-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+	// update the db if get log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, resp.LogLevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// SetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) SetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-SetLogLevel-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetLogLevel(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-SetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+	// update the db if setting log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, req.Loglevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// GetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-GetLogLevel-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLogLevel(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-GetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+
+	// update the db if get log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, resp.LogLevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// GetHWComponentInfo is the adapter implementation for get the details of a particular HW component
+func (c *Client) GetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
+
+	logger.Info(ctx, "Invoked-GetHWComponentInfo-at-grpc-adapter", log.Fields{"req": req})
+
+	resp := new(dmi.HWComponentInfoGetResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.HWComponentInfoGetResponse_INTERNAL_ERROR
+
+	stream, err := c.hwMgmtSvcClient.GetHWComponentInfo(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-GetHWComponentInfo", log.Fields{"error": err})
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return err
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-GetHWComponentInfo-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-GetHWComponentInfo-while-receiving-server-response", log.Fields{"error": err, "request": req})
+			return err
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+			if hwCompRec.State == nil {
+				hwCompRec.State = new(dmi.ComponentState)
+			}
+			err = copy.Copy(&hwCompRec, &respFromDev.Component)
+			if err != nil {
+				logger.Error(ctx, "Failed-at-GetHWComponentInfo-copy-failed", log.Fields{"error": err, "resp": respFromDev.Component})
+			}
+			if respFromDev.Component.State != nil {
+				hwCompRec.State.AdminState = respFromDev.Component.State.AdminState
+			}
+			// Store in DB
+			hwCompRec.DBAddByUuid(ctx, deviceUuid)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil
+}
+
+// SetHWComponentInfo method is the grpc adapter implementation for setting hw component info on device
+func (c *Client) SetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
+	logger.Info(ctx, "Invoked-SetHWComponentInfo", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetHWComponentInfo(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
+		return resp, err
+	}
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		hwCompRec.State = new(dmi.ComponentState)
+		err = copy.Copy(&hwCompRec, &req.Changes)
+		hwCompRec.State.AdminState = req.Changes.AdminState
+		// Store in DB
+		hwCompRec.DBAddByUuid(ctx, deviceUuid)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
+		err = errors.New(resp.ReasonDetail)
+	}
+
+	return resp, err
+}
