blob: 0bfd82f6435130d522fea41f875354fc29ec5b4e [file] [log] [blame]
Prince Pereirac1c21d62021-04-22 08:38:15 +00001/*
2 * Copyright 2020-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 */
16
17// Package nbi holds rpc server apis implemented
18package nbi
19
20import (
21 "context"
22 "errors"
23 "fmt"
24
25 "github.com/jinzhu/copier"
26 "github.com/opencord/device-management-interface/go/dmi"
27 "github.com/opencord/opendevice-manager/pkg/config"
28 "github.com/opencord/voltha-lib-go/v4/pkg/log"
29
30 dev "github.com/opencord/opendevice-manager/pkg/models/device"
31 hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
32
33 empty "github.com/golang/protobuf/ptypes/empty"
34)
35
36// StartManagingDevice refers to the RPC method invoked for start Managing Device.
37// Initializes context for a device and sets up required states
38func (c *NativeHwManagementService) StartManagingDevice(req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) error {
39 ctx := config.GetNewContextFromGlobalContxt("StartManagingDevice")
40
41 logger.Infow(ctx, "StartManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
42 defer logger.Infow(ctx, "StartManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
43
44 if errorResp, ok := validateStartManagingDeviceReq(ctx, req); !ok {
45 streamResp.Send(errorResp)
46 return errors.New("failed at validateStartManagingDeviceReq")
47 }
48
49 devRec, err := dev.NewDeviceRecord(ctx, req)
50
51 if err != nil {
52 streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
53 return err
54 }
55
56 adapter, err := connections.getConnection(ctx, devRec)
57
58 if adapter == nil {
59 streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
60 return err
61 }
62
63 devRec.DBAddByName(ctx)
64
65 err, connMade := adapter.StartManagingDevice(ctx, devRec, req, streamResp)
66
67 if !connMade {
68 devRec.DBDelRecord(ctx)
69 adapter.Disconnect(ctx)
70 connections.delConn(ctx, devRec.Name)
71 streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_UNDEFINED_REASON, err))
72 }
73
74 return err
75}
76
77// StopManagingDevice - Stops management of a device and clean up any context and caches for that device
78// This rpc can be called at any time, even before the StartManagingDevice operation
79// has completed, and should be able to cleanup.
80func (c *NativeHwManagementService) StopManagingDevice(ctx context.Context, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
81
82 var devRec *dev.DeviceRecord
83 resp := new(dmi.StopManagingDeviceResponse)
84 var err error
85
86 ctx = config.GetNewContextFromContxt(ctx, "StopManagingDevice")
87
88 logger.Infow(ctx, "StopManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
89 defer logger.Infow(ctx, "StopManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
90
91 if recTmp, err := dev.DBGetByName(ctx, req.Name); recTmp == nil {
92 return errRespStopManagingDevice(ctx, req, dmi.StopManagingDeviceResponse_UNKNOWN_DEVICE, err), err
93 } else {
94 devRec = recTmp
95 }
96
97 defer devRec.DBDelRecord(ctx)
98 defer hw.DBDelAllHwComponents(ctx, devRec.Uuid)
99
100 adapter, err := connections.getConnection(ctx, devRec)
101
102 if adapter != nil {
103 resp, err = adapter.StopManagingDevice(ctx, devRec, req)
104 adapter.Disconnect(ctx)
105 connections.delConn(ctx, devRec.Name)
106 }
107
108 if err != nil {
109 logger.Errorw(ctx, "Errors-at-StopManagingDevice", log.Fields{"req": req, "error": err})
110 }
111
112 return resp, err
113}
114
115// GetManagedDevices - Returns an object containing a list of devices managed by this entity
116func (c *NativeHwManagementService) GetManagedDevices(ctx context.Context, req *empty.Empty) (*dmi.ManagedDevicesResponse, error) {
117 ctx = config.GetNewContextFromContxt(ctx, "GetManagedDevices")
118 resp := new(dmi.ManagedDevicesResponse)
119
120 logger.Infow(ctx, "GetManagedDevices-invoked-on-grpc-server", log.Fields{"req": req})
121 defer logger.Infow(ctx, "GetManagedDevices-on-grpc-server-completed", log.Fields{"req": req})
122
123 listDevRecs, err := dev.DBGetAll(ctx)
124 for _, devRec := range listDevRecs {
125 modComp := new(dmi.ModifiableComponent)
126 err2 := copier.Copy(&modComp, &devRec)
127 if err2 != nil {
128 logger.Errorw(ctx, "Copy-failed-at-GetManagedDevices", log.Fields{"req": req, "rec": devRec, "error": err})
129 } else {
130 modComp.Uri.Uri = devRec.Uri
131 resp.Devices = append(resp.Devices, modComp)
132 }
133 }
134 logger.Infow(ctx, "GetManagedDevices-completed", log.Fields{"req": req, "resp": resp, "error": err})
135 return resp, err
136}
137
138// GetPhysicalInventory - Place Holder for implementation in future
139func (c *NativeHwManagementService) GetPhysicalInventory(req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
140
141 ctx := config.GetNewContextFromGlobalContxt("GetPhysicalInventory")
142
143 logger.Infow(ctx, "GetPhysicalInventory-invoked-on-grpc-server", log.Fields{"req": req})
144 defer logger.Infow(ctx, "GetPhysicalInventory-on-grpc-server-completed", log.Fields{"req": req})
145
146 var devRec *dev.DeviceRecord
147
148 if recTmp, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); recTmp == nil {
149 streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_UNKNOWN_DEVICE, err))
150 return err
151 } else {
152 devRec = recTmp
153 }
154
155 adapter, err := connections.getConnection(ctx, devRec)
156 if adapter == nil {
157 streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_DEVICE_UNREACHABLE, err))
158 return err
159 }
160
161 err = adapter.GetPhysicalInventory(ctx, devRec, req, streamResp)
162
163 if err != nil {
164 logger.Errorw(ctx, "Errors-at-GetPhysicalInventory", log.Fields{"req": req, "error": err})
165 }
166
167 return err
168}
169
170// GetHWComponentInfo - refers to the RPC method invoked for get the details of a particular HW component
171func (c *NativeHwManagementService) GetHWComponentInfo(req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
172 ctx := config.GetNewContextFromGlobalContxt("GetHWComponentInfo")
173
174 logger.Infow(ctx, "GetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
175 defer logger.Infow(ctx, "GetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
176
177 devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
178 if devRec == nil {
179 streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
180 return err
181 }
182
183 hwCompRec, err := hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid)
184 if hwCompRec == nil {
185 streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
186 return err
187 }
188
189 adapter, err := connections.getConnection(ctx, devRec)
190 if adapter == nil {
191 streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_DEVICE_UNREACHABLE, err))
192 return err
193 }
194
195 err = adapter.GetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req, streamResp)
196 if err != nil {
197 logger.Errorw(ctx, "Errors-at-GetHWComponentInfo", log.Fields{"req": req, "error": err})
198 }
199 return err
200}
201
202// SetHWComponentInfo is the nb api exposed for receiving SetHWComponentInfo from NEM
203func (c *NativeHwManagementService) SetHWComponentInfo(ctx context.Context, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
204 ctx = config.GetNewContextFromContxt(ctx, "SetHWComponentInfo")
205
206 logger.Infow(ctx, "SetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
207 defer logger.Infow(ctx, "SetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
208
209 var devRec *dev.DeviceRecord
210 var hwCompRec *hw.HwCompRecord
211 var err error
212
213 if devRec, err = dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); devRec == nil {
214 return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
215 }
216
217 if hwCompRec, err = hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid); hwCompRec == nil {
218 return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
219 }
220
221 adapter, err := connections.getConnection(ctx, devRec)
222 if adapter == nil {
223 return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_DEVICE_UNREACHABLE, err), err
224 }
225
226 resp, err := adapter.SetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req)
227
228 if err != nil {
229 logger.Errorw(ctx, "Errors-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
230 }
231
232 return resp, err
233}
234
235// SetLoggingEndpoint - refers to the RPC method invoked for set the location to which logs need to be shipped
236func (c *NativeHwManagementService) SetLoggingEndpoint(ctx context.Context, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
237 ctx = config.GetNewContextFromGlobalContxt("SetLoggingEndpoint")
238
239 logger.Infow(ctx, "SetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
240 defer logger.Infow(ctx, "SetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
241
242 // Check device is there or not by Uuid
243 devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
244 if err != nil {
245 return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_UNKNOWN_DEVICE, err), err
246 }
247
248 adapter, err2 := connections.getConnection(ctx, devRec)
249 if adapter == nil {
250 return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_DEVICE_UNREACHABLE, err2), err2
251 }
252
253 resp, err := adapter.SetLoggingEndpoint(ctx, devRec, req)
254 if err != nil {
255 logger.Errorw(ctx, "Errors-at-SetLoggingEndpoint", log.Fields{"req": req, "error": err})
256 }
257
258 return resp, err
259}
260
261// GetLoggingEndpoint - refers to the RPC method invoked for get the location to which logs need to be shipped
262func (c *NativeHwManagementService) GetLoggingEndpoint(ctx context.Context, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
263 ctx = config.GetNewContextFromGlobalContxt("GetLoggingEndpoint")
264
265 logger.Infow(ctx, "GetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
266 defer logger.Infow(ctx, "GetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
267
268 // Check device is there or not by Uuid
269 devRec, err := dev.DBGetByUuid(ctx, req.Uuid.Uuid)
270 if err != nil {
271 return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_UNKNOWN_DEVICE, err), err
272 }
273
274 adapter, err := connections.getConnection(ctx, devRec)
275 if adapter == nil {
276 return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_DEVICE_UNREACHABLE, err), err
277 }
278
279 resp, err := adapter.GetLoggingEndpoint(ctx, devRec, req)
280 if err != nil {
281 logger.Errorw(ctx, "Errors-at-GetLoggingEndpoint", log.Fields{"req": req, "error": err})
282 }
283 return resp, err
284}
285
286// SetMsgBusEndpoint - Place Holder for implementation in future
287func (c *NativeHwManagementService) SetMsgBusEndpoint(ctx context.Context, req *dmi.SetMsgBusEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
288 errMsg := "SetMsgBusEndpoint not yet implemented"
289 fmt.Println(errMsg)
290 return nil, errors.New(errMsg)
291}
292
293// GetMsgBusEndpoint - Place Holder for implementation in future
294func (c *NativeHwManagementService) GetMsgBusEndpoint(ctx context.Context, req *empty.Empty) (*dmi.GetMsgBusEndpointResponse, error) {
295 errMsg := "GetMsgBusEndpoint not yet implemented"
296 fmt.Println(errMsg)
297 return nil, errors.New(errMsg)
298}
299
300// GetLoggableEntities refers to the grpc northbound interface exposed for getting loggable entities from device
301func (c *NativeHwManagementService) GetLoggableEntities(ctx context.Context, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
302
303 ctx = config.GetNewContextFromContxt(ctx, "GetLoggableEntities")
304 resp := new(dmi.GetLogLevelResponse)
305 resp.DeviceUuid = req.DeviceUuid
306
307 logger.Infow(ctx, "GetLoggableEntities-invoked-on-grpc-server", log.Fields{"req": req})
308 defer logger.Infow(ctx, "GetLoggableEntities-on-grpc-server-completed", log.Fields{"req": req})
309
310 devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
311 if err != nil {
312 return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
313 }
314
315 if devRec.Logging.LoggableEntities != nil {
316 resp.Status = dmi.Status_OK_STATUS
317 resp.LogLevels, _ = devRec.GetLoggableEntitiesFromDevRec(ctx, nil)
318 return resp, nil
319 }
320
321 adapter, err := connections.getConnection(ctx, devRec)
322 if adapter == nil {
323 return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
324 }
325
326 return adapter.GetLoggableEntities(ctx, devRec, req)
327}
328
329// SetLogLevel refers to the grpc northbound interface exposed for setting log level for entities
330func (c *NativeHwManagementService) SetLogLevel(ctx context.Context, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
331
332 ctx = config.GetNewContextFromContxt(ctx, "SetLogLevel")
333 resp := new(dmi.SetLogLevelResponse)
334 resp.DeviceUuid = req.DeviceUuid
335
336 logger.Infow(ctx, "SetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
337 defer logger.Infow(ctx, "SetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
338
339 // validate request
340 if ok, err := isValidSetLogLevel(ctx, req.Loglevels); ok {
341 return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_LOG_ENTITY, err), err
342 }
343
344 devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
345 if err != nil {
346 return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_DEVICE, err), err
347 }
348
349 adapter, err := connections.getConnection(ctx, devRec)
350 if adapter == nil {
351 return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_DEVICE_UNREACHABLE, err), err
352 }
353
354 return adapter.SetLogLevel(ctx, devRec, req)
355}
356
357// GetLogLevel refers to the grpc northbound interface exposed for getting log level of entities
358func (c *NativeHwManagementService) GetLogLevel(ctx context.Context, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
359
360 ctx = config.GetNewContextFromContxt(ctx, "GetLogLevel")
361 resp := new(dmi.GetLogLevelResponse)
362 resp.DeviceUuid = req.DeviceUuid
363
364 logger.Infow(ctx, "GetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
365 defer logger.Infow(ctx, "GetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
366
367 devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
368 if err != nil {
369 return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
370 }
371
372 if devRec.Logging.LoggableEntities != nil {
373
374 if output, ok := devRec.GetLoggableEntitiesFromDevRec(ctx, req.Entities); ok {
375 resp.Status = dmi.Status_OK_STATUS
376 resp.LogLevels = output
377 return resp, nil
378 }
379
380 }
381
382 adapter, err := connections.getConnection(ctx, devRec)
383 if adapter == nil {
384 return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
385 }
386
387 return adapter.GetLogLevel(ctx, devRec, req)
388}