blob: f2bd64ad75f76787bbee04f5372640e0895fea66 [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 grpc holds utils for grpc Client implementation
18package grpc
19
20import (
21 "context"
22 "errors"
23 "io"
24
25 "github.com/opencord/device-management-interface/go/dmi"
26 "github.com/opencord/voltha-lib-go/v4/pkg/log"
27
28 copy "github.com/jinzhu/copier"
29 dev "github.com/opencord/opendevice-manager/pkg/models/device"
30 hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
31)
32
33// StartManagingDevice is the adapter implementation for start managing device in grpc adapter layer
34func (c *Client) StartManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) (error, bool) {
35
36 var connMade bool
37
38 resp := new(dmi.StartManagingDeviceResponse)
39 resp.Status = dmi.Status_ERROR_STATUS
40 resp.Reason = dmi.StartManagingDeviceResponse_INTERNAL_ERROR
41
42 logger.Info(ctx, "Invoked-StartManagingDevice-at-grpc-adapter", log.Fields{"req": req})
43
44 stream, err := c.hwMgmtSvcClient.StartManagingDevice(ctx, req)
45
46 if err != nil {
47 logger.Error(ctx, "error-at-StartManagingDevice")
48 resp.ReasonDetail = err.Error()
49 streamResp.Send(resp)
50 return errors.New("RPC Failed for StartManagingDevice"), connMade
51 }
52
53 for {
54
55 respFromDev, err := stream.Recv()
56
57 if err == io.EOF {
58 logger.Info(ctx, "Exiting-StartManagingDevice-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
59 break
60 }
61
62 if err != nil {
63 logger.Error(ctx, "Failed-at-StartManagingDevice-while-receiving-server-response", log.Fields{"error": err, "req": req})
64 return err, connMade
65 }
66
67 if respFromDev.Status == dmi.Status_OK_STATUS {
68 connMade = true
69 devRec.Uuid = respFromDev.DeviceUuid.Uuid
70 // Store in DB
71 devRec.DBAddByName(ctx)
72 devRec.DBAddUuidLookup(ctx)
73 logger.Infow(ctx, "received-success-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
74 } else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
75 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
76 if err == nil {
77 err = errors.New(respFromDev.ReasonDetail)
78 }
79 streamResp.Send(respFromDev)
80 return err, connMade
81 }
82
83 streamResp.Send(respFromDev)
84 }
85
86 return nil, connMade
87
88}
89
90// StopManagingDevice is the adapter implementation for stop managing device in grpc adapter layer
91func (c *Client) StopManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
92
93 logger.Info(ctx, "Invoked-StopManagingDevice-at-grpc-adapter", log.Fields{"req": req})
94
95 return c.hwMgmtSvcClient.StopManagingDevice(ctx, req)
96
97}
98
99// SetLoggingEndpoint is the adapter implementation for set the location to which logs need to be shipped in grpc adapter layer
100func (c *Client) SetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
101 logger.Info(ctx, "Invoked-SetLoggingEndpoint", log.Fields{"req": req})
102
103 resp, err := c.hwMgmtSvcClient.SetLoggingEndpoint(ctx, req)
104 if err != nil {
105 logger.Error(ctx, "error-at-SetLoggingEndpoint")
106 return resp, err
107 }
108 err = errors.New(resp.ReasonDetail)
109
110 if resp.Status == dmi.Status_OK_STATUS {
111 devRec.Logging.EndPoint = req.LoggingEndpoint
112 devRec.Logging.Protocol = req.LoggingProtocol
113 // Store in DB
114 devRec.DBAddByName(ctx)
115 logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
116 } else {
117 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
118 }
119 return resp, err
120}
121
122// GetLoggingEndpoint is the adapter implementation for get the location to which logs need to be shipped in grpc adapter layer
123func (c *Client) GetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
124 logger.Info(ctx, "Invoked-GetLoggingEndpoint", log.Fields{"req": req})
125
126 resp, err := c.hwMgmtSvcClient.GetLoggingEndpoint(ctx, req)
127 if err != nil {
128 logger.Error(ctx, "error-at-GetLoggingEndpoint")
129 return resp, err
130 }
131 err = errors.New(resp.ReasonDetail)
132
133 if resp.Status == dmi.Status_OK_STATUS {
134 devRec.Logging.EndPoint = resp.LoggingEndpoint
135 devRec.Logging.Protocol = resp.LoggingProtocol
136 // Store in DB
137 devRec.DBAddByName(ctx)
138 logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
139 } else {
140 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
141 }
142 return resp, err
143}
144
145// GetPhysicalInventory is the adapter implementation for reading physical inventories in grpc adapter layer
146func (c *Client) GetPhysicalInventory(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
147
148 logger.Info(ctx, "Invoked-GetPhysicalInventory-at-grpc-adapter", log.Fields{"req": req})
149
150 resp := new(dmi.PhysicalInventoryResponse)
151 resp.Status = dmi.Status_ERROR_STATUS
152 resp.Reason = dmi.PhysicalInventoryResponse_INTERNAL_ERROR
153
154 stream, err := c.hwMgmtSvcClient.GetPhysicalInventory(ctx, req)
155
156 if err != nil {
157 logger.Error(ctx, "error-at-GetPhysicalInventory", log.Fields{"error": err})
158 resp.ReasonDetail = err.Error()
159 streamResp.Send(resp)
160 return err
161 }
162
163 for {
164
165 respFromDev, err := stream.Recv()
166
167 if err == io.EOF {
168 logger.Info(ctx, "Exiting-GetPhysicalInventory-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
169 break
170 }
171
172 if err != nil {
173 logger.Error(ctx, "Failed-at-GetPhysicalInventory-while-receiving-server-response", log.Fields{"error": err, "request": req})
174 return err
175 }
176
177 if respFromDev.Status == dmi.Status_OK_STATUS {
178
179 // Store in DB
180 devRec.DBSaveHwInfo(ctx, respFromDev.Inventory)
181 nameToUuidMap := make(map[string]string)
182 hw.DBSaveHwCompsFromPhysicalInventory(ctx, devRec.Uuid, nameToUuidMap, respFromDev.Inventory.Root.Children)
183 hw.DBAddNameToUuidlookup(ctx, devRec.Uuid, nameToUuidMap)
184 logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
185
186 } else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
187
188 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
189 if err == nil {
190 err = errors.New(respFromDev.ReasonDetail)
191 }
192 streamResp.Send(respFromDev)
193 return err
194
195 }
196
197 streamResp.Send(respFromDev)
198 }
199
200 return nil
201}
202
203// GetLoggableEntities is the adapter implementation for reading physical inventories in grpc adapter layer
204func (c *Client) GetLoggableEntities(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
205
206 logger.Info(ctx, "Invoked-GetLoggableEntities-at-grpc-adapter", log.Fields{"req": req})
207
208 resp, err := c.hwMgmtSvcClient.GetLoggableEntities(ctx, req)
209
210 if err != nil {
211 logger.Error(ctx, "Failed-at-GetLoggableEntities-while-receiving-server-response", log.Fields{"error": err, "request": req})
212 return resp, err
213 }
214 // update the db if get log response is success from device
215 if resp.Status == dmi.Status_OK_STATUS {
216 devRec.SaveLoggableEntities(ctx, resp.LogLevels)
217 devRec.DBAddByName(ctx)
218 }
219
220 return resp, err
221}
222
223// SetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
224func (c *Client) SetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
225
226 logger.Info(ctx, "Invoked-SetLogLevel-at-grpc-adapter", log.Fields{"req": req})
227
228 resp, err := c.hwMgmtSvcClient.SetLogLevel(ctx, req)
229
230 if err != nil {
231 logger.Error(ctx, "Failed-at-SetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
232 return resp, err
233 }
234 // update the db if setting log response is success from device
235 if resp.Status == dmi.Status_OK_STATUS {
236 devRec.SaveLoggableEntities(ctx, req.Loglevels)
237 devRec.DBAddByName(ctx)
238 }
239
240 return resp, err
241}
242
243// GetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
244func (c *Client) GetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
245
246 logger.Info(ctx, "Invoked-GetLogLevel-at-grpc-adapter", log.Fields{"req": req})
247
248 resp, err := c.hwMgmtSvcClient.GetLogLevel(ctx, req)
249
250 if err != nil {
251 logger.Error(ctx, "Failed-at-GetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
252 return resp, err
253 }
254
255 // update the db if get log response is success from device
256 if resp.Status == dmi.Status_OK_STATUS {
257 devRec.SaveLoggableEntities(ctx, resp.LogLevels)
258 devRec.DBAddByName(ctx)
259 }
260
261 return resp, err
262}
263
264// GetHWComponentInfo is the adapter implementation for get the details of a particular HW component
265func (c *Client) GetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
266
267 logger.Info(ctx, "Invoked-GetHWComponentInfo-at-grpc-adapter", log.Fields{"req": req})
268
269 resp := new(dmi.HWComponentInfoGetResponse)
270 resp.Status = dmi.Status_ERROR_STATUS
271 resp.Reason = dmi.HWComponentInfoGetResponse_INTERNAL_ERROR
272
273 stream, err := c.hwMgmtSvcClient.GetHWComponentInfo(ctx, req)
274
275 if err != nil {
276 logger.Error(ctx, "error-at-GetHWComponentInfo", log.Fields{"error": err})
277 resp.ReasonDetail = err.Error()
278 streamResp.Send(resp)
279 return err
280 }
281
282 for {
283
284 respFromDev, err := stream.Recv()
285
286 if err == io.EOF {
287 logger.Info(ctx, "Exiting-GetHWComponentInfo-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
288 break
289 }
290
291 if err != nil {
292 logger.Error(ctx, "Failed-at-GetHWComponentInfo-while-receiving-server-response", log.Fields{"error": err, "request": req})
293 return err
294 }
295
296 if respFromDev.Status == dmi.Status_OK_STATUS {
297 if hwCompRec.State == nil {
298 hwCompRec.State = new(dmi.ComponentState)
299 }
300 err = copy.Copy(&hwCompRec, &respFromDev.Component)
301 if err != nil {
302 logger.Error(ctx, "Failed-at-GetHWComponentInfo-copy-failed", log.Fields{"error": err, "resp": respFromDev.Component})
303 }
304 if respFromDev.Component.State != nil {
305 hwCompRec.State.AdminState = respFromDev.Component.State.AdminState
306 }
307 // Store in DB
308 hwCompRec.DBAddByUuid(ctx, deviceUuid)
309 logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
310 } else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
311 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
312 if err == nil {
313 err = errors.New(respFromDev.ReasonDetail)
314 }
315 streamResp.Send(respFromDev)
316 return err
317 }
318
319 streamResp.Send(respFromDev)
320 }
321
322 return nil
323}
324
325// SetHWComponentInfo method is the grpc adapter implementation for setting hw component info on device
326func (c *Client) SetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
327 logger.Info(ctx, "Invoked-SetHWComponentInfo", log.Fields{"req": req})
328
329 resp, err := c.hwMgmtSvcClient.SetHWComponentInfo(ctx, req)
330
331 if err != nil {
332 logger.Error(ctx, "error-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
333 return resp, err
334 }
335
336 if resp.Status == dmi.Status_OK_STATUS {
337 hwCompRec.State = new(dmi.ComponentState)
338 err = copy.Copy(&hwCompRec, &req.Changes)
339 hwCompRec.State.AdminState = req.Changes.AdminState
340 // Store in DB
341 hwCompRec.DBAddByUuid(ctx, deviceUuid)
342 logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
343 } else {
344 logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
345 err = errors.New(resp.ReasonDetail)
346 }
347
348 return resp, err
349}