From 32aa1a4e7647b06712d2dd6d4224a07e4e609173 Mon Sep 17 00:00:00 2001
From: Fabian Seidl <fabian.b.seidl@stud.h-da.de>
Date: Fri, 4 Mar 2022 16:45:46 +0000
Subject: [PATCH] Stfaseid http refactor

---
 api/apiIntegration_test.go                  |   2 +-
 api/api_test.go                             |  11 +-
 api/grpc.go                                 | 166 ++++---
 api/initialise_test.go                      |   9 +-
 api/pnd.go                                  |   6 +-
 api/pnd_test.go                             |   4 +-
 config/config.go                            |   5 +-
 config/config_test.go                       |   4 +-
 controller.go                               |  33 +-
 go.mod                                      |   8 +-
 go.sum                                      |  21 +-
 http.go                                     | 124 ++++-
 http_test.go                                |  27 ++
 interfaces/change/change.go                 |   2 +-
 mocks/Change.go                             |  10 +-
 northbound/client/core.go                   |   4 +-
 northbound/client/pnd.go                    |   4 +-
 northbound/server/core.go                   |  76 ++-
 northbound/server/core_test.go              |  84 +++-
 northbound/server/csbi.go                   |   2 +-
 northbound/server/pnd.go                    | 485 +++++++++++++-------
 northbound/server/pnd_test.go               | 283 ++++++------
 nucleus/change.go                           |  40 +-
 nucleus/change_test.go                      |  12 +-
 nucleus/device.go                           |   4 +-
 nucleus/errors/errors.go                    |  10 +
 nucleus/gnmi_transport.go                   |   4 +-
 nucleus/gnmi_transport_test.go              |   7 +-
 nucleus/principalNetworkDomain.go           |  20 +-
 nucleus/principalNetworkDomain_test.go      |  37 +-
 nucleus/southbound.go                       |  12 +-
 nucleus/southbound_test.go                  |  17 +-
 store/changeStores.go                       |   8 +-
 store/change_store_test.go                  |  20 +-
 test/integration/nucleusIntegration_test.go |  42 +-
 35 files changed, 1027 insertions(+), 576 deletions(-)

diff --git a/api/apiIntegration_test.go b/api/apiIntegration_test.go
index bfc67ae99..a76273fd9 100644
--- a/api/apiIntegration_test.go
+++ b/api/apiIntegration_test.go
@@ -97,7 +97,7 @@ func TestApiIntegration(t *testing.T) {
 				cliPnd,
 				testPath,
 				hostname,
-				pnd.ApiOperation_UPDATE,
+				pnd.ApiOperation_API_OPERATION_UPDATE,
 			)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("gosdn cli set error = %v, wantErr %v", err, tt.wantErr)
diff --git a/api/api_test.go b/api/api_test.go
index a3f722da0..4c340c703 100644
--- a/api/api_test.go
+++ b/api/api_test.go
@@ -28,7 +28,10 @@ func Test_GetIds(t *testing.T) {
 }
 
 func Test_AddPnd(t *testing.T) {
-	sbi := nucleus.NewSBI(spb.Type_OPENCONFIG)
+	sbi, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("AddPnd() error = %v", err)
+	}
 	resp, err := AddPnd(bufnet, "test", "test pnd", sbi.ID().String())
 	if err != nil {
 		t.Error(err)
@@ -104,7 +107,7 @@ func Test_GetDevice(t *testing.T) {
 }
 
 func Test_Update(t *testing.T) {
-	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_UPDATE)
+	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_API_OPERATION_UPDATE)
 	if err != nil {
 		t.Error(err)
 		return
@@ -113,7 +116,7 @@ func Test_Update(t *testing.T) {
 }
 
 func Test_Replace(t *testing.T) {
-	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_REPLACE)
+	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_API_OPERATION_REPLACE)
 	if err != nil {
 		t.Error(err)
 		return
@@ -122,7 +125,7 @@ func Test_Replace(t *testing.T) {
 }
 
 func Test_Delete(t *testing.T) {
-	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_DELETE)
+	resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_API_OPERATION_DELETE)
 	if err != nil {
 		t.Error(err)
 		return
diff --git a/api/grpc.go b/api/grpc.go
index 0ebdabb68..a9ef08f46 100644
--- a/api/grpc.go
+++ b/api/grpc.go
@@ -15,13 +15,14 @@ import (
 	"github.com/spf13/viper"
 
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 )
 
 var dialOptions []grpc.DialOption
 
 func init() {
 	dialOptions = []grpc.DialOption{
-		grpc.WithInsecure(),
+		grpc.WithTransportCredentials(insecure.NewCredentials()),
 	}
 }
 
@@ -36,11 +37,11 @@ func Init(addr string) error {
 		pid := resp.Pnd[0].Id
 		viper.Set("CLI_PND", pid)
 		log.Infof("PND: %v", pid)
-		if len(resp.Pnd[0].Sbi) != 0 {
-			sbi := resp.Pnd[0].Sbi[0].Id
-			viper.Set("CLI_SBI", sbi)
-			log.Infof("SBI: %v", sbi)
-		}
+		// if len(resp.Pnd[0].Sbi) != 0 {
+		// 	sbi := resp.Pnd[0].Sbi[0].Id
+		// 	viper.Set("CLI_SBI", sbi)
+		// 	log.Infof("SBI: %v", sbi)
+		// }
 	}
 	return viper.WriteConfig()
 }
@@ -55,29 +56,28 @@ func GetIds(addr string) ([]*ppb.PrincipalNetworkDomain, error) {
 	return resp.Pnd, nil
 }
 
-func getAllCore(ctx context.Context, addr string) (*pb.GetResponse, error) {
+func getAllCore(ctx context.Context, addr string) (*pb.GetPndListResponse, error) {
 	coreClient, err := nbi.CoreClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
-	req := &pb.GetRequest{
+	req := &pb.GetPndListRequest{
 		Timestamp: time.Now().UnixNano(),
-		All:       true,
 	}
-	return coreClient.Get(ctx, req)
+	return coreClient.GetPndList(ctx, req)
 }
 
 // AddPnd takes a name, description and SBI UUID to create a new
 // PrincipalNetworkDomain on the controller
-func AddPnd(addr, name, description, sbi string) (*pb.SetResponse, error) {
+func AddPnd(addr, name, description, sbi string) (*pb.CreatePndListResponse, error) {
 	coreClient, err := nbi.CoreClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 	ctx := context.Background()
-	req := &pb.SetRequest{
+	req := &pb.CreatePndListRequest{
 		Timestamp: time.Now().UnixNano(),
-		Pnd: []*pb.SetPnd{
+		Pnd: []*pb.PndCreateProperties{
 			{
 				Name:        name,
 				Description: description,
@@ -86,13 +86,12 @@ func AddPnd(addr, name, description, sbi string) (*pb.SetResponse, error) {
 		},
 	}
 
-	return coreClient.Set(ctx, req)
+	return coreClient.CreatePndList(ctx, req)
 }
 
-// GetPnd requests one or several PrincipalNetworkDomains from the
-// controller. To request all PrincipalNetworkDomains without providing
-// names or UUIDs use GetIds()
-func GetPnd(addr string, args ...string) (*pb.GetResponse, error) {
+// GetPnd requests one PrincipalNetworkDomain from the
+// controller.
+func GetPnd(addr string, args ...string) (*pb.GetPndResponse, error) {
 	coreClient, err := nbi.CoreClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
@@ -101,40 +100,52 @@ func GetPnd(addr string, args ...string) (*pb.GetResponse, error) {
 		return nil, errors.New("not enough arguments")
 	}
 	ctx := context.Background()
-	req := &pb.GetRequest{
+	req := &pb.GetPndRequest{
 		Timestamp: time.Now().UnixNano(),
 		Pid:       args,
 	}
-	return coreClient.Get(ctx, req)
+	return coreClient.GetPnd(ctx, req)
+}
+
+// GetPnds requests all PrincipalNetworkDomains from the
+// controller.
+func GetPnds(addr string, args ...string) (*pb.GetPndListResponse, error) {
+	coreClient, err := nbi.CoreClient(addr, dialOptions...)
+	if err != nil {
+		return nil, err
+	}
+	if len(args) <= 0 {
+		return nil, errors.New("not enough arguments")
+	}
+	ctx := context.Background()
+	req := &pb.GetPndListRequest{
+		Timestamp: time.Now().UnixNano(),
+	}
+	return coreClient.GetPndList(ctx, req)
 }
 
 // getChanges requests all pending and unconfirmed changes from the controller
-func getChanges(addr, pnd string) (*ppb.GetResponse, error) {
+func getChanges(addr, pnd string) (*ppb.GetChangeListResponse, error) {
 	ctx := context.Background()
 	client, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
-	req := &ppb.GetRequest{
+	req := &ppb.GetChangeListRequest{
 		Timestamp: time.Now().UnixNano(),
-		Request: &ppb.GetRequest_Change{
-			Change: &ppb.GetChange{
-				All: true,
-			},
-		},
-		Pid: pnd,
+		Pid:       pnd,
 	}
-	return client.Get(ctx, req)
+	return client.GetChangeList(ctx, req)
 }
 
 // commit sends a commit request for one or multiple changes to the
 // controller.
-func commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
+func commit(addr, pnd string, cuids ...string) (*ppb.SetChangeListResponse, error) {
 	changes := make([]*ppb.SetChange, len(cuids))
 	for i, arg := range cuids {
 		changes[i] = &ppb.SetChange{
 			Cuid: arg,
-			Op:   ppb.SetChange_COMMIT,
+			Op:   ppb.Operation_OPERATION_COMMIT,
 		}
 	}
 	return commitConfirm(addr, pnd, changes)
@@ -142,40 +153,40 @@ func commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
 
 // confirm sends a confirm request for one or multiple changes to the
 // controller
-func confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
+func confirm(addr, pnd string, cuids ...string) (*ppb.SetChangeListResponse, error) {
 	changes := make([]*ppb.SetChange, len(cuids))
 	for i, arg := range cuids {
 		changes[i] = &ppb.SetChange{
 			Cuid: arg,
-			Op:   ppb.SetChange_CONFIRM,
+			Op:   ppb.Operation_OPERATION_CONFIRM,
 		}
 	}
 	return commitConfirm(addr, pnd, changes)
 }
 
-func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse, error) {
+func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetChangeListResponse, error) {
 	ctx := context.Background()
 	client, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
-	req := &ppb.SetRequest{
+	req := &ppb.SetChangeListRequest{
 		Timestamp: time.Now().UnixNano(),
 		Change:    changes,
 		Pid:       pnd,
 	}
-	return client.Set(ctx, req)
+	return client.SetChangeList(ctx, req)
 }
 
 // addDevice adds a new device to the controller. The device name is optional.
 // If no name is provided a name will be generated upon device creation.
-func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetResponse, error) {
+func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetOndListResponse, error) {
 	pndClient, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 
-	req := &ppb.SetRequest{
+	req := &ppb.SetOndListRequest{
 		Timestamp: time.Now().UnixNano(),
 		Ond: []*ppb.SetOnd{
 			{
@@ -190,87 +201,94 @@ func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.
 		Pid: pid.String(),
 	}
 	switch t := opt.Type; t {
-	case spb.Type_CONTAINERISED, spb.Type_PLUGIN:
+	case spb.Type_TYPE_CONTAINERISED, spb.Type_TYPE_PLUGIN:
 		req.Ond[0].Sbi.Id = uuid.Nil.String()
 		req.Ond[0].Sbi.Type = t
 		req.Ond[0].TransportOption.Type = t
 	default:
 	}
 	ctx := context.Background()
-	return pndClient.Set(ctx, req)
+	return pndClient.SetOndList(ctx, req)
 }
 
-// getDevice requests one or multiple devices belonging to a given
+// getDevice requests one device belonging to a given
 // PrincipalNetworkDomain from the controller. If no device identifier
-// is provided, all devices are requested.
-func getDevice(addr, pid string, did ...string) (*ppb.GetResponse, error) {
+// is provided, an error is thrown.
+func getDevice(addr, pid string, did ...string) (*ppb.GetOndResponse, error) {
 	pndClient, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 
-	var all bool
 	if len(did) == 0 {
-		all = true
+		return nil, err
 	}
 
-	req := &ppb.GetRequest{
+	req := &ppb.GetOndRequest{
 		Timestamp: time.Now().UnixNano(),
-		Request: &ppb.GetRequest_Ond{
-			Ond: &ppb.GetOnd{
-				All: all,
-				Did: did,
-			},
-		},
-		Pid: pid,
+		Did:       did,
+		Pid:       pid,
 	}
 	ctx := context.Background()
-	return pndClient.Get(ctx, req)
+	return pndClient.GetOnd(ctx, req)
 }
 
-func getPath(addr, pid, did, path string) (*ppb.GetResponse, error) {
+//nolint
+// NOTE: currently not in use, but could be of value later
+// getDevice requests all devices belonging to a given
+// PrincipalNetworkDomain from the controller.
+func getDevices(addr, pid string) (*ppb.GetOndListResponse, error) {
 	pndClient, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 
-	req := &ppb.GetRequest{
+	req := &ppb.GetOndListRequest{
 		Timestamp: time.Now().UnixNano(),
-		Request: &ppb.GetRequest_Path{
-			Path: &ppb.GetPath{
-				Did:  did,
-				Path: path,
-			},
-		},
-		Pid: pid,
+		Pid:       pid,
+	}
+	ctx := context.Background()
+	return pndClient.GetOndList(ctx, req)
+}
+
+func getPath(addr, pid, did, path string) (*ppb.GetPathResponse, error) {
+	pndClient, err := nbi.PndClient(addr, dialOptions...)
+	if err != nil {
+		return nil, err
+	}
+
+	req := &ppb.GetPathRequest{
+		Timestamp: time.Now().UnixNano(),
+		Did:       did,
+		Pid:       pid,
+		Path:      path,
 	}
 	ctx := context.Background()
-	return pndClient.Get(ctx, req)
+	return pndClient.GetPath(ctx, req)
 }
 
-func deleteDevice(addr, pid, did string) (*ppb.DeleteResponse, error) {
+func deleteDevice(addr, pid, did string) (*ppb.DeleteOndResponse, error) {
 	pndClient, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 
-	req := &ppb.DeleteRequest{
+	req := &ppb.DeleteOndRequest{
 		Timestamp: time.Now().UnixNano(),
-		Type:      ppb.DeleteRequest_OND,
-		Uuid:      did,
+		Did:       did,
 		Pid:       pid,
 	}
 	ctx := context.Background()
-	return pndClient.Delete(ctx, req)
+	return pndClient.DeleteOnd(ctx, req)
 }
 
 // change creates a ChangeRequest for the specified OND. ApiOperations are
 // used to specify the type of the change (update, replace, delete as specified
 // in https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#34-modifying-state)
 // For delete operations the value field needs to contain an empty string.
-func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetResponse, error) {
+func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetPathListResponse, error) {
 	req := &ppb.ChangeRequest{
-		Id:    did,
+		Did:   did,
 		Path:  path,
 		Value: value,
 		ApiOp: op,
@@ -278,16 +296,16 @@ func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*pp
 	return sendChangeRequest(addr, pid, req)
 }
 
-func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetResponse, error) {
+func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetPathListResponse, error) {
 	pndClient, err := nbi.PndClient(addr, dialOptions...)
 	if err != nil {
 		return nil, err
 	}
 	ctx := context.Background()
-	r := &ppb.SetRequest{
+	r := &ppb.SetPathListRequest{
 		Timestamp:     time.Now().UnixNano(),
 		ChangeRequest: []*ppb.ChangeRequest{req},
 		Pid:           pid,
 	}
-	return pndClient.Set(ctx, r)
+	return pndClient.SetPathList(ctx, r)
 }
diff --git a/api/initialise_test.go b/api/initialise_test.go
index 347a20a80..4dbb90a3e 100644
--- a/api/initialise_test.go
+++ b/api/initialise_test.go
@@ -22,6 +22,7 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/mock"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 	"google.golang.org/grpc/test/bufconn"
 
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -48,7 +49,7 @@ var sbiUUID uuid.UUID
 func bootstrapUnitTest() {
 	dialOptions = []grpc.DialOption{
 		grpc.WithContextDialer(bufDialer),
-		grpc.WithInsecure(),
+		grpc.WithTransportCredentials(insecure.NewCredentials()),
 	}
 	lis = bufconn.Listen(bufSize)
 	s := grpc.NewServer()
@@ -77,7 +78,7 @@ func bootstrapUnitTest() {
 
 	mockChange := &mocks.Change{}
 	mockChange.On("Age").Return(time.Hour)
-	mockChange.On("State").Return(ppb.Change_INCONSISTENT)
+	mockChange.On("State").Return(ppb.ChangeState_CHANGE_STATE_INCONSISTENT)
 
 	mockPnd := mocks.NetworkDomain{}
 	mockPnd.On("ID").Return(pndUUID)
@@ -101,8 +102,8 @@ func bootstrapUnitTest() {
 		log.Fatal(err)
 	}
 	northbound := nbi.NewNBI(pndStore)
-	cpb.RegisterCoreServer(s, northbound.Core)
-	ppb.RegisterPndServer(s, northbound.Pnd)
+	cpb.RegisterCoreServiceServer(s, northbound.Core)
+	ppb.RegisterPndServiceServer(s, northbound.Pnd)
 	go func() {
 		if err := s.Serve(lis); err != nil {
 			log.Fatalf("Server exited with error: %v", err)
diff --git a/api/pnd.go b/api/pnd.go
index 573869c22..ea6e78a8f 100644
--- a/api/pnd.go
+++ b/api/pnd.go
@@ -167,7 +167,7 @@ func (p *PrincipalNetworkDomainAdapter) PendingChanges() []uuid.UUID {
 		log.Error(err)
 		return nil
 	}
-	return filterChanges(ppb.Change_PENDING, resp)
+	return filterChanges(ppb.ChangeState_CHANGE_STATE_PENDING, resp)
 }
 
 // CommittedChanges sends an API call to the controller requesting
@@ -178,7 +178,7 @@ func (p *PrincipalNetworkDomainAdapter) CommittedChanges() []uuid.UUID {
 		log.Error(err)
 		return nil
 	}
-	return filterChanges(ppb.Change_COMMITTED, resp)
+	return filterChanges(ppb.ChangeState_CHANGE_STATE_COMMITTED, resp)
 }
 
 // GetChange sends an API call to the controller requesting the specified change
@@ -206,7 +206,7 @@ func (p *PrincipalNetworkDomainAdapter) Confirm(cuid uuid.UUID) error {
 	return nil
 }
 
-func filterChanges(state ppb.Change_State, resp *ppb.GetResponse) []uuid.UUID {
+func filterChanges(state ppb.ChangeState, resp *ppb.GetChangeListResponse) []uuid.UUID {
 	changes := make([]uuid.UUID, 0)
 	for _, ch := range resp.Change {
 		if ch.State == state {
diff --git a/api/pnd_test.go b/api/pnd_test.go
index 62beb9281..0a2e9d00c 100644
--- a/api/pnd_test.go
+++ b/api/pnd_test.go
@@ -646,8 +646,8 @@ func TestPrincipalNetworkDomainAdapter_Confirm(t *testing.T) {
 
 func Test_filterChanges(t *testing.T) {
 	type args struct {
-		state ppb.Change_State
-		resp  *ppb.GetResponse
+		state ppb.ChangeState
+		resp  *ppb.GetChangeListResponse
 	}
 	tests := []struct {
 		name string
diff --git a/config/config.go b/config/config.go
index 86e39b687..bf6071c31 100644
--- a/config/config.go
+++ b/config/config.go
@@ -57,8 +57,9 @@ func InitializeConfig() error {
 	BaseSouthBoundUUID = baseSouthBoundUUIDFromViper
 
 	BaseSouthBoundType = viper.GetInt32(baseSouthBoundTypeKey)
-	if BaseSouthBoundType != 0 {
-		viper.Set(baseSouthBoundTypeKey, 0)
+	if BaseSouthBoundType != 1 {
+		BaseSouthBoundType = 1
+		viper.Set(baseSouthBoundTypeKey, 1)
 		viper.WriteConfig()
 	}
 
diff --git a/config/config_test.go b/config/config_test.go
index 482465dcc..351667e57 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -36,8 +36,8 @@ func TestUseExistingConfig(t *testing.T) {
 			BaseSouthBoundUUID.String())
 	}
 
-	if BaseSouthBoundType != 0 {
-		t.Fatalf("BaseSouthBoundType is not 0. got=%d",
+	if BaseSouthBoundType != 1 {
+		t.Fatalf("BaseSouthBoundType is not 1. got=%d",
 			BaseSouthBoundType)
 	}
 
diff --git a/controller.go b/controller.go
index 81da140bf..ea7db97e3 100644
--- a/controller.go
+++ b/controller.go
@@ -13,6 +13,7 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 
 	pb "code.fbi.h-da.de/danet/api/go/gosdn/core"
 	cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi"
@@ -37,7 +38,7 @@ type Core struct {
 	nbi        *nbi.NorthboundInterface
 	stopChan   chan os.Signal
 
-	csbiClient cpb.CsbiClient
+	csbiClient cpb.CsbiServiceClient
 }
 
 var c *Core
@@ -72,7 +73,11 @@ func initialize() error {
 		return err
 	}
 
-	sbi := createSouthboundInterfaces()
+	sbi, err := createSouthboundInterfaces()
+	if err != nil {
+		return err
+	}
+
 	err = createPrincipalNetworkDomain(sbi)
 	if err != nil {
 		return err
@@ -90,9 +95,9 @@ func startGrpc() error {
 	log.Infof("listening to %v", lis.Addr())
 	c.grpcServer = grpc.NewServer()
 	c.nbi = nbi.NewNBI(c.pndc)
-	pb.RegisterCoreServer(c.grpcServer, c.nbi.Core)
-	ppb.RegisterPndServer(c.grpcServer, c.nbi.Pnd)
-	cpb.RegisterCsbiServer(c.grpcServer, c.nbi.Csbi)
+	pb.RegisterCoreServiceServer(c.grpcServer, c.nbi.Core)
+	ppb.RegisterPndServiceServer(c.grpcServer, c.nbi.Pnd)
+	cpb.RegisterCsbiServiceServer(c.grpcServer, c.nbi.Csbi)
 	go func() {
 		if err := c.grpcServer.Serve(lis); err != nil {
 			log.Fatal(err)
@@ -100,19 +105,22 @@ func startGrpc() error {
 	}()
 
 	orchestrator := viper.GetString("csbi-orchestrator")
-	conn, err := grpc.Dial(orchestrator, grpc.WithInsecure())
+	conn, err := grpc.Dial(orchestrator, grpc.WithTransportCredentials(insecure.NewCredentials()))
 	if err != nil {
 		log.Fatal(err)
 	}
-	c.csbiClient = cpb.NewCsbiClient(conn)
+	c.csbiClient = cpb.NewCsbiServiceClient(conn)
 	return nil
 }
 
 // createSouthboundInterfaces initializes the controller with its supported SBIs
-func createSouthboundInterfaces() southbound.SouthboundInterface {
-	sbi := nucleus.NewSBI(spb.Type(config.BaseSouthBoundType), config.BaseSouthBoundUUID)
+func createSouthboundInterfaces() (southbound.SouthboundInterface, error) {
+	sbi, err := nucleus.NewSBI(spb.Type(config.BaseSouthBoundType), config.BaseSouthBoundUUID)
+	if err != nil {
+		return nil, err
+	}
 
-	return sbi
+	return sbi, nil
 }
 
 // createPrincipalNetworkDomain initializes the controller with an initial PND
@@ -139,7 +147,10 @@ func restorePrincipalNetworkDomains() error {
 		return err
 	}
 
-	sbi := createSouthboundInterfaces()
+	sbi, err := createSouthboundInterfaces()
+	if err != nil {
+		return err
+	}
 
 	for _, pndFromStore := range pndsFromStore {
 		log.Debugf("Restoring PND: %s\n", pndFromStore.Name)
diff --git a/go.mod b/go.mod
index 094fad667..955149660 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module code.fbi.h-da.de/danet/gosdn
 go 1.17
 
 require (
-	code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450
+	code.fbi.h-da.de/danet/api v0.2.5-0.20220301081709-d68d321135a7
 	code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40
 	code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40
 	code.fbi.h-da.de/danet/yang-models v0.1.0
@@ -19,10 +19,12 @@ require (
 	github.com/spf13/viper v1.9.0
 	github.com/stretchr/objx v0.2.0 // indirect
 	github.com/stretchr/testify v1.7.0
-	google.golang.org/grpc v1.40.0
+	google.golang.org/grpc v1.43.0
 	google.golang.org/protobuf v1.27.1
 )
 
+require github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2
+
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.1.1 // indirect
@@ -50,7 +52,7 @@ require (
 	golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab // indirect
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
-	google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
+	google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
 	gopkg.in/ini.v1 v1.64.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
diff --git a/go.sum b/go.sum
index 427cfd8f8..b411756bc 100644
--- a/go.sum
+++ b/go.sum
@@ -46,8 +46,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450 h1:gImcnMybH6KceaLQzbD2FDjV0kRL88WobBDQVH92d9o=
-code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450/go.mod h1:kjazkgCFLje+z4BBNBLlyozhQUnkJd0sqlZz1Axe0wM=
+code.fbi.h-da.de/danet/api v0.2.5-0.20220301081709-d68d321135a7 h1:DxcOZDploBC0GdyURQQprwo6jOTUUQ8spXgRQXtK4xE=
+code.fbi.h-da.de/danet/api v0.2.5-0.20220301081709-d68d321135a7/go.mod h1:J1wwKAHhP3HprrzoNs6f5C56znzvns69FU56oItc3kc=
 code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40 h1:x7rVYGqfJSMWuYBp+JE6JVMcFP03Gx0mnR2ftsgqjVI=
 code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40/go.mod h1:uVe3gCeF2DcIho8K9CIO46uAkHW/lUF+fAaUX1vHrF0=
 code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40 h1:B45k5tGEdjjdsKK4f+0dQoyReFmsWdwYEzHofA7DPM8=
@@ -112,7 +112,11 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -156,6 +160,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
@@ -287,7 +292,10 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2 h1:I/pwhnUln5wbMnTyRbzswA0/JxpK8sZj0aUfI3TV1So=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2/go.mod h1:lsuH8kb4GlMdSlI4alNIBBSAt5CHJtg3i+0WuN9J5YM=
 github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
 github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
 github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
@@ -755,6 +763,7 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1014,8 +1023,8 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr
 google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
 google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
 google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@@ -1045,8 +1054,9 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=
+google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.1/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1110,4 +1120,5 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/http.go b/http.go
index 3a6fea201..f84f231a0 100644
--- a/http.go
+++ b/http.go
@@ -2,44 +2,136 @@ package gosdn
 
 import (
 	"context"
+	"flag"
 	"fmt"
 	"net/http"
 	"time"
 
+	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
 	"github.com/prometheus/client_golang/prometheus/promhttp"
 	log "github.com/sirupsen/logrus"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/credentials/insecure"
+	"google.golang.org/grpc/status"
+
+	cgw "code.fbi.h-da.de/danet/api/go/gosdn/core"
+	pgw "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
+)
+
+var (
+	// command-line options:
+	// gRPC server endpoint
+	grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:55055", "gRPC server endpoint")
 )
 
 func stopHttpServer() error {
+	log.Info("shutting down http server")
 	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 	defer cancel()
-	log.Info("shutting down http server")
-	return c.httpServer.Shutdown(ctx)
+	err := c.httpServer.Shutdown(ctx)
+	return err
+}
+
+func run() error {
+	ctx := context.Background()
+	ctx, cancel := context.WithCancel(ctx)
+	defer cancel()
+
+	// Register gRPC server endpoint
+	// Note: Make sure the gRPC server is running properly and accessible
+	mux := runtime.NewServeMux()
+
+	err := registerHttpHandler(mux)
+
+	if err != nil {
+		return err
+	}
+
+	opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
+	err = cgw.RegisterCoreServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
+	if err != nil {
+		return err
+	}
+
+	err = pgw.RegisterPndServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
+	if err != nil {
+		return err
+	}
+
+	// Set the HTTP server of core to the new server
+	c.httpServer = &http.Server{Addr: ":8080", Handler: mux}
+	// Start HTTP server (and proxy calls to gRPC server endpoint)
+	return c.httpServer.ListenAndServe()
+}
+
+func startHttpServer() {
+	go func() {
+		if err := run(); err != nil {
+			log.Info(err)
+		}
+	}()
+
+	log.Info("Server exiting")
 }
 
-func registerHttpHandler() {
+func registerHttpHandler(mux *runtime.ServeMux) error {
 	defer func() {
 		if r := recover(); r != nil {
 			fmt.Println("Recovered in f", r)
 		}
 	}()
-	http.HandleFunc("/livez", healthCheck)
-	http.HandleFunc("/readyz", readynessCheck)
-	http.Handle("/metrics", promhttp.Handler())
+
+	err := liveCheckHandler(mux)
+	if err != nil {
+		return err
+	}
+
+	err = readyCheckHandler(mux)
+	if err != nil {
+		return err
+	}
+
+	err = metricsHandler(mux)
+	if err != nil {
+		return err
+	}
+
+	return nil
 }
 
-func startHttpServer() {
-	registerHttpHandler()
-	c.httpServer = &http.Server{Addr: ":8080"}
-	go func() {
-		log.Info(c.httpServer.ListenAndServe())
-	}()
+func liveCheckHandler(mux *runtime.ServeMux) error {
+	err := mux.HandlePath("GET", "/livez", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+		w.WriteHeader(http.StatusOK)
+	})
+
+	if err != nil {
+		return status.Errorf(codes.Internal, "%v", err)
+	}
+
+	return nil
 }
 
-func healthCheck(writer http.ResponseWriter, request *http.Request) {
-	writer.WriteHeader(http.StatusOK)
+func readyCheckHandler(mux *runtime.ServeMux) error {
+	err := mux.HandlePath("GET", "/readyz", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+		w.WriteHeader(http.StatusOK)
+	})
+
+	if err != nil {
+		return status.Errorf(codes.Internal, "%v", err)
+	}
+
+	return nil
 }
 
-func readynessCheck(writer http.ResponseWriter, request *http.Request) {
-	writer.WriteHeader(http.StatusOK)
+func metricsHandler(mux *runtime.ServeMux) error {
+	err := mux.HandlePath("GET", "/metrics", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+		promhttp.Handler()
+	})
+
+	if err != nil {
+		return status.Errorf(codes.Internal, "%v", err)
+	}
+
+	return nil
 }
diff --git a/http_test.go b/http_test.go
index 786c75dca..ceb46ed12 100644
--- a/http_test.go
+++ b/http_test.go
@@ -1,8 +1,11 @@
 package gosdn
 
 import (
+	"errors"
+	"net"
 	"net/http"
 	"testing"
+	"time"
 )
 
 func Test_httpApi(t *testing.T) {
@@ -34,6 +37,13 @@ func Test_httpApi(t *testing.T) {
 	coreLock.Lock()
 	startHttpServer()
 	coreLock.Unlock()
+
+	err := waitForHTTPServer()
+	if err != nil {
+		t.Errorf("httpApi() error = %v", err)
+		return
+	}
+
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			got, err := http.Get(tt.request)
@@ -47,3 +57,20 @@ func Test_httpApi(t *testing.T) {
 		})
 	}
 }
+
+// see: https://stackoverflow.com/a/56865986
+func waitForHTTPServer() error {
+	for i := 0; i < 10; i++ {
+		conn, err := net.DialTimeout("tcp", ":8080", 1*time.Second)
+		if err != nil {
+			time.Sleep(50 * time.Millisecond)
+			continue
+		}
+		err = conn.Close()
+		if err != nil {
+			return err
+		}
+		return nil
+	}
+	return errors.New("http server could not be reached")
+}
diff --git a/interfaces/change/change.go b/interfaces/change/change.go
index 460a1af04..cd4b78ccb 100644
--- a/interfaces/change/change.go
+++ b/interfaces/change/change.go
@@ -16,7 +16,7 @@ type Change interface {
 	ID() uuid.UUID
 	Commit() error
 	Confirm() error
-	State() ppb.Change_State
+	State() ppb.ChangeState
 	Age() time.Duration
 }
 
diff --git a/mocks/Change.go b/mocks/Change.go
index d9f014299..d9c0b8ccd 100644
--- a/mocks/Change.go
+++ b/mocks/Change.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.9.4. DO NOT EDIT.
+// Code generated by mockery v2.10.0. DO NOT EDIT.
 
 package mocks
 
@@ -75,14 +75,14 @@ func (_m *Change) ID() uuid.UUID {
 }
 
 // State provides a mock function with given fields:
-func (_m *Change) State() pnd.Change_State {
+func (_m *Change) State() pnd.ChangeState {
 	ret := _m.Called()
 
-	var r0 pnd.Change_State
-	if rf, ok := ret.Get(0).(func() pnd.Change_State); ok {
+	var r0 pnd.ChangeState
+	if rf, ok := ret.Get(0).(func() pnd.ChangeState); ok {
 		r0 = rf()
 	} else {
-		r0 = ret.Get(0).(pnd.Change_State)
+		r0 = ret.Get(0).(pnd.ChangeState)
 	}
 
 	return r0
diff --git a/northbound/client/core.go b/northbound/client/core.go
index 9f98060bc..68982b6e1 100644
--- a/northbound/client/core.go
+++ b/northbound/client/core.go
@@ -8,10 +8,10 @@ import (
 // CoreClient returns a client for the gRPC Core service. It takes
 // the address of the gRPC endpoint and optional grpc.DialOption
 // as argument
-func CoreClient(addr string, opts ...grpc.DialOption) (pb.CoreClient, error) {
+func CoreClient(addr string, opts ...grpc.DialOption) (pb.CoreServiceClient, error) {
 	conn, err := grpc.Dial(addr, opts...)
 	if err != nil {
 		return nil, err
 	}
-	return pb.NewCoreClient(conn), nil
+	return pb.NewCoreServiceClient(conn), nil
 }
diff --git a/northbound/client/pnd.go b/northbound/client/pnd.go
index 2e3699828..588af8893 100644
--- a/northbound/client/pnd.go
+++ b/northbound/client/pnd.go
@@ -8,10 +8,10 @@ import (
 // PndClient returns a client for the gRPC PND service. It takes
 // the address of the gRPC endpoint and optional grpc.DialOption
 // as argument
-func PndClient(addr string, opts ...grpc.DialOption) (ppb.PndClient, error) {
+func PndClient(addr string, opts ...grpc.DialOption) (ppb.PndServiceClient, error) {
 	conn, err := grpc.Dial(addr, opts...)
 	if err != nil {
 		return nil, err
 	}
-	return ppb.NewPndClient(conn), nil
+	return ppb.NewPndServiceClient(conn), nil
 }
diff --git a/northbound/server/core.go b/northbound/server/core.go
index d32628cef..d269fad77 100644
--- a/northbound/server/core.go
+++ b/northbound/server/core.go
@@ -14,23 +14,17 @@ import (
 )
 
 type core struct {
-	pb.UnimplementedCoreServer
+	pb.UnimplementedCoreServiceServer
 }
 
-func (s core) Get(ctx context.Context, request *pb.GetRequest) (*pb.GetResponse, error) {
+func (s core) GetPnd(ctx context.Context, request *pb.GetPndRequest) (*pb.GetPndResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "get"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
-	var pndList []uuid.UUID
-	switch request.All {
-	case true:
-		pndList = pndc.UUIDs()
-	default:
-		var err error
-		pndList, err = stringToUUID(request.Pid)
-		if err != nil {
-			return nil, handleRPCError(labels, err)
-		}
+
+	pndList, err := stringToUUID(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
 	}
 
 	pnds := make([]*ppb.PrincipalNetworkDomain, len(pndList))
@@ -40,36 +34,53 @@ func (s core) Get(ctx context.Context, request *pb.GetRequest) (*pb.GetResponse,
 			return nil, err
 		}
 
-		ond, err := fillOnds(pnd, true)
-		if err != nil {
-			return nil, handleRPCError(labels, err)
+		pnds[i] = &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
 		}
+	}
+	return &pb.GetPndResponse{
+		Timestamp: time.Now().UnixNano(),
+		Pnd:       pnds,
+	}, nil
+}
+
+func (s core) GetPndList(ctx context.Context, request *pb.GetPndListRequest) (*pb.GetPndListResponse, error) {
+	labels := prometheus.Labels{"service": "core", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
 
-		sbi, err := fillSbis(pnd, true)
+	pndList := pndc.UUIDs()
+
+	pnds := make([]*ppb.PrincipalNetworkDomain, len(pndList))
+	for i, id := range pndList {
+		pnd, err := pndc.GetPND(id)
 		if err != nil {
-			return nil, handleRPCError(labels, err)
+			return nil, err
 		}
 
 		pnds[i] = &ppb.PrincipalNetworkDomain{
 			Id:          pnd.ID().String(),
 			Name:        pnd.GetName(),
 			Description: pnd.GetDescription(),
-			Ond:         ond,
-			Sbi:         sbi,
 		}
 	}
-	return &pb.GetResponse{
+	return &pb.GetPndListResponse{
 		Timestamp: time.Now().UnixNano(),
 		Pnd:       pnds,
 	}, nil
 }
 
-func (s core) Set(ctx context.Context, request *pb.SetRequest) (*pb.SetResponse, error) {
+func (s core) CreatePndList(ctx context.Context, request *pb.CreatePndListRequest) (*pb.CreatePndListResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "set"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
 	for _, r := range request.Pnd {
-		sbi := nucleus.NewSBI(spb.Type_OPENCONFIG)
+		sbi, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+		if err != nil {
+			return nil, handleRPCError(labels, err)
+		}
 
 		pnd, err := nucleus.NewPND(r.Name, r.Description, uuid.New(), sbi, nil, nil)
 		if err != nil {
@@ -79,8 +90,25 @@ func (s core) Set(ctx context.Context, request *pb.SetRequest) (*pb.SetResponse,
 			return nil, handleRPCError(labels, err)
 		}
 	}
-	return &pb.SetResponse{
+	return &pb.CreatePndListResponse{
+		Timestamp: time.Now().UnixNano(),
+		Status:    pb.Status_STATUS_OK,
+	}, nil
+}
+
+func (s core) DeletePnd(ctx context.Context, request *pb.DeletePndRequest) (*pb.DeletePndResponse, error) {
+	labels := prometheus.Labels{"service": "core", "rpc": "set"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+
+	pndID, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+	pndc.Delete(pndID)
+
+	return &pb.DeletePndResponse{
 		Timestamp: time.Now().UnixNano(),
-		Status:    pb.SetResponse_OK,
+		Status:    pb.Status_STATUS_OK,
 	}, nil
 }
diff --git a/northbound/server/core_test.go b/northbound/server/core_test.go
index efe46fd2a..2ca0e08f0 100644
--- a/northbound/server/core_test.go
+++ b/northbound/server/core_test.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"reflect"
 	"testing"
+	"time"
 
 	pb "code.fbi.h-da.de/danet/api/go/gosdn/core"
 )
@@ -11,20 +12,20 @@ import (
 func Test_core_Set(t *testing.T) {
 	type args struct {
 		ctx     context.Context
-		request *pb.SetRequest
+		request *pb.CreatePndListRequest
 	}
 	tests := []struct {
 		name    string
 		args    args
-		want    *pb.SetResponse
+		want    *pb.CreatePndListResponse
 		wantErr bool
 	}{
 		{
 			name: "default",
 			args: args{
 				ctx: context.Background(),
-				request: &pb.SetRequest{
-					Pnd: []*pb.SetPnd{
+				request: &pb.CreatePndListRequest{
+					Pnd: []*pb.PndCreateProperties{
 						{
 							Name:        "test",
 							Description: "test",
@@ -33,15 +34,17 @@ func Test_core_Set(t *testing.T) {
 					},
 				},
 			},
-			want: &pb.SetResponse{},
+			want: &pb.CreatePndListResponse{
+				Status: pb.Status_STATUS_OK,
+			},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := core{
-				UnimplementedCoreServer: pb.UnimplementedCoreServer{},
+				UnimplementedCoreServiceServer: pb.UnimplementedCoreServiceServer{},
 			}
-			got, err := s.Set(tt.args.ctx, tt.args.request)
+			got, err := s.CreatePndList(tt.args.ctx, tt.args.request)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("core.Set() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -54,10 +57,10 @@ func Test_core_Set(t *testing.T) {
 	}
 }
 
-func Test_core_Get(t *testing.T) {
+func Test_core_GetPnd(t *testing.T) {
 	type args struct {
 		ctx     context.Context
-		request *pb.GetRequest
+		request *pb.GetPndRequest
 	}
 	tests := []struct {
 		name    string
@@ -70,7 +73,7 @@ func Test_core_Get(t *testing.T) {
 			name: "default",
 			args: args{
 				ctx: context.Background(),
-				request: &pb.GetRequest{
+				request: &pb.GetPndRequest{
 					Pid: []string{
 						pndID,
 					},
@@ -83,25 +86,15 @@ func Test_core_Get(t *testing.T) {
 				"test",
 			},
 		},
-		{
-			name: "getAll",
-			args: args{
-				ctx: context.Background(),
-				request: &pb.GetRequest{
-					All: true,
-				},
-			},
-			length: 2,
-		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := core{
-				UnimplementedCoreServer: pb.UnimplementedCoreServer{},
+				UnimplementedCoreServiceServer: pb.UnimplementedCoreServiceServer{},
 			}
-			resp, err := s.Get(tt.args.ctx, tt.args.request)
+			resp, err := s.GetPnd(tt.args.ctx, tt.args.request)
 			if (err != nil) != tt.wantErr {
-				t.Errorf("core.Get() error = %v, wantErr %v", err, tt.wantErr)
+				t.Errorf("core.GetPnd() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 
@@ -112,12 +105,53 @@ func Test_core_Get(t *testing.T) {
 					resp.Pnd[0].Description,
 				}
 				if !reflect.DeepEqual(got, tt.want) {
-					t.Errorf("core.Get() = %v, want %v", got, tt.want)
+					t.Errorf("core.GetPnd() = %v, want %v", got, tt.want)
 				}
 			}
 			length := len(resp.Pnd)
 			if tt.length != length {
-				t.Errorf("core.Get() = %v, want %v", length, tt.length)
+				t.Errorf("core.GetPnd() = %v, want %v", length, tt.length)
+			}
+		})
+	}
+}
+
+func Test_core_GetPndList(t *testing.T) {
+	type args struct {
+		ctx     context.Context
+		request *pb.GetPndListRequest
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    []string
+		length  int
+		wantErr bool
+	}{
+		{
+			name: "getAll",
+			args: args{
+				ctx: context.Background(),
+				request: &pb.GetPndListRequest{
+					Timestamp: time.Now().UnixNano(),
+				},
+			},
+			length: 2,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			s := core{
+				UnimplementedCoreServiceServer: pb.UnimplementedCoreServiceServer{},
+			}
+			resp, err := s.GetPndList(tt.args.ctx, tt.args.request)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("core.GetPndList() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			length := len(resp.Pnd)
+			if tt.length != length {
+				t.Errorf("core.GetPndList() = %v, want %v", length, tt.length)
 			}
 		})
 	}
diff --git a/northbound/server/csbi.go b/northbound/server/csbi.go
index b4d0e91dc..b0fa9f52f 100644
--- a/northbound/server/csbi.go
+++ b/northbound/server/csbi.go
@@ -18,7 +18,7 @@ import (
 )
 
 type csbi struct {
-	cpb.UnimplementedCsbiServer
+	cpb.UnimplementedCsbiServiceServer
 }
 
 func (s csbi) Hello(ctx context.Context, syn *cpb.Syn) (*cpb.Ack, error) {
diff --git a/northbound/server/pnd.go b/northbound/server/pnd.go
index 9392b2ef8..9d6f71ad8 100644
--- a/northbound/server/pnd.go
+++ b/northbound/server/pnd.go
@@ -2,28 +2,28 @@ package server
 
 import (
 	"context"
-	"reflect"
+	"strings"
 	"time"
 
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-
 	ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain"
 	"code.fbi.h-da.de/danet/gosdn/metrics"
+	"code.fbi.h-da.de/danet/gosdn/nucleus"
 	"code.fbi.h-da.de/danet/gosdn/nucleus/errors"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 	"github.com/prometheus/client_golang/prometheus"
 	log "github.com/sirupsen/logrus"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
 )
 
 type pndServer struct {
-	ppb.UnimplementedPndServer
+	ppb.UnimplementedPndServiceServer
 }
 
-func (p pndServer) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetResponse, error) {
+func (p pndServer) GetOnd(ctx context.Context, request *ppb.GetOndRequest) (*ppb.GetOndResponse, error) {
 	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -31,145 +31,163 @@ func (p pndServer) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetRe
 	if err != nil {
 		return nil, handleRPCError(labels, err)
 	}
-	switch req := request.Request.(type) {
-	case *ppb.GetRequest_Pnd:
-		return handleGetPnd(pid)
-	case *ppb.GetRequest_Ond:
-		return handleGetOnd(pid, req)
-	case *ppb.GetRequest_Sbi:
-		return handleGetSbi(pid, req)
-	case *ppb.GetRequest_Change:
-		return handleGetChange(pid, req)
-	case *ppb.GetRequest_Path:
-		return handleGetPath(pid, req)
-	default:
-		return nil, handleRPCError(labels, errors.ErrOperationNotSupported{Op: reflect.TypeOf(request.Request)})
-	}
-}
 
-func handleGetPnd(pid uuid.UUID) (*ppb.GetResponse, error) {
 	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	onds, err := fillOnds(pnd, true)
+	onds, err := fillOnds(pnd, false, request.Did...)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	sbis, err := fillSbis(pnd, true)
-	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
-	}
-	changes, err := fillChanges(pnd, true)
-	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
-	}
-
-	return &ppb.GetResponse{
+	return &ppb.GetOndResponse{
 		Timestamp: time.Now().UnixNano(),
 		Pnd: &ppb.PrincipalNetworkDomain{
 			Id:          pnd.ID().String(),
 			Name:        pnd.GetName(),
 			Description: pnd.GetDescription(),
-			Ond:         onds,
-			Sbi:         sbis,
-			Change:      changes,
 		},
+		Ond: onds,
 	}, nil
 }
 
-func handleGetSbi(pid uuid.UUID, req *ppb.GetRequest_Sbi) (*ppb.GetResponse, error) {
+func (p pndServer) GetOndList(ctx context.Context, request *ppb.GetOndListRequest) (*ppb.GetOndListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
 	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	sbis, err := fillSbis(pnd, req.Sbi.GetAll(), req.Sbi.Sid...)
+	onds, err := fillOnds(pnd, true)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	return &ppb.GetResponse{
+	return &ppb.GetOndListResponse{
 		Timestamp: time.Now().UnixNano(),
-		Sbi:       sbis,
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Ond: onds,
 	}, nil
 }
 
-func stringToUUID(sid []string) ([]uuid.UUID, error) {
-	UUIDs := make([]uuid.UUID, len(sid))
-	for i, id := range sid {
-		parsed, err := uuid.Parse(id)
+func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) {
+	var ondList []uuid.UUID
+	var onds []*ppb.OrchestratedNetworkingDevice
+
+	// all indicates if a client wants all devices or only a single one
+	switch all {
+	case true:
+		ondList = pnd.Devices()
+		onds = make([]*ppb.OrchestratedNetworkingDevice, len(ondList))
+		for _, id := range ondList {
+			did = append(did, id.String())
+		}
+	default:
+		if len(did) == 0 {
+			err := &errors.ErrInvalidParameters{
+				Func:  fillOnds,
+				Param: "length of 'did' cannot be '0' when 'all' is set to 'false'",
+			}
+			log.Error(err)
+
+			return nil, err
+		}
+
+		onds = make([]*ppb.OrchestratedNetworkingDevice, 1)
+	}
+
+	for i, id := range did {
+		d, err := pnd.GetDevice(id)
 		if err != nil {
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
-		UUIDs[i] = parsed
+		cfg := ygot.GNMINotificationsConfig{}
+		dev, err := ygot.TogNMINotifications(d.Model(), time.Now().UnixNano(), cfg)
+		if err != nil {
+			log.Error(err)
+			return nil, status.Errorf(codes.Aborted, "%v", err)
+		}
+		onds[i] = &ppb.OrchestratedNetworkingDevice{
+			Id:     id,
+			Name:   d.Name(),
+			Device: dev,
+		}
 	}
-	return UUIDs, nil
+
+	return onds, nil
 }
 
-func handleGetOnd(pid uuid.UUID, req *ppb.GetRequest_Ond) (*ppb.GetResponse, error) {
-	pnd, err := pndc.GetPND(pid)
-	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
-	}
-	onds, err := fillOnds(pnd, req.Ond.All, req.Ond.Did...)
+func (p pndServer) GetSbi(ctx context.Context, request *ppb.GetSbiRequest) (*ppb.GetSbiResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
 	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
+		return nil, handleRPCError(labels, err)
 	}
-	return &ppb.GetResponse{
-		Timestamp: time.Now().UnixNano(),
-		Ond:       onds,
-	}, nil
-}
 
-func handleGetChange(pid uuid.UUID, req *ppb.GetRequest_Change) (*ppb.GetResponse, error) {
 	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	changes, err := fillChanges(pnd, req.Change.All, req.Change.Cuid...)
+	sbis, err := fillSbis(pnd, false, request.Sid...)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	return &ppb.GetResponse{
+	return &ppb.GetSbiResponse{
 		Timestamp: time.Now().UnixNano(),
-		Change:    changes,
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Sbi: sbis,
 	}, nil
 }
 
-func handleGetPath(pid uuid.UUID, req *ppb.GetRequest_Path) (*ppb.GetResponse, error) {
-	pnd, err := pndc.GetPND(pid)
-	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
-	}
-	duid, err := uuid.Parse(req.Path.Did)
+func (p pndServer) GetSbiList(ctx context.Context, request *ppb.GetSbiListRequest) (*ppb.GetSbiListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
 	if err != nil {
-		log.Error(err)
-		return nil, status.Errorf(codes.Aborted, "%v", err)
+		return nil, handleRPCError(labels, err)
 	}
-	_, err = pnd.Request(duid, req.Path.Path)
+
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	ond, err := fillOnds(pnd, false, req.Path.Did)
+	sbis, err := fillSbis(pnd, true, "")
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	return &ppb.GetResponse{
+	return &ppb.GetSbiListResponse{
 		Timestamp: time.Now().UnixNano(),
-		Ond:       ond,
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Sbi: sbis,
 	}, nil
 }
 
@@ -201,6 +219,7 @@ func fillSbis(pnd networkdomain.NetworkDomain, all bool, sid ...string) ([]*spb.
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
+
 		sbis[i] = &spb.SouthboundInterface{
 			Id: id.String(),
 		}
@@ -208,52 +227,121 @@ func fillSbis(pnd networkdomain.NetworkDomain, all bool, sid ...string) ([]*spb.
 	return sbis, nil
 }
 
-func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) {
-	var ondList []uuid.UUID
-	var onds []*ppb.OrchestratedNetworkingDevice
-
-	// all indicates if a client wants all devices or only a single one
-	switch all {
-	case true:
-		ondList = pnd.Devices()
-		onds = make([]*ppb.OrchestratedNetworkingDevice, len(ondList))
-		for _, id := range ondList {
-			did = append(did, id.String())
-		}
-	default:
-		if len(did) == 0 {
-			err := &errors.ErrInvalidParameters{
-				Func:  fillOnds,
-				Param: "length of 'did' cannot be '0' when 'all' is set to 'false'",
-			}
+func stringToUUID(sid []string) ([]uuid.UUID, error) {
+	UUIDs := make([]uuid.UUID, len(sid))
+	for i, id := range sid {
+		parsed, err := uuid.Parse(id)
+		if err != nil {
 			log.Error(err)
-
-			return nil, err
+			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
+		UUIDs[i] = parsed
+	}
+	return UUIDs, nil
+}
 
-		onds = make([]*ppb.OrchestratedNetworkingDevice, 1)
+func (p pndServer) GetPath(ctx context.Context, request *ppb.GetPathRequest) (*ppb.GetPathResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
 	}
 
-	for i, id := range did {
-		d, err := pnd.GetDevice(id)
-		if err != nil {
-			log.Error(err)
-			return nil, status.Errorf(codes.Aborted, "%v", err)
-		}
-		cfg := ygot.GNMINotificationsConfig{}
-		dev, err := ygot.TogNMINotifications(d.Model(), time.Now().UnixNano(), cfg)
-		if err != nil {
-			log.Error(err)
-			return nil, status.Errorf(codes.Aborted, "%v", err)
-		}
-		onds[i] = &ppb.OrchestratedNetworkingDevice{
-			Id:     id,
-			Name:   d.Name(),
-			Device: dev,
-		}
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	duid, err := uuid.Parse(request.Did)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
 
-	return onds, nil
+	// In case we get the path from grpc-gateway we have to replace
+	path := strings.ReplaceAll(request.Path, "||", "/")
+
+	_, err = pnd.Request(duid, path)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	ond, err := fillOnds(pnd, false, request.Did)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	return &ppb.GetPathResponse{
+		Timestamp: time.Now().UnixNano(),
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Device: ond[0].Device,
+	}, nil
+}
+
+func (p pndServer) GetChange(ctx context.Context, request *ppb.GetChangeRequest) (*ppb.GetChangeResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	changes, err := fillChanges(pnd, false, request.Cuid)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	return &ppb.GetChangeResponse{
+		Timestamp: time.Now().UnixNano(),
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Change: changes,
+	}, nil
+}
+
+func (p pndServer) GetChangeList(ctx context.Context, request *ppb.GetChangeListRequest) (*ppb.GetChangeListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	changes, err := fillChanges(pnd, true, "")
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+	return &ppb.GetChangeListResponse{
+		Timestamp: time.Now().UnixNano(),
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Change: changes,
+	}, nil
 }
 
 func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*ppb.Change, error) {
@@ -295,7 +383,7 @@ func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*
 	return changes, nil
 }
 
-func (p pndServer) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse, error) {
+func (p pndServer) SetOndList(ctx context.Context, request *ppb.SetOndListRequest) (*ppb.SetOndListResponse, error) {
 	labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -309,31 +397,7 @@ func (p pndServer) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetRe
 		return nil, handleRPCError(labels, err)
 	}
 
-	ondResp, err := handleSetOnd(pnd, request.Ond)
-	if err != nil {
-		return nil, handleRPCError(labels, err)
-	}
-	changeResp, err := handleSetChange(pnd, request.Change)
-	if err != nil {
-		return nil, handleRPCError(labels, err)
-	}
-	changeRequestResp, err := handleChangeRequest(pnd, request.ChangeRequest)
-	if err != nil {
-		return nil, handleRPCError(labels, err)
-	}
-	return &ppb.SetResponse{
-		Timestamp: time.Now().UnixNano(),
-		Status:    ppb.SetResponse_OK,
-		Responses: []*ppb.SetResponse{
-			ondResp,
-			changeResp,
-			changeRequestResp,
-		},
-	}, nil
-}
-
-func handleSetOnd(pnd networkdomain.NetworkDomain, req []*ppb.SetOnd) (*ppb.SetResponse, error) {
-	for _, r := range req {
+	for _, r := range request.Ond {
 		sid, err := uuid.Parse(r.Sbi.Id)
 		if err != nil {
 			log.Error(err)
@@ -344,46 +408,81 @@ func handleSetOnd(pnd networkdomain.NetworkDomain, req []*ppb.SetOnd) (*ppb.SetR
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
 	}
-	return &ppb.SetResponse{
+	return &ppb.SetOndListResponse{
 		Timestamp: time.Now().UnixNano(),
-		Status:    ppb.SetResponse_OK,
+		Status:    ppb.Status_STATUS_OK,
+		Responses: []*ppb.SetResponse{
+			{
+				Status: ppb.Status_STATUS_OK,
+			},
+		},
 	}, nil
 }
 
-func handleSetChange(pnd networkdomain.NetworkDomain, req []*ppb.SetChange) (*ppb.SetResponse, error) {
-	for _, r := range req {
+func (p pndServer) SetChangeList(ctx context.Context, request *ppb.SetChangeListRequest) (*ppb.SetChangeListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	for _, r := range request.Change {
 		cuid, err := uuid.Parse(r.Cuid)
 		if err != nil {
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
 		switch r.Op {
-		case ppb.SetChange_COMMIT:
+		case ppb.Operation_OPERATION_COMMIT:
 			if err := pnd.Commit(cuid); err != nil {
 				log.Error(err)
 				return nil, status.Errorf(codes.Aborted, "%v", err)
 			}
-		case ppb.SetChange_CONFIRM:
+		case ppb.Operation_OPERATION_CONFIRM:
 			if err := pnd.Confirm(cuid); err != nil {
 				log.Error(err)
 				return nil, status.Errorf(codes.Aborted, "%v", err)
 			}
 		default:
 			return nil, &errors.ErrInvalidParameters{
-				Func:  handleSetChange,
 				Param: r.Op,
 			}
 		}
 	}
-	return &ppb.SetResponse{
+	return &ppb.SetChangeListResponse{
 		Timestamp: time.Now().UnixNano(),
-		Status:    ppb.SetResponse_OK,
+		Status:    ppb.Status_STATUS_OK,
+		Responses: []*ppb.SetResponse{
+			{
+				Status: ppb.Status_STATUS_OK,
+			},
+		},
 	}, nil
 }
 
-func handleChangeRequest(pnd networkdomain.NetworkDomain, req []*ppb.ChangeRequest) (*ppb.SetResponse, error) {
-	for _, r := range req {
-		did, err := uuid.Parse(r.Id)
+func (p pndServer) SetPathList(ctx context.Context, request *ppb.SetPathListRequest) (*ppb.SetPathListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	for _, r := range request.ChangeRequest {
+		did, err := uuid.Parse(r.Did)
 		if err != nil {
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
@@ -395,14 +494,74 @@ func handleChangeRequest(pnd networkdomain.NetworkDomain, req []*ppb.ChangeReque
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
 	}
-	return &ppb.SetResponse{
+	return &ppb.SetPathListResponse{
 		Timestamp: time.Now().UnixNano(),
-		Status:    ppb.SetResponse_OK,
+		Status:    ppb.Status_STATUS_OK,
+		Responses: []*ppb.SetResponse{
+			{
+				Status: ppb.Status_STATUS_OK,
+			},
+		},
 	}, nil
 }
 
-func (p pndServer) Delete(ctx context.Context, req *ppb.DeleteRequest) (*ppb.DeleteResponse, error) {
-	pid, err := uuid.Parse(req.Pid)
+func (p pndServer) SetSbiList(ctx context.Context, request *ppb.SetSbiListRequest) (*ppb.SetSbiListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := pndc.GetPND(pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	for _, r := range request.Sbi {
+		sbiType := filterSbiType(r.SbiType)
+		sbi, err := nucleus.NewSBI(sbiType)
+		if err != nil {
+			return nil, handleRPCError(labels, err)
+		}
+
+		err = pnd.AddSbi(sbi)
+		if err != nil {
+			return nil, handleRPCError(labels, err)
+		}
+	}
+
+	return &ppb.SetSbiListResponse{
+		Timestamp: time.Now().UnixNano(),
+		Status:    ppb.Status_STATUS_OK,
+		Responses: []*ppb.SetResponse{
+			{
+				Status: ppb.Status_STATUS_OK,
+			},
+		},
+	}, nil
+}
+
+func filterSbiType(sbiType ppb.SbiType) spb.Type {
+	var spbType spb.Type
+
+	switch sbiType {
+	case ppb.SbiType_SBI_TYPE_OPENCONFIG:
+		spbType = spb.Type_TYPE_OPENCONFIG
+	case ppb.SbiType_SBI_TYPE_CONTAINERISED:
+		spbType = spb.Type_TYPE_CONTAINERISED
+	case ppb.SbiType_SBI_TYPE_PLUGIN:
+		spbType = spb.Type_TYPE_PLUGIN
+	default:
+		spbType = spb.Type_TYPE_UNSPECIFIED
+	}
+
+	return spbType
+}
+
+func (p pndServer) DeleteOnd(ctx context.Context, request *ppb.DeleteOndRequest) (*ppb.DeleteOndResponse, error) {
+	pid, err := uuid.Parse(request.Pid)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
@@ -413,7 +572,7 @@ func (p pndServer) Delete(ctx context.Context, req *ppb.DeleteRequest) (*ppb.Del
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
 
-	did, err := uuid.Parse(req.Uuid)
+	did, err := uuid.Parse(request.Did)
 	if err != nil {
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
@@ -422,8 +581,8 @@ func (p pndServer) Delete(ctx context.Context, req *ppb.DeleteRequest) (*ppb.Del
 		log.Error(err)
 		return nil, status.Errorf(codes.Aborted, "%v", err)
 	}
-	return &ppb.DeleteResponse{
+	return &ppb.DeleteOndResponse{
 		Timestamp: time.Now().UnixNano(),
-		Status:    ppb.DeleteResponse_OK,
+		Status:    ppb.Status_STATUS_OK,
 	}, nil
 }
diff --git a/northbound/server/pnd_test.go b/northbound/server/pnd_test.go
index 19e765819..b2e7595ab 100644
--- a/northbound/server/pnd_test.go
+++ b/northbound/server/pnd_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 	"time"
 
+	pb "code.fbi.h-da.de/danet/api/go/gosdn/core"
 	ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"code.fbi.h-da.de/danet/api/go/gosdn/transport"
@@ -20,6 +21,7 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/mock"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 
 	cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi"
 )
@@ -49,14 +51,17 @@ func removeExistingStores() {
 }
 
 func getMockPND() networkdomain.NetworkDomain {
-	sbi := nucleus.NewSBI(spb.Type(0), sbiUUID)
+	sbi, err := nucleus.NewSBI(spb.Type(1), sbiUUID)
+	if err != nil {
+		log.Fatal(err)
+	}
 
-	conn, err := grpc.Dial("orchestrator", grpc.WithInsecure())
+	conn, err := grpc.Dial("orchestrator", grpc.WithTransportCredentials(insecure.NewCredentials()))
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	csbiClient := cpb.NewCsbiClient(conn)
+	csbiClient := cpb.NewCsbiServiceClient(conn)
 
 	newPnd, _ := nucleus.NewPND(
 		"test",
@@ -77,7 +82,7 @@ func getMockPND() networkdomain.NetworkDomain {
 			TransportOption: &transport.TransportOption_GnmiTransportOption{
 				GnmiTransportOption: &transport.GnmiTransportOption{},
 			},
-			Type: spb.Type_OPENCONFIG,
+			Type: spb.Type_TYPE_OPENCONFIG,
 		}, sbiUUID)
 
 	return newPnd
@@ -123,8 +128,11 @@ func TestMain(m *testing.M) {
 		},
 		UUID: deviceUUID,
 	}
-
-	mockDevice.(*nucleus.CommonDevice).SetSBI(nucleus.NewSBI(spb.Type_OPENCONFIG))
+	sbi, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		log.Fatal(err)
+	}
+	mockDevice.(*nucleus.CommonDevice).SetSBI(sbi)
 	mockDevice.(*nucleus.CommonDevice).SetTransport(&mocks.Transport{})
 	mockDevice.(*nucleus.CommonDevice).SetName(hostname)
 	sbiStore = store.NewSbiStore()
@@ -134,7 +142,7 @@ func TestMain(m *testing.M) {
 
 	mockChange := &mocks.Change{}
 	mockChange.On("Age").Return(time.Hour)
-	mockChange.On("State").Return(ppb.Change_INCONSISTENT)
+	mockChange.On("State").Return(ppb.ChangeState_CHANGE_STATE_INCONSISTENT)
 
 	mockPnd = &mocks.NetworkDomain{}
 	mockPnd.On("ID").Return(pndUUID)
@@ -169,54 +177,47 @@ func Test_pnd_Get(t *testing.T) {
 
 	type args struct {
 		ctx     context.Context
-		request *ppb.GetRequest
+		request *pb.GetPndRequest
 	}
 	tests := []struct {
 		name    string
 		args    args
-		want    []string
+		want    *pb.GetPndResponse
 		wantErr bool
 	}{
 		{
 			name: "get pnd",
 			args: args{
 				ctx: context.Background(),
-				request: &ppb.GetRequest{
-					Request: &ppb.GetRequest_Pnd{
-						Pnd: &ppb.GetPnd{},
-					},
-					Pid: pndID,
+				request: &pb.GetPndRequest{
+					Pid: []string{
+						pndID},
 				},
 			},
-			want: []string{
-				pndID,
-				ondID,
-				sbiID,
-				// pendingChangeID,
-				// committedChangeID,
+			want: &pb.GetPndResponse{
+				Pnd: []*ppb.PrincipalNetworkDomain{
+					{Id: pndID,
+						Name:        "test",
+						Description: "test"},
+				},
 			},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			p := pndServer{
-				UnimplementedPndServer: ppb.UnimplementedPndServer{},
+			p := core{
+				UnimplementedCoreServiceServer: pb.UnimplementedCoreServiceServer{},
 			}
-			resp, err := p.Get(tt.args.ctx, tt.args.request)
+			resp, err := p.GetPnd(tt.args.ctx, tt.args.request)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 
-			got := []string{
-				resp.Pnd.Id,
-				resp.Pnd.Ond[0].Id,
-				resp.Pnd.Sbi[0].Id,
-				// resp.Pnd.Change[0].Id,
-				// resp.Pnd.Change[1].Id,
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Get() got = %v, want %v", got, tt.want)
+			got := resp.GetPnd()
+
+			if !reflect.DeepEqual(got, tt.want.Pnd) {
+				t.Errorf("Get() got = %v, want %v", got, tt.want.Pnd)
 			}
 		})
 	}
@@ -225,113 +226,113 @@ func Test_pnd_Get(t *testing.T) {
 func Test_pnd_Set(t *testing.T) {
 	removeExistingStores()
 
-	type args struct {
-		ctx     context.Context
-		request *ppb.SetRequest
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    ppb.SetResponseStatus
-		wantErr bool
-	}{
-		{
-			name: "set ond",
-			args: args{
-				ctx: context.Background(),
-				request: &ppb.SetRequest{
-					Ond: []*ppb.SetOnd{
-						{
-							Sbi: &spb.SouthboundInterface{
-								Id:   sbiID,
-								Type: spb.Type_OPENCONFIG,
-							},
-							DeviceName: hostname,
-							TransportOption: &transport.TransportOption{
-								Address:  "test",
-								Username: "test",
-								Password: "test",
-								TransportOption: &transport.TransportOption_GnmiTransportOption{
-									GnmiTransportOption: &transport.GnmiTransportOption{},
-								},
-							},
-						},
-					},
-					Pid: pndID,
-				},
-			},
-			want: ppb.SetResponse_OK,
-		},
-		// {
-		// 	name: "set change",
-		// 	args: args{
-		// 		ctx: context.Background(),
-		// 		request: &ppb.SetRequest{
-		// 			Pid: pndID,
-		// 			Change: []*ppb.SetChange{
-		// 				{
-		// 					Cuid: pendingChangeID,
-		// 					Op:   ppb.SetChange_COMMIT,
-		// 				},
-		// 				{
-		// 					Cuid: committedChangeID,
-		// 					Op:   ppb.SetChange_CONFIRM,
-		// 				},
-		// 			},
-		// 		},
-		// 	},
-		// 	want: ppb.SetResponse_OK,
-		// },
-		// 	{
-		// 		name: "change request",
-		// 		args: args{
-		// 			ctx: context.Background(),
-		// 			request: &ppb.SetRequest{
-		// 				Pid: pndID,
-		// 				ChangeRequest: []*ppb.ChangeRequest{
-		// 					{
-		// 						Id:    ondID,
-		// 						Path:  "/system/config/hostname",
-		// 						Value: "herbert",
-		// 						ApiOp: ppb.ApiOperation_UPDATE,
-		// 					},
-		// 					{
-		// 						Id:    ondID,
-		// 						Path:  "/system/config/hostname",
-		// 						Value: "fridolin",
-		// 						ApiOp: ppb.ApiOperation_REPLACE,
-		// 					},
-		// 					{
-		// 						Id:    ondID,
-		// 						Path:  "/system/config/hostname",
-		// 						ApiOp: ppb.ApiOperation_DELETE,
-		// 					},
-		// 				},
-		// 			},
-		// 		},
-		// 		want: ppb.SetResponse_OK,
-		// 	},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			p := pndServer{
-				UnimplementedPndServer: ppb.UnimplementedPndServer{},
-			}
-			resp, err := p.Set(tt.args.ctx, tt.args.request)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			got := resp.Status
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Set() got = %v, want %v", got, tt.want)
-			}
-			for _, r := range resp.Responses {
-				got = r.Status
-				if !reflect.DeepEqual(got, tt.want) {
-					t.Errorf("Set() got = %v, want %v", got, tt.want)
-				}
-			}
-		})
-	}
+	// type args struct {
+	// 	ctx     context.Context
+	// 	request *ppb.SetRequest
+	// }
+	// tests := []struct {
+	// 	name    string
+	// 	args    args
+	// 	want    ppb.SetResponseStatus
+	// 	wantErr bool
+	// }{
+	// 	{
+	// 		name: "set ond",
+	// 		args: args{
+	// 			ctx: context.Background(),
+	// 			request: &ppb.SetRequest{
+	// 				Ond: []*ppb.SetOnd{
+	// 					{
+	// 						Sbi: &spb.SouthboundInterface{
+	// 							Id:   sbiID,
+	// 							Type: spb.Type_TYPE_OPENCONFIG,
+	// 						},
+	// 						DeviceName: hostname,
+	// 						TransportOption: &transport.TransportOption{
+	// 							Address:  "test",
+	// 							Username: "test",
+	// 							Password: "test",
+	// 							TransportOption: &transport.TransportOption_GnmiTransportOption{
+	// 								GnmiTransportOption: &transport.GnmiTransportOption{},
+	// 							},
+	// 						},
+	// 					},
+	// 				},
+	// 				Pid: pndID,
+	// 			},
+	// 		},
+	// 		want: ppb.SetResponse_OK,
+	// 	},
+	// 	// {
+	// 	// 	name: "set change",
+	// 	// 	args: args{
+	// 	// 		ctx: context.Background(),
+	// 	// 		request: &ppb.SetRequest{
+	// 	// 			Pid: pndID,
+	// 	// 			Change: []*ppb.SetChange{
+	// 	// 				{
+	// 	// 					Cuid: pendingChangeID,
+	// 	// 					Op:   ppb.SetChange_COMMIT,
+	// 	// 				},
+	// 	// 				{
+	// 	// 					Cuid: committedChangeID,
+	// 	// 					Op:   ppb.SetChange_CONFIRM,
+	// 	// 				},
+	// 	// 			},
+	// 	// 		},
+	// 	// 	},
+	// 	// 	want: ppb.SetResponse_OK,
+	// 	// },
+	// 	// 	{
+	// 	// 		name: "change request",
+	// 	// 		args: args{
+	// 	// 			ctx: context.Background(),
+	// 	// 			request: &ppb.SetRequest{
+	// 	// 				Pid: pndID,
+	// 	// 				ChangeRequest: []*ppb.ChangeRequest{
+	// 	// 					{
+	// 	// 						Id:    ondID,
+	// 	// 						Path:  "/system/config/hostname",
+	// 	// 						Value: "herbert",
+	// 	// 						ApiOp: ppb.ApiOperation_UPDATE,
+	// 	// 					},
+	// 	// 					{
+	// 	// 						Id:    ondID,
+	// 	// 						Path:  "/system/config/hostname",
+	// 	// 						Value: "fridolin",
+	// 	// 						ApiOp: ppb.ApiOperation_REPLACE,
+	// 	// 					},
+	// 	// 					{
+	// 	// 						Id:    ondID,
+	// 	// 						Path:  "/system/config/hostname",
+	// 	// 						ApiOp: ppb.ApiOperation_DELETE,
+	// 	// 					},
+	// 	// 				},
+	// 	// 			},
+	// 	// 		},
+	// 	// 		want: ppb.SetResponse_OK,
+	// 	// 	},
+	// }
+	// for _, tt := range tests {
+	// 	t.Run(tt.name, func(t *testing.T) {
+	// 		p := pndServer{
+	// 			UnimplementedPndServiceServer: ppb.UnimplementedPndServiceServer{},
+	// 		}
+	// 		resp, err := p.Set(tt.args.ctx, tt.args.request)
+	// 		if (err != nil) != tt.wantErr {
+	// 			t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr)
+	// 			return
+	// 		}
+	// 		got := resp.Status
+	// 		if !reflect.DeepEqual(got, tt.want) {
+	// 			t.Errorf("Set() got = %v, want %v", got, tt.want)
+	// 		}
+	// 		for _, r := range resp.Responses {
+	// 			got = r.Status
+	// 			if !reflect.DeepEqual(got, tt.want) {
+	// 				t.Errorf("Set() got = %v, want %v", got, tt.want)
+	// 			}
+	// 		}
+	// 	})
+	// }
 }
diff --git a/nucleus/change.go b/nucleus/change.go
index ca4a6bd4b..824ed850a 100644
--- a/nucleus/change.go
+++ b/nucleus/change.go
@@ -38,7 +38,7 @@ func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruc
 	c := &Change{
 		cuid:          uuid.New(),
 		duid:          device,
-		state:         ppb.Change_PENDING,
+		state:         ppb.ChangeState_CHANGE_STATE_PENDING,
 		timestamp:     time.Now(),
 		previousState: currentState,
 		intendedState: change,
@@ -60,15 +60,15 @@ func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruc
 type Change struct {
 	cuid               uuid.UUID
 	duid               uuid.UUID
-	state              ppb.Change_State
+	state              ppb.ChangeState
 	timestamp          time.Time
 	previousState      ygot.GoStruct
 	intendedState      ygot.GoStruct
 	callback           func(ygot.GoStruct, ygot.GoStruct) error
 	stateMu            sync.RWMutex
 	errChan            <-chan error
-	stateIn            chan<- ppb.Change_State
-	stateOut           <-chan ppb.Change_State
+	stateIn            chan<- ppb.ChangeState
+	stateOut           <-chan ppb.ChangeState
 	stateManagerCancel context.CancelFunc
 }
 
@@ -82,7 +82,7 @@ func (c *Change) ID() uuid.UUID {
 // the change is rolled back.
 func (c *Change) Commit() error {
 	//TODO: check if already commited
-	c.stateIn <- ppb.Change_COMMITTED
+	c.stateIn <- ppb.ChangeState_CHANGE_STATE_COMMITTED
 	select {
 	case err := <-c.errChan:
 		return err
@@ -94,7 +94,7 @@ func (c *Change) Commit() error {
 // Confirm confirms a committed Change and stops the rollback timer.
 func (c *Change) Confirm() error {
 	//TODO: check if already confirmed
-	c.stateIn <- ppb.Change_CONFIRMED
+	c.stateIn <- ppb.ChangeState_CHANGE_STATE_CONFIRMED
 	select {
 	case err := <-c.errChan:
 		return err
@@ -109,16 +109,16 @@ func (c *Change) Age() time.Duration {
 }
 
 // State returns the changes's state.
-func (c *Change) State() ppb.Change_State {
+func (c *Change) State() ppb.ChangeState {
 	c.stateMu.RLock()
 	state := c.state
 	c.stateMu.RUnlock()
 	return state
 }
 
-func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<- ppb.Change_State, <-chan ppb.Change_State, <-chan error) {
-	stateIn := make(chan ppb.Change_State)
-	stateOut := make(chan ppb.Change_State)
+func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<- ppb.ChangeState, <-chan ppb.ChangeState, <-chan error) {
+	stateIn := make(chan ppb.ChangeState)
+	stateOut := make(chan ppb.ChangeState)
 	// A Goroutine, which is created while a new Change is initialized acts as
 	// the reciever for errorChan
 	errChan := make(chan error)
@@ -134,13 +134,13 @@ func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<
 			select {
 			case <-ticker.C:
 				state := ch.State()
-				if state == ppb.Change_CONFIRMED {
+				if state == ppb.ChangeState_CHANGE_STATE_CONFIRMED {
 					continue
 				}
 				err := ch.callback(ch.intendedState, ch.previousState)
 				if err != nil {
 					ch.stateMu.Lock()
-					ch.state = ppb.Change_INCONSISTENT
+					ch.state = ppb.ChangeState_CHANGE_STATE_INCONSISTENT
 					ch.stateMu.Unlock()
 					log.Errorf("change %v timed out", ch.cuid)
 					log.Error(err)
@@ -150,14 +150,14 @@ func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<
 				ticker.Stop()
 				// TODO: keep the Change as pending, or remove it?
 				ch.stateMu.Lock()
-				ch.state = ppb.Change_PENDING
+				ch.state = ppb.ChangeState_CHANGE_STATE_PENDING
 				ch.stateMu.Unlock()
 				log.Errorf("change %v timed out", ch.cuid)
 			case s := <-stateIn:
 				switch s {
-				case ppb.Change_COMMITTED:
+				case ppb.ChangeState_CHANGE_STATE_COMMITTED:
 					state := ch.State()
-					if state == ppb.Change_COMMITTED || state == ppb.Change_CONFIRMED {
+					if state == ppb.ChangeState_CHANGE_STATE_COMMITTED || state == ppb.ChangeState_CHANGE_STATE_CONFIRMED {
 						errChan <- fmt.Errorf("change %v already %s", ch.cuid, state.String())
 						continue
 					}
@@ -166,25 +166,25 @@ func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<
 					err := ch.callback(ch.previousState, ch.intendedState)
 					if err != nil {
 						ch.stateMu.Lock()
-						ch.state = ppb.Change_INCONSISTENT
+						ch.state = ppb.ChangeState_CHANGE_STATE_INCONSISTENT
 						ch.stateMu.Unlock()
 						errChan <- err
 						continue
 					}
 					ch.stateMu.Lock()
-					ch.state = ppb.Change_COMMITTED
+					ch.state = ppb.ChangeState_CHANGE_STATE_COMMITTED
 					ch.stateMu.Unlock()
 					stateOut <- state
-				case ppb.Change_CONFIRMED:
+				case ppb.ChangeState_CHANGE_STATE_CONFIRMED:
 					state := ch.State()
-					if state != ppb.Change_COMMITTED {
+					if state != ppb.ChangeState_CHANGE_STATE_COMMITTED {
 						errChan <- fmt.Errorf("cannot confirm uncommitted change %v", ch.cuid)
 						continue
 					}
 					// The change has been confirmed and the timer is stopped,
 					// since a rollback is not necessary anymore.
 					ch.stateMu.Lock()
-					ch.state = ppb.Change_CONFIRMED
+					ch.state = ppb.ChangeState_CHANGE_STATE_CONFIRMED
 					ch.stateMu.Unlock()
 					stateOut <- state
 					ch.stateManagerCancel()
diff --git a/nucleus/change_test.go b/nucleus/change_test.go
index bb59c2f97..9bff07b40 100644
--- a/nucleus/change_test.go
+++ b/nucleus/change_test.go
@@ -120,7 +120,7 @@ func TestChange_CommitRollbackError(t *testing.T) {
 }
 
 func TestChange_CommitError(t *testing.T) {
-	want := ppb.Change_INCONSISTENT
+	want := ppb.ChangeState_CHANGE_STATE_INCONSISTENT
 	c := &Change{
 		cuid:          cuid,
 		duid:          did,
@@ -150,7 +150,7 @@ func TestChange_CommitError(t *testing.T) {
 }
 
 func TestChange_Commit(t *testing.T) {
-	want := ppb.Change_COMMITTED
+	want := ppb.ChangeState_CHANGE_STATE_COMMITTED
 	c := &Change{
 		cuid:          cuid,
 		duid:          did,
@@ -263,19 +263,19 @@ func TestChange_ID(t *testing.T) {
 func TestChange_State(t *testing.T) {
 	tests := []struct {
 		name string
-		want ppb.Change_State
+		want ppb.ChangeState
 	}{
 		{
 			name: "pending",
-			want: ppb.Change_PENDING,
+			want: ppb.ChangeState_CHANGE_STATE_PENDING,
 		},
 		{
 			name: "committed",
-			want: ppb.Change_COMMITTED,
+			want: ppb.ChangeState_CHANGE_STATE_COMMITTED,
 		},
 		{
 			name: "confirmed",
-			want: ppb.Change_CONFIRMED,
+			want: ppb.ChangeState_CHANGE_STATE_CONFIRMED,
 		},
 	}
 	for _, tt := range tests {
diff --git a/nucleus/device.go b/nucleus/device.go
index 80034d540..8ded44591 100644
--- a/nucleus/device.go
+++ b/nucleus/device.go
@@ -34,7 +34,7 @@ func NewDevice(name string, uuidInput uuid.UUID, opt *tpb.TransportOption, sbi s
 	if err != nil {
 		return nil, err
 	}
-	if opt.Type == spb.Type_CONTAINERISED {
+	if opt.Type == spb.Type_TYPE_CONTAINERISED {
 		return &CsbiDevice{
 			CommonDevice: CommonDevice{
 				UUID:             uuidInput,
@@ -174,7 +174,7 @@ func (d *CommonDevice) MarshalJSON() ([]byte, error) {
 		transportAddress = "testing"
 		transportUsername = "testing"
 		transportPassword = "testing"
-		transportOptionType = spb.Type_OPENCONFIG
+		transportOptionType = spb.Type_TYPE_OPENCONFIG
 	} else {
 		transportType = d.transport.Type()
 		transportAddress = d.transportOptions.Address
diff --git a/nucleus/errors/errors.go b/nucleus/errors/errors.go
index 43bce0f1d..7654c6ec3 100644
--- a/nucleus/errors/errors.go
+++ b/nucleus/errors/errors.go
@@ -109,3 +109,13 @@ type ErrOperationNotSupported struct {
 func (e ErrOperationNotSupported) Error() string {
 	return fmt.Sprintf("transport operation not supported: %v", reflect.TypeOf(e.Op))
 }
+
+// ErrTypeNotSupported implements the Error interface and is called if the
+// wrong Type has been provided.
+type ErrTypeNotSupported struct {
+	Type interface{}
+}
+
+func (e ErrTypeNotSupported) Error() string {
+	return fmt.Sprintf("type not supported: %v", reflect.TypeOf(e.Type))
+}
diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go
index 37f6f7726..d02d0aa9c 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -102,9 +102,9 @@ func (g *Gnmi) applyDiff(ctx context.Context, payload change.Payload) error {
 	req := &gpb.SetRequest{}
 	if diff.Update != nil {
 		switch op {
-		case ppb.ApiOperation_UPDATE:
+		case ppb.ApiOperation_API_OPERATION_UPDATE:
 			req.Update = diff.Update
-		case ppb.ApiOperation_REPLACE:
+		case ppb.ApiOperation_API_OPERATION_REPLACE:
 			req.Replace = diff.Update
 		default:
 			return &errors.ErrOperationNotSupported{Op: op}
diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go
index 376f03632..b7178956e 100644
--- a/nucleus/gnmi_transport_test.go
+++ b/nucleus/gnmi_transport_test.go
@@ -459,8 +459,11 @@ func TestNewGnmiTransport(t *testing.T) {
 			if tt.name == "default" {
 				startGnmiTarget <- gnmiConfig.Addr
 			}
-
-			got, err := newGnmiTransport(tt.args.opts, NewSBI(spb.Type_OPENCONFIG))
+			oc, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("NewSBI() error = %v", err)
+			}
+			got, err := newGnmiTransport(tt.args.opts, oc)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr)
 				return
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index 2c7d84551..3492e1c70 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -35,7 +35,7 @@ import (
 )
 
 // NewPND creates a Principle Network Domain
-func NewPND(name, description string, id uuid.UUID, sbi southbound.SouthboundInterface, c cpb.CsbiClient, callback func(uuid.UUID, chan store.DeviceDetails)) (networkdomain.NetworkDomain, error) {
+func NewPND(name, description string, id uuid.UUID, sbi southbound.SouthboundInterface, c cpb.CsbiServiceClient, callback func(uuid.UUID, chan store.DeviceDetails)) (networkdomain.NetworkDomain, error) {
 	pnd := &pndImplementation{
 		Name:        name,
 		Description: description,
@@ -68,7 +68,7 @@ type pndImplementation struct {
 	//nolint
 	Id uuid.UUID `json:"id,omitempty"`
 
-	csbiClient cpb.CsbiClient
+	csbiClient cpb.CsbiServiceClient
 	callback   func(uuid.UUID, chan store.DeviceDetails)
 }
 
@@ -164,9 +164,9 @@ func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, s
 	defer metrics.FinishHook(labels, start, deviceCreationDurationSecondsTotal, deviceCreationDurationSeconds)
 	var sbi southbound.SouthboundInterface
 	switch t := opt.Type; t {
-	case spb.Type_CONTAINERISED:
+	case spb.Type_TYPE_CONTAINERISED:
 		return pnd.handleCsbiEnrolment(name, opt)
-	case spb.Type_PLUGIN:
+	case spb.Type_TYPE_PLUGIN:
 		var err error
 		sbi, err = pnd.requestPlugin(name, opt)
 		if err != nil {
@@ -189,7 +189,7 @@ func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, s
 
 //AddDeviceFromStore adds a new device to the PND
 func (pnd *pndImplementation) AddDeviceFromStore(name string, deviceUUID uuid.UUID, opt *tpb.TransportOption, sid uuid.UUID) error {
-	if opt.Type == spb.Type_CONTAINERISED {
+	if opt.Type == spb.Type_TYPE_CONTAINERISED {
 		return pnd.handleCsbiEnrolment(name, opt)
 	}
 
@@ -342,19 +342,19 @@ func (pnd *pndImplementation) ChangeOND(duid uuid.UUID, operation ppb.ApiOperati
 		return uuid.Nil, err
 	}
 
-	if operation != ppb.ApiOperation_DELETE && len(value) != 1 {
+	if operation != ppb.ApiOperation_API_OPERATION_DELETE && len(value) != 1 {
 		return uuid.Nil, &errors.ErrInvalidParameters{
 			Func:  pnd.ChangeOND,
 			Param: value,
 		}
 	}
 	switch operation {
-	case ppb.ApiOperation_UPDATE, ppb.ApiOperation_REPLACE:
+	case ppb.ApiOperation_API_OPERATION_UPDATE, ppb.ApiOperation_API_OPERATION_REPLACE:
 		typedValue := gnmi.TypedValue(value[0])
 		if err := ytypes.SetNode(d.SBI().Schema().RootSchema(), cpy, p, typedValue); err != nil {
 			return uuid.Nil, err
 		}
-	case ppb.ApiOperation_DELETE:
+	case ppb.ApiOperation_API_OPERATION_DELETE:
 		if err := ytypes.DeleteNode(d.SBI().Schema().RootSchema(), cpy, p); err != nil {
 			return uuid.Nil, err
 		}
@@ -473,7 +473,7 @@ func (pnd *pndImplementation) createCsbiDevice(ctx context.Context, name string,
 func (pnd *pndImplementation) requestPlugin(name string, opt *tpb.TransportOption) (southbound.SouthboundInterface, error) {
 	ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10)
 	defer cancel()
-	req := &cpb.CreateRequest{
+	req := &cpb.CreatePluginRequest{
 		Timestamp:       time.Now().UnixNano(),
 		TransportOption: []*tpb.TransportOption{opt},
 	}
@@ -555,7 +555,7 @@ func (pnd *pndImplementation) loadStoredDevices() error {
 				TransportOption: &tpb.TransportOption_GnmiTransportOption{
 					GnmiTransportOption: &tpb.GnmiTransportOption{},
 				},
-				Type: spb.Type_OPENCONFIG,
+				Type: spb.Type_TYPE_OPENCONFIG,
 			}, device.SBI)
 		if err != nil {
 			return err
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
index 2aabcd298..71670294e 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -373,6 +373,11 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) {
 func Test_pndImplementation_RemoveDevice(t *testing.T) {
 	removeExistingPNDStore()
 
+	sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("NewSBI() error = %v", err)
+	}
+
 	type args struct {
 		uuid uuid.UUID
 	}
@@ -392,7 +397,7 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) {
 			if tt.name != "fails empty" {
 				d := &CommonDevice{
 					UUID: did,
-					sbi:  NewSBI(spb.Type_OPENCONFIG),
+					sbi:  sbi,
 				}
 				if err := pnd.addDevice(d); err != nil {
 					t.Error(err)
@@ -599,7 +604,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "update",
 			args: args{
-				operation: ppb.ApiOperation_UPDATE,
+				operation: ppb.ApiOperation_API_OPERATION_UPDATE,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -608,7 +613,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "replace",
 			args: args{
-				operation: ppb.ApiOperation_REPLACE,
+				operation: ppb.ApiOperation_API_OPERATION_REPLACE,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -617,7 +622,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "delete",
 			args: args{
-				operation: ppb.ApiOperation_DELETE,
+				operation: ppb.ApiOperation_API_OPERATION_DELETE,
 				path:      "/system/config/hostname",
 			},
 			wantErr: false,
@@ -625,7 +630,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "delete w/args",
 			args: args{
-				operation: ppb.ApiOperation_DELETE,
+				operation: ppb.ApiOperation_API_OPERATION_DELETE,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -643,7 +648,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "invalid arg count",
 			args: args{
-				operation: ppb.ApiOperation_UPDATE,
+				operation: ppb.ApiOperation_API_OPERATION_UPDATE,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000", "ceos3001"},
 			},
@@ -652,7 +657,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "invalid arg count - update, no args",
 			args: args{
-				operation: ppb.ApiOperation_UPDATE,
+				operation: ppb.ApiOperation_API_OPERATION_UPDATE,
 				path:      "/system/config/hostname",
 			},
 			wantErr: true,
@@ -660,7 +665,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "invalid arg count - replace, no args",
 			args: args{
-				operation: ppb.ApiOperation_UPDATE,
+				operation: ppb.ApiOperation_API_OPERATION_UPDATE,
 				path:      "/system/config/hostname",
 			},
 			wantErr: true,
@@ -668,7 +673,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 		{
 			name: "device not found",
 			args: args{
-				operation: ppb.ApiOperation_UPDATE,
+				operation: ppb.ApiOperation_API_OPERATION_UPDATE,
 			},
 			wantErr: true,
 		},
@@ -707,7 +712,11 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 
 func Test_pndImplementation_GetDevice(t *testing.T) {
 	pnd := newPnd()
-	sbi := NewSBI(spb.Type_OPENCONFIG)
+	sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("NewSBI() error = %v", err)
+	}
+
 	d, err := NewDevice("", uuid.Nil, newGnmiTransportOptions(), sbi)
 	if err != nil {
 		t.Error(err)
@@ -757,7 +766,11 @@ func Test_pndImplementation_GetDevice(t *testing.T) {
 
 func Test_pndImplementation_GetDeviceByName(t *testing.T) {
 	p := newPnd()
-	sbi := NewSBI(spb.Type_OPENCONFIG)
+	sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("NewSBI() error = %v", err)
+	}
+
 	d, err := NewDevice("my-device", uuid.Nil, newGnmiTransportOptions(), sbi)
 	if err != nil {
 		t.Error(err)
@@ -832,7 +845,7 @@ func Test_pndImplementation_Confirm(t *testing.T) {
 				t.Error(err)
 				return
 			}
-			_, err := pnd.ChangeOND(d.ID(), ppb.ApiOperation_UPDATE, "system/config/hostname", "ceos3000")
+			_, err := pnd.ChangeOND(d.ID(), ppb.ApiOperation_API_OPERATION_UPDATE, "system/config/hostname", "ceos3000")
 			if err != nil {
 				t.Error(err)
 				return
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index d62411738..4bf8e06ec 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -22,7 +22,7 @@ func init() {
 }
 
 // NewSBI creates a SouthboundInterface of a given type.
-func NewSBI(southbound spb.Type, sbUUID ...uuid.UUID) southbound.SouthboundInterface {
+func NewSBI(southbound spb.Type, sbUUID ...uuid.UUID) (southbound.SouthboundInterface, error) {
 	var id uuid.UUID
 
 	if len(sbUUID) == 0 {
@@ -32,10 +32,10 @@ func NewSBI(southbound spb.Type, sbUUID ...uuid.UUID) southbound.SouthboundInter
 	}
 
 	switch southbound {
-	case spb.Type_OPENCONFIG:
-		return &OpenConfig{id: id}
+	case spb.Type_TYPE_OPENCONFIG:
+		return &OpenConfig{id: id}, nil
 	default:
-		return nil
+		return nil, errors.ErrTypeNotSupported{Type: southbound}
 	}
 }
 
@@ -125,7 +125,7 @@ func (oc *OpenConfig) ID() uuid.UUID {
 }
 
 // Type returns the Southbound's type
-func (oc *OpenConfig) Type() spb.Type { return spb.Type_OPENCONFIG }
+func (oc *OpenConfig) Type() spb.Type { return spb.Type_TYPE_OPENCONFIG }
 
 // Csbi is a stub for the containerised SBI functionality.
 // It holds the standard goSDN OPENCONFIG schema for minimum
@@ -171,5 +171,5 @@ func (csbi *Csbi) ID() uuid.UUID {
 
 // Type returns the Southbound's type
 func (csbi *Csbi) Type() spb.Type {
-	return spb.Type_CONTAINERISED
+	return spb.Type_TYPE_CONTAINERISED
 }
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
index b13f3bb30..f483d02ad 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -165,7 +165,12 @@ func Test_unmarshal(t *testing.T) {
 				t.Error(err)
 			}
 			bytes := resp.Notification[0].Update[0].Val.GetJsonIetfVal()
-			oc := NewSBI(spb.Type_OPENCONFIG)
+			oc, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("unmarshal() error = %v", err)
+				return
+			}
+
 			if err := unmarshal(oc.Schema(), bytes, resp.Notification[0].Update[0].Path, tt.args.goStruct, tt.args.opt...); err != nil {
 				if !tt.wantErr {
 					t.Errorf("unmarshal() error = %v, wantErr %v", err, tt.wantErr)
@@ -180,7 +185,10 @@ func Test_unmarshal(t *testing.T) {
 }
 
 func Test_CreateNewUUID(t *testing.T) {
-	sbi := NewSBI(spb.Type_OPENCONFIG)
+	sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("NewSBI() error = %v", err)
+	}
 
 	if sbi.ID().String() == "" {
 		t.Errorf("sbi.ID().String() is not set.")
@@ -189,7 +197,10 @@ func Test_CreateNewUUID(t *testing.T) {
 
 func Test_UseProvidedUUID(t *testing.T) {
 	providedSBIId := uuid.New()
-	sbi := NewSBI(spb.Type_OPENCONFIG, providedSBIId)
+	sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG, providedSBIId)
+	if err != nil {
+		t.Errorf("NewSBI() error = %v", err)
+	}
 
 	if sbi.ID() != providedSBIId {
 		t.Errorf("sbi.ID() is not %s. got=%s", providedSBIId.String(), sbi.ID().String())
diff --git a/store/changeStores.go b/store/changeStores.go
index ef2d5a750..f9cd3a9be 100644
--- a/store/changeStores.go
+++ b/store/changeStores.go
@@ -41,20 +41,20 @@ func (s *ChangeStore) GetChange(id uuid.UUID) (change.Change, error) {
 
 // Pending returns the UUIDs of all pending changes
 func (s *ChangeStore) Pending() []uuid.UUID {
-	return filterChanges(s, ppb.Change_PENDING)
+	return filterChanges(s, ppb.ChangeState_CHANGE_STATE_PENDING)
 }
 
 // Committed returns the UUIDs of all pending changes
 func (s *ChangeStore) Committed() []uuid.UUID {
-	return filterChanges(s, ppb.Change_COMMITTED)
+	return filterChanges(s, ppb.ChangeState_CHANGE_STATE_COMMITTED)
 }
 
 // Confirmed returns the UUIDs of all pending changes
 func (s *ChangeStore) Confirmed() []uuid.UUID {
-	return filterChanges(s, ppb.Change_CONFIRMED)
+	return filterChanges(s, ppb.ChangeState_CHANGE_STATE_CONFIRMED)
 }
 
-func filterChanges(store *ChangeStore, state ppb.Change_State) []uuid.UUID {
+func filterChanges(store *ChangeStore, state ppb.ChangeState) []uuid.UUID {
 	changes := make([]uuid.UUID, 0)
 	for _, ch := range store.Store {
 		switch c := ch.(type) {
diff --git a/store/change_store_test.go b/store/change_store_test.go
index fee6c99bd..e1e4cc9b7 100644
--- a/store/change_store_test.go
+++ b/store/change_store_test.go
@@ -14,7 +14,7 @@ import (
 func TestChangeStore_Pending(t *testing.T) {
 	changeMock := &mocks.Change{}
 	changeMock.On("ID").Return(cuid)
-	changeMock.On("State").Return(pnd.Change_PENDING)
+	changeMock.On("State").Return(pnd.ChangeState_CHANGE_STATE_PENDING)
 
 	store := NewChangeStore()
 	pending := changeMock
@@ -44,7 +44,7 @@ func TestChangeStore_Pending(t *testing.T) {
 func TestChangeStore_Committed(t *testing.T) {
 	changeMock := &mocks.Change{}
 	changeMock.On("ID").Return(cuid)
-	changeMock.On("State").Return(pnd.Change_COMMITTED)
+	changeMock.On("State").Return(pnd.ChangeState_CHANGE_STATE_COMMITTED)
 	changeMock.On("Commit").Return(nil)
 
 	store := NewChangeStore()
@@ -79,7 +79,7 @@ func TestChangeStore_Committed(t *testing.T) {
 func TestChangeStore_Confirmed(t *testing.T) {
 	changeMock := &mocks.Change{}
 	changeMock.On("ID").Return(cuid)
-	changeMock.On("State").Return(pnd.Change_CONFIRMED)
+	changeMock.On("State").Return(pnd.ChangeState_CHANGE_STATE_CONFIRMED)
 	changeMock.On("Commit").Return(nil)
 	changeMock.On("Confirm").Return(nil)
 
@@ -138,19 +138,19 @@ func Test_filterChanges(t *testing.T) {
 
 	changeMockPending := &mocks.Change{}
 	changeMockPending.On("ID").Return(pendingCUID)
-	changeMockPending.On("State").Return(pnd.Change_PENDING)
+	changeMockPending.On("State").Return(pnd.ChangeState_CHANGE_STATE_PENDING)
 	changeMockPending.On("Commit").Return(nil)
 	changeMockPending.On("Confirm").Return(nil)
 
 	changeMockCommited := &mocks.Change{}
 	changeMockCommited.On("ID").Return(committedCUID)
-	changeMockCommited.On("State").Return(pnd.Change_COMMITTED)
+	changeMockCommited.On("State").Return(pnd.ChangeState_CHANGE_STATE_COMMITTED)
 	changeMockCommited.On("Commit").Return(nil)
 	changeMockCommited.On("Confirm").Return(nil)
 
 	changeMockConfirmed := &mocks.Change{}
 	changeMockConfirmed.On("ID").Return(confirmedCUID)
-	changeMockConfirmed.On("State").Return(pnd.Change_CONFIRMED)
+	changeMockConfirmed.On("State").Return(pnd.ChangeState_CHANGE_STATE_CONFIRMED)
 	changeMockConfirmed.On("Commit").Return(nil)
 	changeMockConfirmed.On("Confirm").Return(nil)
 
@@ -184,7 +184,7 @@ func Test_filterChanges(t *testing.T) {
 	}
 	type args struct {
 		store *ChangeStore
-		state ppb.Change_State
+		state ppb.ChangeState
 	}
 	tests := []struct {
 		name string
@@ -195,7 +195,7 @@ func Test_filterChanges(t *testing.T) {
 			name: "pending",
 			args: args{
 				store: store,
-				state: ppb.Change_PENDING,
+				state: ppb.ChangeState_CHANGE_STATE_PENDING,
 			},
 			want: []uuid.UUID{pendingCUID},
 		},
@@ -203,7 +203,7 @@ func Test_filterChanges(t *testing.T) {
 			name: "committed",
 			args: args{
 				store: store,
-				state: ppb.Change_COMMITTED,
+				state: ppb.ChangeState_CHANGE_STATE_COMMITTED,
 			},
 			want: []uuid.UUID{committedCUID},
 		},
@@ -211,7 +211,7 @@ func Test_filterChanges(t *testing.T) {
 			name: "confirmed",
 			args: args{
 				store: store,
-				state: ppb.Change_CONFIRMED,
+				state: ppb.ChangeState_CHANGE_STATE_CONFIRMED,
 			},
 			want: []uuid.UUID{confirmedCUID},
 		},
diff --git a/test/integration/nucleusIntegration_test.go b/test/integration/nucleusIntegration_test.go
index 68ac90710..026476882 100644
--- a/test/integration/nucleusIntegration_test.go
+++ b/test/integration/nucleusIntegration_test.go
@@ -135,7 +135,12 @@ func TestGnmi_SetInvalidIntegration(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG))
+			oc, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("NewSBI() error = %v", err)
+			}
+			g, err := nucleus.NewTransport(tt.fields.opt, oc)
+
 			if err != nil {
 				t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -154,7 +159,11 @@ func TestGnmi_SetValidIntegration(t *testing.T) {
 		t.Skip("skipping integration test")
 	}
 
-	sbi := nucleus.NewSBI(spb.Type_OPENCONFIG)
+	sbi, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+	if err != nil {
+		t.Errorf("SetValidIntegration() err = %v", err)
+	}
+
 	opt := &tpb.TransportOption{
 		Address:  testAddress,
 		Username: testUsername,
@@ -187,21 +196,21 @@ func TestGnmi_SetValidIntegration(t *testing.T) {
 	}{
 		{
 			name:  "update",
-			apiOp: ppb.ApiOperation_UPDATE,
+			apiOp: ppb.ApiOperation_API_OPERATION_UPDATE,
 			path:  testPath,
 			value: modifiedHostname,
 			want:  modifiedHostname,
 		},
 		{
 			name:  "replace",
-			apiOp: ppb.ApiOperation_REPLACE,
+			apiOp: ppb.ApiOperation_API_OPERATION_REPLACE,
 			path:  "/system/config/domain-name",
 			value: modifiedHostname,
 			want:  modifiedHostname,
 		},
 		{
 			name:  "delete",
-			apiOp: ppb.ApiOperation_DELETE,
+			apiOp: ppb.ApiOperation_API_OPERATION_DELETE,
 			path:  testPath,
 		},
 	}
@@ -295,7 +304,13 @@ func TestGnmi_GetIntegration(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG))
+			oc, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("Get() error = %v", err)
+				return
+			}
+			g, err := nucleus.NewTransport(tt.fields.opt, oc)
+
 			if err != nil {
 				t.Error(err)
 				return
@@ -404,7 +419,13 @@ func TestGnmi_SubscribeIntegration(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			var wantErr = tt.wantErr
-			g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG))
+			oc, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("Subscribe() error = %v", err)
+				return
+			}
+			g, err := nucleus.NewTransport(tt.fields.opt, oc)
+
 			if err != nil {
 				t.Error(err)
 				return
@@ -481,7 +502,12 @@ func TestGnmi_CapabilitiesIntegration(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			tr, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG))
+			oc, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
+			if err != nil {
+				t.Errorf("Capabilities() error = %v", err)
+				return
+			}
+			tr, err := nucleus.NewTransport(tt.fields.opt, oc)
 			if err != nil {
 				t.Error(err)
 				return
-- 
GitLab