Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package server
import (
"context"
"time"
apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
"code.fbi.h-da.de/danet/gosdn/controller/topology"
"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"
"github.com/google/uuid"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Topology holds a topologyService and represents a TopologyServiceServer.
type Topology struct {
apb.UnimplementedTopologyServiceServer
topologyService topology.Service
}
// NewTopologyrServer receives a topologyService and returns a new TopologyServer.
func NewTopologyrServer(service topology.Service) *Topology {
return &Topology{
topologyService: service,
}
}
// AddLink adds a new link to the topology
func (t Topology) AddLink(ctx context.Context, request *apb.AddLinkRequest) (*apb.AddLinkResponse, error) {
sourceNode, sourcePort, err := t.ensureNodeAndPortExists(request.Link.SourceNode, request.Link.SourcePort)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
targetNode, targetPort, err := t.ensureNodeAndPortExists(request.Link.TargetNode, request.Link.TargetPort)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
link := links.Link{
ID: uuid.New(),
Name: request.Link.Name,
SourceNode: sourceNode,
SourcePort: sourcePort,
TargetNode: targetNode,
TargetPort: targetPort,
}
err = topologyService.AddLink(link)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &apb.AddLinkResponse{
Timestamp: time.Now().UnixNano(),
Status: apb.Status_STATUS_OK,
}, nil
}
// GetTopology returns the current topology in the form of all links
func (t Topology) GetTopology(ctx context.Context, request *apb.GetTopologyRequest) (*apb.GetTopologyResponse, error) {
topo, err := topologyService.GetAll()
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
topology := &apb.Topology{}
for _, link := range topo {
topology.Links = append(topology.Links, &apb.Link{
Id: link.ID.String(),
Name: link.Name,
SourceNode: &apb.Node{
Id: link.SourceNode.ID.String(),
Name: link.SourceNode.Name,
},
SourcePort: &apb.Port{
Id: link.SourcePort.ID.String(),
},
TargetNode: &apb.Node{
Id: link.TargetNode.ID.String(),
Name: link.TargetNode.Name,
},
TargetPort: &apb.Port{
Id: link.TargetPort.ID.String(),
},
})
}
return &apb.GetTopologyResponse{
Timestamp: time.Now().UnixNano(),
Status: apb.Status_STATUS_OK,
Toplogy: topology,
}, nil
}
func (t Topology) ensureNodeAndPortExists(incomingNode *apb.Node, incomingPort *apb.Port) (nodes.Node, ports.Port, error) {
node, err := nodeService.EnsureExists(
nodes.Node{
ID: getExistingOrCreateNewUUIDFromString(incomingNode.Id),
},
)
if err != nil {
return node, ports.Port{}, status.Errorf(codes.Aborted, "%v", err)
}
port, err := portService.EnsureExists(
ports.Port{
ID: getExistingOrCreateNewUUIDFromString(incomingPort.Id),
},
)
if err != nil {
return nodes.Node{}, port, status.Errorf(codes.Aborted, "%v", err)
}
return node, port, nil
}
func getExistingOrCreateNewUUIDFromString(id string) uuid.UUID {
parsedID, err := uuid.Parse(id)
if err != nil {
return uuid.Nil
}
return parsedID
}