blob: 64ccf2835b7a30cbf6a57daca29e02f0c6d09d3a [file] [log] [blame]
Stephane Barbariea75791c2019-01-24 10:58:06 -05001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package core
17
18import (
19 "context"
20 "github.com/opencord/voltha-go/common/log"
21 "github.com/opencord/voltha-go/db/model"
22 "github.com/opencord/voltha-go/protos/voltha"
23 "google.golang.org/grpc/codes"
24 "google.golang.org/grpc/status"
25 "sync"
26)
27
28type LogicalDeviceManager struct {
29 logicalDeviceAgents map[string]*LogicalDeviceAgent
30 deviceMgr *DeviceManager
31 grpcNbiHdlr *APIHandler
32 clusterDataProxy *model.Proxy
33 exitChannel chan int
34 lockLogicalDeviceAgentsMap sync.RWMutex
35}
36
37func newLogicalDeviceManager(deviceMgr *DeviceManager, cdProxy *model.Proxy) *LogicalDeviceManager {
38 var logicalDeviceMgr LogicalDeviceManager
39 logicalDeviceMgr.exitChannel = make(chan int, 1)
40 logicalDeviceMgr.logicalDeviceAgents = make(map[string]*LogicalDeviceAgent)
41 logicalDeviceMgr.deviceMgr = deviceMgr
42 logicalDeviceMgr.clusterDataProxy = cdProxy
43 logicalDeviceMgr.lockLogicalDeviceAgentsMap = sync.RWMutex{}
44 return &logicalDeviceMgr
45}
46
47func (ldMgr *LogicalDeviceManager) setGrpcNbiHandler(grpcNbiHandler *APIHandler) {
48 ldMgr.grpcNbiHdlr = grpcNbiHandler
49}
50
51func (ldMgr *LogicalDeviceManager) start(ctx context.Context) {
52 log.Info("starting-logical-device-manager")
53 log.Info("logical-device-manager-started")
54}
55
56func (ldMgr *LogicalDeviceManager) stop(ctx context.Context) {
57 log.Info("stopping-logical-device-manager")
58 ldMgr.exitChannel <- 1
59 log.Info("logical-device-manager-stopped")
60}
61
62func (ldMgr *LogicalDeviceManager) addLogicalDeviceAgentToMap(agent *LogicalDeviceAgent) {
63 ldMgr.lockLogicalDeviceAgentsMap.Lock()
64 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
65 if _, exist := ldMgr.logicalDeviceAgents[agent.logicalDeviceId]; !exist {
66 ldMgr.logicalDeviceAgents[agent.logicalDeviceId] = agent
67 }
68}
69
70func (ldMgr *LogicalDeviceManager) getLogicalDeviceAgent(logicalDeviceId string) *LogicalDeviceAgent {
71 ldMgr.lockLogicalDeviceAgentsMap.Lock()
72 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
73 if agent, ok := ldMgr.logicalDeviceAgents[logicalDeviceId]; ok {
74 return agent
75 }
76 return nil
77}
78
79func (ldMgr *LogicalDeviceManager) deleteLogicalDeviceAgent(logicalDeviceId string) {
80 ldMgr.lockLogicalDeviceAgentsMap.Lock()
81 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
82 delete(ldMgr.logicalDeviceAgents, logicalDeviceId)
83}
84
85// GetLogicalDevice provides a cloned most up to date logical device
86func (ldMgr *LogicalDeviceManager) getLogicalDevice(id string) (*voltha.LogicalDevice, error) {
87 log.Debugw("getlogicalDevice", log.Fields{"logicaldeviceid": id})
88 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
89 return agent.GetLogicalDevice()
90 }
91 return nil, status.Errorf(codes.NotFound, "%s", id)
92}
93
94func (ldMgr *LogicalDeviceManager) listLogicalDevices() (*voltha.LogicalDevices, error) {
95 log.Debug("ListAllLogicalDevices")
96 result := &voltha.LogicalDevices{}
97 if logicalDevices := ldMgr.clusterDataProxy.Get("/logical_devices", 0, false, ""); logicalDevices != nil {
98 for _, logicalDevice := range logicalDevices.([]interface{}) {
99 if agent := ldMgr.getLogicalDeviceAgent(logicalDevice.(*voltha.LogicalDevice).Id); agent == nil {
100 agent = newLogicalDeviceAgent(
101 logicalDevice.(*voltha.LogicalDevice).Id,
102 logicalDevice.(*voltha.LogicalDevice).RootDeviceId,
103 ldMgr,
104 ldMgr.deviceMgr,
105 ldMgr.clusterDataProxy,
106 )
107 ldMgr.addLogicalDeviceAgentToMap(agent)
108 go agent.start(nil)
109 }
110 result.Items = append(result.Items, logicalDevice.(*voltha.LogicalDevice))
111 }
112 }
113 return result, nil
114}
115
116func (ldMgr *LogicalDeviceManager) getLogicalDeviceId(device *voltha.Device) (*string, error) {
117 // Device can either be a parent or a child device
118 if device.Root {
119 // Parent device. The ID of a parent device is the logical device ID
120 return &device.ParentId, nil
121 }
122 // Device is child device
123 // retrieve parent device using child device ID
124 if parentDevice := ldMgr.deviceMgr.getParentDevice(device); parentDevice != nil {
125 return &parentDevice.ParentId, nil
126 }
127 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
128}
129
130func (ldMgr *LogicalDeviceManager) getLogicalPortId(device *voltha.Device) (*voltha.LogicalPortId, error) {
131 // Get the logical device where this device is attached
132 var lDeviceId *string
133 var err error
134 if lDeviceId, err = ldMgr.getLogicalDeviceId(device); err != nil {
135 return nil, err
136 }
137 var lDevice *voltha.LogicalDevice
138 if lDevice, err = ldMgr.getLogicalDevice(*lDeviceId); err != nil {
139 return nil, err
140 }
141 // Go over list of ports
142 for _, port := range lDevice.Ports {
143 if port.DeviceId == device.Id {
144 return &voltha.LogicalPortId{Id: *lDeviceId, PortId: port.Id}, nil
145 }
146 }
147 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
148}
149
150func (ldMgr *LogicalDeviceManager) ListLogicalDevicePorts(ctx context.Context, id string) (*voltha.LogicalPorts, error) {
151 log.Debugw("ListLogicalDevicePorts", log.Fields{"logicaldeviceid": id})
152 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
153 return agent.ListLogicalDevicePorts()
154 }
155 return nil, status.Errorf(codes.NotFound, "%s", id)
156
157}
158
159func (ldMgr *LogicalDeviceManager) ListLogicalDeviceFlows(ctx context.Context, id string) (*voltha.Flows, error) {
160 log.Debugw("ListLogicalDeviceFlows", log.Fields{"logicaldeviceid": id})
161 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
162 return agent.ListLogicalDeviceFlows()
163 }
164 return nil, status.Errorf(codes.NotFound, "%s", id)
165
166}
167
168func (ldMgr *LogicalDeviceManager) ListLogicalDeviceFlowGroups(ctx context.Context, id string) (*voltha.FlowGroups, error) {
169 log.Debugw("ListLogicalDeviceFlowGroups", log.Fields{"logicaldeviceid": id})
170 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
171 return agent.ListLogicalDeviceFlowGroups()
172 }
173 return nil, status.Errorf(codes.NotFound, "%s", id)
174
175}
176
177func (ldMgr *LogicalDeviceManager) getLogicalPort(lPortId *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
178 // Get the logical device where this device is attached
179 var err error
180 var lDevice *voltha.LogicalDevice
181 if lDevice, err = ldMgr.getLogicalDevice(lPortId.Id); err != nil {
182 return nil, err
183 }
184 // Go over list of ports
185 for _, port := range lDevice.Ports {
186 if port.Id == lPortId.PortId {
187 return port, nil
188 }
189 }
190 return nil, status.Errorf(codes.NotFound, "%s-$s", lPortId.Id, lPortId.PortId)
191}