blob: e502ff1a0c47cb20c7f9c769b0e6c614460d4477 [file] [log] [blame]
khenaidoo21d51152019-02-01 13:48:37 -05001/*
2 * Copyright 2019-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 */
npujar1d86a522019-11-14 17:11:16 +053016
khenaidoo21d51152019-02-01 13:48:37 -050017package core
18
19import (
20 "context"
khenaidoo21d51152019-02-01 13:48:37 -050021 "fmt"
npujar1d86a522019-11-14 17:11:16 +053022 "reflect"
23 "sync"
24
khenaidoo21d51152019-02-01 13:48:37 -050025 "github.com/gogo/protobuf/proto"
sbarbari17d7e222019-11-05 10:02:29 -050026 "github.com/opencord/voltha-go/db/model"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080027 "github.com/opencord/voltha-lib-go/v3/pkg/log"
28 "github.com/opencord/voltha-lib-go/v3/pkg/probe"
29 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo21d51152019-02-01 13:48:37 -050030)
31
npujar1d86a522019-11-14 17:11:16 +053032// sentinel constants
khenaidoo21d51152019-02-01 13:48:37 -050033const (
npujar1d86a522019-11-14 17:11:16 +053034 SentinelAdapterID = "adapter_sentinel"
35 SentinelDevicetypeID = "device_type_sentinel"
khenaidoo21d51152019-02-01 13:48:37 -050036)
37
npujar1d86a522019-11-14 17:11:16 +053038// AdapterAgent represents adapter agent
khenaidoo21d51152019-02-01 13:48:37 -050039type AdapterAgent struct {
khenaidoo1ce37ad2019-03-24 22:07:24 -040040 adapter *voltha.Adapter
khenaidoo21d51152019-02-01 13:48:37 -050041 deviceTypes map[string]*voltha.DeviceType
khenaidoo1ce37ad2019-03-24 22:07:24 -040042 lock sync.RWMutex
khenaidoo21d51152019-02-01 13:48:37 -050043}
44
45func newAdapterAgent(adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) *AdapterAgent {
46 var adapterAgent AdapterAgent
47 adapterAgent.adapter = adapter
48 adapterAgent.lock = sync.RWMutex{}
49 adapterAgent.deviceTypes = make(map[string]*voltha.DeviceType)
50 if deviceTypes != nil {
51 for _, dType := range deviceTypes.Items {
52 adapterAgent.deviceTypes[dType.Id] = dType
53 }
54 }
55 return &adapterAgent
56}
57
khenaidoo21d51152019-02-01 13:48:37 -050058func (aa *AdapterAgent) getDeviceType(deviceType string) *voltha.DeviceType {
59 aa.lock.RLock()
60 defer aa.lock.RUnlock()
61 if _, exist := aa.deviceTypes[deviceType]; exist {
62 return aa.deviceTypes[deviceType]
63 }
64 return nil
65}
66
67func (aa *AdapterAgent) getAdapter() *voltha.Adapter {
68 aa.lock.RLock()
69 defer aa.lock.RUnlock()
70 log.Debugw("getAdapter", log.Fields{"adapter": aa.adapter})
71 return aa.adapter
72}
73
74func (aa *AdapterAgent) updateAdapter(adapter *voltha.Adapter) {
khenaidoo1ce37ad2019-03-24 22:07:24 -040075 aa.lock.Lock()
76 defer aa.lock.Unlock()
khenaidoo21d51152019-02-01 13:48:37 -050077 aa.adapter = adapter
78}
79
khenaidoo1ce37ad2019-03-24 22:07:24 -040080func (aa *AdapterAgent) updateDeviceType(deviceType *voltha.DeviceType) {
81 aa.lock.Lock()
82 defer aa.lock.Unlock()
khenaidoo21d51152019-02-01 13:48:37 -050083 aa.deviceTypes[deviceType.Id] = deviceType
84}
85
npujar1d86a522019-11-14 17:11:16 +053086// AdapterManager represents adapter manager attributes
khenaidoo21d51152019-02-01 13:48:37 -050087type AdapterManager struct {
88 adapterAgents map[string]*AdapterAgent
89 deviceTypeToAdapterMap map[string]string
90 clusterDataProxy *model.Proxy
91 adapterProxy *model.Proxy
92 deviceTypeProxy *model.Proxy
khenaidooba6b6c42019-08-02 09:11:56 -040093 deviceMgr *DeviceManager
npujar1d86a522019-11-14 17:11:16 +053094 coreInstanceID string
khenaidoo21d51152019-02-01 13:48:37 -050095 exitChannel chan int
96 lockAdaptersMap sync.RWMutex
97 lockdDeviceTypeToAdapterMap sync.RWMutex
98}
99
npujar1d86a522019-11-14 17:11:16 +0530100func newAdapterManager(cdProxy *model.Proxy, coreInstanceID string, deviceMgr *DeviceManager) *AdapterManager {
khenaidoo21d51152019-02-01 13:48:37 -0500101 var adapterMgr AdapterManager
102 adapterMgr.exitChannel = make(chan int, 1)
npujar1d86a522019-11-14 17:11:16 +0530103 adapterMgr.coreInstanceID = coreInstanceID
khenaidoo21d51152019-02-01 13:48:37 -0500104 adapterMgr.clusterDataProxy = cdProxy
105 adapterMgr.adapterAgents = make(map[string]*AdapterAgent)
106 adapterMgr.deviceTypeToAdapterMap = make(map[string]string)
107 adapterMgr.lockAdaptersMap = sync.RWMutex{}
108 adapterMgr.lockdDeviceTypeToAdapterMap = sync.RWMutex{}
khenaidooba6b6c42019-08-02 09:11:56 -0400109 adapterMgr.deviceMgr = deviceMgr
khenaidoo21d51152019-02-01 13:48:37 -0500110 return &adapterMgr
111}
112
Thomas Lee Se5a44012019-11-07 20:32:24 +0530113func (aMgr *AdapterManager) start(ctx context.Context) error {
khenaidoo21d51152019-02-01 13:48:37 -0500114 log.Info("starting-adapter-manager")
115
116 // Load the existing adapterAgents and device types - this will also ensure the correct paths have been
117 // created if there are no data in the dB to start
Thomas Lee Se5a44012019-11-07 20:32:24 +0530118 err := aMgr.loadAdaptersAndDevicetypesInMemory()
119 if err != nil {
120 log.Errorw("Failed-to-load-adapters-and-device-types-in-memeory", log.Fields{"error": err})
121 return err
122 }
khenaidoo21d51152019-02-01 13:48:37 -0500123
124 //// Create the proxies
Thomas Lee Se5a44012019-11-07 20:32:24 +0530125 aMgr.adapterProxy, err = aMgr.clusterDataProxy.CreateProxy(context.Background(), "/adapters", false)
126 if err != nil {
127 log.Errorw("Failed-to-create-adapter-proxy", log.Fields{"error": err})
128 return err
129 }
130 aMgr.deviceTypeProxy, err = aMgr.clusterDataProxy.CreateProxy(context.Background(), "/device_types", false)
131 if err != nil {
132 log.Errorw("Failed-to-create-device-proxy", log.Fields{"error": err})
133 return err
134 }
khenaidoo21d51152019-02-01 13:48:37 -0500135
136 // Register the callbacks
npujar9a30c702019-11-14 17:06:39 +0530137 aMgr.adapterProxy.RegisterCallback(model.PostUpdate, aMgr.adapterUpdated)
138 aMgr.deviceTypeProxy.RegisterCallback(model.PostUpdate, aMgr.deviceTypesUpdated)
David K. Bainbridgeb4a9ab02019-09-20 15:12:16 -0700139 probe.UpdateStatusFromContext(ctx, "adapter-manager", probe.ServiceStatusRunning)
khenaidoo21d51152019-02-01 13:48:37 -0500140 log.Info("adapter-manager-started")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530141 return nil
khenaidoo21d51152019-02-01 13:48:37 -0500142}
143
khenaidoo21d51152019-02-01 13:48:37 -0500144//loadAdaptersAndDevicetypesInMemory loads the existing set of adapters and device types in memory
Thomas Lee Se5a44012019-11-07 20:32:24 +0530145func (aMgr *AdapterManager) loadAdaptersAndDevicetypesInMemory() error {
khenaidoo21d51152019-02-01 13:48:37 -0500146 // Load the adapters
Thomas Lee Se5a44012019-11-07 20:32:24 +0530147 adaptersIf, err := aMgr.clusterDataProxy.List(context.Background(), "/adapters", 0, false, "")
148 if err != nil {
149 log.Errorw("Failed-to-list-adapters-from-cluster-data-proxy", log.Fields{"error": err})
150 return err
151 }
152 if adaptersIf != nil {
khenaidoo21d51152019-02-01 13:48:37 -0500153 for _, adapterIf := range adaptersIf.([]interface{}) {
154 if adapter, ok := adapterIf.(*voltha.Adapter); ok {
155 log.Debugw("found-existing-adapter", log.Fields{"adapterId": adapter.Id})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530156 return aMgr.addAdapter(adapter, false)
khenaidoo21d51152019-02-01 13:48:37 -0500157 }
158 }
159 } else {
160 log.Debug("no-existing-adapter-found")
161 // No adapter data. In order to have a proxy setup for that path let's create a fake adapter
Thomas Lee Se5a44012019-11-07 20:32:24 +0530162 return aMgr.addAdapter(&voltha.Adapter{Id: SentinelAdapterID}, true)
khenaidoo21d51152019-02-01 13:48:37 -0500163 }
164
165 // Load the device types
Thomas Lee Se5a44012019-11-07 20:32:24 +0530166 deviceTypesIf, err := aMgr.clusterDataProxy.List(context.Background(), "/device_types", 0, false, "")
167 if err != nil {
168 log.Errorw("Failed-to-list-device-types-from-cluster-data-proxy", log.Fields{"error": err})
169 return err
170 }
171 if deviceTypesIf != nil {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400172 dTypes := &voltha.DeviceTypes{Items: []*voltha.DeviceType{}}
khenaidoo21d51152019-02-01 13:48:37 -0500173 for _, deviceTypeIf := range deviceTypesIf.([]interface{}) {
174 if dType, ok := deviceTypeIf.(*voltha.DeviceType); ok {
175 log.Debugw("found-existing-device-types", log.Fields{"deviceTypes": dTypes})
176 dTypes.Items = append(dTypes.Items, dType)
177 }
178 }
Thomas Lee Se5a44012019-11-07 20:32:24 +0530179 return aMgr.addDeviceTypes(dTypes, false)
khenaidoo21d51152019-02-01 13:48:37 -0500180 }
Thomas Lee Se5a44012019-11-07 20:32:24 +0530181
182 log.Debug("no-existing-device-type-found")
183 // No device types data. In order to have a proxy setup for that path let's create a fake device type
184 return aMgr.addDeviceTypes(&voltha.DeviceTypes{Items: []*voltha.DeviceType{{Id: SentinelDevicetypeID, Adapter: SentinelAdapterID}}}, true)
khenaidoo21d51152019-02-01 13:48:37 -0500185}
186
khenaidoo297cd252019-02-07 22:10:23 -0500187//updateAdaptersAndDevicetypesInMemory loads the existing set of adapters and device types in memory
khenaidooba6b6c42019-08-02 09:11:56 -0400188func (aMgr *AdapterManager) updateAdaptersAndDevicetypesInMemory(adapter *voltha.Adapter) {
A R Karthicked2a77b2019-10-08 01:40:51 +0000189 aMgr.lockAdaptersMap.Lock()
190 defer aMgr.lockAdaptersMap.Unlock()
191
192 if adapterAgent, ok := aMgr.adapterAgents[adapter.Id]; ok {
193 if adapterAgent.getAdapter() != nil {
194 // Already registered - Adapter may have restarted. Trigger the reconcile process for that adapter
npujar1d86a522019-11-14 17:11:16 +0530195 go func() {
196 err := aMgr.deviceMgr.adapterRestarted(adapter)
197 if err != nil {
198 log.Errorw("unable-to-restart-adapter", log.Fields{"error": err})
199 }
200 }()
A R Karthicked2a77b2019-10-08 01:40:51 +0000201 return
202 }
khenaidooba6b6c42019-08-02 09:11:56 -0400203 }
204
khenaidoo297cd252019-02-07 22:10:23 -0500205 // Update the adapters
Thomas Lee Se5a44012019-11-07 20:32:24 +0530206 adaptersIf, err := aMgr.clusterDataProxy.List(context.Background(), "/adapters", 0, false, "")
207 if err != nil {
208 log.Errorw("failed-to-list-adapters-from-cluster-proxy", log.Fields{"error": err})
209 return
210 }
211 if adaptersIf != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500212 for _, adapterIf := range adaptersIf.([]interface{}) {
213 if adapter, ok := adapterIf.(*voltha.Adapter); ok {
214 log.Debugw("found-existing-adapter", log.Fields{"adapterId": adapter.Id})
A R Karthicked2a77b2019-10-08 01:40:51 +0000215 aMgr.updateAdapterWithoutLock(adapter)
khenaidoo297cd252019-02-07 22:10:23 -0500216 }
217 }
218 }
A R Karthicked2a77b2019-10-08 01:40:51 +0000219 aMgr.lockdDeviceTypeToAdapterMap.Lock()
220 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
khenaidoo297cd252019-02-07 22:10:23 -0500221 // Update the device types
Thomas Lee Se5a44012019-11-07 20:32:24 +0530222 deviceTypesIf, err := aMgr.clusterDataProxy.List(context.Background(), "/device_types", 0, false, "")
223 if err != nil {
224 log.Errorw("Failed-to-list-device-types-in-cluster-data-proxy", log.Fields{"error": err})
225 return
226 }
227 if deviceTypesIf != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500228 dTypes := &voltha.DeviceTypes{Items: []*voltha.DeviceType{}}
229 for _, deviceTypeIf := range deviceTypesIf.([]interface{}) {
230 if dType, ok := deviceTypeIf.(*voltha.DeviceType); ok {
231 log.Debugw("found-existing-device-types", log.Fields{"deviceTypes": dTypes})
A R Karthicked2a77b2019-10-08 01:40:51 +0000232 aMgr.updateDeviceTypeWithoutLock(dType)
khenaidoo297cd252019-02-07 22:10:23 -0500233 }
234 }
235 }
236}
237
Thomas Lee Se5a44012019-11-07 20:32:24 +0530238func (aMgr *AdapterManager) addAdapter(adapter *voltha.Adapter, saveToDb bool) error {
khenaidoo21d51152019-02-01 13:48:37 -0500239 aMgr.lockAdaptersMap.Lock()
240 defer aMgr.lockAdaptersMap.Unlock()
241 log.Debugw("adding-adapter", log.Fields{"adapter": adapter})
242 if _, exist := aMgr.adapterAgents[adapter.Id]; !exist {
243 clonedAdapter := (proto.Clone(adapter)).(*voltha.Adapter)
244 aMgr.adapterAgents[adapter.Id] = newAdapterAgent(clonedAdapter, nil)
245 if saveToDb {
246 // Save the adapter to the KV store - first check if it already exist
Thomas Lee Se5a44012019-11-07 20:32:24 +0530247 kvAdapter, err := aMgr.clusterDataProxy.Get(context.Background(), "/adapters/"+adapter.Id, 0, false, "")
248 if err != nil {
249 log.Errorw("failed-to-get-adapters-from-cluster-proxy", log.Fields{"error": err})
250 return err
251 }
252 if kvAdapter == nil {
253 added, err := aMgr.clusterDataProxy.AddWithID(context.Background(), "/adapters", adapter.Id, clonedAdapter, "")
254 if err != nil {
255 log.Errorw("failed-to-save-adapter-to-cluster-proxy", log.Fields{"error": err})
256 return err
257 }
258 if added == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500259 //TODO: Errors when saving to KV would require a separate go routine to be launched and try the saving again
260 log.Errorw("failed-to-save-adapter", log.Fields{"adapter": adapter})
261 } else {
262 log.Debugw("adapter-saved-to-KV-Store", log.Fields{"adapter": adapter})
263 }
264 }
265 }
266 }
Thomas Lee Se5a44012019-11-07 20:32:24 +0530267 return nil
khenaidoo21d51152019-02-01 13:48:37 -0500268}
269
Thomas Lee Se5a44012019-11-07 20:32:24 +0530270func (aMgr *AdapterManager) addDeviceTypes(deviceTypes *voltha.DeviceTypes, saveToDb bool) error {
khenaidoo21d51152019-02-01 13:48:37 -0500271 if deviceTypes == nil {
Thomas Lee Se5a44012019-11-07 20:32:24 +0530272 return fmt.Errorf("no-device-type")
khenaidoo21d51152019-02-01 13:48:37 -0500273 }
274 log.Debugw("adding-device-types", log.Fields{"deviceTypes": deviceTypes})
275 aMgr.lockAdaptersMap.Lock()
276 defer aMgr.lockAdaptersMap.Unlock()
277 aMgr.lockdDeviceTypeToAdapterMap.Lock()
278 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
279 for _, deviceType := range deviceTypes.Items {
280 clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
281 if adapterAgent, exist := aMgr.adapterAgents[clonedDType.Adapter]; exist {
282 adapterAgent.updateDeviceType(clonedDType)
283 } else {
284 log.Debugw("adapter-not-exist", log.Fields{"deviceTypes": deviceTypes, "adapterId": clonedDType.Adapter})
khenaidoo1ce37ad2019-03-24 22:07:24 -0400285 aMgr.adapterAgents[clonedDType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: clonedDType.Adapter}, deviceTypes)
khenaidoo21d51152019-02-01 13:48:37 -0500286 }
287 aMgr.deviceTypeToAdapterMap[clonedDType.Id] = clonedDType.Adapter
288 }
289 if saveToDb {
290 // Save the device types to the KV store as well
291 for _, deviceType := range deviceTypes.Items {
Thomas Lee Se5a44012019-11-07 20:32:24 +0530292 dType, err := aMgr.clusterDataProxy.Get(context.Background(), "/device_types/"+deviceType.Id, 0, false, "")
293 if err != nil {
294 log.Errorw("Failed-to--device-types-from-cluster-data-proxy", log.Fields{"error": err})
295 return err
296 }
297 if dType == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500298 // Does not exist - save it
299 clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530300 added, err := aMgr.clusterDataProxy.AddWithID(context.Background(), "/device_types", deviceType.Id, clonedDType, "")
301 if err != nil {
302 log.Errorw("Failed-to-add-device-types-to-cluster-data-proxy", log.Fields{"error": err})
303 return err
304 }
305 if added == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500306 log.Errorw("failed-to-save-deviceType", log.Fields{"deviceType": deviceType})
307 } else {
308 log.Debugw("device-type-saved-to-KV-Store", log.Fields{"deviceType": deviceType})
309 }
310 }
311 }
312 }
Thomas Lee Se5a44012019-11-07 20:32:24 +0530313 return nil
khenaidoo21d51152019-02-01 13:48:37 -0500314}
315
316func (aMgr *AdapterManager) listAdapters(ctx context.Context) (*voltha.Adapters, error) {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400317 result := &voltha.Adapters{Items: []*voltha.Adapter{}}
318 aMgr.lockAdaptersMap.RLock()
319 defer aMgr.lockAdaptersMap.RUnlock()
khenaidoo21d51152019-02-01 13:48:37 -0500320 for _, adapterAgent := range aMgr.adapterAgents {
321 if a := adapterAgent.getAdapter(); a != nil {
npujar1d86a522019-11-14 17:11:16 +0530322 if a.Id != SentinelAdapterID { // don't report the sentinel
khenaidoo297cd252019-02-07 22:10:23 -0500323 result.Items = append(result.Items, (proto.Clone(a)).(*voltha.Adapter))
324 }
khenaidoo21d51152019-02-01 13:48:37 -0500325 }
326 }
327 return result, nil
328}
329
npujar1d86a522019-11-14 17:11:16 +0530330func (aMgr *AdapterManager) getAdapter(adapterID string) *voltha.Adapter {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400331 aMgr.lockAdaptersMap.RLock()
332 defer aMgr.lockAdaptersMap.RUnlock()
npujar1d86a522019-11-14 17:11:16 +0530333 if adapterAgent, ok := aMgr.adapterAgents[adapterID]; ok {
khenaidoo21d51152019-02-01 13:48:37 -0500334 return adapterAgent.getAdapter()
335 }
336 return nil
337}
338
339//updateAdapter updates an adapter if it exist. Otherwise, it creates it.
khenaidoo1ce37ad2019-03-24 22:07:24 -0400340func (aMgr *AdapterManager) updateAdapter(adapter *voltha.Adapter) {
khenaidoo21d51152019-02-01 13:48:37 -0500341 aMgr.lockAdaptersMap.Lock()
342 defer aMgr.lockAdaptersMap.Unlock()
A R Karthicked2a77b2019-10-08 01:40:51 +0000343 aMgr.updateAdapterWithoutLock(adapter)
344}
345
346func (aMgr *AdapterManager) updateAdapterWithoutLock(adapter *voltha.Adapter) {
khenaidoo21d51152019-02-01 13:48:37 -0500347 if adapterAgent, ok := aMgr.adapterAgents[adapter.Id]; ok {
348 adapterAgent.updateAdapter(adapter)
349 } else {
350 aMgr.adapterAgents[adapter.Id] = newAdapterAgent(adapter, nil)
351 }
352}
353
354//updateDeviceType updates an adapter if it exist. Otherwise, it creates it.
khenaidoo1ce37ad2019-03-24 22:07:24 -0400355func (aMgr *AdapterManager) updateDeviceType(deviceType *voltha.DeviceType) {
khenaidoo21d51152019-02-01 13:48:37 -0500356 aMgr.lockAdaptersMap.Lock()
357 defer aMgr.lockAdaptersMap.Unlock()
358 aMgr.lockdDeviceTypeToAdapterMap.Lock()
359 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
A R Karthicked2a77b2019-10-08 01:40:51 +0000360 aMgr.updateDeviceTypeWithoutLock(deviceType)
361}
362
363func (aMgr *AdapterManager) updateDeviceTypeWithoutLock(deviceType *voltha.DeviceType) {
khenaidoo297cd252019-02-07 22:10:23 -0500364 if adapterAgent, exist := aMgr.adapterAgents[deviceType.Adapter]; exist {
khenaidoo21d51152019-02-01 13:48:37 -0500365 adapterAgent.updateDeviceType(deviceType)
366 } else {
367 aMgr.adapterAgents[deviceType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: deviceType.Adapter},
khenaidoo1ce37ad2019-03-24 22:07:24 -0400368 &voltha.DeviceTypes{Items: []*voltha.DeviceType{deviceType}})
khenaidoo21d51152019-02-01 13:48:37 -0500369 }
370 aMgr.deviceTypeToAdapterMap[deviceType.Id] = deviceType.Adapter
371}
372
Thomas Lee Se5a44012019-11-07 20:32:24 +0530373func (aMgr *AdapterManager) registerAdapter(adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) (*voltha.CoreInstance, error) {
khenaidoo21d51152019-02-01 13:48:37 -0500374 log.Debugw("registerAdapter", log.Fields{"adapter": adapter, "deviceTypes": deviceTypes.Items})
375
376 if aMgr.getAdapter(adapter.Id) != nil {
khenaidooba6b6c42019-08-02 09:11:56 -0400377 // Already registered - Adapter may have restarted. Trigger the reconcile process for that adapter
npujar1d86a522019-11-14 17:11:16 +0530378 go func() {
379 err := aMgr.deviceMgr.adapterRestarted(adapter)
380 if err != nil {
381 log.Errorw("unable-to-restart-adapter", log.Fields{"error": err})
382 }
383 }()
Thomas Lee Se5a44012019-11-07 20:32:24 +0530384 return &voltha.CoreInstance{InstanceId: aMgr.coreInstanceID}, nil
khenaidoo21d51152019-02-01 13:48:37 -0500385 }
386 // Save the adapter and the device types
Thomas Lee Se5a44012019-11-07 20:32:24 +0530387 if err := aMgr.addAdapter(adapter, true); err != nil {
388 log.Errorw("failed-to-add-adapter", log.Fields{"error": err})
389 return nil, err
390 }
391 if err := aMgr.addDeviceTypes(deviceTypes, true); err != nil {
392 log.Errorw("failed-to-add-device-types", log.Fields{"error": err})
393 return nil, err
394 }
khenaidoo21d51152019-02-01 13:48:37 -0500395
396 log.Debugw("adapter-registered", log.Fields{"adapter": adapter.Id})
397
Thomas Lee Se5a44012019-11-07 20:32:24 +0530398 return &voltha.CoreInstance{InstanceId: aMgr.coreInstanceID}, nil
khenaidoo21d51152019-02-01 13:48:37 -0500399}
400
401//getAdapterName returns the name of the device adapter that service this device type
402func (aMgr *AdapterManager) getAdapterName(deviceType string) (string, error) {
403 aMgr.lockdDeviceTypeToAdapterMap.Lock()
404 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
npujar1d86a522019-11-14 17:11:16 +0530405 if adapterID, exist := aMgr.deviceTypeToAdapterMap[deviceType]; exist {
406 return adapterID, nil
khenaidoo21d51152019-02-01 13:48:37 -0500407 }
npujar1d86a522019-11-14 17:11:16 +0530408 return "", fmt.Errorf("Adapter-not-registered-for-device-type %s", deviceType)
khenaidoo21d51152019-02-01 13:48:37 -0500409}
410
Kent Hagermanc2c73ff2019-11-20 16:22:32 -0500411func (aMgr *AdapterManager) listDeviceTypes() []*voltha.DeviceType {
412 aMgr.lockdDeviceTypeToAdapterMap.Lock()
413 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
414
415 deviceTypes := make([]*voltha.DeviceType, 0, len(aMgr.deviceTypeToAdapterMap))
npujar1d86a522019-11-14 17:11:16 +0530416 for deviceTypeID, adapterID := range aMgr.deviceTypeToAdapterMap {
417 if adapterAgent, have := aMgr.adapterAgents[adapterID]; have {
418 if deviceType := adapterAgent.getDeviceType(deviceTypeID); deviceType != nil {
khenaidoob64fc8a2019-11-27 15:08:19 -0500419 if deviceType.Id != SentinelDevicetypeID { // don't report the sentinel
420 deviceTypes = append(deviceTypes, deviceType)
421 }
Kent Hagermanc2c73ff2019-11-20 16:22:32 -0500422 }
423 }
424 }
425 return deviceTypes
426}
427
khenaidoo21d51152019-02-01 13:48:37 -0500428// getDeviceType returns the device type proto definition given the name of the device type
khenaidoo1ce37ad2019-03-24 22:07:24 -0400429func (aMgr *AdapterManager) getDeviceType(deviceType string) *voltha.DeviceType {
khenaidoo21d51152019-02-01 13:48:37 -0500430 aMgr.lockdDeviceTypeToAdapterMap.Lock()
431 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
Kent Hagermanc2c73ff2019-11-20 16:22:32 -0500432
npujar1d86a522019-11-14 17:11:16 +0530433 if adapterID, exist := aMgr.deviceTypeToAdapterMap[deviceType]; exist {
434 if adapterAgent := aMgr.adapterAgents[adapterID]; adapterAgent != nil {
khenaidoo21d51152019-02-01 13:48:37 -0500435 return adapterAgent.getDeviceType(deviceType)
436 }
437 }
438 return nil
439}
440
441//adapterUpdated is a callback invoked when an adapter change has been noticed
442func (aMgr *AdapterManager) adapterUpdated(args ...interface{}) interface{} {
443 log.Debugw("updateAdapter-callback", log.Fields{"argsLen": len(args)})
444
445 var previousData *voltha.Adapters
446 var latestData *voltha.Adapters
447
448 var ok bool
449 if previousData, ok = args[0].(*voltha.Adapters); !ok {
450 log.Errorw("invalid-args", log.Fields{"args0": args[0]})
khenaidoo433f54a2019-02-05 14:02:57 -0500451 return nil
khenaidoo21d51152019-02-01 13:48:37 -0500452 }
453 if latestData, ok = args[1].(*voltha.Adapters); !ok {
454 log.Errorw("invalid-args", log.Fields{"args1": args[1]})
khenaidoo21d51152019-02-01 13:48:37 -0500455 return nil
456 }
457
khenaidoo433f54a2019-02-05 14:02:57 -0500458 if previousData != nil && latestData != nil {
459 if reflect.DeepEqual(previousData.Items, latestData.Items) {
460 log.Debug("update-not-required")
461 return nil
462 }
khenaidoo21d51152019-02-01 13:48:37 -0500463 }
khenaidoo433f54a2019-02-05 14:02:57 -0500464
465 if latestData != nil {
466 for _, adapter := range latestData.Items {
467 aMgr.updateAdapter(adapter)
468 }
469 }
470
khenaidoo21d51152019-02-01 13:48:37 -0500471 return nil
472}
473
474//deviceTypesUpdated is a callback invoked when a device type change has been noticed
475func (aMgr *AdapterManager) deviceTypesUpdated(args ...interface{}) interface{} {
476 log.Debugw("deviceTypesUpdated-callback", log.Fields{"argsLen": len(args)})
477
478 var previousData *voltha.DeviceTypes
479 var latestData *voltha.DeviceTypes
480
481 var ok bool
482 if previousData, ok = args[0].(*voltha.DeviceTypes); !ok {
483 log.Errorw("invalid-args", log.Fields{"args0": args[0]})
khenaidoo21d51152019-02-01 13:48:37 -0500484 return nil
485 }
486
khenaidoo433f54a2019-02-05 14:02:57 -0500487 if latestData, ok = args[1].(*voltha.DeviceTypes); !ok {
488 log.Errorw("invalid-args", log.Fields{"args1": args[1]})
489 return nil
490 }
491
492 if previousData != nil && latestData != nil {
493 if reflect.DeepEqual(previousData.Items, latestData.Items) {
494 log.Debug("update-not-required")
495 return nil
496 }
497 }
498
499 if latestData != nil {
500 for _, dType := range latestData.Items {
501 aMgr.updateDeviceType(dType)
502 }
khenaidoo21d51152019-02-01 13:48:37 -0500503 }
504 return nil
khenaidoo1ce37ad2019-03-24 22:07:24 -0400505}