blob: e036998d1dc1aeef80ed9b1ff8bccf56162540f2 [file] [log] [blame]
khenaidoobf6e7bb2018-08-14 22:27:29 -04001/*
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 */
khenaidoob9203542018-09-17 22:56:37 -040016package core
khenaidoobf6e7bb2018-08-14 22:27:29 -040017
18import (
19 "context"
20 "errors"
21 "github.com/golang/protobuf/ptypes/empty"
22 da "github.com/opencord/voltha-go/common/core/northbound/grpc"
23 "github.com/opencord/voltha-go/common/log"
24 "github.com/opencord/voltha-go/protos/common"
25 "github.com/opencord/voltha-go/protos/openflow_13"
26 "github.com/opencord/voltha-go/protos/voltha"
khenaidoob9203542018-09-17 22:56:37 -040027 "google.golang.org/grpc/codes"
khenaidoobf6e7bb2018-08-14 22:27:29 -040028 "google.golang.org/grpc/metadata"
khenaidoob9203542018-09-17 22:56:37 -040029 "google.golang.org/grpc/status"
khenaidoobf6e7bb2018-08-14 22:27:29 -040030)
31
32type APIHandler struct {
khenaidoob9203542018-09-17 22:56:37 -040033 deviceMgr *DeviceManager
34 logicalDeviceMgr *LogicalDeviceManager
khenaidoobf6e7bb2018-08-14 22:27:29 -040035 da.DefaultAPIHandler
36}
37
khenaidoo9a468962018-09-19 15:33:13 -040038func NewAPIHandler(deviceMgr *DeviceManager, lDeviceMgr *LogicalDeviceManager) *APIHandler {
khenaidoob9203542018-09-17 22:56:37 -040039 handler := &APIHandler{deviceMgr: deviceMgr,
khenaidoo9a468962018-09-19 15:33:13 -040040 logicalDeviceMgr: lDeviceMgr}
khenaidoobf6e7bb2018-08-14 22:27:29 -040041 return handler
42}
khenaidoo4d4802d2018-10-04 21:59:49 -040043
44// isTestMode is a helper function to determine a function is invoked for testing only
khenaidoobf6e7bb2018-08-14 22:27:29 -040045func isTestMode(ctx context.Context) bool {
46 md, _ := metadata.FromIncomingContext(ctx)
47 _, exist := md[common.TestModeKeys_api_test.String()]
48 return exist
49}
50
khenaidoo4d4802d2018-10-04 21:59:49 -040051// waitForNilResponseOnSuccess is a helper function to wait for a response on channel ch where an nil
52// response is expected in a successful scenario
53func waitForNilResponseOnSuccess(ctx context.Context, ch chan interface{}) (*empty.Empty, error) {
54 select {
55 case res := <-ch:
56 if res == nil {
57 return new(empty.Empty), nil
58 } else if err, ok := res.(error); ok {
59 return new(empty.Empty), err
60 } else {
61 log.Warnw("unexpected-return-type", log.Fields{"result": res})
62 err = status.Errorf(codes.Internal, "%s", res)
63 return new(empty.Empty), err
64 }
65 case <-ctx.Done():
66 log.Debug("client-timeout")
67 return nil, ctx.Err()
68 }
69}
70
khenaidoobf6e7bb2018-08-14 22:27:29 -040071func (handler *APIHandler) UpdateLogLevel(ctx context.Context, logging *voltha.Logging) (*empty.Empty, error) {
72 log.Debugw("UpdateLogLevel-request", log.Fields{"newloglevel": logging.Level, "intval": int(logging.Level)})
khenaidoo92e62c52018-10-03 14:02:54 -040073 out := new(empty.Empty)
74 log.SetPackageLogLevel(logging.PackageName, int(logging.Level))
75 return out, nil
khenaidoobf6e7bb2018-08-14 22:27:29 -040076}
77
khenaidoo4d4802d2018-10-04 21:59:49 -040078func processEnableDevicePort(ctx context.Context, id *voltha.LogicalPortId, ch chan interface{}) {
khenaidoob9203542018-09-17 22:56:37 -040079 log.Debugw("processEnableDevicePort", log.Fields{"id": id, "test": common.TestModeKeys_api_test.String()})
80 ch <- status.Errorf(100, "%d-%s", 100, "erreur")
khenaidoob9203542018-09-17 22:56:37 -040081}
82
khenaidoobf6e7bb2018-08-14 22:27:29 -040083func (handler *APIHandler) EnableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
84 log.Debugw("EnableLogicalDevicePort-request", log.Fields{"id": id, "test": common.TestModeKeys_api_test.String()})
85 if isTestMode(ctx) {
86 out := new(empty.Empty)
87 return out, nil
88 }
khenaidoo4d4802d2018-10-04 21:59:49 -040089 ch := make(chan interface{})
90 defer close(ch)
khenaidoob9203542018-09-17 22:56:37 -040091 go processEnableDevicePort(ctx, id, ch)
khenaidoo4d4802d2018-10-04 21:59:49 -040092 return waitForNilResponseOnSuccess(ctx, ch)
khenaidoobf6e7bb2018-08-14 22:27:29 -040093}
94
95func (handler *APIHandler) DisableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
96 log.Debugw("DisableLogicalDevicePort-request", log.Fields{"id": id, "test": common.TestModeKeys_api_test.String()})
97 if isTestMode(ctx) {
98 out := new(empty.Empty)
99 return out, nil
100 }
101 return nil, errors.New("Unimplemented")
102}
103
104func (handler *APIHandler) UpdateLogicalDeviceFlowTable(ctx context.Context, flow *openflow_13.FlowTableUpdate) (*empty.Empty, error) {
105 log.Debugw("UpdateLogicalDeviceFlowTable-request", log.Fields{"flow": flow, "test": common.TestModeKeys_api_test.String()})
106 if isTestMode(ctx) {
107 out := new(empty.Empty)
108 return out, nil
109 }
110 return nil, errors.New("Unimplemented")
111}
112
113func (handler *APIHandler) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, flow *openflow_13.FlowGroupTableUpdate) (*empty.Empty, error) {
114 log.Debugw("UpdateLogicalDeviceFlowGroupTable-request", log.Fields{"flow": flow, "test": common.TestModeKeys_api_test.String()})
115 if isTestMode(ctx) {
116 out := new(empty.Empty)
117 return out, nil
118 }
119 return nil, errors.New("Unimplemented")
120}
121
khenaidoob9203542018-09-17 22:56:37 -0400122// GetDevice must be implemented in the read-only containers - should it also be implemented here?
123func (handler *APIHandler) GetDevice(ctx context.Context, id *voltha.ID) (*voltha.Device, error) {
124 log.Debugw("GetDevice-request", log.Fields{"id": id})
125 return handler.deviceMgr.getDevice(id.Id)
126}
127
128// GetDevice must be implemented in the read-only containers - should it also be implemented here?
129func (handler *APIHandler) ListDevices(ctx context.Context, empty *empty.Empty) (*voltha.Devices, error) {
130 log.Debug("ListDevices")
131 return handler.deviceMgr.ListDevices()
132}
133
134// GetLogicalDevice must be implemented in the read-only containers - should it also be implemented here?
135func (handler *APIHandler) GetLogicalDevice(ctx context.Context, id *voltha.ID) (*voltha.LogicalDevice, error) {
136 log.Debugw("GetLogicalDevice-request", log.Fields{"id": id})
137 return handler.logicalDeviceMgr.getLogicalDevice(id.Id)
138}
139
140// ListLogicalDevices must be implemented in the read-only containers - should it also be implemented here?
141func (handler *APIHandler) ListLogicalDevices(ctx context.Context, empty *empty.Empty) (*voltha.LogicalDevices, error) {
142 log.Debug("ListLogicalDevices")
143 return handler.logicalDeviceMgr.listLogicalDevices()
144}
145
khenaidoo4d4802d2018-10-04 21:59:49 -0400146// CreateDevice creates a new parent device in the data model
khenaidoobf6e7bb2018-08-14 22:27:29 -0400147func (handler *APIHandler) CreateDevice(ctx context.Context, device *voltha.Device) (*voltha.Device, error) {
khenaidoob9203542018-09-17 22:56:37 -0400148 log.Debugw("createdevice", log.Fields{"device": *device})
khenaidoobf6e7bb2018-08-14 22:27:29 -0400149 if isTestMode(ctx) {
150 return &voltha.Device{Id: device.Id}, nil
151 }
khenaidoob9203542018-09-17 22:56:37 -0400152 ch := make(chan interface{})
153 defer close(ch)
154 go handler.deviceMgr.createDevice(ctx, device, ch)
155 select {
156 case res := <-ch:
khenaidoo92e62c52018-10-03 14:02:54 -0400157 if res != nil {
158 if err, ok := res.(error); ok {
159 return &voltha.Device{}, err
160 }
161 if d, ok := res.(*voltha.Device); ok {
162 return d, nil
163 }
khenaidoob9203542018-09-17 22:56:37 -0400164 }
khenaidoo92e62c52018-10-03 14:02:54 -0400165 log.Warnw("create-device-unexpected-return-type", log.Fields{"result": res})
166 err := status.Errorf(codes.Internal, "%s", res)
167 return &voltha.Device{}, err
khenaidoob9203542018-09-17 22:56:37 -0400168 case <-ctx.Done():
169 log.Debug("createdevice-client-timeout")
170 return nil, ctx.Err()
171 }
khenaidoobf6e7bb2018-08-14 22:27:29 -0400172}
173
khenaidoo4d4802d2018-10-04 21:59:49 -0400174// EnableDevice activates a device by invoking the adopt_device API on the appropriate adapter
khenaidoobf6e7bb2018-08-14 22:27:29 -0400175func (handler *APIHandler) EnableDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
khenaidoob9203542018-09-17 22:56:37 -0400176 log.Debugw("enabledevice", log.Fields{"id": id})
khenaidoobf6e7bb2018-08-14 22:27:29 -0400177 if isTestMode(ctx) {
khenaidoo4d4802d2018-10-04 21:59:49 -0400178 return new(empty.Empty), nil
khenaidoobf6e7bb2018-08-14 22:27:29 -0400179 }
khenaidoob9203542018-09-17 22:56:37 -0400180 ch := make(chan interface{})
181 defer close(ch)
182 go handler.deviceMgr.enableDevice(ctx, id, ch)
khenaidoo4d4802d2018-10-04 21:59:49 -0400183 return waitForNilResponseOnSuccess(ctx, ch)
khenaidoobf6e7bb2018-08-14 22:27:29 -0400184}
185
khenaidoo4d4802d2018-10-04 21:59:49 -0400186// DisableDevice disables a device along with any child device it may have
khenaidoobf6e7bb2018-08-14 22:27:29 -0400187func (handler *APIHandler) DisableDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
188 log.Debugw("disabledevice-request", log.Fields{"id": id})
189 if isTestMode(ctx) {
khenaidoo4d4802d2018-10-04 21:59:49 -0400190 return new(empty.Empty), nil
khenaidoobf6e7bb2018-08-14 22:27:29 -0400191 }
khenaidoo92e62c52018-10-03 14:02:54 -0400192 ch := make(chan interface{})
193 defer close(ch)
194 go handler.deviceMgr.disableDevice(ctx, id, ch)
khenaidoo4d4802d2018-10-04 21:59:49 -0400195 return waitForNilResponseOnSuccess(ctx, ch)
khenaidoobf6e7bb2018-08-14 22:27:29 -0400196}
197
khenaidoo4d4802d2018-10-04 21:59:49 -0400198//RebootDevice invoked the reboot API to the corresponding adapter
khenaidoobf6e7bb2018-08-14 22:27:29 -0400199func (handler *APIHandler) RebootDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
khenaidoo4d4802d2018-10-04 21:59:49 -0400200 log.Debugw("rebootDevice-request", log.Fields{"id": id})
khenaidoobf6e7bb2018-08-14 22:27:29 -0400201 if isTestMode(ctx) {
khenaidoo4d4802d2018-10-04 21:59:49 -0400202 return new(empty.Empty), nil
khenaidoobf6e7bb2018-08-14 22:27:29 -0400203 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400204 ch := make(chan interface{})
205 defer close(ch)
206 go handler.deviceMgr.rebootDevice(ctx, id, ch)
207 return waitForNilResponseOnSuccess(ctx, ch)
khenaidoobf6e7bb2018-08-14 22:27:29 -0400208}
209
khenaidoo4d4802d2018-10-04 21:59:49 -0400210// DeleteDevice removes a device from the data model
khenaidoobf6e7bb2018-08-14 22:27:29 -0400211func (handler *APIHandler) DeleteDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
212 log.Debugw("deletedevice-request", log.Fields{"id": id})
213 if isTestMode(ctx) {
khenaidoo4d4802d2018-10-04 21:59:49 -0400214 return new(empty.Empty), nil
khenaidoobf6e7bb2018-08-14 22:27:29 -0400215 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400216 ch := make(chan interface{})
217 defer close(ch)
218 go handler.deviceMgr.deleteDevice(ctx, id, ch)
219 return waitForNilResponseOnSuccess(ctx, ch)
khenaidoobf6e7bb2018-08-14 22:27:29 -0400220}
221
222func (handler *APIHandler) DownloadImage(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
223 log.Debugw("DownloadImage-request", log.Fields{"img": *img})
224 if isTestMode(ctx) {
225 resp := &common.OperationResp{Code: common.OperationResp_OPERATION_SUCCESS}
226 return resp, nil
227 }
228
229 return nil, errors.New("UnImplemented")
230}
231
232func (handler *APIHandler) CancelImageDownload(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
233 log.Debugw("CancelImageDownload-request", log.Fields{"img": *img})
234 if isTestMode(ctx) {
235 resp := &common.OperationResp{Code: common.OperationResp_OPERATION_SUCCESS}
236 return resp, nil
237 }
238 return nil, errors.New("UnImplemented")
239}
240
241func (handler *APIHandler) ActivateImageUpdate(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
242 log.Debugw("ActivateImageUpdate-request", log.Fields{"img": *img})
243 if isTestMode(ctx) {
244 resp := &common.OperationResp{Code: common.OperationResp_OPERATION_SUCCESS}
245 return resp, nil
246 }
247 return nil, errors.New("UnImplemented")
248}
249
250func (handler *APIHandler) RevertImageUpdate(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
251 log.Debugw("RevertImageUpdate-request", log.Fields{"img": *img})
252 if isTestMode(ctx) {
253 resp := &common.OperationResp{Code: common.OperationResp_OPERATION_SUCCESS}
254 return resp, nil
255 }
256 return nil, errors.New("UnImplemented")
257}
258
259func (handler *APIHandler) UpdateDevicePmConfigs(ctx context.Context, configs *voltha.PmConfigs) (*empty.Empty, error) {
260 log.Debugw("UpdateDevicePmConfigs-request", log.Fields{"configs": *configs})
261 if isTestMode(ctx) {
262 out := new(empty.Empty)
263 return out, nil
264 }
265 return nil, errors.New("UnImplemented")
266}
267
268func (handler *APIHandler) CreateAlarmFilter(ctx context.Context, filter *voltha.AlarmFilter) (*voltha.AlarmFilter, error) {
269 log.Debugw("CreateAlarmFilter-request", log.Fields{"filter": *filter})
270 if isTestMode(ctx) {
271 f := &voltha.AlarmFilter{Id: filter.Id}
272 return f, nil
273 }
274 return nil, errors.New("UnImplemented")
275}
276
277func (handler *APIHandler) UpdateAlarmFilter(ctx context.Context, filter *voltha.AlarmFilter) (*voltha.AlarmFilter, error) {
278 log.Debugw("UpdateAlarmFilter-request", log.Fields{"filter": *filter})
279 if isTestMode(ctx) {
280 f := &voltha.AlarmFilter{Id: filter.Id}
281 return f, nil
282 }
283 return nil, errors.New("UnImplemented")
284}
285
286func (handler *APIHandler) DeleteAlarmFilter(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
287 log.Debugw("DeleteAlarmFilter-request", log.Fields{"id": *id})
288 if isTestMode(ctx) {
289 out := new(empty.Empty)
290 return out, nil
291 }
292 return nil, errors.New("UnImplemented")
293}
294
295func (handler *APIHandler) SelfTest(ctx context.Context, id *voltha.ID) (*voltha.SelfTestResponse, error) {
296 log.Debugw("SelfTest-request", log.Fields{"id": id})
297 if isTestMode(ctx) {
298 resp := &voltha.SelfTestResponse{Result: voltha.SelfTestResponse_SUCCESS}
299 return resp, nil
300 }
301 return nil, errors.New("UnImplemented")
302}