diff --git a/controller/controller.go b/controller/controller.go index 431791eb1cf3a8b768f0bec968f7d5445c8c35a6..6a8f5c5a51651fb6c43be614bddb2cee863983f0 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -77,7 +77,7 @@ func initialize() error { return err } - nodeService := nodes.NewNodeService(nodes.NewDatabaseNodeStore()) + nodeService := nodes.NewNodeService(nodes.NewDatabaseNodeStore(), eventService) portService := ports.NewPortService(ports.NewDatabasePortStore()) c = &Core{ diff --git a/controller/topology/nodes/nodeService.go b/controller/topology/nodes/nodeService.go index 1a444a48b18db7d5c519e94b8ef80d8df2f39912..520add41ce21d4dcd8ecd85ae7627c250283bd99 100644 --- a/controller/topology/nodes/nodeService.go +++ b/controller/topology/nodes/nodeService.go @@ -1,10 +1,17 @@ package nodes import ( + "code.fbi.h-da.de/danet/gosdn/controller/event" + eventInterfaces "code.fbi.h-da.de/danet/gosdn/controller/interfaces/event" "code.fbi.h-da.de/danet/gosdn/controller/topology/store" "github.com/google/uuid" ) +const ( + // NodeEventTopic is the used topic for node related entity changes + NodeEventTopic = "node" +) + // Service defines a interface for a NodeService type Service interface { EnsureExists(Node) (Node, error) @@ -16,29 +23,33 @@ type Service interface { // NodeService is a NodeService type NodeService struct { - store Store + store Store + eventService eventInterfaces.Service } // NewNodeService creates a NodeService -func NewNodeService(store Store) Service { +func NewNodeService(store Store, eventService eventInterfaces.Service) Service { return &NodeService{ - store: store, + store: store, + eventService: eventService, } } // EnsureExists either creates a new node or returns an already existing node -func (p *NodeService) EnsureExists(node Node) (Node, error) { +func (n *NodeService) EnsureExists(node Node) (Node, error) { if node.ID == uuid.Nil { node.ID = uuid.New() - err := p.store.Add(node) + err := n.store.Add(node) if err != nil { return node, err } + n.eventService.PublishEvent(NodeEventTopic, event.NewAddEvent(node.ID)) + return node, nil } - node, err := p.Get(store.Query{ID: node.ID}) + node, err := n.Get(store.Query{ID: node.ID}) if err != nil { return node, err } @@ -47,28 +58,32 @@ func (p *NodeService) EnsureExists(node Node) (Node, error) { } // Update updates an existing node -func (p *NodeService) Update(node Node) error { - err := p.store.Update(node) +func (n *NodeService) Update(node Node) error { + err := n.store.Update(node) if err != nil { return err } + n.eventService.PublishEvent(NodeEventTopic, event.NewUpdateEvent(node.ID)) + return nil } // Delete deletes a node -func (p *NodeService) Delete(node Node) error { - err := p.store.Delete(node) +func (n *NodeService) Delete(node Node) error { + err := n.store.Delete(node) if err != nil { return err } + n.eventService.PublishEvent(NodeEventTopic, event.NewDeleteEvent(node.ID)) + return nil } // Get gets a node -func (p *NodeService) Get(query store.Query) (Node, error) { - node, err := p.store.Get(query) +func (n *NodeService) Get(query store.Query) (Node, error) { + node, err := n.store.Get(query) if err != nil { return node, err } @@ -77,8 +92,8 @@ func (p *NodeService) Get(query store.Query) (Node, error) { } // GetAll gets all existing nodes -func (p *NodeService) GetAll() ([]Node, error) { - nodes, err := p.store.GetAll() +func (n *NodeService) GetAll() ([]Node, error) { + nodes, err := n.store.GetAll() if err != nil { return nodes, err } diff --git a/controller/topology/nodes/nodeService_test.go b/controller/topology/nodes/nodeService_test.go index e9b76b8634babdbbb44942ab55eecda17837e009..d4457b050c3ae01b85ac3b1486c41072ea7c46cd 100644 --- a/controller/topology/nodes/nodeService_test.go +++ b/controller/topology/nodes/nodeService_test.go @@ -4,6 +4,8 @@ import ( "reflect" "testing" + eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService" + "code.fbi.h-da.de/danet/gosdn/controller/interfaces/event" "code.fbi.h-da.de/danet/gosdn/controller/topology/store" "github.com/google/uuid" ) @@ -37,7 +39,8 @@ func getTestStoreWithNodes(t *testing.T, nodes []Node) Store { func TestNewNodeService(t *testing.T) { type args struct { - store Store + store Store + eventService event.Service } tests := []struct { name string @@ -47,14 +50,15 @@ func TestNewNodeService(t *testing.T) { { name: "should create a new node service", args: args{ - store: getTestStoreWithNodes(t, []Node{}), + store: getTestStoreWithNodes(t, []Node{}), + eventService: eventservice.NewMockEventService(), }, - want: NewNodeService(getTestStoreWithNodes(t, []Node{})), + want: NewNodeService(getTestStoreWithNodes(t, []Node{}), eventservice.NewMockEventService()), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewNodeService(tt.args.store); !reflect.DeepEqual(got, tt.want) { + if got := NewNodeService(tt.args.store, tt.args.eventService); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewNodeService() = %v, want %v", got, tt.want) } }) @@ -63,7 +67,8 @@ func TestNewNodeService(t *testing.T) { func TestNodeService_EnsureExists(t *testing.T) { type fields struct { - store Store + store Store + eventService event.Service } type args struct { node Node @@ -94,7 +99,8 @@ func TestNodeService_EnsureExists(t *testing.T) { { name: "should error if node with uuid is not in store", fields: fields{ - store: store.NewGenericStore[Node](), + store: store.NewGenericStore[Node](), + eventService: eventservice.NewMockEventService(), }, args: args{ node: getTestNode(), @@ -105,7 +111,8 @@ func TestNodeService_EnsureExists(t *testing.T) { { name: "should return node that is in the store", fields: fields{ - store: getTestStoreWithNodes(t, []Node{getTestNode()}), + store: getTestStoreWithNodes(t, []Node{getTestNode()}), + eventService: eventservice.NewMockEventService(), }, args: args{ node: getTestNode(), @@ -117,7 +124,8 @@ func TestNodeService_EnsureExists(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := &NodeService{ - store: tt.fields.store, + store: tt.fields.store, + eventService: tt.fields.eventService, } got, err := p.EnsureExists(tt.args.node) if (err != nil) != tt.wantErr { @@ -133,7 +141,8 @@ func TestNodeService_EnsureExists(t *testing.T) { func TestNodeService_Update(t *testing.T) { type fields struct { - store Store + store Store + eventService event.Service } type args struct { node Node @@ -148,7 +157,8 @@ func TestNodeService_Update(t *testing.T) { { name: "should update an existing node", fields: fields{ - store: getTestStoreWithNodes(t, []Node{getTestNode()}), + store: getTestStoreWithNodes(t, []Node{getTestNode()}), + eventService: eventservice.NewMockEventService(), }, args: args{ node: getTestNode(), @@ -160,7 +170,8 @@ func TestNodeService_Update(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := &NodeService{ - store: tt.fields.store, + store: tt.fields.store, + eventService: tt.fields.eventService, } if err := p.Update(tt.args.node); (err != nil) != tt.wantErr { t.Errorf("NodeService.Update() error = %v, wantErr %v", err, tt.wantErr) @@ -180,7 +191,8 @@ func TestNodeService_Update(t *testing.T) { func TestNodeService_Delete(t *testing.T) { type fields struct { - store Store + store Store + eventService event.Service } type args struct { node Node @@ -194,7 +206,8 @@ func TestNodeService_Delete(t *testing.T) { { name: "should delete an existing node", fields: fields{ - store: getTestStoreWithNodes(t, []Node{getTestNode()}), + store: getTestStoreWithNodes(t, []Node{getTestNode()}), + eventService: eventservice.NewMockEventService(), }, args: args{ node: getTestNode(), @@ -204,7 +217,8 @@ func TestNodeService_Delete(t *testing.T) { { name: "should fail if a node does not exists", fields: fields{ - store: store.NewGenericStore[Node](), + store: store.NewGenericStore[Node](), + eventService: eventservice.NewMockEventService(), }, args: args{ node: getTestNode(), @@ -215,7 +229,8 @@ func TestNodeService_Delete(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := &NodeService{ - store: tt.fields.store, + store: tt.fields.store, + eventService: tt.fields.eventService, } if err := p.Delete(tt.args.node); (err != nil) != tt.wantErr { t.Errorf("NodeService.Delete() error = %v, wantErr %v", err, tt.wantErr) @@ -226,7 +241,8 @@ func TestNodeService_Delete(t *testing.T) { func TestNodeService_Get(t *testing.T) { type fields struct { - store Store + store Store + eventService event.Service } type args struct { query store.Query @@ -241,7 +257,8 @@ func TestNodeService_Get(t *testing.T) { { name: "should error if node with uuid is not in store", fields: fields{ - store: store.NewGenericStore[Node](), + store: store.NewGenericStore[Node](), + eventService: eventservice.NewMockEventService(), }, args: args{ query: store.Query{ @@ -255,7 +272,8 @@ func TestNodeService_Get(t *testing.T) { { name: "should return node that is in the store", fields: fields{ - store: getTestStoreWithNodes(t, []Node{getTestNode()}), + store: getTestStoreWithNodes(t, []Node{getTestNode()}), + eventService: eventservice.NewMockEventService(), }, args: args{ query: store.Query{ @@ -270,7 +288,8 @@ func TestNodeService_Get(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := &NodeService{ - store: tt.fields.store, + store: tt.fields.store, + eventService: tt.fields.eventService, } got, err := p.Get(tt.args.query) if (err != nil) != tt.wantErr { @@ -286,7 +305,8 @@ func TestNodeService_Get(t *testing.T) { func TestNodeService_GetAll(t *testing.T) { type fields struct { - store Store + store Store + eventService event.Service } tests := []struct { name string @@ -297,7 +317,8 @@ func TestNodeService_GetAll(t *testing.T) { { name: "should get all stored nodes", fields: fields{ - store: getTestStoreWithNodes(t, []Node{getTestNode()}), + store: getTestStoreWithNodes(t, []Node{getTestNode()}), + eventService: eventservice.NewMockEventService(), }, want: []Node{getTestNode()}, wantErr: false, @@ -306,7 +327,8 @@ func TestNodeService_GetAll(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := &NodeService{ - store: tt.fields.store, + store: tt.fields.store, + eventService: tt.fields.eventService, } got, err := p.GetAll() if (err != nil) != tt.wantErr { diff --git a/controller/topology/topologyService_test.go b/controller/topology/topologyService_test.go index 06c25eb38f756b6123d05d3b0bff644ec5944b24..68b17027a48418022f79de42645fa11fc3f123a0 100644 --- a/controller/topology/topologyService_test.go +++ b/controller/topology/topologyService_test.go @@ -4,10 +4,12 @@ import ( "reflect" "testing" + eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService" "code.fbi.h-da.de/danet/gosdn/controller/topology/links" "code.fbi.h-da.de/danet/gosdn/controller/topology/nodes" "code.fbi.h-da.de/danet/gosdn/controller/topology/ports" "code.fbi.h-da.de/danet/gosdn/controller/topology/store" + "github.com/google/uuid" ) @@ -108,12 +110,12 @@ func TestNewTopologyService(t *testing.T) { name: "should create a new topology service", args: args{ store: getTestStoreWithLinks(t, []links.Link{}), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, want: NewTopologyService( getTestStoreWithLinks(t, []links.Link{}), - nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), ), }, @@ -150,7 +152,7 @@ func TestTopologyService_AddLink(t *testing.T) { nodeService: nodes.NewNodeService(getTestStoreWithNodes( t, []nodes.Node{getTestSourceNode(), getTestTargetNode()}, - )), + ), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts( t, []ports.Port{getTestSourcePort(), getTestTargetPort()}, @@ -208,7 +210,7 @@ func TestTopologyService_Update(t *testing.T) { name: "should update an existing link", fields: fields{ store: getTestStoreWithLinks(t, []links.Link{getTestLink()}), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, args: args{ @@ -263,7 +265,7 @@ func TestNodeService_Delete(t *testing.T) { name: "should delete an existing link", fields: fields{ store: getTestStoreWithLinks(t, []links.Link{getTestLink()}), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, args: args{ @@ -275,7 +277,7 @@ func TestNodeService_Delete(t *testing.T) { name: "should fail if a node does not exists", fields: fields{ store: store.NewGenericStore[links.Link](), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, args: args{ @@ -318,7 +320,7 @@ func TestTopologyService_Get(t *testing.T) { name: "should error if link with uuid is not in store", fields: fields{ store: getTestStoreWithLinks(t, []links.Link{}), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, args: args{ @@ -380,7 +382,7 @@ func TestTopologyService_GetAll(t *testing.T) { name: "should get all stored links", fields: fields{ store: getTestStoreWithLinks(t, []links.Link{getTestLink()}), - nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{})), + nodeService: nodes.NewNodeService(getTestStoreWithNodes(t, []nodes.Node{}), eventservice.NewMockEventService()), portService: ports.NewPortService(getTestStoreWithPorts(t, []ports.Port{})), }, want: []links.Link{getTestLink()},