diff --git a/pkg/mocks/etcd/common.go b/pkg/mocks/etcd/common.go
index 0276357..c893312 100644
--- a/pkg/mocks/etcd/common.go
+++ b/pkg/mocks/etcd/common.go
@@ -16,7 +16,7 @@
 package etcd
 
 import (
-	"github.com/opencord/voltha-lib-go/v6/pkg/log"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 )
 
 var logger log.CLogger
diff --git a/pkg/mocks/etcd/etcd_server.go b/pkg/mocks/etcd/etcd_server.go
index 6113b3a..951baa9 100644
--- a/pkg/mocks/etcd/etcd_server.go
+++ b/pkg/mocks/etcd/etcd_server.go
@@ -18,10 +18,12 @@
 import (
 	"context"
 	"fmt"
-	"go.etcd.io/etcd/embed"
 	"net/url"
 	"os"
+	"strings"
 	"time"
+
+	"go.etcd.io/etcd/embed"
 )
 
 const (
@@ -56,11 +58,15 @@
 	cfg := embed.NewConfig()
 	cfg.Name = configName
 	cfg.Dir = localPersistentStorageDir
-	cfg.Logger = "zap"
+	// cfg.Logger = "zap"
 	if !islogLevelValid(logLevel) {
 		logger.Fatalf(ctx, "Invalid log level -%s", logLevel)
 	}
-	cfg.LogLevel = logLevel
+	// cfg.LogLevel = logLevel
+	cfg.Debug = strings.EqualFold(logLevel, "debug")
+	cfg.LogPkgLevels = "*=C"
+	cfg.SetupLogging()
+
 	acurl, err := url.Parse(fmt.Sprintf("http://localhost:%d", clientPort))
 	if err != nil {
 		logger.Fatalf(ctx, "Invalid client port -%d", clientPort)
@@ -84,9 +90,10 @@
 //getDefaultCfg specifies the default config
 func getDefaultCfg() *embed.Config {
 	cfg := embed.NewConfig()
+	cfg.Debug = false
+	cfg.LogPkgLevels = "*=C"
+	cfg.SetupLogging()
 	cfg.Dir = defaultLocalPersistentStorage
-	cfg.Logger = "zap"
-	cfg.LogLevel = "error"
 	return cfg
 }
 
diff --git a/pkg/mocks/etcd/etcd_server_test.go b/pkg/mocks/etcd/etcd_server_test.go
index 15837bc..2d39dd1 100644
--- a/pkg/mocks/etcd/etcd_server_test.go
+++ b/pkg/mocks/etcd/etcd_server_test.go
@@ -19,13 +19,14 @@
 import (
 	"context"
 	"fmt"
-	"github.com/opencord/voltha-lib-go/v6/pkg/db/kvstore"
-	"github.com/opencord/voltha-lib-go/v6/pkg/log"
-	"github.com/phayes/freeport"
-	"github.com/stretchr/testify/assert"
 	"os"
 	"testing"
 	"time"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"github.com/phayes/freeport"
+	"github.com/stretchr/testify/assert"
 )
 
 var etcdServer *EtcdServer
diff --git a/pkg/mocks/grpc/common.go b/pkg/mocks/grpc/common.go
new file mode 100644
index 0000000..1d0c2bc
--- /dev/null
+++ b/pkg/mocks/grpc/common.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021-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
+
+import (
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/pkg/mocks/grpc/mock_adapter_services.go b/pkg/mocks/grpc/mock_adapter_services.go
new file mode 100644
index 0000000..cbab060
--- /dev/null
+++ b/pkg/mocks/grpc/mock_adapter_services.go
@@ -0,0 +1,1710 @@
+/*
+ * Copyright 2021-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.
+ */
+// Code generated by MockGen. DO NOT EDIT.
+// Source: ./adapter_services.pb.go
+
+package grpc
+
+import (
+	context "context"
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	inter_container "github.com/opencord/voltha-protos/v5/go/inter_container"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	grpc "google.golang.org/grpc"
+)
+
+// MockAdapterServiceClient is a mock of AdapterServiceClient interface.
+type MockAdapterServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockAdapterServiceClientMockRecorder
+}
+
+// MockAdapterServiceClientMockRecorder is the mock recorder for MockAdapterServiceClient.
+type MockAdapterServiceClientMockRecorder struct {
+	mock *MockAdapterServiceClient
+}
+
+// NewMockAdapterServiceClient creates a new mock instance.
+func NewMockAdapterServiceClient(ctrl *gomock.Controller) *MockAdapterServiceClient {
+	mock := &MockAdapterServiceClient{ctrl: ctrl}
+	mock.recorder = &MockAdapterServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockAdapterServiceClient) EXPECT() *MockAdapterServiceClientMockRecorder {
+	return m.recorder
+}
+
+// AbortOnuImageUpgrade mocks base method.
+func (m *MockAdapterServiceClient) AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "AbortOnuImageUpgrade", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortOnuImageUpgrade indicates an expected call of AbortOnuImageUpgrade.
+func (mr *MockAdapterServiceClientMockRecorder) AbortOnuImageUpgrade(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortOnuImageUpgrade", reflect.TypeOf((*MockAdapterServiceClient)(nil).AbortOnuImageUpgrade), varargs...)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockAdapterServiceClient) ActivateImageUpdate(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockAdapterServiceClientMockRecorder) ActivateImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockAdapterServiceClient)(nil).ActivateImageUpdate), varargs...)
+}
+
+// ActivateOnuImage mocks base method.
+func (m *MockAdapterServiceClient) ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateOnuImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateOnuImage indicates an expected call of ActivateOnuImage.
+func (mr *MockAdapterServiceClientMockRecorder) ActivateOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).ActivateOnuImage), varargs...)
+}
+
+// AdoptDevice mocks base method.
+func (m *MockAdapterServiceClient) AdoptDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "AdoptDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AdoptDevice indicates an expected call of AdoptDevice.
+func (mr *MockAdapterServiceClientMockRecorder) AdoptDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdoptDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).AdoptDevice), varargs...)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockAdapterServiceClient) CancelImageDownload(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CancelImageDownload", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockAdapterServiceClientMockRecorder) CancelImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockAdapterServiceClient)(nil).CancelImageDownload), varargs...)
+}
+
+// ChildDeviceLost mocks base method.
+func (m *MockAdapterServiceClient) ChildDeviceLost(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ChildDeviceLost", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDeviceLost indicates an expected call of ChildDeviceLost.
+func (mr *MockAdapterServiceClientMockRecorder) ChildDeviceLost(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceLost", reflect.TypeOf((*MockAdapterServiceClient)(nil).ChildDeviceLost), varargs...)
+}
+
+// CommitOnuImage mocks base method.
+func (m *MockAdapterServiceClient) CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CommitOnuImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitOnuImage indicates an expected call of CommitOnuImage.
+func (mr *MockAdapterServiceClientMockRecorder) CommitOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).CommitOnuImage), varargs...)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockAdapterServiceClient) DeleteDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockAdapterServiceClientMockRecorder) DeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).DeleteDevice), varargs...)
+}
+
+// DisableDevice mocks base method.
+func (m *MockAdapterServiceClient) DisableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockAdapterServiceClientMockRecorder) DisableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).DisableDevice), varargs...)
+}
+
+// DisablePort mocks base method.
+func (m *MockAdapterServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockAdapterServiceClientMockRecorder) DisablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockAdapterServiceClient)(nil).DisablePort), varargs...)
+}
+
+// DownloadImage mocks base method.
+func (m *MockAdapterServiceClient) DownloadImage(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadImage", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockAdapterServiceClientMockRecorder) DownloadImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).DownloadImage), varargs...)
+}
+
+// DownloadOnuImage mocks base method.
+func (m *MockAdapterServiceClient) DownloadOnuImage(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadOnuImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadOnuImage indicates an expected call of DownloadOnuImage.
+func (mr *MockAdapterServiceClientMockRecorder) DownloadOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).DownloadOnuImage), varargs...)
+}
+
+// EnablePort mocks base method.
+func (m *MockAdapterServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockAdapterServiceClientMockRecorder) EnablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockAdapterServiceClient)(nil).EnablePort), varargs...)
+}
+
+// GetExtValue mocks base method.
+func (m *MockAdapterServiceClient) GetExtValue(ctx context.Context, in *inter_container.GetExtValueMessage, opts ...grpc.CallOption) (*common.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetExtValue", varargs...)
+	ret0, _ := ret[0].(*common.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockAdapterServiceClientMockRecorder) GetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetExtValue), varargs...)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetHealthStatus), varargs...)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockAdapterServiceClient) GetImageDownloadStatus(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockAdapterServiceClientMockRecorder) GetImageDownloadStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetImageDownloadStatus), varargs...)
+}
+
+// GetOfpDeviceInfo mocks base method.
+func (m *MockAdapterServiceClient) GetOfpDeviceInfo(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*inter_container.SwitchCapability, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetOfpDeviceInfo", varargs...)
+	ret0, _ := ret[0].(*inter_container.SwitchCapability)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOfpDeviceInfo indicates an expected call of GetOfpDeviceInfo.
+func (mr *MockAdapterServiceClientMockRecorder) GetOfpDeviceInfo(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOfpDeviceInfo", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOfpDeviceInfo), varargs...)
+}
+
+// GetOnuImageStatus mocks base method.
+func (m *MockAdapterServiceClient) GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetOnuImageStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImageStatus indicates an expected call of GetOnuImageStatus.
+func (mr *MockAdapterServiceClientMockRecorder) GetOnuImageStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImageStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOnuImageStatus), varargs...)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockAdapterServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetOnuImages", varargs...)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockAdapterServiceClientMockRecorder) GetOnuImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOnuImages), varargs...)
+}
+
+// GetSingleValue mocks base method.
+func (m *MockAdapterServiceClient) GetSingleValue(ctx context.Context, in *extension.SingleGetValueRequest, opts ...grpc.CallOption) (*extension.SingleGetValueResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetSingleValue", varargs...)
+	ret0, _ := ret[0].(*extension.SingleGetValueResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetSingleValue indicates an expected call of GetSingleValue.
+func (mr *MockAdapterServiceClientMockRecorder) GetSingleValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSingleValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetSingleValue), varargs...)
+}
+
+// ReEnableDevice mocks base method.
+func (m *MockAdapterServiceClient) ReEnableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReEnableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReEnableDevice indicates an expected call of ReEnableDevice.
+func (mr *MockAdapterServiceClientMockRecorder) ReEnableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReEnableDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).ReEnableDevice), varargs...)
+}
+
+// RebootDevice mocks base method.
+func (m *MockAdapterServiceClient) RebootDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RebootDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockAdapterServiceClientMockRecorder) RebootDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).RebootDevice), varargs...)
+}
+
+// ReconcileDevice mocks base method.
+func (m *MockAdapterServiceClient) ReconcileDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReconcileDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevice indicates an expected call of ReconcileDevice.
+func (mr *MockAdapterServiceClientMockRecorder) ReconcileDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).ReconcileDevice), varargs...)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockAdapterServiceClient) RevertImageUpdate(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RevertImageUpdate", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockAdapterServiceClientMockRecorder) RevertImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockAdapterServiceClient)(nil).RevertImageUpdate), varargs...)
+}
+
+// SelfTestDevice mocks base method.
+func (m *MockAdapterServiceClient) SelfTestDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SelfTestDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTestDevice indicates an expected call of SelfTestDevice.
+func (mr *MockAdapterServiceClientMockRecorder) SelfTestDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTestDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).SelfTestDevice), varargs...)
+}
+
+// SendPacketOut mocks base method.
+func (m *MockAdapterServiceClient) SendPacketOut(ctx context.Context, in *inter_container.PacketOut, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SendPacketOut", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SendPacketOut indicates an expected call of SendPacketOut.
+func (mr *MockAdapterServiceClientMockRecorder) SendPacketOut(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketOut", reflect.TypeOf((*MockAdapterServiceClient)(nil).SendPacketOut), varargs...)
+}
+
+// SetExtValue mocks base method.
+func (m *MockAdapterServiceClient) SetExtValue(ctx context.Context, in *inter_container.SetExtValueMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SetExtValue", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockAdapterServiceClientMockRecorder) SetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).SetExtValue), varargs...)
+}
+
+// SetSingleValue mocks base method.
+func (m *MockAdapterServiceClient) SetSingleValue(ctx context.Context, in *extension.SingleSetValueRequest, opts ...grpc.CallOption) (*extension.SingleSetValueResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SetSingleValue", varargs...)
+	ret0, _ := ret[0].(*extension.SingleSetValueResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetSingleValue indicates an expected call of SetSingleValue.
+func (mr *MockAdapterServiceClientMockRecorder) SetSingleValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSingleValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).SetSingleValue), varargs...)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockAdapterServiceClient) SimulateAlarm(ctx context.Context, in *inter_container.SimulateAlarmMessage, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SimulateAlarm", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockAdapterServiceClientMockRecorder) SimulateAlarm(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockAdapterServiceClient)(nil).SimulateAlarm), varargs...)
+}
+
+// StartOmciTest mocks base method.
+func (m *MockAdapterServiceClient) StartOmciTest(ctx context.Context, in *inter_container.OMCITest, opts ...grpc.CallOption) (*voltha.TestResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "StartOmciTest", varargs...)
+	ret0, _ := ret[0].(*voltha.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTest indicates an expected call of StartOmciTest.
+func (mr *MockAdapterServiceClientMockRecorder) StartOmciTest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTest", reflect.TypeOf((*MockAdapterServiceClient)(nil).StartOmciTest), varargs...)
+}
+
+// SuppressEvent mocks base method.
+func (m *MockAdapterServiceClient) SuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SuppressEvent", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SuppressEvent indicates an expected call of SuppressEvent.
+func (mr *MockAdapterServiceClientMockRecorder) SuppressEvent(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuppressEvent", reflect.TypeOf((*MockAdapterServiceClient)(nil).SuppressEvent), varargs...)
+}
+
+// UnSuppressEvent mocks base method.
+func (m *MockAdapterServiceClient) UnSuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UnSuppressEvent", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UnSuppressEvent indicates an expected call of UnSuppressEvent.
+func (mr *MockAdapterServiceClientMockRecorder) UnSuppressEvent(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnSuppressEvent", reflect.TypeOf((*MockAdapterServiceClient)(nil).UnSuppressEvent), varargs...)
+}
+
+// UpdateFlowsBulk mocks base method.
+func (m *MockAdapterServiceClient) UpdateFlowsBulk(ctx context.Context, in *inter_container.BulkFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateFlowsBulk", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateFlowsBulk indicates an expected call of UpdateFlowsBulk.
+func (mr *MockAdapterServiceClientMockRecorder) UpdateFlowsBulk(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsBulk", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdateFlowsBulk), varargs...)
+}
+
+// UpdateFlowsIncrementally mocks base method.
+func (m *MockAdapterServiceClient) UpdateFlowsIncrementally(ctx context.Context, in *inter_container.IncrementalFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateFlowsIncrementally", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateFlowsIncrementally indicates an expected call of UpdateFlowsIncrementally.
+func (mr *MockAdapterServiceClientMockRecorder) UpdateFlowsIncrementally(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsIncrementally", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdateFlowsIncrementally), varargs...)
+}
+
+// UpdatePmConfig mocks base method.
+func (m *MockAdapterServiceClient) UpdatePmConfig(ctx context.Context, in *inter_container.PmConfigsInfo, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdatePmConfig", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdatePmConfig indicates an expected call of UpdatePmConfig.
+func (mr *MockAdapterServiceClientMockRecorder) UpdatePmConfig(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePmConfig", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdatePmConfig), varargs...)
+}
+
+// MockAdapterServiceServer is a mock of AdapterServiceServer interface.
+type MockAdapterServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockAdapterServiceServerMockRecorder
+}
+
+// MockAdapterServiceServerMockRecorder is the mock recorder for MockAdapterServiceServer.
+type MockAdapterServiceServerMockRecorder struct {
+	mock *MockAdapterServiceServer
+}
+
+// NewMockAdapterServiceServer creates a new mock instance.
+func NewMockAdapterServiceServer(ctrl *gomock.Controller) *MockAdapterServiceServer {
+	mock := &MockAdapterServiceServer{ctrl: ctrl}
+	mock.recorder = &MockAdapterServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockAdapterServiceServer) EXPECT() *MockAdapterServiceServerMockRecorder {
+	return m.recorder
+}
+
+// AbortOnuImageUpgrade mocks base method.
+func (m *MockAdapterServiceServer) AbortOnuImageUpgrade(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AbortOnuImageUpgrade", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortOnuImageUpgrade indicates an expected call of AbortOnuImageUpgrade.
+func (mr *MockAdapterServiceServerMockRecorder) AbortOnuImageUpgrade(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortOnuImageUpgrade", reflect.TypeOf((*MockAdapterServiceServer)(nil).AbortOnuImageUpgrade), arg0, arg1)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockAdapterServiceServer) ActivateImageUpdate(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockAdapterServiceServerMockRecorder) ActivateImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockAdapterServiceServer)(nil).ActivateImageUpdate), arg0, arg1)
+}
+
+// ActivateOnuImage mocks base method.
+func (m *MockAdapterServiceServer) ActivateOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateOnuImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateOnuImage indicates an expected call of ActivateOnuImage.
+func (mr *MockAdapterServiceServerMockRecorder) ActivateOnuImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).ActivateOnuImage), arg0, arg1)
+}
+
+// AdoptDevice mocks base method.
+func (m *MockAdapterServiceServer) AdoptDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AdoptDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AdoptDevice indicates an expected call of AdoptDevice.
+func (mr *MockAdapterServiceServerMockRecorder) AdoptDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdoptDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).AdoptDevice), arg0, arg1)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockAdapterServiceServer) CancelImageDownload(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CancelImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockAdapterServiceServerMockRecorder) CancelImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockAdapterServiceServer)(nil).CancelImageDownload), arg0, arg1)
+}
+
+// ChildDeviceLost mocks base method.
+func (m *MockAdapterServiceServer) ChildDeviceLost(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ChildDeviceLost", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDeviceLost indicates an expected call of ChildDeviceLost.
+func (mr *MockAdapterServiceServerMockRecorder) ChildDeviceLost(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceLost", reflect.TypeOf((*MockAdapterServiceServer)(nil).ChildDeviceLost), arg0, arg1)
+}
+
+// CommitOnuImage mocks base method.
+func (m *MockAdapterServiceServer) CommitOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CommitOnuImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitOnuImage indicates an expected call of CommitOnuImage.
+func (mr *MockAdapterServiceServerMockRecorder) CommitOnuImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).CommitOnuImage), arg0, arg1)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockAdapterServiceServer) DeleteDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockAdapterServiceServerMockRecorder) DeleteDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).DeleteDevice), arg0, arg1)
+}
+
+// DisableDevice mocks base method.
+func (m *MockAdapterServiceServer) DisableDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockAdapterServiceServerMockRecorder) DisableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).DisableDevice), arg0, arg1)
+}
+
+// DisablePort mocks base method.
+func (m *MockAdapterServiceServer) DisablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockAdapterServiceServerMockRecorder) DisablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockAdapterServiceServer)(nil).DisablePort), arg0, arg1)
+}
+
+// DownloadImage mocks base method.
+func (m *MockAdapterServiceServer) DownloadImage(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockAdapterServiceServerMockRecorder) DownloadImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).DownloadImage), arg0, arg1)
+}
+
+// DownloadOnuImage mocks base method.
+func (m *MockAdapterServiceServer) DownloadOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadOnuImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadOnuImage indicates an expected call of DownloadOnuImage.
+func (mr *MockAdapterServiceServerMockRecorder) DownloadOnuImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).DownloadOnuImage), arg0, arg1)
+}
+
+// EnablePort mocks base method.
+func (m *MockAdapterServiceServer) EnablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockAdapterServiceServerMockRecorder) EnablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockAdapterServiceServer)(nil).EnablePort), arg0, arg1)
+}
+
+// GetExtValue mocks base method.
+func (m *MockAdapterServiceServer) GetExtValue(arg0 context.Context, arg1 *inter_container.GetExtValueMessage) (*common.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*common.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockAdapterServiceServerMockRecorder) GetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetExtValue), arg0, arg1)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockAdapterServiceServer) GetImageDownloadStatus(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockAdapterServiceServerMockRecorder) GetImageDownloadStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetImageDownloadStatus), arg0, arg1)
+}
+
+// GetOfpDeviceInfo mocks base method.
+func (m *MockAdapterServiceServer) GetOfpDeviceInfo(arg0 context.Context, arg1 *voltha.Device) (*inter_container.SwitchCapability, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOfpDeviceInfo", arg0, arg1)
+	ret0, _ := ret[0].(*inter_container.SwitchCapability)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOfpDeviceInfo indicates an expected call of GetOfpDeviceInfo.
+func (mr *MockAdapterServiceServerMockRecorder) GetOfpDeviceInfo(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOfpDeviceInfo", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOfpDeviceInfo), arg0, arg1)
+}
+
+// GetOnuImageStatus mocks base method.
+func (m *MockAdapterServiceServer) GetOnuImageStatus(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOnuImageStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImageStatus indicates an expected call of GetOnuImageStatus.
+func (mr *MockAdapterServiceServerMockRecorder) GetOnuImageStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImageStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOnuImageStatus), arg0, arg1)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockAdapterServiceServer) GetOnuImages(arg0 context.Context, arg1 *common.ID) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOnuImages", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockAdapterServiceServerMockRecorder) GetOnuImages(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOnuImages), arg0, arg1)
+}
+
+// GetSingleValue mocks base method.
+func (m *MockAdapterServiceServer) GetSingleValue(arg0 context.Context, arg1 *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetSingleValue", arg0, arg1)
+	ret0, _ := ret[0].(*extension.SingleGetValueResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetSingleValue indicates an expected call of GetSingleValue.
+func (mr *MockAdapterServiceServerMockRecorder) GetSingleValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSingleValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetSingleValue), arg0, arg1)
+}
+
+// ReEnableDevice mocks base method.
+func (m *MockAdapterServiceServer) ReEnableDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReEnableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReEnableDevice indicates an expected call of ReEnableDevice.
+func (mr *MockAdapterServiceServerMockRecorder) ReEnableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReEnableDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).ReEnableDevice), arg0, arg1)
+}
+
+// RebootDevice mocks base method.
+func (m *MockAdapterServiceServer) RebootDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RebootDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockAdapterServiceServerMockRecorder) RebootDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).RebootDevice), arg0, arg1)
+}
+
+// ReconcileDevice mocks base method.
+func (m *MockAdapterServiceServer) ReconcileDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReconcileDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevice indicates an expected call of ReconcileDevice.
+func (mr *MockAdapterServiceServerMockRecorder) ReconcileDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).ReconcileDevice), arg0, arg1)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockAdapterServiceServer) RevertImageUpdate(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RevertImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockAdapterServiceServerMockRecorder) RevertImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockAdapterServiceServer)(nil).RevertImageUpdate), arg0, arg1)
+}
+
+// SelfTestDevice mocks base method.
+func (m *MockAdapterServiceServer) SelfTestDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SelfTestDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTestDevice indicates an expected call of SelfTestDevice.
+func (mr *MockAdapterServiceServerMockRecorder) SelfTestDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTestDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).SelfTestDevice), arg0, arg1)
+}
+
+// SendPacketOut mocks base method.
+func (m *MockAdapterServiceServer) SendPacketOut(arg0 context.Context, arg1 *inter_container.PacketOut) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendPacketOut", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SendPacketOut indicates an expected call of SendPacketOut.
+func (mr *MockAdapterServiceServerMockRecorder) SendPacketOut(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketOut", reflect.TypeOf((*MockAdapterServiceServer)(nil).SendPacketOut), arg0, arg1)
+}
+
+// SetExtValue mocks base method.
+func (m *MockAdapterServiceServer) SetExtValue(arg0 context.Context, arg1 *inter_container.SetExtValueMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockAdapterServiceServerMockRecorder) SetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).SetExtValue), arg0, arg1)
+}
+
+// SetSingleValue mocks base method.
+func (m *MockAdapterServiceServer) SetSingleValue(arg0 context.Context, arg1 *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetSingleValue", arg0, arg1)
+	ret0, _ := ret[0].(*extension.SingleSetValueResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetSingleValue indicates an expected call of SetSingleValue.
+func (mr *MockAdapterServiceServerMockRecorder) SetSingleValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSingleValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).SetSingleValue), arg0, arg1)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockAdapterServiceServer) SimulateAlarm(arg0 context.Context, arg1 *inter_container.SimulateAlarmMessage) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SimulateAlarm", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockAdapterServiceServerMockRecorder) SimulateAlarm(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockAdapterServiceServer)(nil).SimulateAlarm), arg0, arg1)
+}
+
+// StartOmciTest mocks base method.
+func (m *MockAdapterServiceServer) StartOmciTest(arg0 context.Context, arg1 *inter_container.OMCITest) (*voltha.TestResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StartOmciTest", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTest indicates an expected call of StartOmciTest.
+func (mr *MockAdapterServiceServerMockRecorder) StartOmciTest(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTest", reflect.TypeOf((*MockAdapterServiceServer)(nil).StartOmciTest), arg0, arg1)
+}
+
+// SuppressEvent mocks base method.
+func (m *MockAdapterServiceServer) SuppressEvent(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SuppressEvent", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SuppressEvent indicates an expected call of SuppressEvent.
+func (mr *MockAdapterServiceServerMockRecorder) SuppressEvent(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuppressEvent", reflect.TypeOf((*MockAdapterServiceServer)(nil).SuppressEvent), arg0, arg1)
+}
+
+// UnSuppressEvent mocks base method.
+func (m *MockAdapterServiceServer) UnSuppressEvent(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UnSuppressEvent", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UnSuppressEvent indicates an expected call of UnSuppressEvent.
+func (mr *MockAdapterServiceServerMockRecorder) UnSuppressEvent(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnSuppressEvent", reflect.TypeOf((*MockAdapterServiceServer)(nil).UnSuppressEvent), arg0, arg1)
+}
+
+// UpdateFlowsBulk mocks base method.
+func (m *MockAdapterServiceServer) UpdateFlowsBulk(arg0 context.Context, arg1 *inter_container.BulkFlows) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateFlowsBulk", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateFlowsBulk indicates an expected call of UpdateFlowsBulk.
+func (mr *MockAdapterServiceServerMockRecorder) UpdateFlowsBulk(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsBulk", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdateFlowsBulk), arg0, arg1)
+}
+
+// UpdateFlowsIncrementally mocks base method.
+func (m *MockAdapterServiceServer) UpdateFlowsIncrementally(arg0 context.Context, arg1 *inter_container.IncrementalFlows) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateFlowsIncrementally", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateFlowsIncrementally indicates an expected call of UpdateFlowsIncrementally.
+func (mr *MockAdapterServiceServerMockRecorder) UpdateFlowsIncrementally(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsIncrementally", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdateFlowsIncrementally), arg0, arg1)
+}
+
+// UpdatePmConfig mocks base method.
+func (m *MockAdapterServiceServer) UpdatePmConfig(arg0 context.Context, arg1 *inter_container.PmConfigsInfo) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdatePmConfig", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdatePmConfig indicates an expected call of UpdatePmConfig.
+func (mr *MockAdapterServiceServerMockRecorder) UpdatePmConfig(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePmConfig", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdatePmConfig), arg0, arg1)
+}
+
+// MockOnuInterAdapterServiceClient is a mock of OnuInterAdapterServiceClient interface.
+type MockOnuInterAdapterServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockOnuInterAdapterServiceClientMockRecorder
+}
+
+// MockOnuInterAdapterServiceClientMockRecorder is the mock recorder for MockOnuInterAdapterServiceClient.
+type MockOnuInterAdapterServiceClientMockRecorder struct {
+	mock *MockOnuInterAdapterServiceClient
+}
+
+// NewMockOnuInterAdapterServiceClient creates a new mock instance.
+func NewMockOnuInterAdapterServiceClient(ctrl *gomock.Controller) *MockOnuInterAdapterServiceClient {
+	mock := &MockOnuInterAdapterServiceClient{ctrl: ctrl}
+	mock.recorder = &MockOnuInterAdapterServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockOnuInterAdapterServiceClient) EXPECT() *MockOnuInterAdapterServiceClientMockRecorder {
+	return m.recorder
+}
+
+// DeleteGemPort mocks base method.
+func (m *MockOnuInterAdapterServiceClient) DeleteGemPort(ctx context.Context, in *inter_container.DeleteGemPortMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteGemPort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteGemPort indicates an expected call of DeleteGemPort.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) DeleteGemPort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGemPort", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DeleteGemPort), varargs...)
+}
+
+// DeleteTCont mocks base method.
+func (m *MockOnuInterAdapterServiceClient) DeleteTCont(ctx context.Context, in *inter_container.DeleteTcontMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteTCont", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteTCont indicates an expected call of DeleteTCont.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) DeleteTCont(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTCont", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DeleteTCont), varargs...)
+}
+
+// DownloadTechProfile mocks base method.
+func (m *MockOnuInterAdapterServiceClient) DownloadTechProfile(ctx context.Context, in *inter_container.TechProfileDownloadMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadTechProfile", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadTechProfile indicates an expected call of DownloadTechProfile.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) DownloadTechProfile(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadTechProfile", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DownloadTechProfile), varargs...)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockOnuInterAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).GetHealthStatus), varargs...)
+}
+
+// OmciResponse mocks base method.
+func (m *MockOnuInterAdapterServiceClient) OmciResponse(ctx context.Context, in *inter_container.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "OmciResponse", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// OmciResponse indicates an expected call of OmciResponse.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) OmciResponse(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OmciResponse", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).OmciResponse), varargs...)
+}
+
+// OnuIndication mocks base method.
+func (m *MockOnuInterAdapterServiceClient) OnuIndication(ctx context.Context, in *inter_container.OnuIndicationMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "OnuIndication", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// OnuIndication indicates an expected call of OnuIndication.
+func (mr *MockOnuInterAdapterServiceClientMockRecorder) OnuIndication(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnuIndication", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).OnuIndication), varargs...)
+}
+
+// MockOnuInterAdapterServiceServer is a mock of OnuInterAdapterServiceServer interface.
+type MockOnuInterAdapterServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockOnuInterAdapterServiceServerMockRecorder
+}
+
+// MockOnuInterAdapterServiceServerMockRecorder is the mock recorder for MockOnuInterAdapterServiceServer.
+type MockOnuInterAdapterServiceServerMockRecorder struct {
+	mock *MockOnuInterAdapterServiceServer
+}
+
+// NewMockOnuInterAdapterServiceServer creates a new mock instance.
+func NewMockOnuInterAdapterServiceServer(ctrl *gomock.Controller) *MockOnuInterAdapterServiceServer {
+	mock := &MockOnuInterAdapterServiceServer{ctrl: ctrl}
+	mock.recorder = &MockOnuInterAdapterServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockOnuInterAdapterServiceServer) EXPECT() *MockOnuInterAdapterServiceServerMockRecorder {
+	return m.recorder
+}
+
+// DeleteGemPort mocks base method.
+func (m *MockOnuInterAdapterServiceServer) DeleteGemPort(arg0 context.Context, arg1 *inter_container.DeleteGemPortMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteGemPort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteGemPort indicates an expected call of DeleteGemPort.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) DeleteGemPort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGemPort", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DeleteGemPort), arg0, arg1)
+}
+
+// DeleteTCont mocks base method.
+func (m *MockOnuInterAdapterServiceServer) DeleteTCont(arg0 context.Context, arg1 *inter_container.DeleteTcontMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteTCont", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteTCont indicates an expected call of DeleteTCont.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) DeleteTCont(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTCont", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DeleteTCont), arg0, arg1)
+}
+
+// DownloadTechProfile mocks base method.
+func (m *MockOnuInterAdapterServiceServer) DownloadTechProfile(arg0 context.Context, arg1 *inter_container.TechProfileDownloadMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadTechProfile", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadTechProfile indicates an expected call of DownloadTechProfile.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) DownloadTechProfile(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadTechProfile", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DownloadTechProfile), arg0, arg1)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockOnuInterAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
+}
+
+// OmciResponse mocks base method.
+func (m *MockOnuInterAdapterServiceServer) OmciResponse(arg0 context.Context, arg1 *inter_container.OmciMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "OmciResponse", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// OmciResponse indicates an expected call of OmciResponse.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) OmciResponse(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OmciResponse", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).OmciResponse), arg0, arg1)
+}
+
+// OnuIndication mocks base method.
+func (m *MockOnuInterAdapterServiceServer) OnuIndication(arg0 context.Context, arg1 *inter_container.OnuIndicationMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "OnuIndication", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// OnuIndication indicates an expected call of OnuIndication.
+func (mr *MockOnuInterAdapterServiceServerMockRecorder) OnuIndication(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnuIndication", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).OnuIndication), arg0, arg1)
+}
+
+// MockOltInterAdapterServiceClient is a mock of OltInterAdapterServiceClient interface.
+type MockOltInterAdapterServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockOltInterAdapterServiceClientMockRecorder
+}
+
+// MockOltInterAdapterServiceClientMockRecorder is the mock recorder for MockOltInterAdapterServiceClient.
+type MockOltInterAdapterServiceClientMockRecorder struct {
+	mock *MockOltInterAdapterServiceClient
+}
+
+// NewMockOltInterAdapterServiceClient creates a new mock instance.
+func NewMockOltInterAdapterServiceClient(ctrl *gomock.Controller) *MockOltInterAdapterServiceClient {
+	mock := &MockOltInterAdapterServiceClient{ctrl: ctrl}
+	mock.recorder = &MockOltInterAdapterServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockOltInterAdapterServiceClient) EXPECT() *MockOltInterAdapterServiceClientMockRecorder {
+	return m.recorder
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockOltInterAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockOltInterAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).GetHealthStatus), varargs...)
+}
+
+// GetTechProfileInstance mocks base method.
+func (m *MockOltInterAdapterServiceClient) GetTechProfileInstance(ctx context.Context, in *inter_container.TechProfileInstanceRequestMessage, opts ...grpc.CallOption) (*inter_container.TechProfileDownloadMessage, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetTechProfileInstance", varargs...)
+	ret0, _ := ret[0].(*inter_container.TechProfileDownloadMessage)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetTechProfileInstance indicates an expected call of GetTechProfileInstance.
+func (mr *MockOltInterAdapterServiceClientMockRecorder) GetTechProfileInstance(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTechProfileInstance", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).GetTechProfileInstance), varargs...)
+}
+
+// ProxyOmciRequest mocks base method.
+func (m *MockOltInterAdapterServiceClient) ProxyOmciRequest(ctx context.Context, in *inter_container.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ProxyOmciRequest", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ProxyOmciRequest indicates an expected call of ProxyOmciRequest.
+func (mr *MockOltInterAdapterServiceClientMockRecorder) ProxyOmciRequest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProxyOmciRequest", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).ProxyOmciRequest), varargs...)
+}
+
+// MockOltInterAdapterServiceServer is a mock of OltInterAdapterServiceServer interface.
+type MockOltInterAdapterServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockOltInterAdapterServiceServerMockRecorder
+}
+
+// MockOltInterAdapterServiceServerMockRecorder is the mock recorder for MockOltInterAdapterServiceServer.
+type MockOltInterAdapterServiceServerMockRecorder struct {
+	mock *MockOltInterAdapterServiceServer
+}
+
+// NewMockOltInterAdapterServiceServer creates a new mock instance.
+func NewMockOltInterAdapterServiceServer(ctrl *gomock.Controller) *MockOltInterAdapterServiceServer {
+	mock := &MockOltInterAdapterServiceServer{ctrl: ctrl}
+	mock.recorder = &MockOltInterAdapterServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockOltInterAdapterServiceServer) EXPECT() *MockOltInterAdapterServiceServerMockRecorder {
+	return m.recorder
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockOltInterAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockOltInterAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
+}
+
+// GetTechProfileInstance mocks base method.
+func (m *MockOltInterAdapterServiceServer) GetTechProfileInstance(arg0 context.Context, arg1 *inter_container.TechProfileInstanceRequestMessage) (*inter_container.TechProfileDownloadMessage, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetTechProfileInstance", arg0, arg1)
+	ret0, _ := ret[0].(*inter_container.TechProfileDownloadMessage)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetTechProfileInstance indicates an expected call of GetTechProfileInstance.
+func (mr *MockOltInterAdapterServiceServerMockRecorder) GetTechProfileInstance(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTechProfileInstance", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).GetTechProfileInstance), arg0, arg1)
+}
+
+// ProxyOmciRequest mocks base method.
+func (m *MockOltInterAdapterServiceServer) ProxyOmciRequest(arg0 context.Context, arg1 *inter_container.OmciMessage) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ProxyOmciRequest", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ProxyOmciRequest indicates an expected call of ProxyOmciRequest.
+func (mr *MockOltInterAdapterServiceServerMockRecorder) ProxyOmciRequest(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProxyOmciRequest", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).ProxyOmciRequest), arg0, arg1)
+}
diff --git a/pkg/mocks/grpc/mock_core_services.go b/pkg/mocks/grpc/mock_core_services.go
new file mode 100644
index 0000000..49abae7
--- /dev/null
+++ b/pkg/mocks/grpc/mock_core_services.go
@@ -0,0 +1,917 @@
+/*
+ * Copyright 2021-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.
+ */
+// Code generated by MockGen. DO NOT EDIT.
+// Source: core.pb.go
+
+package grpc
+
+import (
+	context "context"
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	inter_container "github.com/opencord/voltha-protos/v5/go/inter_container"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	grpc "google.golang.org/grpc"
+)
+
+// MockCoreServiceClient is a mock of CoreServiceClient interface.
+type MockCoreServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockCoreServiceClientMockRecorder
+}
+
+// MockCoreServiceClientMockRecorder is the mock recorder for MockCoreServiceClient.
+type MockCoreServiceClientMockRecorder struct {
+	mock *MockCoreServiceClient
+}
+
+// NewMockCoreServiceClient creates a new mock instance.
+func NewMockCoreServiceClient(ctrl *gomock.Controller) *MockCoreServiceClient {
+	mock := &MockCoreServiceClient{ctrl: ctrl}
+	mock.recorder = &MockCoreServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockCoreServiceClient) EXPECT() *MockCoreServiceClientMockRecorder {
+	return m.recorder
+}
+
+// ChildDeviceDetected mocks base method.
+func (m *MockCoreServiceClient) ChildDeviceDetected(ctx context.Context, in *inter_container.DeviceDiscovery, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ChildDeviceDetected", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
+func (mr *MockCoreServiceClientMockRecorder) ChildDeviceDetected(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDeviceDetected), varargs...)
+}
+
+// ChildDevicesDetected mocks base method.
+func (m *MockCoreServiceClient) ChildDevicesDetected(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ChildDevicesDetected", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
+func (mr *MockCoreServiceClientMockRecorder) ChildDevicesDetected(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesDetected), varargs...)
+}
+
+// ChildDevicesLost mocks base method.
+func (m *MockCoreServiceClient) ChildDevicesLost(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ChildDevicesLost", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDevicesLost indicates an expected call of ChildDevicesLost.
+func (mr *MockCoreServiceClientMockRecorder) ChildDevicesLost(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesLost), varargs...)
+}
+
+// ChildrenStateUpdate mocks base method.
+func (m *MockCoreServiceClient) ChildrenStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ChildrenStateUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
+func (mr *MockCoreServiceClientMockRecorder) ChildrenStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildrenStateUpdate), varargs...)
+}
+
+// DeleteAllPorts mocks base method.
+func (m *MockCoreServiceClient) DeleteAllPorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteAllPorts", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteAllPorts indicates an expected call of DeleteAllPorts.
+func (mr *MockCoreServiceClientMockRecorder) DeleteAllPorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).DeleteAllPorts), varargs...)
+}
+
+// DevicePMConfigUpdate mocks base method.
+func (m *MockCoreServiceClient) DevicePMConfigUpdate(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DevicePMConfigUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
+func (mr *MockCoreServiceClientMockRecorder) DevicePMConfigUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DevicePMConfigUpdate), varargs...)
+}
+
+// DeviceReasonUpdate mocks base method.
+func (m *MockCoreServiceClient) DeviceReasonUpdate(ctx context.Context, in *inter_container.DeviceReason, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeviceReasonUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
+func (mr *MockCoreServiceClientMockRecorder) DeviceReasonUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceReasonUpdate), varargs...)
+}
+
+// DeviceStateUpdate mocks base method.
+func (m *MockCoreServiceClient) DeviceStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeviceStateUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
+func (mr *MockCoreServiceClientMockRecorder) DeviceStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceStateUpdate), varargs...)
+}
+
+// DeviceUpdate mocks base method.
+func (m *MockCoreServiceClient) DeviceUpdate(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeviceUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceUpdate indicates an expected call of DeviceUpdate.
+func (mr *MockCoreServiceClientMockRecorder) DeviceUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceUpdate), varargs...)
+}
+
+// GetChildDevice mocks base method.
+func (m *MockCoreServiceClient) GetChildDevice(ctx context.Context, in *inter_container.ChildDeviceFilter, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetChildDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDevice indicates an expected call of GetChildDevice.
+func (mr *MockCoreServiceClientMockRecorder) GetChildDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevice", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevice), varargs...)
+}
+
+// GetChildDeviceWithProxyAddress mocks base method.
+func (m *MockCoreServiceClient) GetChildDeviceWithProxyAddress(ctx context.Context, in *voltha.Device_ProxyAddress, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetChildDeviceWithProxyAddress", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
+func (mr *MockCoreServiceClientMockRecorder) GetChildDeviceWithProxyAddress(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDeviceWithProxyAddress), varargs...)
+}
+
+// GetChildDevices mocks base method.
+func (m *MockCoreServiceClient) GetChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetChildDevices", varargs...)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDevices indicates an expected call of GetChildDevices.
+func (mr *MockCoreServiceClientMockRecorder) GetChildDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevices), varargs...)
+}
+
+// GetDevice mocks base method.
+func (m *MockCoreServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockCoreServiceClientMockRecorder) GetDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockCoreServiceClient)(nil).GetDevice), varargs...)
+}
+
+// GetDevicePort mocks base method.
+func (m *MockCoreServiceClient) GetDevicePort(ctx context.Context, in *inter_container.PortFilter, opts ...grpc.CallOption) (*voltha.Port, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDevicePort", varargs...)
+	ret0, _ := ret[0].(*voltha.Port)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevicePort indicates an expected call of GetDevicePort.
+func (mr *MockCoreServiceClientMockRecorder) GetDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevicePort", reflect.TypeOf((*MockCoreServiceClient)(nil).GetDevicePort), varargs...)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockCoreServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockCoreServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceClient)(nil).GetHealthStatus), varargs...)
+}
+
+// GetPorts mocks base method.
+func (m *MockCoreServiceClient) GetPorts(ctx context.Context, in *inter_container.PortFilter, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetPorts", varargs...)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPorts indicates an expected call of GetPorts.
+func (mr *MockCoreServiceClientMockRecorder) GetPorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).GetPorts), varargs...)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockCoreServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevicePorts", varargs...)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockCoreServiceClientMockRecorder) ListDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockCoreServiceClient)(nil).ListDevicePorts), varargs...)
+}
+
+// PortCreated mocks base method.
+func (m *MockCoreServiceClient) PortCreated(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "PortCreated", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortCreated indicates an expected call of PortCreated.
+func (mr *MockCoreServiceClientMockRecorder) PortCreated(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortCreated", reflect.TypeOf((*MockCoreServiceClient)(nil).PortCreated), varargs...)
+}
+
+// PortStateUpdate mocks base method.
+func (m *MockCoreServiceClient) PortStateUpdate(ctx context.Context, in *inter_container.PortState, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "PortStateUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortStateUpdate indicates an expected call of PortStateUpdate.
+func (mr *MockCoreServiceClientMockRecorder) PortStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortStateUpdate), varargs...)
+}
+
+// PortsStateUpdate mocks base method.
+func (m *MockCoreServiceClient) PortsStateUpdate(ctx context.Context, in *inter_container.PortStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "PortsStateUpdate", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortsStateUpdate indicates an expected call of PortsStateUpdate.
+func (mr *MockCoreServiceClientMockRecorder) PortsStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortsStateUpdate), varargs...)
+}
+
+// ReconcileChildDevices mocks base method.
+func (m *MockCoreServiceClient) ReconcileChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReconcileChildDevices", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
+func (mr *MockCoreServiceClientMockRecorder) ReconcileChildDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).ReconcileChildDevices), varargs...)
+}
+
+// RegisterAdapter mocks base method.
+func (m *MockCoreServiceClient) RegisterAdapter(ctx context.Context, in *inter_container.AdapterRegistration, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RegisterAdapter", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RegisterAdapter indicates an expected call of RegisterAdapter.
+func (mr *MockCoreServiceClientMockRecorder) RegisterAdapter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceClient)(nil).RegisterAdapter), varargs...)
+}
+
+// SendPacketIn mocks base method.
+func (m *MockCoreServiceClient) SendPacketIn(ctx context.Context, in *inter_container.PacketIn, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SendPacketIn", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SendPacketIn indicates an expected call of SendPacketIn.
+func (mr *MockCoreServiceClientMockRecorder) SendPacketIn(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketIn", reflect.TypeOf((*MockCoreServiceClient)(nil).SendPacketIn), varargs...)
+}
+
+// UpdateImageDownload mocks base method.
+func (m *MockCoreServiceClient) UpdateImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateImageDownload", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateImageDownload indicates an expected call of UpdateImageDownload.
+func (mr *MockCoreServiceClientMockRecorder) UpdateImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceClient)(nil).UpdateImageDownload), varargs...)
+}
+
+// MockCoreServiceServer is a mock of CoreServiceServer interface.
+type MockCoreServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockCoreServiceServerMockRecorder
+}
+
+// MockCoreServiceServerMockRecorder is the mock recorder for MockCoreServiceServer.
+type MockCoreServiceServerMockRecorder struct {
+	mock *MockCoreServiceServer
+}
+
+// NewMockCoreServiceServer creates a new mock instance.
+func NewMockCoreServiceServer(ctrl *gomock.Controller) *MockCoreServiceServer {
+	mock := &MockCoreServiceServer{ctrl: ctrl}
+	mock.recorder = &MockCoreServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockCoreServiceServer) EXPECT() *MockCoreServiceServerMockRecorder {
+	return m.recorder
+}
+
+// ChildDeviceDetected mocks base method.
+func (m *MockCoreServiceServer) ChildDeviceDetected(arg0 context.Context, arg1 *inter_container.DeviceDiscovery) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ChildDeviceDetected", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
+func (mr *MockCoreServiceServerMockRecorder) ChildDeviceDetected(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDeviceDetected), arg0, arg1)
+}
+
+// ChildDevicesDetected mocks base method.
+func (m *MockCoreServiceServer) ChildDevicesDetected(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ChildDevicesDetected", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
+func (mr *MockCoreServiceServerMockRecorder) ChildDevicesDetected(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesDetected), arg0, arg1)
+}
+
+// ChildDevicesLost mocks base method.
+func (m *MockCoreServiceServer) ChildDevicesLost(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ChildDevicesLost", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildDevicesLost indicates an expected call of ChildDevicesLost.
+func (mr *MockCoreServiceServerMockRecorder) ChildDevicesLost(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesLost), arg0, arg1)
+}
+
+// ChildrenStateUpdate mocks base method.
+func (m *MockCoreServiceServer) ChildrenStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ChildrenStateUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
+func (mr *MockCoreServiceServerMockRecorder) ChildrenStateUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildrenStateUpdate), arg0, arg1)
+}
+
+// DeleteAllPorts mocks base method.
+func (m *MockCoreServiceServer) DeleteAllPorts(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteAllPorts", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteAllPorts indicates an expected call of DeleteAllPorts.
+func (mr *MockCoreServiceServerMockRecorder) DeleteAllPorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).DeleteAllPorts), arg0, arg1)
+}
+
+// DevicePMConfigUpdate mocks base method.
+func (m *MockCoreServiceServer) DevicePMConfigUpdate(arg0 context.Context, arg1 *voltha.PmConfigs) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DevicePMConfigUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
+func (mr *MockCoreServiceServerMockRecorder) DevicePMConfigUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DevicePMConfigUpdate), arg0, arg1)
+}
+
+// DeviceReasonUpdate mocks base method.
+func (m *MockCoreServiceServer) DeviceReasonUpdate(arg0 context.Context, arg1 *inter_container.DeviceReason) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeviceReasonUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
+func (mr *MockCoreServiceServerMockRecorder) DeviceReasonUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceReasonUpdate), arg0, arg1)
+}
+
+// DeviceStateUpdate mocks base method.
+func (m *MockCoreServiceServer) DeviceStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeviceStateUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
+func (mr *MockCoreServiceServerMockRecorder) DeviceStateUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceStateUpdate), arg0, arg1)
+}
+
+// DeviceUpdate mocks base method.
+func (m *MockCoreServiceServer) DeviceUpdate(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeviceUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeviceUpdate indicates an expected call of DeviceUpdate.
+func (mr *MockCoreServiceServerMockRecorder) DeviceUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceUpdate), arg0, arg1)
+}
+
+// GetChildDevice mocks base method.
+func (m *MockCoreServiceServer) GetChildDevice(arg0 context.Context, arg1 *inter_container.ChildDeviceFilter) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetChildDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDevice indicates an expected call of GetChildDevice.
+func (mr *MockCoreServiceServerMockRecorder) GetChildDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevice), arg0, arg1)
+}
+
+// GetChildDeviceWithProxyAddress mocks base method.
+func (m *MockCoreServiceServer) GetChildDeviceWithProxyAddress(arg0 context.Context, arg1 *voltha.Device_ProxyAddress) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetChildDeviceWithProxyAddress", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
+func (mr *MockCoreServiceServerMockRecorder) GetChildDeviceWithProxyAddress(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDeviceWithProxyAddress), arg0, arg1)
+}
+
+// GetChildDevices mocks base method.
+func (m *MockCoreServiceServer) GetChildDevices(arg0 context.Context, arg1 *common.ID) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetChildDevices", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetChildDevices indicates an expected call of GetChildDevices.
+func (mr *MockCoreServiceServerMockRecorder) GetChildDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevices), arg0, arg1)
+}
+
+// GetDevice mocks base method.
+func (m *MockCoreServiceServer) GetDevice(arg0 context.Context, arg1 *common.ID) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockCoreServiceServerMockRecorder) GetDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevice), arg0, arg1)
+}
+
+// GetDevicePort mocks base method.
+func (m *MockCoreServiceServer) GetDevicePort(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Port, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Port)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevicePort indicates an expected call of GetDevicePort.
+func (mr *MockCoreServiceServerMockRecorder) GetDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevicePort", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevicePort), arg0, arg1)
+}
+
+// GetHealthStatus mocks base method.
+func (m *MockCoreServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.HealthStatus)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealthStatus indicates an expected call of GetHealthStatus.
+func (mr *MockCoreServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceServer)(nil).GetHealthStatus), arg0, arg1)
+}
+
+// GetPorts mocks base method.
+func (m *MockCoreServiceServer) GetPorts(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPorts indicates an expected call of GetPorts.
+func (mr *MockCoreServiceServerMockRecorder) GetPorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).GetPorts), arg0, arg1)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockCoreServiceServer) ListDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevicePorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockCoreServiceServerMockRecorder) ListDevicePorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockCoreServiceServer)(nil).ListDevicePorts), arg0, arg1)
+}
+
+// PortCreated mocks base method.
+func (m *MockCoreServiceServer) PortCreated(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PortCreated", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortCreated indicates an expected call of PortCreated.
+func (mr *MockCoreServiceServerMockRecorder) PortCreated(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortCreated", reflect.TypeOf((*MockCoreServiceServer)(nil).PortCreated), arg0, arg1)
+}
+
+// PortStateUpdate mocks base method.
+func (m *MockCoreServiceServer) PortStateUpdate(arg0 context.Context, arg1 *inter_container.PortState) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PortStateUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortStateUpdate indicates an expected call of PortStateUpdate.
+func (mr *MockCoreServiceServerMockRecorder) PortStateUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortStateUpdate), arg0, arg1)
+}
+
+// PortsStateUpdate mocks base method.
+func (m *MockCoreServiceServer) PortsStateUpdate(arg0 context.Context, arg1 *inter_container.PortStateFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PortsStateUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// PortsStateUpdate indicates an expected call of PortsStateUpdate.
+func (mr *MockCoreServiceServerMockRecorder) PortsStateUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortsStateUpdate), arg0, arg1)
+}
+
+// ReconcileChildDevices mocks base method.
+func (m *MockCoreServiceServer) ReconcileChildDevices(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReconcileChildDevices", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
+func (mr *MockCoreServiceServerMockRecorder) ReconcileChildDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).ReconcileChildDevices), arg0, arg1)
+}
+
+// RegisterAdapter mocks base method.
+func (m *MockCoreServiceServer) RegisterAdapter(arg0 context.Context, arg1 *inter_container.AdapterRegistration) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RegisterAdapter", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RegisterAdapter indicates an expected call of RegisterAdapter.
+func (mr *MockCoreServiceServerMockRecorder) RegisterAdapter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceServer)(nil).RegisterAdapter), arg0, arg1)
+}
+
+// SendPacketIn mocks base method.
+func (m *MockCoreServiceServer) SendPacketIn(arg0 context.Context, arg1 *inter_container.PacketIn) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendPacketIn", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SendPacketIn indicates an expected call of SendPacketIn.
+func (mr *MockCoreServiceServerMockRecorder) SendPacketIn(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketIn", reflect.TypeOf((*MockCoreServiceServer)(nil).SendPacketIn), arg0, arg1)
+}
+
+// UpdateImageDownload mocks base method.
+func (m *MockCoreServiceServer) UpdateImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateImageDownload indicates an expected call of UpdateImageDownload.
+func (mr *MockCoreServiceServerMockRecorder) UpdateImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceServer)(nil).UpdateImageDownload), arg0, arg1)
+}
diff --git a/pkg/mocks/grpc/mock_grpc_server.go b/pkg/mocks/grpc/mock_grpc_server.go
new file mode 100644
index 0000000..789fc8b
--- /dev/null
+++ b/pkg/mocks/grpc/mock_grpc_server.go
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021-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
+
+import (
+	"context"
+	"strconv"
+
+	vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"github.com/opencord/voltha-lib-go/v7/pkg/probe"
+	"github.com/opencord/voltha-protos/v5/go/adapter_services"
+	"github.com/opencord/voltha-protos/v5/go/core"
+	"github.com/phayes/freeport"
+	"google.golang.org/grpc"
+)
+
+const (
+	mockGrpcServer = "mock-grpc-server"
+)
+
+type MockGRPCServer struct {
+	ApiEndpoint string
+	server      *vgrpc.GrpcServer
+	probe       *probe.Probe
+}
+
+func NewMockGRPCServer(ctx context.Context) (*MockGRPCServer, error) {
+	grpcPort, err := freeport.GetFreePort()
+	if err != nil {
+		return nil, err
+	}
+	s := &MockGRPCServer{
+		ApiEndpoint: "127.0.0.1:" + strconv.Itoa(grpcPort),
+		probe:       &probe.Probe{},
+	}
+	probePort, err := freeport.GetFreePort()
+	if err != nil {
+		return nil, err
+	}
+	probeEndpoint := "127.0.0.1:" + strconv.Itoa(probePort)
+	go s.probe.ListenAndServe(ctx, probeEndpoint)
+	s.probe.RegisterService(ctx, mockGrpcServer)
+	s.server = vgrpc.NewGrpcServer(s.ApiEndpoint, nil, false, s.probe)
+
+	logger.Infow(ctx, "mock-grpc-server-created", log.Fields{"endpoint": s.ApiEndpoint})
+	return s, nil
+}
+
+func (s *MockGRPCServer) AddCoreService(ctx context.Context, srv core.CoreServiceServer) {
+	s.server.AddService(func(server *grpc.Server) {
+		core.RegisterCoreServiceServer(server, srv)
+	})
+}
+
+func (s *MockGRPCServer) AddAdapterService(ctx context.Context, srv adapter_services.AdapterServiceServer) {
+	s.server.AddService(func(server *grpc.Server) {
+		adapter_services.RegisterAdapterServiceServer(server, srv)
+	})
+}
+
+func (s *MockGRPCServer) Start(ctx context.Context) {
+	s.probe.UpdateStatus(ctx, mockGrpcServer, probe.ServiceStatusRunning)
+	s.server.Start(ctx)
+	s.probe.UpdateStatus(ctx, mockGrpcServer, probe.ServiceStatusStopped)
+}
+
+func (s *MockGRPCServer) Stop() {
+	if s.server != nil {
+		s.server.Stop()
+	}
+}
diff --git a/pkg/mocks/kafka/common.go b/pkg/mocks/kafka/common.go
index 5c46fb1..ff4aec9 100644
--- a/pkg/mocks/kafka/common.go
+++ b/pkg/mocks/kafka/common.go
@@ -16,7 +16,7 @@
 package kafka
 
 import (
-	"github.com/opencord/voltha-lib-go/v6/pkg/log"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 )
 
 var logger log.CLogger
diff --git a/pkg/mocks/kafka/endpoint_manager.go b/pkg/mocks/kafka/endpoint_manager.go
deleted file mode 100644
index 807815d..0000000
--- a/pkg/mocks/kafka/endpoint_manager.go
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2018-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 kafka
-
-import (
-	"context"
-	"github.com/opencord/voltha-lib-go/v6/pkg/kafka"
-)
-
-type EndpointManager struct{}
-
-func NewEndpointManager() kafka.EndpointManager {
-	mock := &EndpointManager{}
-	return mock
-}
-
-func (em *EndpointManager) GetEndpoint(ctx context.Context, deviceID string, serviceType string) (kafka.Endpoint, error) {
-	// TODO add mocks call and args
-	return kafka.Endpoint(serviceType), nil
-}
-
-func (em *EndpointManager) IsDeviceOwnedByService(ctx context.Context, deviceID string, serviceType string, replicaNumber int32) (bool, error) {
-	// TODO add mocks call and args
-	return true, nil
-}
-
-func (em *EndpointManager) GetReplicaAssignment(ctx context.Context, deviceID string, serviceType string) (kafka.ReplicaID, error) {
-	return kafka.ReplicaID(1), nil
-}
diff --git a/pkg/mocks/kafka/kafka_client.go b/pkg/mocks/kafka/kafka_client.go
index ce9dada..ea410ac 100644
--- a/pkg/mocks/kafka/kafka_client.go
+++ b/pkg/mocks/kafka/kafka_client.go
@@ -18,30 +18,34 @@
 import (
 	"context"
 	"fmt"
-	"github.com/golang/protobuf/ptypes"
 	"sync"
 	"time"
 
 	"github.com/golang/protobuf/proto"
-	"github.com/opencord/voltha-lib-go/v6/pkg/kafka"
-	"github.com/opencord/voltha-lib-go/v6/pkg/log"
-	ic "github.com/opencord/voltha-protos/v4/go/inter_container"
-	"github.com/opencord/voltha-protos/v4/go/voltha"
+	"github.com/opencord/voltha-lib-go/v7/pkg/kafka"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 )
 
+const (
+	maxConcurrentMessage = 100
+)
+
 // static check to ensure KafkaClient implements kafka.Client
 var _ kafka.Client = &KafkaClient{}
 
 type KafkaClient struct {
-	topicsChannelMap map[string][]chan *ic.InterContainerMessage
+	topicsChannelMap map[string][]chan proto.Message
 	lock             sync.RWMutex
+	alive            bool
+	livenessMutex    sync.Mutex
+	liveness         chan bool
 }
 
 func NewKafkaClient() *KafkaClient {
 	return &KafkaClient{
-		topicsChannelMap: make(map[string][]chan *ic.InterContainerMessage),
+		topicsChannelMap: make(map[string][]chan proto.Message),
 		lock:             sync.RWMutex{},
 	}
 }
@@ -70,7 +74,7 @@
 	if _, ok := kc.topicsChannelMap[topic.Name]; ok {
 		return fmt.Errorf("Topic %s already exist", topic.Name)
 	}
-	ch := make(chan *ic.InterContainerMessage)
+	ch := make(chan proto.Message)
 	kc.topicsChannelMap[topic.Name] = append(kc.topicsChannelMap[topic.Name], ch)
 	return nil
 }
@@ -83,21 +87,21 @@
 	return nil
 }
 
-func (kc *KafkaClient) Subscribe(ctx context.Context, topic *kafka.Topic, kvArgs ...*kafka.KVArg) (<-chan *ic.InterContainerMessage, error) {
+func (kc *KafkaClient) Subscribe(ctx context.Context, topic *kafka.Topic, kvArgs ...*kafka.KVArg) (<-chan proto.Message, error) {
 	logger.Debugw(ctx, "Subscribe", log.Fields{"topic": topic.Name, "args": kvArgs})
 	kc.lock.Lock()
 	defer kc.lock.Unlock()
-	ch := make(chan *ic.InterContainerMessage)
+	ch := make(chan proto.Message, maxConcurrentMessage)
 	kc.topicsChannelMap[topic.Name] = append(kc.topicsChannelMap[topic.Name], ch)
 	return ch, nil
 }
 
-func removeChannel(s []chan *ic.InterContainerMessage, i int) []chan *ic.InterContainerMessage {
+func removeChannel(s []chan proto.Message, i int) []chan proto.Message {
 	s[i] = s[len(s)-1]
 	return s[:len(s)-1]
 }
 
-func (kc *KafkaClient) UnSubscribe(ctx context.Context, topic *kafka.Topic, ch <-chan *ic.InterContainerMessage) error {
+func (kc *KafkaClient) UnSubscribe(ctx context.Context, topic *kafka.Topic, ch <-chan proto.Message) error {
 	logger.Debugw(ctx, "UnSubscribe", log.Fields{"topic": topic.Name})
 	kc.lock.Lock()
 	defer kc.lock.Unlock()
@@ -120,55 +124,50 @@
 	logger.Debug(ctx, "SubscribeForMetadata - unimplemented")
 }
 
-func toIntercontainerMessage(event *voltha.Event) *ic.InterContainerMessage {
-	msg := &ic.InterContainerMessage{
-		Header: &ic.Header{
-			Id:        event.Header.Id,
-			Type:      ic.MessageType_REQUEST,
-			Timestamp: event.Header.RaisedTs,
-		},
-	}
-	// Marshal event
-	if eventBody, err := ptypes.MarshalAny(event); err == nil {
-		msg.Body = eventBody
-	}
-	return msg
-}
-
 func (kc *KafkaClient) Send(ctx context.Context, msg interface{}, topic *kafka.Topic, keys ...string) error {
 	// Assert message is a proto message
-	// ascertain the value interface type is a proto.Message
-	if _, ok := msg.(proto.Message); !ok {
+	protoMsg, ok := msg.(proto.Message)
+	if !ok {
 		logger.Warnw(ctx, "message-not-a-proto-message", log.Fields{"msg": msg})
 		return status.Error(codes.InvalidArgument, "msg-not-a-proto-msg")
 	}
-	req, ok := msg.(*ic.InterContainerMessage)
-	if !ok {
-		event, ok := msg.(*voltha.Event) //This is required as event message will be of type voltha.Event
-		if !ok {
-			return status.Error(codes.InvalidArgument, "unexpected-message-type")
-		}
-		req = toIntercontainerMessage(event)
-	}
-	if req == nil {
-		return status.Error(codes.InvalidArgument, "msg-nil")
-	}
 	kc.lock.RLock()
 	defer kc.lock.RUnlock()
 	for _, ch := range kc.topicsChannelMap[topic.Name] {
-		logger.Debugw(ctx, "Publishing", log.Fields{"fromTopic": req.Header.FromTopic, "toTopic": topic.Name, "id": req.Header.Id})
-		ch <- req
+		select {
+		case ch <- protoMsg:
+			logger.Debugw(ctx, "publishing", log.Fields{"toTopic": topic.Name, "msg": protoMsg})
+		default:
+			logger.Debugw(ctx, "ignoring-event-channel-busy", log.Fields{"toTopic": topic.Name, "msg": protoMsg})
+		}
 	}
 	return nil
 }
 
 func (kc *KafkaClient) SendLiveness(ctx context.Context) error {
-	return status.Error(codes.Unimplemented, "SendLiveness")
+	kc.livenessMutex.Lock()
+	defer kc.livenessMutex.Unlock()
+	if kc.liveness != nil {
+		kc.liveness <- true // I am a mock
+	}
+	return nil
 }
 
 func (kc *KafkaClient) EnableLivenessChannel(ctx context.Context, enable bool) chan bool {
-	logger.Debug(ctx, "EnableLivenessChannel - unimplemented")
-	return nil
+	logger.Infow(ctx, "kafka-enable-liveness-channel", log.Fields{"enable": enable})
+	if enable {
+		kc.livenessMutex.Lock()
+		defer kc.livenessMutex.Unlock()
+		if kc.liveness == nil {
+			logger.Info(ctx, "kafka-create-liveness-channel")
+			kc.liveness = make(chan bool, 10)
+			// post intial state to the channel
+			kc.liveness <- kc.alive
+		}
+	} else {
+		panic("Turning off liveness reporting is not supported")
+	}
+	return kc.liveness
 }
 
 func (kc *KafkaClient) EnableHealthinessChannel(ctx context.Context, enable bool) chan bool {
diff --git a/pkg/mocks/kafka/kafka_client_test.go b/pkg/mocks/kafka/kafka_client_test.go
index edd531e..cc3a779 100644
--- a/pkg/mocks/kafka/kafka_client_test.go
+++ b/pkg/mocks/kafka/kafka_client_test.go
@@ -18,11 +18,12 @@
 
 import (
 	"context"
-	"github.com/opencord/voltha-lib-go/v6/pkg/kafka"
-	ic "github.com/opencord/voltha-protos/v4/go/inter_container"
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"time"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/kafka"
+	ic "github.com/opencord/voltha-protos/v5/go/inter_container"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestKafkaClientCreateTopic(t *testing.T) {
@@ -50,9 +51,9 @@
 	assert.NotNil(t, ch)
 	testCh := make(chan bool)
 	maxWait := 5 * time.Millisecond
-	msg := &ic.InterContainerMessage{
-		Header: &ic.Header{Id: "1234", ToTopic: topic.Name},
-		Body:   nil,
+	msg := &ic.DeviceReason{
+		DeviceId: "1234",
+		Reason:   "mock",
 	}
 	timer := time.NewTimer(maxWait)
 	defer timer.Stop()
diff --git a/pkg/mocks/kafka/kafka_inter_container_proxy.go b/pkg/mocks/kafka/kafka_inter_container_proxy.go
deleted file mode 100644
index 10fcaf0..0000000
--- a/pkg/mocks/kafka/kafka_inter_container_proxy.go
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2018-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 kafka
-
-import (
-	"context"
-
-	"github.com/gogo/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
-	"github.com/golang/protobuf/ptypes/any"
-	"github.com/opencord/voltha-lib-go/v6/pkg/kafka"
-	ic "github.com/opencord/voltha-protos/v4/go/inter_container"
-)
-
-type InvokeRpcArgs struct {
-	Rpc             string
-	ToTopic         *kafka.Topic
-	ReplyToTopic    *kafka.Topic
-	WaitForResponse bool
-	Key             string
-	ParentDeviceId  string
-	KvArgs          map[int]interface{}
-}
-
-type InvokeRpcSpy struct {
-	CallCount int
-	Calls     map[int]InvokeRpcArgs
-	Timeout   bool
-	Response  proto.Message
-}
-
-type InvokeAsyncRpcSpy struct {
-	CallCount int
-	Calls     map[int]InvokeRpcArgs
-	Timeout   bool
-	Response  proto.Message
-}
-
-type MockKafkaICProxy struct {
-	InvokeRpcSpy InvokeRpcSpy
-}
-
-func (s *MockKafkaICProxy) Start(ctx context.Context) error { return nil }
-func (s *MockKafkaICProxy) GetDefaultTopic() *kafka.Topic {
-	t := kafka.Topic{
-		Name: "test-topic",
-	}
-	return &t
-}
-
-func (s *MockKafkaICProxy) DeleteTopic(ctx context.Context, topic kafka.Topic) error { return nil }
-
-func (s *MockKafkaICProxy) Stop(ctx context.Context) {}
-
-func (s *MockKafkaICProxy) InvokeAsyncRPC(ctx context.Context, rpc string, toTopic *kafka.Topic, replyToTopic *kafka.Topic,
-	waitForResponse bool, key string, kvArgs ...*kafka.KVArg) chan *kafka.RpcResponse {
-
-	args := make(map[int]interface{}, 4)
-	for k, v := range kvArgs {
-		args[k] = v
-	}
-
-	s.InvokeRpcSpy.Calls[s.InvokeRpcSpy.CallCount] = InvokeRpcArgs{
-		Rpc:             rpc,
-		ToTopic:         toTopic,
-		ReplyToTopic:    replyToTopic,
-		WaitForResponse: waitForResponse,
-		Key:             key,
-		KvArgs:          args,
-	}
-
-	chnl := make(chan *kafka.RpcResponse)
-
-	return chnl
-}
-
-func (s *MockKafkaICProxy) InvokeRPC(ctx context.Context, rpc string, toTopic *kafka.Topic, replyToTopic *kafka.Topic, waitForResponse bool, key string, kvArgs ...*kafka.KVArg) (bool, *any.Any) {
-	s.InvokeRpcSpy.CallCount++
-
-	success := true
-
-	args := make(map[int]interface{}, 4)
-	for k, v := range kvArgs {
-		args[k] = v
-	}
-
-	s.InvokeRpcSpy.Calls[s.InvokeRpcSpy.CallCount] = InvokeRpcArgs{
-		Rpc:             rpc,
-		ToTopic:         toTopic,
-		ReplyToTopic:    replyToTopic,
-		WaitForResponse: waitForResponse,
-		Key:             key,
-		KvArgs:          args,
-	}
-
-	var response any.Any
-	if s.InvokeRpcSpy.Timeout {
-
-		success = false
-
-		err := &ic.Error{Reason: "context deadline exceeded", Code: ic.ErrorCode_DEADLINE_EXCEEDED}
-		res, _ := ptypes.MarshalAny(err)
-		response = *res
-	} else {
-		res, _ := ptypes.MarshalAny(s.InvokeRpcSpy.Response)
-		response = *res
-	}
-
-	return success, &response
-}
-func (s *MockKafkaICProxy) SubscribeWithRequestHandlerInterface(ctx context.Context, topic kafka.Topic, handler interface{}) error {
-	return nil
-}
-func (s *MockKafkaICProxy) SubscribeWithDefaultRequestHandler(ctx context.Context, topic kafka.Topic, initialOffset int64) error {
-	return nil
-}
-func (s *MockKafkaICProxy) UnSubscribeFromRequestHandler(ctx context.Context, topic kafka.Topic) error {
-	return nil
-}
-func (s *MockKafkaICProxy) EnableLivenessChannel(ctx context.Context, enable bool) chan bool {
-	return nil
-}
-func (s *MockKafkaICProxy) SendLiveness(ctx context.Context) error { return nil }
