blob: 23261f512739b1c056f7f2e226202f989d4fc2a7 [file] [log] [blame]
Stephane Barbariea75791c2019-01-24 10:58:06 -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 */
16package core
17
18import (
19 "context"
David K. Bainbridgef430cd52019-05-28 15:00:35 -070020 "encoding/json"
Scott Baker807addd2019-10-24 15:16:21 -070021 "github.com/opencord/voltha-lib-go/v2/pkg/db/model"
22 "github.com/opencord/voltha-lib-go/v2/pkg/log"
23 "github.com/opencord/voltha-lib-go/v2/pkg/version"
Scott Baker555307d2019-11-04 08:58:01 -080024 "github.com/opencord/voltha-protos/v2/go/voltha"
Stephane Barbariea75791c2019-01-24 10:58:06 -050025 "google.golang.org/grpc/codes"
26 "google.golang.org/grpc/status"
27)
28
29// Enumerated type to keep track of miscellaneous data path agents
30type DataModelType int
31
32// Enumerated list of data path agents
33const (
34 Adapters DataModelType = 1 + iota
35 AlarmFilters
36 CoreInstances
37 DeviceTypes
38 DeviceGroups
39 Voltha
40)
41
David K. Bainbridgebe883962019-05-22 14:49:12 -070042const SENTINEL_ADAPTER_ID = "adapter_sentinel"
43
Stephane Barbariea75791c2019-01-24 10:58:06 -050044// String equivalent for data path agents
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040045var commonTypes = []string{
Stephane Barbariea75791c2019-01-24 10:58:06 -050046 "Adapters",
47 "AlarmFilters",
48 "CoreInstances",
49 "DeviceTypes",
50 "DeviceGroups",
51 "Voltha",
52}
53
54// String converts the enumerated data path agent value to its string equivalent
55func (t DataModelType) String() string {
56 return commonTypes[t-1]
57}
58
David K. Bainbridgee14914d2019-05-24 13:43:05 -070059const MultipleValuesMsg = "Expected a single value for KV query for an instance (%s) of type '%s', but received multiple values"
60
Stephane Barbariea75791c2019-01-24 10:58:06 -050061// ModelProxyManager controls requests made to the miscellaneous data path agents
62type ModelProxyManager struct {
63 modelProxy map[string]*ModelProxy
64 clusterDataProxy *model.Proxy
65}
66
67func newModelProxyManager(cdProxy *model.Proxy) *ModelProxyManager {
68 var mgr ModelProxyManager
69 mgr.modelProxy = make(map[string]*ModelProxy)
70 mgr.clusterDataProxy = cdProxy
71 return &mgr
72}
73
74// GetDeviceType returns the device type associated to the provided id
75func (mpMgr *ModelProxyManager) GetVoltha(ctx context.Context) (*voltha.Voltha, error) {
76 log.Debug("GetVoltha")
77
David K. Bainbridgef430cd52019-05-28 15:00:35 -070078 /*
79 * For now, encode all the version information into a JSON object and
80 * pass that back as "version" so the client can get all the
81 * information associated with the version. Long term the API should
82 * better accomidate this, but for now this will work.
83 */
84 data, err := json.Marshal(&version.VersionInfo)
85 info := version.VersionInfo.Version
86 if err != nil {
87 log.Warnf("Unable to encode version information as JSON: %s", err.Error())
88 } else {
89 info = string(data)
90 }
91
David K. Bainbridgee14914d2019-05-24 13:43:05 -070092 return &voltha.Voltha{
David K. Bainbridgef430cd52019-05-28 15:00:35 -070093 Version: info,
David K. Bainbridgee14914d2019-05-24 13:43:05 -070094 }, nil
Stephane Barbariea75791c2019-01-24 10:58:06 -050095}
96
97// ListCoreInstances returns all the core instances known to the system
98func (mpMgr *ModelProxyManager) ListCoreInstances(ctx context.Context) (*voltha.CoreInstances, error) {
99 log.Debug("ListCoreInstances")
100
101 // TODO: Need to retrieve the list of registered cores
102
103 return &voltha.CoreInstances{}, status.Errorf(codes.NotFound, "no-core-instances")
104}
105
106// GetCoreInstance returns the core instance associated to the provided id
107func (mpMgr *ModelProxyManager) GetCoreInstance(ctx context.Context, id string) (*voltha.CoreInstance, error) {
108 log.Debugw("GetCoreInstance", log.Fields{"id": id})
109
110 // TODO: Need to retrieve the list of registered cores
111
112 return &voltha.CoreInstance{}, status.Errorf(codes.NotFound, "core-instance-%s", id)
113}
114
115// ListAdapters returns all the device types known to the system
116func (mpMgr *ModelProxyManager) ListAdapters(ctx context.Context) (*voltha.Adapters, error) {
117 log.Debug("ListAdapters")
118
119 var agent *ModelProxy
120 var exists bool
David K. Bainbridgebe883962019-05-22 14:49:12 -0700121 var adapter *voltha.Adapter
Stephane Barbariea75791c2019-01-24 10:58:06 -0500122
123 if agent, exists = mpMgr.modelProxy[Adapters.String()]; !exists {
124 agent = newModelProxy("adapters", mpMgr.clusterDataProxy)
125 mpMgr.modelProxy[Adapters.String()] = agent
126 }
127
128 adapters := &voltha.Adapters{}
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700129 if items, err := agent.Get(); err != nil {
130 return nil, status.Errorf(codes.Internal, err.Error())
131 } else if items != nil {
132 list, ok := items.([]interface{})
133 if !ok {
134 list = []interface{}{items}
135 }
136 for _, item := range list {
David K. Bainbridgebe883962019-05-22 14:49:12 -0700137 adapter = item.(*voltha.Adapter)
138 if adapter.Id != SENTINEL_ADAPTER_ID { // don't report the sentinel
139 adapters.Items = append(adapters.Items, adapter)
140 }
Stephane Barbariea75791c2019-01-24 10:58:06 -0500141 }
142 log.Debugw("retrieved-adapters", log.Fields{"adapters": adapters})
143 return adapters, nil
144 }
145
146 return adapters, status.Errorf(codes.NotFound, "no-adapters")
147}
148
149// ListDeviceTypes returns all the device types known to the system
150func (mpMgr *ModelProxyManager) ListDeviceTypes(ctx context.Context) (*voltha.DeviceTypes, error) {
151 log.Debug("ListDeviceTypes")
152
153 var agent *ModelProxy
154 var exists bool
155
156 if agent, exists = mpMgr.modelProxy[DeviceTypes.String()]; !exists {
157 agent = newModelProxy("device_types", mpMgr.clusterDataProxy)
158 mpMgr.modelProxy[DeviceTypes.String()] = agent
159 }
160
161 deviceTypes := &voltha.DeviceTypes{}
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700162 if items, err := agent.Get(); err != nil {
163 return nil, status.Errorf(codes.Internal, err.Error())
164 } else if items != nil {
165 list, ok := items.([]interface{})
166 if !ok {
167 list = []interface{}{items}
168 }
169 for _, item := range list {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500170 deviceTypes.Items = append(deviceTypes.Items, item.(*voltha.DeviceType))
171 }
172 return deviceTypes, nil
173 }
174
175 return deviceTypes, status.Errorf(codes.NotFound, "no-device-types")
176}
177
178// GetDeviceType returns the device type associated to the provided id
179func (mpMgr *ModelProxyManager) GetDeviceType(ctx context.Context, id string) (*voltha.DeviceType, error) {
180 log.Debugw("GetDeviceType", log.Fields{"id": id})
181
182 var agent *ModelProxy
183 var exists bool
184
185 if agent, exists = mpMgr.modelProxy[DeviceTypes.String()]; !exists {
186 agent = newModelProxy("device_types", mpMgr.clusterDataProxy)
187 mpMgr.modelProxy[DeviceTypes.String()] = agent
188 }
189
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700190 if deviceType, err := agent.Get(id); err != nil {
191 return nil, status.Errorf(codes.Internal, err.Error())
192 } else if deviceType != nil {
193 _, ok := deviceType.(*voltha.DeviceType)
194 if !ok {
195 return nil, status.Errorf(codes.Internal, MultipleValuesMsg,
196 id, DeviceTypes.String())
197 }
Stephane Barbariea75791c2019-01-24 10:58:06 -0500198 return deviceType.(*voltha.DeviceType), nil
199 }
200
201 return &voltha.DeviceType{}, status.Errorf(codes.NotFound, "device-type-%s", id)
202}
203
204// ListDeviceGroups returns all the device groups known to the system
205func (mpMgr *ModelProxyManager) ListDeviceGroups(ctx context.Context) (*voltha.DeviceGroups, error) {
206 log.Debug("ListDeviceGroups")
207
208 var agent *ModelProxy
209 var exists bool
210
211 if agent, exists = mpMgr.modelProxy[DeviceGroups.String()]; !exists {
212 agent = newModelProxy("device_groups", mpMgr.clusterDataProxy)
213 mpMgr.modelProxy[DeviceGroups.String()] = agent
214 }
215
216 deviceGroups := &voltha.DeviceGroups{}
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700217 if items, err := agent.Get(); err != nil {
218 return nil, status.Errorf(codes.Internal, err.Error())
219 } else if items != nil {
220 list, ok := items.([]interface{})
221 if !ok {
222 list = []interface{}{items}
223 }
224 for _, item := range list {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500225 deviceGroups.Items = append(deviceGroups.Items, item.(*voltha.DeviceGroup))
226 }
227 return deviceGroups, nil
228 }
229
230 return deviceGroups, status.Errorf(codes.NotFound, "no-device-groups")
231}
232
233// GetDeviceGroup returns the device group associated to the provided id
234func (mpMgr *ModelProxyManager) GetDeviceGroup(ctx context.Context, id string) (*voltha.DeviceGroup, error) {
235 log.Debugw("GetDeviceGroup", log.Fields{"id": id})
236
237 var agent *ModelProxy
238 var exists bool
239
240 if agent, exists = mpMgr.modelProxy[DeviceGroups.String()]; !exists {
241 agent = newModelProxy("device_groups", mpMgr.clusterDataProxy)
242 mpMgr.modelProxy[DeviceGroups.String()] = agent
243 }
244
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700245 if deviceGroup, err := agent.Get(id); err != nil {
246 return nil, status.Errorf(codes.Internal, err.Error())
247 } else if deviceGroup != nil {
248 _, ok := deviceGroup.(*voltha.DeviceGroup)
249 if !ok {
250 return nil, status.Errorf(codes.Internal, MultipleValuesMsg,
251 id, DeviceGroups.String())
252 }
Stephane Barbariea75791c2019-01-24 10:58:06 -0500253 return deviceGroup.(*voltha.DeviceGroup), nil
254 }
255
256 return &voltha.DeviceGroup{}, status.Errorf(codes.NotFound, "device-group-%s", id)
257}
258
259// ListAlarmFilters returns all the alarm filters known to the system
260func (mpMgr *ModelProxyManager) ListAlarmFilters(ctx context.Context) (*voltha.AlarmFilters, error) {
261 log.Debug("ListAlarmFilters")
262
263 var agent *ModelProxy
264 var exists bool
265
266 if agent, exists = mpMgr.modelProxy[AlarmFilters.String()]; !exists {
267 agent = newModelProxy("alarm_filters", mpMgr.clusterDataProxy)
268 mpMgr.modelProxy[AlarmFilters.String()] = agent
269 }
270
271 alarmFilters := &voltha.AlarmFilters{}
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700272 if items, err := agent.Get(); err != nil {
273 return nil, status.Errorf(codes.Internal, err.Error())
274 } else if items != nil {
275 list, ok := items.([]interface{})
276 if !ok {
277 list = []interface{}{items}
278 }
279 for _, item := range list {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500280 alarmFilters.Filters = append(alarmFilters.Filters, item.(*voltha.AlarmFilter))
281 }
282 return alarmFilters, nil
283 }
284
285 return alarmFilters, status.Errorf(codes.NotFound, "no-alarm-filters")
286}
287
288// GetAlarmFilter returns the alarm filter associated to the provided id
289func (mpMgr *ModelProxyManager) GetAlarmFilter(ctx context.Context, id string) (*voltha.AlarmFilter, error) {
290 log.Debugw("GetAlarmFilter", log.Fields{"id": id})
291
292 var agent *ModelProxy
293 var exists bool
294
295 if agent, exists = mpMgr.modelProxy[AlarmFilters.String()]; !exists {
296 agent = newModelProxy("alarm_filters", mpMgr.clusterDataProxy)
297 mpMgr.modelProxy[AlarmFilters.String()] = agent
298 }
299
David K. Bainbridgee14914d2019-05-24 13:43:05 -0700300 if alarmFilter, err := agent.Get(id); err != nil {
301 return nil, status.Errorf(codes.Internal, err.Error())
302 } else if alarmFilter != nil {
303 _, ok := alarmFilter.(*voltha.AlarmFilter)
304 if !ok {
305 return nil, status.Errorf(codes.Internal, MultipleValuesMsg,
306 id, AlarmFilters.String())
307 }
Stephane Barbariea75791c2019-01-24 10:58:06 -0500308 return alarmFilter.(*voltha.AlarmFilter), nil
309 }
310 return &voltha.AlarmFilter{}, status.Errorf(codes.NotFound, "alarm-filter-%s", id)
311}