Add bounds to sphinx requirement
[ccsdk/features.git] / sdnr / wt / devicemanager-o-ran-sc / o-ran / ru-fh / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / oran / impl / binding / ORanNetworkElement.java
1 /*
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding;
19
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Optional;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
28 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
29 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement;
30 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService;
31 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider;
32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService;
33 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
34 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
35 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor;
36 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor;
37 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.Hardware;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfirmedCommit;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionEnd;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionStart;
47 import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.NetconfCallhomeServer;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.AllowedDevices;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.allowed.devices.Device;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
55 import org.opendaylight.yangtools.concepts.ListenerRegistration;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.binding.NotificationListener;
58 import org.opendaylight.yangtools.yang.common.QName;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public class ORanNetworkElement implements NetworkElement {
63
64     private static final Logger LOG = LoggerFactory.getLogger(ORanNetworkElement.class);
65
66     public static final QName ONAP_SYSTEM =
67             org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.$YangModuleInfoImpl.getInstance().getName();
68     private static final InstanceIdentifier<System1> SYSTEM1_IID = InstanceIdentifier
69             .builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.system.rev140806.System.class)
70             .augmentation(System1.class).build();
71
72     private final NetconfBindingAccessor netconfAccessor;
73     private final Optional<NetconfBindingAccessor> netconfAccessorOpt;
74
75     private final Optional<NetconfDomAccessor> netconfDomAccessor;
76     private final DataProvider databaseService;
77     private final ORanRegistrationToVESpnfRegistrationMapper mapper;
78     private final VESCollectorService vesCollectorService;
79
80     private ListenerRegistration<NotificationListener> oRanListenerRegistrationResult;
81     //private @NonNull final ORanChangeNotificationListener oRanListener;
82     private ListenerRegistration<NotificationListener> oRanFaultListenerRegistrationResult;
83     private @NonNull final ORanFaultNotificationListener oRanFaultListener;
84
85     //ORanNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) {
86     ORanNetworkElement(NetconfAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) {
87         LOG.info("Create {}", ORanNetworkElement.class.getSimpleName());
88         // Read parameters
89         this.netconfAccessorOpt = netconfAccess.getNetconfBindingAccessor();
90         this.netconfAccessor = netconfAccessorOpt.get();
91         this.netconfDomAccessor = netconfAccess.getNetconfDomAccessor();
92         // Get services
93         this.databaseService = serviceProvider.getDataProvider();
94         this.vesCollectorService = serviceProvider.getVESCollectorService();
95
96         this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService);
97
98         // Register callbacks
99         this.oRanListenerRegistrationResult = null;
100         //this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, serviceProvider);
101
102         this.oRanFaultListenerRegistrationResult = null;
103         this.oRanFaultListener = new ORanFaultNotificationListener(netconfAccessor, vesCollectorService,
104                 serviceProvider.getFaultService(), serviceProvider.getWebsocketService(), databaseService);
105
106     }
107
108     private Collection<Component> initialReadFromNetworkElement() {
109         Collection<Component> componentList;
110         Hardware hardware = readHardware();
111         if (hardware != null) {
112             componentList = YangHelper.getCollection(hardware.nonnullComponent());
113             List<Inventory> inventoryList =
114                     ORanToInternalDataModel.getInventoryList(netconfAccessor.getNodeId(), componentList);
115             databaseService.writeInventory(netconfAccessor.getNodeId().getValue(), inventoryList);
116         } else {
117             componentList = Collections.emptyList();
118         }
119
120         Optional<Guicutthrough> oGuicutthrough = ORanToInternalDataModel.getGuicutthrough(getOnapSystemData());
121         if (oGuicutthrough.isPresent()) {
122             databaseService.writeGuiCutThroughData(oGuicutthrough.get(), netconfAccessor.getNodeId().getValue());
123         }
124         return componentList;
125     }
126
127     @Override
128     public NetworkElementDeviceType getDeviceType() {
129         return NetworkElementDeviceType.ORAN;
130     }
131
132     @Override
133     public void register() {
134         // Read data from device
135         Collection<Component> componentList = initialReadFromNetworkElement();
136         oRanFaultListener.setComponentList(componentList);
137         // Publish the mountpoint to VES if enabled
138         publishMountpointToVES(componentList);
139         // Register call back class for receiving notifications
140         //this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener);
141         this.oRanFaultListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanFaultListener);
142         // Register notifications stream
143         /*if (netconfAccessor.isNotificationsRFC5277Supported()) {
144             netconfAccessor.registerNotificationsStream();
145         }*/
146
147         QName[] notifications = { NetconfConfigChange.QNAME, NetconfConfirmedCommit.QNAME,
148                 NetconfSessionStart.QNAME, NetconfSessionEnd.QNAME, NetconfCapabilityChange.QNAME };
149         //netconfDomAccessor.get().doRegisterNotificationListener(new ORanDOMChangeNotificationListener(netconfDomAccessor.get(), databaseService), notifications);
150      // Output notification streams to LOG
151         Map<StreamKey, Stream> streams = netconfDomAccessor.get().getNotificationStreamsAsMap();
152         LOG.info("Available notifications streams: {}", streams);
153         // Register to default stream
154         netconfDomAccessor.get().invokeCreateSubscription();
155     }
156
157     @Override
158     public void deregister() {
159         if (oRanListenerRegistrationResult != null) {
160             this.oRanListenerRegistrationResult.close();
161         }
162         if (oRanFaultListenerRegistrationResult != null) {
163             this.oRanFaultListenerRegistrationResult.close();
164         } ;
165         databaseService.clearGuiCutThroughEntriesOfNode(getMountpointId());
166     }
167
168     @Override
169     public NodeId getNodeId() {
170         return netconfAccessor.getNodeId();
171     }
172
173     @Override
174     public <L extends NetworkElementService> Optional<L> getService(Class<L> clazz) {
175         return Optional.empty();
176     }
177
178     @Override
179     public void warmstart() {}
180
181     @Override
182     public Optional<NetconfAccessor> getAcessor() {
183         return Optional.of(netconfAccessor);
184     }
185
186     // Private functions
187
188     private String getMountpointId() {
189         return getNodeId().getValue();
190     }
191
192     // Read from device
193     /**
194      * Read system data with GUI cut through information from device if ONAP_SYSTEM YANG is supported.
195      *
196      * @return System1 data with GUI cut through information or null if not available.
197      */
198     private @Nullable System1 getOnapSystemData() {
199         LOG.info("Get System1 for class {} from mountpoint {}", netconfAccessor.getNodeId().getValue());
200         Capabilities x = netconfAccessor.getCapabilites();
201         LOG.info("Capabilites: {}", x);
202         if (x.isSupportingNamespace(ONAP_SYSTEM)) {
203             @Nullable
204             System1 res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(),
205                     LogicalDatastoreType.OPERATIONAL, SYSTEM1_IID);
206             LOG.debug("Result of System1 = {}", res);
207             return res;
208         } else {
209             LOG.debug("No GUI cut through support");
210             return null;
211         }
212     }
213
214     private Hardware readHardware() {
215         final Class<Hardware> clazzPac = Hardware.class;
216         LOG.info("DBRead Get hardware for class {} from mountpoint {}", clazzPac.getSimpleName(),
217                 netconfAccessor.getNodeId().getValue());
218         InstanceIdentifier<Hardware> hardwareIID = InstanceIdentifier.builder(clazzPac).build();
219         Hardware res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(),
220                 LogicalDatastoreType.OPERATIONAL, hardwareIID);
221         LOG.debug("Result of Hardware = {}", res);
222         return res;
223     }
224
225     // VES related
226     private void publishMountpointToVES(Collection<Component> componentList) {
227
228         LOG.debug("In publishMountpointToVES()");
229
230         /*
231          * 1. Check if this device is in the list of allowed-devices. 2. If device
232          * exists in allowed-devices, then create VES pnfRegistration event and publish
233          * to VES
234          */
235         if (inAllowedDevices(getMountpointId())) {
236             if (vesCollectorService.getConfig().isVESCollectorEnabled()) {
237                 for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) {
238                     // Just get one component. At the moment we don't care which one. Also since
239                     // there is only one management address, we assume there will be only one
240                     // chassis.
241                     // If the device supports subtended configuration then it is assumed that the
242                     // Chassis containing the management interface will be the root component and
243                     // there will be only one root.
244                     /*VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(component);
245                     VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(component);
246                     try {
247                         vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body));
248                     } catch (JsonProcessingException e) {
249                         LOG.warn("Error while serializing VES Event to String ", e);
250                     }*/
251                 }
252             }
253         }
254     }
255
256     private boolean inAllowedDevices(String mountpointName) {
257         final InstanceIdentifier<AllowedDevices> ALL_DEVICES =
258                 InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class);
259
260         AllowedDevices allowedDevices = netconfAccessor.getTransactionUtils().readData(
261                 netconfAccessor.getControllerBindingDataBroker(), LogicalDatastoreType.CONFIGURATION, ALL_DEVICES);
262
263         if (allowedDevices != null) {
264             Collection<Device> deviceList = YangHelper.getCollection(allowedDevices.nonnullDevice());
265             for (Device device : deviceList) {
266                 LOG.info("Device in allowed-devices is - {}", device.getUniqueId());
267                 if (device.getUniqueId().equals(netconfAccessor.getNodeId().getValue())) {
268                     LOG.info("Mountpoint is part of allowed-devices list");
269                     return true;
270                 }
271             }
272         }
273
274         LOG.info("Mountpoint {} is not part of allowed-devices list", mountpointName);
275         return false;
276     }
277
278 }