From eb2a7c97c0007b013bd1784ac17d57be02b63d03 Mon Sep 17 00:00:00 2001 From: Michael DÜrre Date: Thu, 10 Mar 2022 10:39:16 +0100 Subject: migrate sdnr features to phosphorus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix mapper and switch to dom api Updated to use phosphorus version of parent poms Issue-ID: CCSDK-3566 Signed-off-by: Michael DÜrre Change-Id: I98c5bef9286622e0d66b53db687557d798cd53f5 Signed-off-by: Michael DÜrre --- .../oran/impl/DeviceManagerORanImpl.java | 89 -- .../oran/impl/ORanChangeNotificationListener.java | 138 --- .../oran/impl/ORanFaultNotificationListener.java | 166 --- .../oran/impl/ORanFaultToVESFaultMapper.java | 164 --- .../oran/impl/ORanNetworkElement.java | 258 ----- .../oran/impl/ORanNetworkElementFactory.java | 56 - .../oran/impl/ORanNotifToVESEventAssembly.java | 99 -- ...ORanRegistrationToVESpnfRegistrationMapper.java | 90 -- .../oran/impl/ORanToInternalDataModel.java | 276 ----- .../oran/impl/binding/DeviceManagerORanImpl.java | 90 ++ .../binding/ORanChangeNotificationListener.java | 138 +++ .../binding/ORanFaultNotificationListener.java | 166 +++ .../impl/binding/ORanFaultToVESFaultMapper.java | 164 +++ .../oran/impl/binding/ORanNetworkElement.java | 278 +++++ .../impl/binding/ORanNotifToVESEventAssembly.java | 99 ++ ...ORanRegistrationToVESpnfRegistrationMapper.java | 114 ++ .../oran/impl/binding/ORanToInternalDataModel.java | 276 +++++ .../oran/impl/dom/DOMNotificationToXPath.java | 235 ++++ .../oran/impl/dom/ORanDMDOMUtility.java | 90 ++ .../dom/ORanDOMChangeNotificationListener.java | 150 +++ .../impl/dom/ORanDOMFaultNotificationListener.java | 171 +++ .../impl/dom/ORanDOMFaultToVESFaultMapper.java | 155 +++ .../oran/impl/dom/ORanDOMNetworkElement.java | 283 +++++ .../impl/dom/ORanDOMNotifToVESEventAssembly.java | 102 ++ .../oran/impl/dom/ORanDOMToInternalDataModel.java | 293 +++++ .../oran/impl/dom/ORanDeviceManagerQNames.java | 114 ++ .../impl/startup/ORanNetworkElementFactory.java | 59 + .../org/opendaylight/blueprint/impl-blueprint.xml | 2 +- .../devicemanager/oran/impl/ComponentHelper.java | 179 --- .../wt/devicemanager/oran/impl/TestAlarmNotif.java | 89 -- .../oran/impl/TestDeviceManagerORanImpl.java | 50 - .../devicemanager/oran/impl/TestHardwareClass.java | 24 - .../impl/TestORanChangeNotificationListener.java | 110 -- .../impl/TestORanFaultNotificationListener.java | 114 -- .../oran/impl/TestORanNetworkElement.java | 111 -- .../oran/impl/TestORanNetworkElementFactory.java | 94 -- .../TestORanRegistrationToVESpnfRegistration.java | 72 -- .../oran/impl/TestORanToInternalDataModel.java | 97 -- .../oran/impl/binding/ComponentHelper.java | 179 +++ .../oran/impl/binding/TestAlarmNotif.java | 88 ++ .../oran/impl/binding/TestHardwareClass.java | 24 + .../TestORanChangeNotificationListener.java | 111 ++ .../binding/TestORanFaultNotificationListener.java | 115 ++ .../oran/impl/binding/TestORanNetworkElement.java | 115 ++ .../impl/binding/TestORanToInternalDataModel.java | 96 ++ .../oran/impl/dom/TestDeviceManagerORanImpl.java | 52 + .../oran/impl/dom/TestORANInventory.java | 250 +++++ .../oran/impl/dom/TestORANReadHardware.java | 383 +++++++ .../dom/TestORanDOMFaultNotificationListener.java | 164 +++ .../oran/impl/dom/TestORanDOMNetworkElement.java | 111 ++ .../oran/impl/dom/TestORanDOMNotification.java | 184 ++++ .../impl/dom/TestORanDOMToInternalDataModel.java | 202 ++++ .../impl/dom/TestORanNetworkElementFactory.java | 101 ++ .../TestORanRegistrationToVESpnfRegistration.java | 119 ++ .../oran/impl/dom/YangParserTestUtils.java | 380 +++++++ .../test/resources/iana-crypt-hash@2014-08-06.yang | 120 ++ .../provider/src/test/resources/iana-hardware.yang | 180 +++ .../provider/src/test/resources/ietf-hardware.xml | 418 +++++++ .../provider/src/test/resources/ietf-hardware.yang | 1141 ++++++++++++++++++++ .../src/test/resources/ietf-inet-types.yang | 429 ++++++++ .../src/test/resources/ietf-netconf-acm.yang | 464 ++++++++ .../src/test/resources/ietf-system@2014-08-06.yang | 800 ++++++++++++++ .../src/test/resources/ietf-yang-types.yang | 435 ++++++++ .../test/resources/o-ran-hardware@2019-07-03.yang | 271 +++++ .../provider/src/test/resources/onap-system.xml | 15 + .../provider/src/test/resources/onap-system.yang | 59 + 66 files changed, 9984 insertions(+), 2277 deletions(-) delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/DeviceManagerORanImpl.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElementFactory.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/DeviceManagerORanImpl.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanChangeNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultToVESFaultMapper.java create mode 100644 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 create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanNotifToVESEventAssembly.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanRegistrationToVESpnfRegistrationMapper.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/DOMNotificationToXPath.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDMDOMUtility.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMChangeNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultToVESFaultMapper.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNetworkElement.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNotifToVESEventAssembly.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDeviceManagerQNames.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/startup/ORanNetworkElementFactory.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ComponentHelper.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestAlarmNotif.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestDeviceManagerORanImpl.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestHardwareClass.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanChangeNotificationListener.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanFaultNotificationListener.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElement.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElementFactory.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanRegistrationToVESpnfRegistration.java delete mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ComponentHelper.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestAlarmNotif.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestHardwareClass.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanChangeNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanFaultNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanNetworkElement.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestDeviceManagerORanImpl.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANInventory.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANReadHardware.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMFaultNotificationListener.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNetworkElement.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNotification.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMToInternalDataModel.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanNetworkElementFactory.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanRegistrationToVESpnfRegistration.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/YangParserTestUtils.java create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-crypt-hash@2014-08-06.yang create mode 100755 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-hardware.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.xml create mode 100755 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-inet-types.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-netconf-acm.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-system@2014-08-06.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-yang-types.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/o-ran-hardware@2019-07-03.yang create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.xml create mode 100644 sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.yang (limited to 'sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src') diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/DeviceManagerORanImpl.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/DeviceManagerORanImpl.java deleted file mode 100644 index 87157e8ce..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/DeviceManagerORanImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.FactoryRegistration; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeviceManagerORanImpl implements AutoCloseable { - - private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerORanImpl.class); - private static final String APPLICATION_NAME = "DeviceManagerORan"; - @SuppressWarnings("unused") - private static final String CONFIGURATIONFILE = "etc/devicemanager-oran.properties"; - - - private NetconfNetworkElementService netconfNetworkElementService; - - private HtDatabaseClient htDatabaseClient; - private Boolean devicemanagerInitializationOk = false; - private FactoryRegistration resORan; - - // Blueprint begin - public DeviceManagerORanImpl() { - LOG.info("Creating provider for {}", APPLICATION_NAME); - resORan = null; - } - - public void setNetconfNetworkElementService(NetconfNetworkElementService netconfNetworkElementService) { - this.netconfNetworkElementService = netconfNetworkElementService; - } - - public void init() throws Exception { - - LOG.info("Session Initiated start {}", APPLICATION_NAME); - - resORan = netconfNetworkElementService.registerBindingNetworkElementFactory(new ORanNetworkElementFactory()); - - - netconfNetworkElementService.writeToEventLog(APPLICATION_NAME, "startup", "done"); - this.devicemanagerInitializationOk = true; - - LOG.info("Session Initiated end. Initialization done {}", devicemanagerInitializationOk); - } - // Blueprint end - - @Override - public void close() throws Exception { - LOG.info("closing ..."); - close(htDatabaseClient); - close(resORan); - LOG.info("closing done"); - } - - /** - * Used to close all Services, that should support AutoCloseable Pattern - * - * @param toClose - * @throws Exception - */ - private void close(AutoCloseable... toCloseList) { - for (AutoCloseable element : toCloseList) { - if (element != null) { - try { - element.close(); - } catch (Exception e) { - LOG.warn("Fail during close: ", e); - } - } - } - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java deleted file mode 100644 index c0aa0ac9b..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.List; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.IetfNetconfNotificationsListener; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfirmedCommit; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionEnd; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionStart; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.Edit; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Listener for change notifications - */ -public class ORanChangeNotificationListener implements IetfNetconfNotificationsListener { - - private static final Logger log = LoggerFactory.getLogger(ORanChangeNotificationListener.class); - - private final NetconfBindingAccessor netconfAccessor; - private final DataProvider databaseService; - private final NotificationService notificationService; - private final VESCollectorService vesCollectorService; - private final NotificationProxyParser notificationProxyParser; - private ORanNotifToVESEventAssembly mapper = null; - - private static int sequenceNo = 0; - - public ORanChangeNotificationListener(NetconfBindingAccessor netconfAccessor, - DeviceManagerServiceProvider serviceProvider) { - this.netconfAccessor = netconfAccessor; - this.databaseService = serviceProvider.getDataProvider(); - this.notificationService = serviceProvider.getNotificationService(); - this.vesCollectorService = serviceProvider.getVESCollectorService(); - this.notificationProxyParser = vesCollectorService.getNotificationProxyParser(); - } - - @Override - public void onNetconfConfirmedCommit(NetconfConfirmedCommit notification) { - log.info("onNetconfConfirmedCommit {}", notification); - } - - @Override - public void onNetconfSessionStart(NetconfSessionStart notification) { - log.info("onNetconfSessionStart {}", notification); - } - - @Override - public void onNetconfSessionEnd(NetconfSessionEnd notification) { - log.info("onNetconfSessionEnd {}", notification); - } - - @Override - public void onNetconfCapabilityChange(NetconfCapabilityChange notification) { - log.info("onNetconfCapabilityChange {}", notification); - } - - @Override - public void onNetconfConfigChange(NetconfConfigChange notification) { - log.info("onNetconfConfigChange (1) {}", notification.toString()); - - StringBuffer sb = new StringBuffer(); - List editList = notification.nonnullEdit(); - for (Edit edit : editList) { - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(edit); - - InstanceIdentifier target = edit.getTarget(); - if (target != null) { - log.info("TARGET: {} {}", target.getClass(), target.getTargetType()); - for (PathArgument pa : target.getPathArguments()) { - log.info("PathArgument {} Type {}", pa, pa.getType().getFields()); - } - - EventlogEntity eventLogEntity1 = new EventlogBuilder().setNodeId(netconfAccessor.getNodeId().getValue()) - .setCounter(sequenceNo++).setTimestamp(NetconfTimeStampImpl.getConverter().getTimeStamp()) - .setObjectId(target.getTargetType().getCanonicalName()).setAttributeName("N.A") - .setSourceType(SourceType.Netconf).setNewValue(String.valueOf(edit.getOperation())).build(); - databaseService.writeEventLog(eventLogEntity1); - } - } - log.info("onNetconfConfigChange (2) {}", sb); - - if (vesCollectorService.getConfig().isVESCollectorEnabled()) { - if (mapper == null) { - this.mapper = new ORanNotifToVESEventAssembly(netconfAccessor, vesCollectorService); - } - VESCommonEventHeaderPOJO header = - mapper.createVESCommonEventHeader(notificationProxyParser.getTime(notification), - NetconfConfigChange.class.getSimpleName(), sequenceNo); - VESNotificationFieldsPOJO body = - mapper.createVESNotificationFields(notificationProxyParser.parseNotificationProxy(notification), - NetconfConfigChange.class.getSimpleName()); - try { - vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); - } catch (JsonProcessingException e) { - log.warn("Exception while generating JSON object ", e); - - } - } - - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java deleted file mode 100644 index a17dcd726..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.time.Instant; -import java.time.format.DateTimeParseException; -import java.util.Collection; -import java.util.Date; -import java.util.Objects; -import org.eclipse.jdt.annotation.NonNull; -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.ORanFmListener; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ORanFaultNotificationListener implements ORanFmListener { - - private static final Logger LOG = LoggerFactory.getLogger(ORanFaultNotificationListener.class); - - private final @NonNull NetconfBindingAccessor netconfAccessor; - private final @NonNull VESCollectorService vesCollectorService; - private final @NonNull ORanFaultToVESFaultMapper mapper; - private final @NonNull FaultService faultService; - private final @NonNull WebsocketManagerService websocketManagerService; - private final @NonNull DataProvider databaseService; - private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); - - private Integer counter; //Local counter is assigned to Notifications - - public ORanFaultNotificationListener(@NonNull NetconfBindingAccessor netconfAccessor, - @NonNull VESCollectorService vesCollectorService, @NonNull FaultService faultService, - @NonNull WebsocketManagerService websocketManagerService, @NonNull DataProvider databaseService) { - this.netconfAccessor = Objects.requireNonNull(netconfAccessor); - this.vesCollectorService = Objects.requireNonNull(vesCollectorService); - this.faultService = Objects.requireNonNull(faultService); - this.websocketManagerService = Objects.requireNonNull(websocketManagerService); - this.databaseService = Objects.requireNonNull(databaseService); - - this.mapper = new ORanFaultToVESFaultMapper(netconfAccessor.getNodeId(), vesCollectorService, - AlarmNotif.class.getSimpleName()); - this.counter = 0; - } - - /** - * Gets the mfg name, mode-name and Uuid of the root component (Ex: Chassis.) - * In cases where there are multiple root components i.e., components with no parent, - * the Uuid of the last occurred component from the componentList will be considered. - * Till now we haven't seen Uuid set for root components, so not an issue for now. - * @param componentList - */ - public void setComponentList(Collection componentList) { - for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { - mapper.setMfgName(component.getMfgName()); - mapper.setUuid(component.getUuid()!=null?component.getUuid().getValue():netconfAccessor.getNodeId().getValue()); - mapper.setModelName(component.getModelName()); - } - } - - @Override - public void onAlarmNotif(AlarmNotif notification) { - - LOG.debug("onAlarmNotif {}", notification.getClass().getSimpleName()); - counter++; - - // Send devicemanager specific notification for database and ODLUX - Instant eventTimeInstant = ORanToInternalDataModel.getInstantTime(notification.getEventTime()); - faultService.faultNotification( - ORanToInternalDataModel.getFaultLog(notification, netconfAccessor.getNodeId(), counter)); - // Send model specific notification to WebSocketManager - websocketManagerService.sendNotification(notification, netconfAccessor.getNodeId(), AlarmNotif.QNAME); - - try { - if (vesCollectorService.getConfig().isVESCollectorEnabled()) { - VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(notification, eventTimeInstant, counter); - VESFaultFieldsPOJO body = mapper.mapFaultFields(notification); - VESMessage vesMsg = vesCollectorService.generateVESEvent(header, body); - vesCollectorService.publishVESMessage(vesMsg); - LOG.info("VES Message is {}",vesMsg.getMessage()); - writeToEventLog(vesMsg.getMessage(), eventTimeInstant, AlarmNotif.QNAME.toString(), counter); - } - } catch (JsonProcessingException | DateTimeParseException e) { - LOG.debug("Can not convert event into VES message {}", notification, e); - } - } - - private void writeToEventLog(String data, Instant instant, String notificationName, - int sequenceNo) { - EventlogBuilder eventlogBuilder = new EventlogBuilder(); - - eventlogBuilder.setObjectId("Device"); - eventlogBuilder.setCounter(sequenceNo); - eventlogBuilder.setAttributeName(notificationName); - eventlogBuilder.setNodeId(netconfAccessor.getNodeId().getValue()); - String eventLogMsgLvl = vesCollectorService.getConfig().getEventLogMsgDetail(); - if (eventLogMsgLvl.equalsIgnoreCase("SHORT")) { - data = getShortEventLogMessage(data); - } else if (eventLogMsgLvl.equalsIgnoreCase("MEDIUM")) { - data = getMediumEventLogMessage(data); - } else if (eventLogMsgLvl.equalsIgnoreCase("LONG")) { - // do nothing, data already contains long message - } else { // Unknown value, default to "SHORT" - data = getShortEventLogMessage(data); - } - eventlogBuilder.setNewValue(data); - eventlogBuilder.setSourceType(SourceType.Netconf); - - Date eventDate = Date.from(instant); - eventlogBuilder.setTimestamp(new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp(eventDate))); - - databaseService.writeEventLog(eventlogBuilder.build()); - } - - private String getShortEventLogMessage(String data) { - try { - JSONObject jsonObj = new JSONObject(data); - String domain = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("domain"); - String eventId = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("eventId"); - return "domain:" + domain + " eventId:" + eventId; - } catch (JSONException e) { - LOG.debug("{}", e); - return "Invalid message received"; - } - } - - private String getMediumEventLogMessage(String data) { - try { - JSONObject jsonObj = new JSONObject(data); - return jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").toString(); - } catch (JSONException e) { - LOG.debug("{}", e); - return "Invalid message received"; - } - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java deleted file mode 100644 index ec8eaa7b7..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.time.Instant; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -//@formatter:off -/* - * Maps ORAN Fault fields to VES fault domain fields and VES commonEventHeader fields - * - * - * VES Fields Mapping - * ---------- ------- - * domain "fault" - * eventId "nt:network-topology/nt:topology/nt:node/nt:node-id" - * eventName "nt:network-topology/nt:topology/nt:node/nt:node-id" - * eventType "O-RAN-RU-Fault" - * lastEpochMicrosec TimeStamp represented by field in NetConf notification header in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. - * nfcNamingCode always "" - * nfNamingCode always "" - * nfVendorName /ietf-hardware:hardware/component[not(parent)][1]/mfg-name - * priority "Normal" - * reportingEntityId The OAM-Controller identifier with in the SMO - e.g. the fully qualified domain name or IP-Address. - * reportingEntityName as configured by helm charts for the OpenDaylight cluster name ?????? - * sequence As per NetConf notification increasing sequence number as unsigned integer 32 bits. The value is reused in the eventId field. - * sourceId Value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/uuid or 'nt:network-topology/nt:topology/nt:node/nt:node-id' if ietf component not found. - * sourceName "nt:network-topology/nt:topology/nt:node/nt:node-id" - * startEpochMicrosec Current OAM-Controller Node timestamp in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. - * timeZoneOffset Static text: "+00:00" - * version "4.1" - * vesEventListenerVersion "7.2.1" - * - * - * alarmAdditionalInformation - * alarmCondition Value of "o-ran-fm:alarm-notif/fault-id" - * alarmInterfaceA Value of "o-ran-fm:alarm-notif/fault-source" - * eventCategory Static text "O-RU failure" - * eventSeverity Value of "o-ran-fm:alarm-notif/fault-severity". But if "o-ran-fm:alarm-notif/is-cleared" then "NORMAL" - * eventSourceType The value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/model-name or "O-RU" if not found. - * faultFieldsVersion "4.0" - * specificProblem A mapping of the fault-id to its description according to O-RAN OpenFronthaul specification. - * vfStatus "Active" - * - */ -//@formatter:on - -public class ORanFaultToVESFaultMapper { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); - private static final String VES_EVENT_DOMAIN = "fault"; - private static final String VES_EVENTTYPE = "ORAN_Fault"; - private static final String VES_EVENT_PRIORITY = "Normal"; - private static final String VES_EVENT_CATEGORY = "O-RU Failure"; - private static final String VES_FAULT_FIELDS_VERSION = "4.0"; - private static final String VES_FAULT_FIELDS_VFSTATUS = "Active"; //virtual function status - - private final VESCollectorService vesProvider; - private final String notifName; // Name - private final String nodeIdString; // Sourcename - private String mfgName; - private String uuid; - private String modelName; - - public ORanFaultToVESFaultMapper(NodeId nodeId, VESCollectorService vesCollectorService, - String notifName) { - this.nodeIdString = nodeId.getValue(); - this.vesProvider = vesCollectorService; - this.notifName = notifName; - } - - public void setMfgName(String mfgName) { - this.mfgName= mfgName; - } - - private String getMfgName() { - return mfgName; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - private String getUuid() { - return uuid; - } - - public void setModelName(String modelName) { - this.modelName = modelName; - } - - private String getModelName() { - return modelName; - } - - public VESCommonEventHeaderPOJO mapCommonEventHeader(AlarmNotif notification, Instant eventTime, int sequenceNo) { - VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); - vesCEH.setDomain(VES_EVENT_DOMAIN); - vesCEH.setEventName(notifName); - vesCEH.setEventType(VES_EVENTTYPE); - vesCEH.setPriority(VES_EVENT_PRIORITY); - - String eventId; - - eventId = notifName + "-" + Long.toUnsignedString(sequenceNo); - - vesCEH.setEventId(eventId); - vesCEH.setStartEpochMicrosec(eventTime.toEpochMilli() * 1000); - vesCEH.setLastEpochMicrosec(eventTime.toEpochMilli() * 1000); - vesCEH.setNfVendorName(getMfgName()); - vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); - vesCEH.setSequence(sequenceNo); - vesCEH.setSourceId(getUuid()); - vesCEH.setSourceName(nodeIdString); - - return vesCEH; - } - - public VESFaultFieldsPOJO mapFaultFields(AlarmNotif alarmNotif) { - VESFaultFieldsPOJO vesFaultFields = new VESFaultFieldsPOJO(); - - vesFaultFields.setAlarmCondition(alarmNotif.getFaultId().toString()); - vesFaultFields.setAlarmInterfaceA(alarmNotif.getFaultSource()); - vesFaultFields.setEventCategory(VES_EVENT_CATEGORY); - if (alarmNotif.getIsCleared()) { - vesFaultFields.setEventSeverity("NORMAL"); - } else { - vesFaultFields.setEventSeverity(alarmNotif.getFaultSeverity().getName()); - } - vesFaultFields.setEventSourceType(getModelName()); - vesFaultFields.setFaultFieldsVersion(VES_FAULT_FIELDS_VERSION); - vesFaultFields.setSpecificProblem(alarmNotif.getFaultText()); - vesFaultFields.setVfStatus(VES_FAULT_FIELDS_VFSTATUS); - - return vesFaultFields; - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java deleted file mode 100644 index d3ae5014e..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.onap.ccsdk.features.sdnr.wt.common.YangHelper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.Hardware; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.NetconfCallhomeServer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.AllowedDevices; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.allowed.devices.Device; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.NotificationListener; -import org.opendaylight.yangtools.yang.common.QName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ORanNetworkElement implements NetworkElement { - - private static final Logger LOG = LoggerFactory.getLogger(ORanNetworkElement.class); - - public static final QName ONAP_SYSTEM = - org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.$YangModuleInfoImpl.getInstance().getName(); - private static final InstanceIdentifier SYSTEM1_IID = InstanceIdentifier - .builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.system.rev140806.System.class) - .augmentation(System1.class).build(); - - private final NetconfBindingAccessor netconfAccessor; - private final DataProvider databaseService; - private final ORanRegistrationToVESpnfRegistrationMapper mapper; - private final VESCollectorService vesCollectorService; - - private ListenerRegistration oRanListenerRegistrationResult; - private @NonNull final ORanChangeNotificationListener oRanListener; - private ListenerRegistration oRanFaultListenerRegistrationResult; - private @NonNull final ORanFaultNotificationListener oRanFaultListener; - - ORanNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { - LOG.info("Create {}", ORanNetworkElement.class.getSimpleName()); - // Read parameters - this.netconfAccessor = netconfAccess; - - // Get services - this.databaseService = serviceProvider.getDataProvider(); - this.vesCollectorService = serviceProvider.getVESCollectorService(); - - this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService); - - // Register callbacks - this.oRanListenerRegistrationResult = null; - this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, serviceProvider); - - this.oRanFaultListenerRegistrationResult = null; - this.oRanFaultListener = new ORanFaultNotificationListener(netconfAccessor, vesCollectorService, - serviceProvider.getFaultService(), serviceProvider.getWebsocketService(), databaseService); - } - - private Collection initialReadFromNetworkElement() { - Collection componentList; - Hardware hardware = readHardware(); - if (hardware != null) { - componentList = YangHelper.getCollection(hardware.nonnullComponent()); - List inventoryList = - ORanToInternalDataModel.getInventoryList(netconfAccessor.getNodeId(), componentList); - databaseService.writeInventory(netconfAccessor.getNodeId().getValue(), inventoryList); - } else { - componentList = Collections.emptyList(); - } - - Optional oGuicutthrough = ORanToInternalDataModel.getGuicutthrough(getOnapSystemData()); - if (oGuicutthrough.isPresent()) { - databaseService.writeGuiCutThroughData(oGuicutthrough.get(), netconfAccessor.getNodeId().getValue()); - } - return componentList; - } - - @Override - public NetworkElementDeviceType getDeviceType() { - return NetworkElementDeviceType.ORAN; - } - - @Override - public void register() { - // Read data from device - Collection componentList = initialReadFromNetworkElement(); - oRanFaultListener.setComponentList(componentList); - // Publish the mountpoint to VES if enabled - publishMountpointToVES(componentList); - // Register call back class for receiving notifications - this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener); - this.oRanFaultListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanFaultListener); - // Register notifications stream - if (netconfAccessor.isNotificationsRFC5277Supported()) { - netconfAccessor.registerNotificationsStream(); - } - } - - @Override - public void deregister() { - if (oRanListenerRegistrationResult != null) { - this.oRanListenerRegistrationResult.close(); - } - if (oRanFaultListenerRegistrationResult != null) { - this.oRanFaultListenerRegistrationResult.close(); - } ; - databaseService.clearGuiCutThroughEntriesOfNode(getMountpointId()); - } - - @Override - public NodeId getNodeId() { - return netconfAccessor.getNodeId(); - } - - @Override - public Optional getService(Class clazz) { - return Optional.empty(); - } - - @Override - public void warmstart() {} - - @Override - public Optional getAcessor() { - return Optional.of(netconfAccessor); - } - - // Private functions - - private String getMountpointId() { - return getNodeId().getValue(); - } - - // Read from device - /** - * Read system data with GUI cut through information from device if ONAP_SYSTEM YANG is supported. - * - * @return System1 data with GUI cut through information or null if not available. - */ - private @Nullable System1 getOnapSystemData() { - LOG.info("Get System1 for class {} from mountpoint {}", netconfAccessor.getNodeId().getValue()); - Capabilities x = netconfAccessor.getCapabilites(); - LOG.info("Capabilites: {}", x); - if (x.isSupportingNamespace(ONAP_SYSTEM)) { - @Nullable - System1 res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), - LogicalDatastoreType.OPERATIONAL, SYSTEM1_IID); - LOG.debug("Result of System1 = {}", res); - return res; - } else { - LOG.debug("No GUI cut through support"); - return null; - } - } - - private Hardware readHardware() { - final Class clazzPac = Hardware.class; - LOG.info("DBRead Get hardware for class {} from mountpoint {}", clazzPac.getSimpleName(), - netconfAccessor.getNodeId().getValue()); - InstanceIdentifier hardwareIID = InstanceIdentifier.builder(clazzPac).build(); - Hardware res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), - LogicalDatastoreType.OPERATIONAL, hardwareIID); - LOG.debug("Result of Hardware = {}", res); - return res; - } - - // VES related - private void publishMountpointToVES(Collection componentList) { - - LOG.debug("In publishMountpointToVES()"); - - /* - * 1. Check if this device is in the list of allowed-devices. 2. If device - * exists in allowed-devices, then create VES pnfRegistration event and publish - * to VES - */ - if (inAllowedDevices(getMountpointId())) { - if (vesCollectorService.getConfig().isVESCollectorEnabled()) { - for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { - // Just get one component. At the moment we don't care which one. Also since - // there is only one management address, we assume there will be only one - // chassis. - // If the device supports subtended configuration then it is assumed that the - // Chassis containing the management interface will be the root component and - // there will be only one root. - VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(component); - VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(component); - try { - vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); - } catch (JsonProcessingException e) { - LOG.warn("Error while serializing VES Event to String ", e); - e.printStackTrace(); - } - } - } - } - } - - private boolean inAllowedDevices(String mountpointName) { - final InstanceIdentifier ALL_DEVICES = - InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class); - - AllowedDevices allowedDevices = netconfAccessor.getTransactionUtils().readData( - netconfAccessor.getControllerBindingDataBroker(), LogicalDatastoreType.CONFIGURATION, ALL_DEVICES); - - if (allowedDevices != null) { - Collection deviceList = YangHelper.getCollection(allowedDevices.nonnullDevice()); - for (Device device : deviceList) { - LOG.info("Device in allowed-devices is - {}", device.getUniqueId()); - if (device.getUniqueId().equals(netconfAccessor.getNodeId().getValue())) { - LOG.info("Mountpoint is part of allowed-devices list"); - return true; - } - } - } - - LOG.info("Mountpoint {} is not part of allowed-devices list", mountpointName); - return false; - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElementFactory.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElementFactory.java deleted file mode 100644 index fff1fba79..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElementFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.util.Optional; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.NetworkElementFactory; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; -import org.opendaylight.yangtools.yang.common.QName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ORanNetworkElementFactory implements NetworkElementFactory { - - private static final Logger log = LoggerFactory.getLogger(ORanNetworkElementFactory.class); - //Workaround - private static final QName OneCell = - QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); - - @Override - public Optional create(NetconfAccessor accessor, DeviceManagerServiceProvider serviceProvider) { - Capabilities capabilites = accessor.getCapabilites(); - if (!capabilites.isSupportingNamespace(OneCell)) { - if (capabilites.isSupportingNamespace(ORANHWCOMPONENT.QNAME)) { - log.info("Create device {} ", ORanNetworkElement.class.getName()); - Optional bindingAccessor = accessor.getNetconfBindingAccessor(); - if (bindingAccessor.isPresent()) { - return Optional.of(new ORanNetworkElement(bindingAccessor.get(), serviceProvider)); - } - } - } - return Optional.empty(); - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java deleted file mode 100644 index d99f1c874..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ORanNotifToVESEventAssembly { - - private static final Logger log = LoggerFactory.getLogger(ORanNotifToVESEventAssembly.class); - private static final String VES_EVENT_DOMAIN = "notification"; - private static final String VES_EVENTTYPE = "ORAN_notification"; - private static final String VES_EVENT_PRIORITY = "Normal"; - private NetconfBindingAccessor netconfAccessor; - private VESCollectorService vesProvider; - - public ORanNotifToVESEventAssembly(NetconfBindingAccessor netconfAccessor, VESCollectorService vesProvider) { - this.netconfAccessor = netconfAccessor; - this.vesProvider = vesProvider; - } - - // VES CommonEventHeader fields - public VESCommonEventHeaderPOJO createVESCommonEventHeader(Instant time, String notificationTypeName, - long sequenceNo) { - VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); - vesCEH.setDomain(VES_EVENT_DOMAIN); - vesCEH.setEventName(notificationTypeName); - vesCEH.setEventType(VES_EVENTTYPE); - vesCEH.setPriority(VES_EVENT_PRIORITY); - - String eventId; - - eventId = notificationTypeName + "-" + Long.toUnsignedString(sequenceNo); - - vesCEH.setEventId(eventId); - vesCEH.setStartEpochMicrosec(time.toEpochMilli() * 1000); - vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 1000); - vesCEH.setNfVendorName("ORAN"); - vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); - vesCEH.setSequence(sequenceNo); - vesCEH.setSourceId("ORAN"); - vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); - return vesCEH; - } - - // Notification fields - public VESNotificationFieldsPOJO createVESNotificationFields(HashMap xPathFields, - String notificationTypeName) { - VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO(); - - vesNotifFields.setChangeType(notificationTypeName); - vesNotifFields.setChangeIdentifier(netconfAccessor.getNodeId().getValue()); - - StringBuffer buf = new StringBuffer(); - Iterator> it = xPathFields.entrySet().iterator(); - while (it.hasNext()) { - Entry pair = it.next(); - buf.append("\n" + pair.getKey() + " = " + pair.getValue()); - } - log.info("Resultlist({}):{}", xPathFields.size(), buf.toString()); - - ArrayList> arrayOfNamedHashMap = new ArrayList>(); - HashMap namedHashMap = new HashMap(); - namedHashMap.put("hashMap", xPathFields); - namedHashMap.put("name", notificationTypeName); - arrayOfNamedHashMap.add(namedHashMap); - vesNotifFields.setArrayOfNamedHashMap(arrayOfNamedHashMap); - return vesNotifFields; - - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java deleted file mode 100644 index 3524383f2..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.time.Instant; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ORanRegistrationToVESpnfRegistrationMapper { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); - //CommonEventHeader fields - private static final String VES_EVENT_DOMAIN = "pnfRegistration"; - private static final String VES_EVENTTYPE = "NetConf Callhome Registration"; - private static final String VES_EVENT_PRIORITY = "Normal"; - - private final VESCollectorService vesProvider; - private final NetconfAccessor netconfAccessor; - - private Integer sequenceNo; - - - public ORanRegistrationToVESpnfRegistrationMapper(NetconfAccessor netconfAccessor, - VESCollectorService vesCollectorService) { - this.netconfAccessor = netconfAccessor; - this.vesProvider = vesCollectorService; - - this.sequenceNo = 0; - } - - public VESCommonEventHeaderPOJO mapCommonEventHeader(Component component) { - VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); - vesCEH.setDomain(VES_EVENT_DOMAIN); - vesCEH.setEventId(netconfAccessor.getNodeId().getValue()); - vesCEH.setEventName(netconfAccessor.getNodeId().getValue()); - vesCEH.setEventType(VES_EVENTTYPE); - vesCEH.setPriority(VES_EVENT_PRIORITY); - - vesCEH.setStartEpochMicrosec(Instant.now().toEpochMilli() * 1000); - vesCEH.setLastEpochMicrosec(Instant.now().toEpochMilli() * 1000); - vesCEH.setNfVendorName(component.getMfgName()); - vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); - vesCEH.setSequence(sequenceNo++); - vesCEH.setSourceId(component.getUuid() != null ? component.getUuid().toString():netconfAccessor.getNodeId().getValue()); - vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); - - return vesCEH; - } - - public VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields(Component component) { - VESPNFRegistrationFieldsPOJO vesPnfFields = new VESPNFRegistrationFieldsPOJO(); - vesPnfFields.setModelNumber(component.getModelName()); - vesPnfFields.setOamV4IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv4Address()!=null?netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv4Address().getValue():null); - vesPnfFields.setOamV6IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv6Address()!=null?netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv6Address().getValue():null); - vesPnfFields.setSerialNumber(component.getSerialNum()); - vesPnfFields.setVendorName(component.getMfgName()); - vesPnfFields.setSoftwareVersion(component.getSoftwareRev()); - vesPnfFields.setUnitType(component.getAlias()); - vesPnfFields.setUnitFamily(component.getXmlClass().toString()); - vesPnfFields.setManufactureDate(component.getMfgDate()!=null?component.getMfgDate().toString():"Unknown"); - //vesPnfFields.setLastServiceDate(component.getLastChange()); - - return vesPnfFields; - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java deleted file mode 100644 index 71ab613d2..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.Alarm.FaultSeverity; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; -import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.yang.binding.CodeHelpers; -import org.opendaylight.yangtools.yang.common.Uint32; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Convert data to data-provider model and perform consistency checks.
- * Component list characteristics:
- *
    - *
  • component list is a flat list tree structure specified - *
  • via "component.getParent()": - *
      - *
    • If null we have a root element - *
    • if not null it is a child element with generated child level
      - *
    - *
- * Example of List:
- * - * - */ -public class ORanToInternalDataModel { - - private static final Logger log = LoggerFactory.getLogger(ORanToInternalDataModel.class); - - public static List getInventoryList(NodeId nodeId, Collection componentList) { - - List inventoryResultList = new ArrayList(); - for (Component component : getRootComponents(componentList)) { - inventoryResultList = recurseGetInventory(nodeId, component, componentList, 0, inventoryResultList); - } - // Verify if result is complete - if (componentList.size() != inventoryResultList.size()) { - log.warn( - "Not all data were written to the Inventory. Potential entries with missing " - + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", - nodeId.getValue(), componentList.size(), inventoryResultList.size()); - } - return inventoryResultList; - } - - private static List recurseGetInventory(NodeId nodeId, Component component, - Collection componentList, int treeLevel, List inventoryResultList) { - - //Add element to list, if conversion successfull - Optional oInventory = getInternalEquipment(nodeId, component, treeLevel); - if (oInventory.isPresent()) { - inventoryResultList.add(oInventory.get()); - } - //Walk trough list of child keys and add to list - for (String childUuid : CodeHelpers.nonnull(component.getContainsChild())) { - for (Component c : getComponentsByName(childUuid, componentList)) { - inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList); - } - } - return inventoryResultList; - } - - public static List getRootComponents(Collection componentList) { - List resultList = new ArrayList<>(); - for (Component c : componentList) { - if (c.getParent() == null) { // Root elements do not have a parent - resultList.add(c); - } - } - return resultList; - } - - private static List getComponentsByName(String name, Collection componentList) { - List resultList = new ArrayList<>(); - for (Component c : componentList) { - if (name.equals(c.getName())) { // <-- Component list is flat search for child's of name - resultList.add(c); - } - } - return resultList; - } - - /** - * Convert equipment into Inventory. Decide if inventory can by created from content or not. Public for test case. - * - * @param nodeId of node (Similar to mountpointId) - * @param component to handle - * @param treeLevel of components - * @return Inventory if possible to be created. - */ - public static Optional getInternalEquipment(NodeId nodeId, Component component, int treeLevel) { - - // Make sure that expected data are not null - Objects.requireNonNull(nodeId); - Objects.requireNonNull(component); - - // Read manadatory data - - @Nullable - String nodeIdString = nodeId.getValue(); - @Nullable - String uuid = component.getName(); - @Nullable - String idParent = component.getParent(); - @Nullable - String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht - - // do consistency check if all mandatory parameters are there - if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) { - - // Build output data - - InventoryBuilder inventoryBuilder = new InventoryBuilder(); - - // General assumed as mandatory - inventoryBuilder.setNodeId(nodeIdString); - inventoryBuilder.setUuid(uuid); - inventoryBuilder.setParentUuid(uuidParent); - inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); - - // -- String list with ids of holders (optional) - inventoryBuilder.setContainedHolder(CodeHelpers.nonnull(component.getContainsChild())); - - // -- Manufacturer related things (optional) - @Nullable - String mfgName = component.getMfgName(); - inventoryBuilder.setManufacturerName(mfgName); - inventoryBuilder.setManufacturerIdentifier(mfgName); - - // Equipment type (optional) - inventoryBuilder.setDescription(component.getDescription()); - inventoryBuilder.setModelIdentifier(component.getModelName()); - @Nullable - Class xmlClass = component.getXmlClass(); - if (xmlClass != null) { - inventoryBuilder.setPartTypeId(xmlClass.getName()); - } - inventoryBuilder.setTypeName(component.getName()); - inventoryBuilder.setVersion(component.getHardwareRev()); - - // Equipment instance (optional) - @Nullable - DateAndTime mfgDate = component.getMfgDate(); - if (mfgDate != null) { - inventoryBuilder.setDate(mfgDate.getValue()); - } - inventoryBuilder.setSerial(component.getSerialNum()); - - return Optional.of(inventoryBuilder.build()); - } - return Optional.empty(); - } - - /** - * If system data is available convert - * - * @param sys - * @return - */ - public static Optional getGuicutthrough(@Nullable System1 sys) { - if (sys != null) { - String name = sys.getName(); - @Nullable - Uri uri = sys.getWebUi(); - if (uri != null) { - GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder(); - if (name != null) { - gcBuilder.setName(name); - } - gcBuilder.setWeburi(uri.getValue()); - return Optional.of(gcBuilder.build()); - } - log.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device"); - } - log.warn("Retrieving augmented System details failed. Gui cut through information not available"); - return Optional.empty(); - } - - /** - * Convert netconf time into Instant - * - * @param eventTime with netconf time - * @return Instant with converted time. If not convertable provide Instant.Min - */ - public static Instant getInstantTime(@Nullable DateAndTime eventTime) { - return eventTime != null ? Instant.parse(eventTime.getValue()) : Instant.MIN; - } - - /** - * Convert fault notification into data-provider FaultLogEntity - * - * @param notification with O-RAN notification - * @param nodeId of node to handle - * @param counter to be integrated into data - * @return FaultlogEntity with data - */ - public static FaultlogEntity getFaultLog(AlarmNotif notification, NodeId nodeId, Integer counter) { - FaultlogBuilder faultAlarm = new FaultlogBuilder(); - faultAlarm.setNodeId(nodeId.getValue()); - faultAlarm.setObjectId(notification.getFaultSource()); - faultAlarm.setProblem(notification.getFaultText()); - faultAlarm.setSeverity(getSeverityType(notification.getFaultSeverity(), notification.isIsCleared())); - faultAlarm.setCounter(counter); - faultAlarm.setId(String.valueOf(notification.getFaultId())); - faultAlarm.setSourceType(SourceType.Netconf); - faultAlarm.setTimestamp(notification.getEventTime()); - return faultAlarm.build(); - } - - /** - * Convert O-RAN specific severity into data-provider severity - * - * @param faultSeverity O-RAN severity - * @param isCleared clear indicator - * @return data-provider severity type - * @throws IllegalArgumentException if conversion not possible. - */ - public static SeverityType getSeverityType(@Nullable FaultSeverity faultSeverity, @Nullable Boolean isCleared) - throws IllegalArgumentException { - if (isCleared != null && isCleared) { - return SeverityType.NonAlarmed; - } - if (faultSeverity != null) { - switch (faultSeverity) { - case CRITICAL: - return SeverityType.Critical; - case MAJOR: - return SeverityType.Major; - case MINOR: - return SeverityType.Minor; - case WARNING: - return SeverityType.Warning; - } - } - throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared - + " faultSeverity=" + faultSeverity); - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/DeviceManagerORanImpl.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/DeviceManagerORanImpl.java new file mode 100644 index 000000000..7e04e8c1a --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/DeviceManagerORanImpl.java @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.FactoryRegistration; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.startup.ORanNetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeviceManagerORanImpl implements AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerORanImpl.class); + private static final String APPLICATION_NAME = "DeviceManagerORan"; + @SuppressWarnings("unused") + private static final String CONFIGURATIONFILE = "etc/devicemanager-oran.properties"; + + + private NetconfNetworkElementService netconfNetworkElementService; + + private HtDatabaseClient htDatabaseClient; + private Boolean devicemanagerInitializationOk = false; + private FactoryRegistration resORan; + + // Blueprint begin + public DeviceManagerORanImpl() { + LOG.info("Creating provider for {}", APPLICATION_NAME); + resORan = null; + } + + public void setNetconfNetworkElementService(NetconfNetworkElementService netconfNetworkElementService) { + this.netconfNetworkElementService = netconfNetworkElementService; + } + + public void init() throws Exception { + + LOG.info("Session Initiated start {}", APPLICATION_NAME); + + resORan = netconfNetworkElementService.registerBindingNetworkElementFactory(new ORanNetworkElementFactory()); + + + netconfNetworkElementService.writeToEventLog(APPLICATION_NAME, "startup", "done"); + this.devicemanagerInitializationOk = true; + + LOG.info("Session Initiated end. Initialization done {}", devicemanagerInitializationOk); + } + // Blueprint end + + @Override + public void close() throws Exception { + LOG.info("closing ..."); + close(htDatabaseClient); + close(resORan); + LOG.info("closing done"); + } + + /** + * Used to close all Services, that should support AutoCloseable Pattern + * + * @param toClose + * @throws Exception + */ + private void close(AutoCloseable... toCloseList) { + for (AutoCloseable element : toCloseList) { + if (element != null) { + try { + element.close(); + } catch (Exception e) { + LOG.warn("Fail during close: ", e); + } + } + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanChangeNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanChangeNotificationListener.java new file mode 100644 index 000000000..abed01a44 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanChangeNotificationListener.java @@ -0,0 +1,138 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.IetfNetconfNotificationsListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfirmedCommit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionEnd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionStart; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.Edit; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Listener for change notifications + */ +public class ORanChangeNotificationListener implements IetfNetconfNotificationsListener { + + private static final Logger log = LoggerFactory.getLogger(ORanChangeNotificationListener.class); + + private final NetconfBindingAccessor netconfAccessor; + private final DataProvider databaseService; + private final NotificationService notificationService; + private final VESCollectorService vesCollectorService; + private final NotificationProxyParser notificationProxyParser; + private ORanNotifToVESEventAssembly mapper = null; + + private static int sequenceNo = 0; + + public ORanChangeNotificationListener(NetconfBindingAccessor netconfAccessor, + DeviceManagerServiceProvider serviceProvider) { + this.netconfAccessor = netconfAccessor; + this.databaseService = serviceProvider.getDataProvider(); + this.notificationService = serviceProvider.getNotificationService(); + this.vesCollectorService = serviceProvider.getVESCollectorService(); + this.notificationProxyParser = vesCollectorService.getNotificationProxyParser(); + } + + @Override + public void onNetconfConfirmedCommit(NetconfConfirmedCommit notification) { + log.info("onNetconfConfirmedCommit {}", notification); + } + + @Override + public void onNetconfSessionStart(NetconfSessionStart notification) { + log.info("onNetconfSessionStart {}", notification); + } + + @Override + public void onNetconfSessionEnd(NetconfSessionEnd notification) { + log.info("onNetconfSessionEnd {}", notification); + } + + @Override + public void onNetconfCapabilityChange(NetconfCapabilityChange notification) { + log.info("onNetconfCapabilityChange {}", notification); + } + + @Override + public void onNetconfConfigChange(NetconfConfigChange notification) { + log.info("onNetconfConfigChange (1) {}", notification.toString()); + + StringBuffer sb = new StringBuffer(); + List editList = notification.nonnullEdit(); + for (Edit edit : editList) { + if (sb.length() > 0) { + sb.append(", "); + } + sb.append(edit); + + InstanceIdentifier target = edit.getTarget(); + if (target != null) { + log.info("TARGET: {} {}", target.getClass(), target.getTargetType()); + for (PathArgument pa : target.getPathArguments()) { + log.info("PathArgument {} Type {}", pa, pa.getType().getFields()); + } + + EventlogEntity eventLogEntity1 = new EventlogBuilder().setNodeId(netconfAccessor.getNodeId().getValue()) + .setCounter(sequenceNo++).setTimestamp(NetconfTimeStampImpl.getConverter().getTimeStamp()) + .setObjectId(target.getTargetType().getCanonicalName()).setAttributeName("N.A") + .setSourceType(SourceType.Netconf).setNewValue(String.valueOf(edit.getOperation())).build(); + databaseService.writeEventLog(eventLogEntity1); + } + } + log.info("onNetconfConfigChange (2) {}", sb); + + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + if (mapper == null) { + this.mapper = new ORanNotifToVESEventAssembly(netconfAccessor, vesCollectorService); + } + VESCommonEventHeaderPOJO header = + mapper.createVESCommonEventHeader(notificationProxyParser.getTime(notification), + NetconfConfigChange.class.getSimpleName(), sequenceNo); + VESNotificationFieldsPOJO body = + mapper.createVESNotificationFields(notificationProxyParser.parseNotificationProxy(notification), + NetconfConfigChange.class.getSimpleName()); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + log.warn("Exception while generating JSON object ", e); + + } + } + + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultNotificationListener.java new file mode 100644 index 000000000..d03b39480 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultNotificationListener.java @@ -0,0 +1,166 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.util.Collection; +import java.util.Date; +import java.util.Objects; +import org.eclipse.jdt.annotation.NonNull; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.ORanFmListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanFaultNotificationListener implements ORanFmListener { + + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultNotificationListener.class); + + private final @NonNull NetconfBindingAccessor netconfAccessor; + private final @NonNull VESCollectorService vesCollectorService; + private final @NonNull ORanFaultToVESFaultMapper mapper; + private final @NonNull FaultService faultService; + private final @NonNull WebsocketManagerService websocketManagerService; + private final @NonNull DataProvider databaseService; + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + private Integer counter; //Local counter is assigned to Notifications + + public ORanFaultNotificationListener(@NonNull NetconfBindingAccessor netconfAccessor, + @NonNull VESCollectorService vesCollectorService, @NonNull FaultService faultService, + @NonNull WebsocketManagerService websocketManagerService, @NonNull DataProvider databaseService) { + this.netconfAccessor = Objects.requireNonNull(netconfAccessor); + this.vesCollectorService = Objects.requireNonNull(vesCollectorService); + this.faultService = Objects.requireNonNull(faultService); + this.websocketManagerService = Objects.requireNonNull(websocketManagerService); + this.databaseService = Objects.requireNonNull(databaseService); + + this.mapper = new ORanFaultToVESFaultMapper(netconfAccessor.getNodeId(), vesCollectorService, + AlarmNotif.class.getSimpleName()); + this.counter = 0; + } + + /** + * Gets the mfg name, mode-name and Uuid of the root component (Ex: Chassis.) + * In cases where there are multiple root components i.e., components with no parent, + * the Uuid of the last occurred component from the componentList will be considered. + * Till now we haven't seen Uuid set for root components, so not an issue for now. + * @param componentList + */ + public void setComponentList(Collection componentList) { + for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { + mapper.setMfgName(component.getMfgName()); + mapper.setUuid(component.getUuid()!=null?component.getUuid().getValue():netconfAccessor.getNodeId().getValue()); + mapper.setModelName(component.getModelName()); + } + } + + @Override + public void onAlarmNotif(AlarmNotif notification) { + + LOG.debug("onAlarmNotif {}", notification.getClass().getSimpleName()); + counter++; + + // Send devicemanager specific notification for database and ODLUX + Instant eventTimeInstant = ORanToInternalDataModel.getInstantTime(notification.getEventTime()); + faultService.faultNotification( + ORanToInternalDataModel.getFaultLog(notification, netconfAccessor.getNodeId(), counter)); + // Send model specific notification to WebSocketManager + websocketManagerService.sendNotification(notification, netconfAccessor.getNodeId(), AlarmNotif.QNAME); + + try { + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(notification, eventTimeInstant, counter); + VESFaultFieldsPOJO body = mapper.mapFaultFields(notification); + VESMessage vesMsg = vesCollectorService.generateVESEvent(header, body); + vesCollectorService.publishVESMessage(vesMsg); + LOG.info("VES Message is {}",vesMsg.getMessage()); + writeToEventLog(vesMsg.getMessage(), eventTimeInstant, AlarmNotif.QNAME.toString(), counter); + } + } catch (JsonProcessingException | DateTimeParseException e) { + LOG.debug("Can not convert event into VES message {}", notification, e); + } + } + + private void writeToEventLog(String data, Instant instant, String notificationName, + int sequenceNo) { + EventlogBuilder eventlogBuilder = new EventlogBuilder(); + + eventlogBuilder.setObjectId("Device"); + eventlogBuilder.setCounter(sequenceNo); + eventlogBuilder.setAttributeName(notificationName); + eventlogBuilder.setNodeId(netconfAccessor.getNodeId().getValue()); + String eventLogMsgLvl = vesCollectorService.getConfig().getEventLogMsgDetail(); + if (eventLogMsgLvl.equalsIgnoreCase("SHORT")) { + data = getShortEventLogMessage(data); + } else if (eventLogMsgLvl.equalsIgnoreCase("MEDIUM")) { + data = getMediumEventLogMessage(data); + } else if (eventLogMsgLvl.equalsIgnoreCase("LONG")) { + // do nothing, data already contains long message + } else { // Unknown value, default to "SHORT" + data = getShortEventLogMessage(data); + } + eventlogBuilder.setNewValue(data); + eventlogBuilder.setSourceType(SourceType.Netconf); + + Date eventDate = Date.from(instant); + eventlogBuilder.setTimestamp(new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp(eventDate))); + + databaseService.writeEventLog(eventlogBuilder.build()); + } + + private String getShortEventLogMessage(String data) { + try { + JSONObject jsonObj = new JSONObject(data); + String domain = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("domain"); + String eventId = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("eventId"); + return "domain:" + domain + " eventId:" + eventId; + } catch (JSONException e) { + LOG.debug("{}", e); + return "Invalid message received"; + } + } + + private String getMediumEventLogMessage(String data) { + try { + JSONObject jsonObj = new JSONObject(data); + return jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").toString(); + } catch (JSONException e) { + LOG.debug("{}", e); + return "Invalid message received"; + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultToVESFaultMapper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultToVESFaultMapper.java new file mode 100644 index 000000000..f5873df96 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanFaultToVESFaultMapper.java @@ -0,0 +1,164 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.time.Instant; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//@formatter:off +/* + * Maps ORAN Fault fields to VES fault domain fields and VES commonEventHeader fields + * + * + * VES Fields Mapping + * ---------- ------- + * domain "fault" + * eventId "nt:network-topology/nt:topology/nt:node/nt:node-id" + * eventName "nt:network-topology/nt:topology/nt:node/nt:node-id" + * eventType "O-RAN-RU-Fault" + * lastEpochMicrosec TimeStamp represented by field in NetConf notification header in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. + * nfcNamingCode always "" + * nfNamingCode always "" + * nfVendorName /ietf-hardware:hardware/component[not(parent)][1]/mfg-name + * priority "Normal" + * reportingEntityId The OAM-Controller identifier with in the SMO - e.g. the fully qualified domain name or IP-Address. + * reportingEntityName as configured by helm charts for the OpenDaylight cluster name ?????? + * sequence As per NetConf notification increasing sequence number as unsigned integer 32 bits. The value is reused in the eventId field. + * sourceId Value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/uuid or 'nt:network-topology/nt:topology/nt:node/nt:node-id' if ietf component not found. + * sourceName "nt:network-topology/nt:topology/nt:node/nt:node-id" + * startEpochMicrosec Current OAM-Controller Node timestamp in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. + * timeZoneOffset Static text: "+00:00" + * version "4.1" + * vesEventListenerVersion "7.2.1" + * + * + * alarmAdditionalInformation + * alarmCondition Value of "o-ran-fm:alarm-notif/fault-id" + * alarmInterfaceA Value of "o-ran-fm:alarm-notif/fault-source" + * eventCategory Static text "O-RU failure" + * eventSeverity Value of "o-ran-fm:alarm-notif/fault-severity". But if "o-ran-fm:alarm-notif/is-cleared" then "NORMAL" + * eventSourceType The value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/model-name or "O-RU" if not found. + * faultFieldsVersion "4.0" + * specificProblem A mapping of the fault-id to its description according to O-RAN OpenFronthaul specification. + * vfStatus "Active" + * + */ +//@formatter:on + +public class ORanFaultToVESFaultMapper { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + private static final String VES_EVENT_DOMAIN = "fault"; + private static final String VES_EVENTTYPE = "ORAN_Fault"; + private static final String VES_EVENT_PRIORITY = "Normal"; + private static final String VES_EVENT_CATEGORY = "O-RU Failure"; + private static final String VES_FAULT_FIELDS_VERSION = "4.0"; + private static final String VES_FAULT_FIELDS_VFSTATUS = "Active"; //virtual function status + + private final VESCollectorService vesProvider; + private final String notifName; // Name + private final String nodeIdString; // Sourcename + private String mfgName; + private String uuid; + private String modelName; + + public ORanFaultToVESFaultMapper(NodeId nodeId, VESCollectorService vesCollectorService, + String notifName) { + this.nodeIdString = nodeId.getValue(); + this.vesProvider = vesCollectorService; + this.notifName = notifName; + } + + public void setMfgName(String mfgName) { + this.mfgName= mfgName; + } + + private String getMfgName() { + return mfgName; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + private String getUuid() { + return uuid; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + + private String getModelName() { + return modelName; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(AlarmNotif notification, Instant eventTime, int sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventName(notifName); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + String eventId; + + eventId = notifName + "-" + Long.toUnsignedString(sequenceNo); + + vesCEH.setEventId(eventId); + vesCEH.setStartEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setNfVendorName(getMfgName()); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId(getUuid()); + vesCEH.setSourceName(nodeIdString); + + return vesCEH; + } + + public VESFaultFieldsPOJO mapFaultFields(AlarmNotif alarmNotif) { + VESFaultFieldsPOJO vesFaultFields = new VESFaultFieldsPOJO(); + + vesFaultFields.setAlarmCondition(alarmNotif.getFaultId().toString()); + vesFaultFields.setAlarmInterfaceA(alarmNotif.getFaultSource()); + vesFaultFields.setEventCategory(VES_EVENT_CATEGORY); + if (alarmNotif.getIsCleared()) { + vesFaultFields.setEventSeverity("NORMAL"); + } else { + vesFaultFields.setEventSeverity(alarmNotif.getFaultSeverity().getName()); + } + vesFaultFields.setEventSourceType(getModelName()); + vesFaultFields.setFaultFieldsVersion(VES_FAULT_FIELDS_VERSION); + vesFaultFields.setSpecificProblem(alarmNotif.getFaultText()); + vesFaultFields.setVfStatus(VES_FAULT_FIELDS_VFSTATUS); + + return vesFaultFields; + } + +} diff --git a/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 b/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 new file mode 100644 index 000000000..e16df1d1c --- /dev/null +++ b/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 @@ -0,0 +1,278 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.common.YangHelper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.Hardware; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfirmedCommit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionEnd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionStart; +import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.NetconfCallhomeServer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.AllowedDevices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev201015.netconf.callhome.server.allowed.devices.Device; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.opendaylight.yangtools.yang.common.QName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanNetworkElement implements NetworkElement { + + private static final Logger LOG = LoggerFactory.getLogger(ORanNetworkElement.class); + + public static final QName ONAP_SYSTEM = + org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.$YangModuleInfoImpl.getInstance().getName(); + private static final InstanceIdentifier SYSTEM1_IID = InstanceIdentifier + .builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.system.rev140806.System.class) + .augmentation(System1.class).build(); + + private final NetconfBindingAccessor netconfAccessor; + private final Optional netconfAccessorOpt; + + private final Optional netconfDomAccessor; + private final DataProvider databaseService; + private final ORanRegistrationToVESpnfRegistrationMapper mapper; + private final VESCollectorService vesCollectorService; + + private ListenerRegistration oRanListenerRegistrationResult; + //private @NonNull final ORanChangeNotificationListener oRanListener; + private ListenerRegistration oRanFaultListenerRegistrationResult; + private @NonNull final ORanFaultNotificationListener oRanFaultListener; + + //ORanNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { + ORanNetworkElement(NetconfAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { + LOG.info("Create {}", ORanNetworkElement.class.getSimpleName()); + // Read parameters + this.netconfAccessorOpt = netconfAccess.getNetconfBindingAccessor(); + this.netconfAccessor = netconfAccessorOpt.get(); + this.netconfDomAccessor = netconfAccess.getNetconfDomAccessor(); + // Get services + this.databaseService = serviceProvider.getDataProvider(); + this.vesCollectorService = serviceProvider.getVESCollectorService(); + + this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService); + + // Register callbacks + this.oRanListenerRegistrationResult = null; + //this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, serviceProvider); + + this.oRanFaultListenerRegistrationResult = null; + this.oRanFaultListener = new ORanFaultNotificationListener(netconfAccessor, vesCollectorService, + serviceProvider.getFaultService(), serviceProvider.getWebsocketService(), databaseService); + + } + + private Collection initialReadFromNetworkElement() { + Collection componentList; + Hardware hardware = readHardware(); + if (hardware != null) { + componentList = YangHelper.getCollection(hardware.nonnullComponent()); + List inventoryList = + ORanToInternalDataModel.getInventoryList(netconfAccessor.getNodeId(), componentList); + databaseService.writeInventory(netconfAccessor.getNodeId().getValue(), inventoryList); + } else { + componentList = Collections.emptyList(); + } + + Optional oGuicutthrough = ORanToInternalDataModel.getGuicutthrough(getOnapSystemData()); + if (oGuicutthrough.isPresent()) { + databaseService.writeGuiCutThroughData(oGuicutthrough.get(), netconfAccessor.getNodeId().getValue()); + } + return componentList; + } + + @Override + public NetworkElementDeviceType getDeviceType() { + return NetworkElementDeviceType.ORAN; + } + + @Override + public void register() { + // Read data from device + Collection componentList = initialReadFromNetworkElement(); + oRanFaultListener.setComponentList(componentList); + // Publish the mountpoint to VES if enabled + publishMountpointToVES(componentList); + // Register call back class for receiving notifications + //this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener); + this.oRanFaultListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanFaultListener); + // Register notifications stream + /*if (netconfAccessor.isNotificationsRFC5277Supported()) { + netconfAccessor.registerNotificationsStream(); + }*/ + + QName[] notifications = { NetconfConfigChange.QNAME, NetconfConfirmedCommit.QNAME, + NetconfSessionStart.QNAME, NetconfSessionEnd.QNAME, NetconfCapabilityChange.QNAME }; + //netconfDomAccessor.get().doRegisterNotificationListener(new ORanDOMChangeNotificationListener(netconfDomAccessor.get(), databaseService), notifications); + // Output notification streams to LOG + Map streams = netconfDomAccessor.get().getNotificationStreamsAsMap(); + LOG.info("Available notifications streams: {}", streams); + // Register to default stream + netconfDomAccessor.get().invokeCreateSubscription(); + } + + @Override + public void deregister() { + if (oRanListenerRegistrationResult != null) { + this.oRanListenerRegistrationResult.close(); + } + if (oRanFaultListenerRegistrationResult != null) { + this.oRanFaultListenerRegistrationResult.close(); + } ; + databaseService.clearGuiCutThroughEntriesOfNode(getMountpointId()); + } + + @Override + public NodeId getNodeId() { + return netconfAccessor.getNodeId(); + } + + @Override + public Optional getService(Class clazz) { + return Optional.empty(); + } + + @Override + public void warmstart() {} + + @Override + public Optional getAcessor() { + return Optional.of(netconfAccessor); + } + + // Private functions + + private String getMountpointId() { + return getNodeId().getValue(); + } + + // Read from device + /** + * Read system data with GUI cut through information from device if ONAP_SYSTEM YANG is supported. + * + * @return System1 data with GUI cut through information or null if not available. + */ + private @Nullable System1 getOnapSystemData() { + LOG.info("Get System1 for class {} from mountpoint {}", netconfAccessor.getNodeId().getValue()); + Capabilities x = netconfAccessor.getCapabilites(); + LOG.info("Capabilites: {}", x); + if (x.isSupportingNamespace(ONAP_SYSTEM)) { + @Nullable + System1 res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), + LogicalDatastoreType.OPERATIONAL, SYSTEM1_IID); + LOG.debug("Result of System1 = {}", res); + return res; + } else { + LOG.debug("No GUI cut through support"); + return null; + } + } + + private Hardware readHardware() { + final Class clazzPac = Hardware.class; + LOG.info("DBRead Get hardware for class {} from mountpoint {}", clazzPac.getSimpleName(), + netconfAccessor.getNodeId().getValue()); + InstanceIdentifier hardwareIID = InstanceIdentifier.builder(clazzPac).build(); + Hardware res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), + LogicalDatastoreType.OPERATIONAL, hardwareIID); + LOG.debug("Result of Hardware = {}", res); + return res; + } + + // VES related + private void publishMountpointToVES(Collection componentList) { + + LOG.debug("In publishMountpointToVES()"); + + /* + * 1. Check if this device is in the list of allowed-devices. 2. If device + * exists in allowed-devices, then create VES pnfRegistration event and publish + * to VES + */ + if (inAllowedDevices(getMountpointId())) { + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { + // Just get one component. At the moment we don't care which one. Also since + // there is only one management address, we assume there will be only one + // chassis. + // If the device supports subtended configuration then it is assumed that the + // Chassis containing the management interface will be the root component and + // there will be only one root. + /*VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(component); + VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(component); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + LOG.warn("Error while serializing VES Event to String ", e); + }*/ + } + } + } + } + + private boolean inAllowedDevices(String mountpointName) { + final InstanceIdentifier ALL_DEVICES = + InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class); + + AllowedDevices allowedDevices = netconfAccessor.getTransactionUtils().readData( + netconfAccessor.getControllerBindingDataBroker(), LogicalDatastoreType.CONFIGURATION, ALL_DEVICES); + + if (allowedDevices != null) { + Collection deviceList = YangHelper.getCollection(allowedDevices.nonnullDevice()); + for (Device device : deviceList) { + LOG.info("Device in allowed-devices is - {}", device.getUniqueId()); + if (device.getUniqueId().equals(netconfAccessor.getNodeId().getValue())) { + LOG.info("Mountpoint is part of allowed-devices list"); + return true; + } + } + } + + LOG.info("Mountpoint {} is not part of allowed-devices list", mountpointName); + return false; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanNotifToVESEventAssembly.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanNotifToVESEventAssembly.java new file mode 100644 index 000000000..6e31ffb6f --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanNotifToVESEventAssembly.java @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanNotifToVESEventAssembly { + + private static final Logger log = LoggerFactory.getLogger(ORanNotifToVESEventAssembly.class); + private static final String VES_EVENT_DOMAIN = "notification"; + private static final String VES_EVENTTYPE = "ORAN_notification"; + private static final String VES_EVENT_PRIORITY = "Normal"; + private NetconfBindingAccessor netconfAccessor; + private VESCollectorService vesProvider; + + public ORanNotifToVESEventAssembly(NetconfBindingAccessor netconfAccessor, VESCollectorService vesProvider) { + this.netconfAccessor = netconfAccessor; + this.vesProvider = vesProvider; + } + + // VES CommonEventHeader fields + public VESCommonEventHeaderPOJO createVESCommonEventHeader(Instant time, String notificationTypeName, + long sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventName(notificationTypeName); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + String eventId; + + eventId = notificationTypeName + "-" + Long.toUnsignedString(sequenceNo); + + vesCEH.setEventId(eventId); + vesCEH.setStartEpochMicrosec(time.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 1000); + vesCEH.setNfVendorName("ORAN"); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId("ORAN"); + vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); + return vesCEH; + } + + // Notification fields + public VESNotificationFieldsPOJO createVESNotificationFields(HashMap xPathFields, + String notificationTypeName) { + VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO(); + + vesNotifFields.setChangeType(notificationTypeName); + vesNotifFields.setChangeIdentifier(netconfAccessor.getNodeId().getValue()); + + StringBuffer buf = new StringBuffer(); + Iterator> it = xPathFields.entrySet().iterator(); + while (it.hasNext()) { + Entry pair = it.next(); + buf.append("\n" + pair.getKey() + " = " + pair.getValue()); + } + log.info("Resultlist({}):{}", xPathFields.size(), buf.toString()); + + ArrayList> arrayOfNamedHashMap = new ArrayList>(); + HashMap namedHashMap = new HashMap(); + namedHashMap.put("hashMap", xPathFields); + namedHashMap.put("name", notificationTypeName); + arrayOfNamedHashMap.add(namedHashMap); + vesNotifFields.setArrayOfNamedHashMap(arrayOfNamedHashMap); + return vesNotifFields; + + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanRegistrationToVESpnfRegistrationMapper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanRegistrationToVESpnfRegistrationMapper.java new file mode 100644 index 000000000..206abb5d7 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanRegistrationToVESpnfRegistrationMapper.java @@ -0,0 +1,114 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.time.Instant; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom.ORanDMDOMUtility; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom.ORanDeviceManagerQNames; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanRegistrationToVESpnfRegistrationMapper { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + //CommonEventHeader fields + private static final String VES_EVENT_DOMAIN = "pnfRegistration"; + private static final String VES_EVENTTYPE = "NetConf Callhome Registration"; + private static final String VES_EVENT_PRIORITY = "Normal"; + + private final VESCollectorService vesProvider; + private final NetconfAccessor netconfAccessor; + + private Integer sequenceNo; + + + public ORanRegistrationToVESpnfRegistrationMapper(NetconfAccessor netconfAccessor, + VESCollectorService vesCollectorService) { + this.netconfAccessor = netconfAccessor; + this.vesProvider = vesCollectorService; + + this.sequenceNo = 0; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(MapEntryNode component) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventId(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventName(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + vesCEH.setStartEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setNfVendorName( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME)); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo++); + vesCEH.setSourceId( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_UUID) != null + ? ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_UUID) + : netconfAccessor.getNodeId().getValue()); + vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); + + return vesCEH; + } + + public VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields(MapEntryNode component) { + VESPNFRegistrationFieldsPOJO vesPnfFields = new VESPNFRegistrationFieldsPOJO(); + vesPnfFields.setModelNumber( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME)); + vesPnfFields + .setOamV4IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv4Address() != null + ? netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv4Address().getValue() + : null); + vesPnfFields + .setOamV6IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv6Address() != null + ? netconfAccessor.getNetconfNode().getHost().getIpAddress().getIpv6Address().getValue() + : null); + vesPnfFields.setSerialNumber( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_SER_NUM)); + vesPnfFields.setVendorName( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME)); + vesPnfFields.setSoftwareVersion( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_SW_REV)); + vesPnfFields.setUnitType( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_ALIAS)); + vesPnfFields.setUnitFamily( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CLASS)); + vesPnfFields + .setManufactureDate( + ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_DATE) != null + ? ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_DATE) + : "Unknown"); + //vesPnfFields.setLastServiceDate(component.getLastChange()); + + return vesPnfFields; + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanToInternalDataModel.java new file mode 100644 index 000000000..2469e46b7 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanToInternalDataModel.java @@ -0,0 +1,276 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.Alarm.FaultSeverity; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Convert data to data-provider model and perform consistency checks.
+ * Component list characteristics:
+ *
    + *
  • component list is a flat list tree structure specified + *
  • via "component.getParent()": + *
      + *
    • If null we have a root element + *
    • if not null it is a child element with generated child level
      + *
    + *
+ * Example of List:
+ * + * + */ +public class ORanToInternalDataModel { + + private static final Logger log = LoggerFactory.getLogger(ORanToInternalDataModel.class); + + public static List getInventoryList(NodeId nodeId, Collection componentList) { + + List inventoryResultList = new ArrayList(); + for (Component component : getRootComponents(componentList)) { + inventoryResultList = recurseGetInventory(nodeId, component, componentList, 0, inventoryResultList); + } + // Verify if result is complete + if (componentList.size() != inventoryResultList.size()) { + log.warn( + "Not all data were written to the Inventory. Potential entries with missing " + + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", + nodeId.getValue(), componentList.size(), inventoryResultList.size()); + } + return inventoryResultList; + } + + private static List recurseGetInventory(NodeId nodeId, Component component, + Collection componentList, int treeLevel, List inventoryResultList) { + + //Add element to list, if conversion successfull + Optional oInventory = getInternalEquipment(nodeId, component, treeLevel); + if (oInventory.isPresent()) { + inventoryResultList.add(oInventory.get()); + } + //Walk trough list of child keys and add to list + for (String childUuid : CodeHelpers.nonnull(component.getContainsChild())) { + for (Component c : getComponentsByName(childUuid, componentList)) { + inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList); + } + } + return inventoryResultList; + } + + public static List getRootComponents(Collection componentList) { + List resultList = new ArrayList<>(); + for (Component c : componentList) { + if (c.getParent() == null) { // Root elements do not have a parent + resultList.add(c); + } + } + return resultList; + } + + private static List getComponentsByName(String name, Collection componentList) { + List resultList = new ArrayList<>(); + for (Component c : componentList) { + if (name.equals(c.getName())) { // <-- Component list is flat search for child's of name + resultList.add(c); + } + } + return resultList; + } + + /** + * Convert equipment into Inventory. Decide if inventory can by created from content or not. Public for test case. + * + * @param nodeId of node (Similar to mountpointId) + * @param component to handle + * @param treeLevel of components + * @return Inventory if possible to be created. + */ + public static Optional getInternalEquipment(NodeId nodeId, Component component, int treeLevel) { + + // Make sure that expected data are not null + Objects.requireNonNull(nodeId); + Objects.requireNonNull(component); + + // Read manadatory data + + @Nullable + String nodeIdString = nodeId.getValue(); + @Nullable + String uuid = component.getName(); + @Nullable + String idParent = component.getParent(); + @Nullable + String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht + + // do consistency check if all mandatory parameters are there + if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) { + + // Build output data + + InventoryBuilder inventoryBuilder = new InventoryBuilder(); + + // General assumed as mandatory + inventoryBuilder.setNodeId(nodeIdString); + inventoryBuilder.setUuid(uuid); + inventoryBuilder.setParentUuid(uuidParent); + inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); + + // -- String list with ids of holders (optional) + inventoryBuilder.setContainedHolder(CodeHelpers.nonnull(component.getContainsChild())); + + // -- Manufacturer related things (optional) + @Nullable + String mfgName = component.getMfgName(); + inventoryBuilder.setManufacturerName(mfgName); + inventoryBuilder.setManufacturerIdentifier(mfgName); + + // Equipment type (optional) + inventoryBuilder.setDescription(component.getDescription()); + inventoryBuilder.setModelIdentifier(component.getModelName()); + @Nullable + Class xmlClass = component.getXmlClass(); + if (xmlClass != null) { + inventoryBuilder.setPartTypeId(xmlClass.getName()); + } + inventoryBuilder.setTypeName(component.getName()); + inventoryBuilder.setVersion(component.getHardwareRev()); + + // Equipment instance (optional) + @Nullable + DateAndTime mfgDate = component.getMfgDate(); + if (mfgDate != null) { + inventoryBuilder.setDate(mfgDate.getValue()); + } + inventoryBuilder.setSerial(component.getSerialNum()); + + return Optional.of(inventoryBuilder.build()); + } + return Optional.empty(); + } + + /** + * If system data is available convert + * + * @param sys + * @return + */ + public static Optional getGuicutthrough(@Nullable System1 sys) { + if (sys != null) { + String name = sys.getName(); + @Nullable + Uri uri = sys.getWebUi(); + if (uri != null) { + GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder(); + if (name != null) { + gcBuilder.setName(name); + } + gcBuilder.setWeburi(uri.getValue()); + return Optional.of(gcBuilder.build()); + } + log.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device"); + } + log.warn("Retrieving augmented System details failed. Gui cut through information not available"); + return Optional.empty(); + } + + /** + * Convert netconf time into Instant + * + * @param eventTime with netconf time + * @return Instant with converted time. If not convertable provide Instant.Min + */ + public static Instant getInstantTime(@Nullable DateAndTime eventTime) { + return eventTime != null ? Instant.parse(eventTime.getValue()) : Instant.MIN; + } + + /** + * Convert fault notification into data-provider FaultLogEntity + * + * @param notification with O-RAN notification + * @param nodeId of node to handle + * @param counter to be integrated into data + * @return FaultlogEntity with data + */ + public static FaultlogEntity getFaultLog(AlarmNotif notification, NodeId nodeId, Integer counter) { + FaultlogBuilder faultAlarm = new FaultlogBuilder(); + faultAlarm.setNodeId(nodeId.getValue()); + faultAlarm.setObjectId(notification.getFaultSource()); + faultAlarm.setProblem(notification.getFaultText()); + faultAlarm.setSeverity(getSeverityType(notification.getFaultSeverity(), notification.getIsCleared())); + faultAlarm.setCounter(counter); + faultAlarm.setId(String.valueOf(notification.getFaultId())); + faultAlarm.setSourceType(SourceType.Netconf); + faultAlarm.setTimestamp(notification.getEventTime()); + return faultAlarm.build(); + } + + /** + * Convert O-RAN specific severity into data-provider severity + * + * @param faultSeverity O-RAN severity + * @param isCleared clear indicator + * @return data-provider severity type + * @throws IllegalArgumentException if conversion not possible. + */ + public static SeverityType getSeverityType(@Nullable FaultSeverity faultSeverity, @Nullable Boolean isCleared) + throws IllegalArgumentException { + if (isCleared != null && isCleared) { + return SeverityType.NonAlarmed; + } + if (faultSeverity != null) { + switch (faultSeverity) { + case CRITICAL: + return SeverityType.Critical; + case MAJOR: + return SeverityType.Major; + case MINOR: + return SeverityType.Minor; + case WARNING: + return SeverityType.Warning; + } + } + throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared + + " faultSeverity=" + faultSeverity); + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/DOMNotificationToXPath.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/DOMNotificationToXPath.java new file mode 100644 index 000000000..64fb9b857 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/DOMNotificationToXPath.java @@ -0,0 +1,235 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.time.Instant; +import java.util.Collection; +import java.util.HashMap; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.VerifyException; + +public class DOMNotificationToXPath { + private static final Logger LOG = LoggerFactory.getLogger(DOMNotificationToXPath.class); + + public HashMap convertDomNotifToXPath(@NonNull DOMNotification domNotification) { + @NonNull + ContainerNode notifContainer = domNotification.getBody(); + HashMap xPathData = new HashMap(); + + Collection data = notifContainer.body(); + for (DataContainerChild data1 : data) { + String namePath = ""; + recurseDOMData(notifContainer, data1, notifContainer, xPathData, namePath); + } + LOG.debug("XPath Data = {}", xPathData); + return xPathData; + + } + + private void recurseDOMData(@NonNull ContainerNode notifContainer, DataContainerChild domData, DataContainerNode cn, + HashMap result, String namePath) { + PathArgument pa1 = domData.getIdentifier(); + namePath += "/" + pa1.getNodeType().getLocalName(); + if (domData.getClass().getSimpleName().equals("ImmutableContainerNode")) { + try { + ContainerNode cn1 = (ContainerNode) cn.getChildByArg(pa1); + for (DataContainerChild data1 : cn1.body()) { + recurseDOMData(notifContainer, data1, cn1, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (domData.getClass().getSimpleName().equals("ImmutableChoiceNode")) { + try { + ChoiceNode cn1 = (ChoiceNode) cn.getChildByArg(pa1); + for (DataContainerChild data1 : cn1.body()) { + // recurseChoiceData(data1, cn1, namePath); + recurseDOMData(notifContainer, data1, cn1, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (domData.getClass().getSimpleName().equals("ImmutableUnkeyedListNode")) { + try { + UnkeyedListNode cn1 = (UnkeyedListNode) cn.getChildByArg(pa1); + for (UnkeyedListEntryNode data1 : cn1.body()) { + recurseUnkeyedListEntryNodeData(data1, cn1, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (domData.getClass().getSimpleName().equals("ImmutableMapNode")) { + try { + MapNode cn1 = (MapNode) cn.getChildByArg(pa1); + for (MapEntryNode data1 : cn1.body()) { + recurseMapEntryNodeData(notifContainer, data1, cn1, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (domData.getClass().getSimpleName().equals("ImmutableLeafSetNode")) { + try { + LeafSetNode cn1 = (LeafSetNode) cn.getChildByArg(pa1); + for (LeafSetEntryNode data1 : cn1.body()) { + recurseLeafSetEntryNodeData(data1, cn1, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (domData.getClass().getSimpleName().equals("ImmutableLeafNode")) { + recurseLeafNode(domData, result, namePath); + } + } + + private void recurseLeafSetEntryNodeData(LeafSetEntryNode data, LeafSetNode cn1, + HashMap result, String namePath) { + PathArgument pa1 = data.getIdentifier(); + namePath += "/" + pa1.getNodeType().getLocalName(); + + if (data.getClass().getSimpleName().equals("ImmutableLeafSetEntryNode")) { + LOG.debug("{}={}", namePath, data.body()); + result.put(namePath, data.body().toString()); + } + } + + private void recurseMapEntryNodeData(@NonNull ContainerNode notifContainer, MapEntryNode data, MapNode cn1, + HashMap result, String namePath) { + PathArgument pa1 = data.getIdentifier(); + NodeIdentifierWithPredicates ni = data.getIdentifier(); + + for (QName qn : ni.keySet()) { + namePath += "/" + ni.getValue(qn); + } + + if (data.getClass().getSimpleName().equals("ImmutableMapEntryNode")) { + for (DataContainerChild data1 : data.body()) { + if (data1.getClass().getSimpleName().equals("ImmutableLeafSetNode")) { + try { + LeafSetNode cn2 = (LeafSetNode) data.getChildByArg(data1.getIdentifier()); + for (LeafSetEntryNode data2 : cn2.body()) { + recurseLeafSetEntryNodeData(data2, cn2, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", data1.getIdentifier()); + } + } else { + recurseLeafNode(data1, result, namePath); + } + } + } + + if (data.getClass().getSimpleName().equals("ImmutableLeafSetNode")) { + try { + LeafSetNode cn2 = (LeafSetNode) notifContainer.getChildByArg(pa1); + for (LeafSetEntryNode data1 : cn2.body()) { + recurseLeafSetEntryNodeData(data1, cn2, result, namePath); + } + } catch (VerifyException ve) { + LOG.debug("{} does not exist", pa1); + } + } + + if (data.getClass().getSimpleName().equals("ImmutableLeafNode")) { + LOG.debug("{}={}", namePath, data.body()); + result.put(namePath, data.body().toString()); + } + } + + private void recurseUnkeyedListEntryNodeData(UnkeyedListEntryNode data, UnkeyedListNode cn1, + HashMap result, String namePath) { + PathArgument pa1 = data.getIdentifier(); + namePath += "/" + pa1.getNodeType().getLocalName(); + + if (data.getClass().getSimpleName().equals("ImmutableUnkeyedListEntryNode")) { + for (DataContainerChild data1 : data.body()) { + recurseLeafNode(data1, result, namePath); + } + } + + if (data.getClass().getSimpleName().equals("ImmutableLeafNode")) { + LOG.debug("{}={}", namePath, data.body()); + result.put(namePath, data.body().toString()); + } + } + + public void recurseLeafNode(DataContainerChild data, HashMap result, String namePath) { + PathArgument pa1 = data.getIdentifier(); + if (!(data.getClass().getSimpleName().equals("ImmutableAugmentationNode"))) + namePath += "/" + pa1.getNodeType().getLocalName(); + if (data.getClass().getSimpleName().equals("ImmutableLeafNode")) { + LOG.debug("{}={}", namePath, data.body()); + result.put(namePath, data.body().toString()); + } + } + + public void recurseChoiceData(HashMap result, DataContainerChild data, ChoiceNode cn, + String namePath) { + PathArgument pa1 = data.getIdentifier(); + namePath += "/" + pa1.getNodeType().getLocalName(); + // NodeIdentifier nodeId = new NodeIdentifier(pa1.getNodeType()); + if (data.getClass().getSimpleName().equals("ImmutableLeafNode")) { + LOG.debug("{}={}", namePath, data.body()); + result.put(namePath, data.body().toString()); + } + } + + public Instant getTime(@NonNull DOMNotification domNotification) { + @NonNull + Instant eventTime; + if (domNotification instanceof DOMEvent) { + eventTime = ((DOMEvent) domNotification).getEventInstant(); + LOG.info("Event time {}", eventTime); + } else { + eventTime = Instant.now(); + LOG.info("Defaulting to actual time of processing the notification - {}", eventTime); + } + return eventTime; + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDMDOMUtility.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDMDOMUtility.java new file mode 100644 index 000000000..947677bb6 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDMDOMUtility.java @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.VerifyException; + +public class ORanDMDOMUtility { + public static final Logger LOG = LoggerFactory.getLogger(ORanDMDOMUtility.class); + + public static String getKeyValue(MapEntryNode componentEntry) { + NodeIdentifierWithPredicates componentKey = componentEntry.getIdentifier(); // list key + return (String) componentKey.getValue(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_KEY); + } + + public static String getLeafValue(DataContainerNode componentEntry, QName leafQName) { + NodeIdentifier leafNodeIdentifier = new NodeIdentifier(leafQName); + try { + LeafNode optLeafNode = (LeafNode) componentEntry.getChildByArg(leafNodeIdentifier); + if (optLeafNode.body() instanceof QName) { + LOG.debug("Leaf is of type QName"); + } + return optLeafNode.body().toString(); + } catch (VerifyException ve) { + LOG.debug("Leaf with QName {} not found", leafQName.toString()); + return null; + } + } + + public static List getLeafListValue(DataContainerNode componentEntry, QName leafListQName) { + List containsChildList = new ArrayList(); + try { + DataContainerChild childSet = componentEntry.getChildByArg(new NodeIdentifier(leafListQName)); + Collection childEntry = (Collection) childSet.body(); + Iterator childEntryItr = childEntry.iterator(); + while (childEntryItr.hasNext()) { + LeafSetEntryNode childEntryNode = (LeafSetEntryNode) childEntryItr.next(); + containsChildList.add(childEntryNode.body().toString()); + } + } catch (VerifyException ve) { + LOG.debug("Child for {} does not exist", leafListQName); + } + return containsChildList; + } + + public static Instant getNotificationInstant(DOMNotification notification) { + if (notification instanceof DOMEvent) { + return ((DOMEvent) notification).getEventInstant(); + } else { + return Instant.now(); + } + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMChangeNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMChangeNotificationListener.java new file mode 100644 index 000000000..aa375eff7 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMChangeNotificationListener.java @@ -0,0 +1,150 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.time.Instant; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.mdsal.dom.api.DOMNotificationListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanDOMChangeNotificationListener implements DOMNotificationListener { + + private static final Logger log = LoggerFactory.getLogger(ORanDOMChangeNotificationListener.class); + + private final NetconfDomAccessor netconfDomAccessor; + private final DataProvider databaseService; + private @NonNull VESCollectorService vesCollectorService; + private final DOMNotificationToXPath domNotificationXPath; + private ORanDOMNotifToVESEventAssembly mapper = null; + private static int sequenceNo = 0; + + public ORanDOMChangeNotificationListener(NetconfDomAccessor netconfDomAccessor, + @NonNull VESCollectorService vesCollectorService, DataProvider databaseService) { + this.netconfDomAccessor = netconfDomAccessor; + this.databaseService = databaseService; + this.vesCollectorService = vesCollectorService; + domNotificationXPath = new DOMNotificationToXPath(); + } + + @Override + public void onNotification(@NonNull DOMNotification domNotification) { + if (domNotification.getType() + .equals(Absolute.of(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE))) { + handleNetconfConfigChange(domNotification); + } + } + + private void handleNetconfConfigChange(@NonNull DOMNotification domNotification) { + DateAndTime eventTime; + Instant notificationEventTime = null; + if (domNotification instanceof DOMEvent) { + notificationEventTime = ((DOMEvent) domNotification).getEventInstant(); + eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(notificationEventTime.toString()); + } else { + eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(); + } + + ContainerNode cn = domNotification.getBody(); + + // Process the changed-by child +// ContainerNode changedByContainerNode = (ContainerNode) cn +// .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_CHANGEDBY)); +// ChoiceNode serverOrUserIDVal = (ChoiceNode) changedByContainerNode +// .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_SERVERORUSER)); +// @SuppressWarnings("unused") +// String userIDValue = serverOrUserIDVal +// .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_USERNAME)).body() +// .toString(); +// @SuppressWarnings("unused") +// Integer sessionIDVal = Integer.valueOf(serverOrUserIDVal +// .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_SESSIONID)).body() +// .toString()); +// +// // Process the datastore child +// @SuppressWarnings("unused") +// String datastoreValue = cn +// .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_DATASTORE)).body() +// .toString(); + + // Process the edit child + UnkeyedListNode editList = (UnkeyedListNode) cn + .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_EDITNODE)); + if (editList != null) { + for (int listCnt = 0; listCnt < editList.size(); listCnt++) { + String operationValue = editList.childAt(listCnt) + .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_OPERATION)) + .body().toString(); + String targetValue = editList.childAt(listCnt) + .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_TARGET)) + .body().toString(); + + EventlogEntity eventLogEntity1 = new EventlogBuilder() + .setNodeId(netconfDomAccessor.getNodeId().getValue()).setCounter(sequenceNo++) + .setTimestamp(eventTime).setObjectId(targetValue).setAttributeName("N.A") + .setSourceType(SourceType.Netconf).setNewValue(String.valueOf(operationValue)).build(); + databaseService.writeEventLog(eventLogEntity1); + } + } + + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + if (mapper == null) { + this.mapper = new ORanDOMNotifToVESEventAssembly(netconfDomAccessor, vesCollectorService); + } + VESCommonEventHeaderPOJO header = mapper.createVESCommonEventHeader( + domNotificationXPath.getTime(domNotification), + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE.getLocalName(), + sequenceNo); + VESNotificationFieldsPOJO body = mapper.createVESNotificationFields( + domNotificationXPath.convertDomNotifToXPath(domNotification), + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE.getLocalName()); + log.info("domNotification in XPath format = {}", + domNotificationXPath.convertDomNotifToXPath(domNotification)); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + log.warn("Exception while generating JSON object ", e); + + } + } + + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultNotificationListener.java new file mode 100644 index 000000000..494a01f71 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultNotificationListener.java @@ -0,0 +1,171 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.util.Collection; +import java.util.Objects; +import org.eclipse.jdt.annotation.NonNull; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.mdsal.dom.api.DOMNotificationListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanDOMFaultNotificationListener implements DOMNotificationListener { + + private static final Logger LOG = LoggerFactory.getLogger(ORanDOMFaultNotificationListener.class); + + private final @NonNull NetconfDomAccessor netconfDomAccessor; + private final @NonNull VESCollectorService vesCollectorService; + private final @NonNull ORanDOMFaultToVESFaultMapper mapper; + private final @NonNull FaultService faultService; + private final @NonNull WebsocketManagerService websocketManagerService; + private final @NonNull DataProvider databaseService; + + private Integer counter; //Local counter is assigned to Notifications + + public ORanDOMFaultNotificationListener(@NonNull NetconfDomAccessor netconfDomAccessor, + @NonNull VESCollectorService vesCollectorService, @NonNull FaultService faultService, + @NonNull WebsocketManagerService websocketManagerService, @NonNull DataProvider databaseService) { + this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor); + this.vesCollectorService = Objects.requireNonNull(vesCollectorService); + this.faultService = Objects.requireNonNull(faultService); + this.websocketManagerService = Objects.requireNonNull(websocketManagerService); + this.databaseService = Objects.requireNonNull(databaseService); + + this.mapper = + new ORanDOMFaultToVESFaultMapper(netconfDomAccessor.getNodeId(), vesCollectorService, "AlarmNotif"); + this.counter = 0; + } + + @Override + public void onNotification(@NonNull DOMNotification notification) { + onAlarmNotif(notification); + } + + /** + * Gets the mfg name, mode-name and Uuid of the root component (Ex: Chassis.) In cases where there are multiple root + * components i.e., components with no parent, the Uuid of the last occurred component from the componentList will + * be considered. Till now we haven't seen Uuid set for root components, so not an issue for now. + * + * @param componentList + */ + public void setComponentList(Collection componentList) { + for (MapEntryNode component : ORanDOMToInternalDataModel.getRootComponents(componentList)) { + mapper.setMfgName( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME)); + mapper.setUuid(ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_UUID) != null + ? ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_UUID) + : netconfDomAccessor.getNodeId().getValue()); + mapper.setModelName(ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MODEL_NAME)); + } + } + + public void onAlarmNotif(DOMNotification notification) { + + LOG.debug("onAlarmNotif {}", notification.getClass().getSimpleName()); + counter++; + // Send devicemanager specific notification for database and ODLUX + Instant eventTimeInstant = ORanDMDOMUtility.getNotificationInstant(notification); + faultService.faultNotification( + ORanDOMToInternalDataModel.getFaultLog(notification, netconfDomAccessor.getNodeId(), counter)); + // Send model specific notification to WebSocketManager + websocketManagerService.sendNotification(notification, netconfDomAccessor.getNodeId(), ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF); + + try { + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(notification, eventTimeInstant, counter); + VESFaultFieldsPOJO body = mapper.mapFaultFields(notification); + VESMessage vesMsg = vesCollectorService.generateVESEvent(header, body); + vesCollectorService.publishVESMessage(vesMsg); + LOG.info("VES Message is {}", vesMsg.getMessage()); + writeToEventLog(vesMsg.getMessage(), eventTimeInstant, ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF.getLocalName(), counter); + } + } catch (JsonProcessingException | DateTimeParseException e) { + LOG.debug("Can not convert event into VES message {}", notification, e); + } + } + + private void writeToEventLog(String data, Instant eventTimeInstant, String notificationName, int sequenceNo) { + EventlogBuilder eventlogBuilder = new EventlogBuilder(); + + eventlogBuilder.setObjectId("Device"); + eventlogBuilder.setCounter(sequenceNo); + eventlogBuilder.setAttributeName(notificationName); + eventlogBuilder.setNodeId(netconfDomAccessor.getNodeId().getValue()); + String eventLogMsgLvl = vesCollectorService.getConfig().getEventLogMsgDetail(); + if (eventLogMsgLvl.equalsIgnoreCase("SHORT")) { + data = getShortEventLogMessage(data); + } else if (eventLogMsgLvl.equalsIgnoreCase("MEDIUM")) { + data = getMediumEventLogMessage(data); + } else if (eventLogMsgLvl.equalsIgnoreCase("LONG")) { + // do nothing, data already contains long message + } else { // Unknown value, default to "SHORT" + data = getShortEventLogMessage(data); + } + eventlogBuilder.setNewValue(data); + eventlogBuilder.setSourceType(SourceType.Netconf); + eventlogBuilder.setTimestamp(ORanDOMToInternalDataModel.getDateAndTimeOfInstant(eventTimeInstant)); + + databaseService.writeEventLog(eventlogBuilder.build()); + } + + private String getShortEventLogMessage(String data) { + try { + JSONObject jsonObj = new JSONObject(data); + String domain = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("domain"); + String eventId = jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").getString("eventId"); + return "domain:" + domain + " eventId:" + eventId; + } catch (JSONException e) { + LOG.debug("{}", e); + return "Invalid message received"; + } + } + + private String getMediumEventLogMessage(String data) { + try { + JSONObject jsonObj = new JSONObject(data); + return jsonObj.getJSONObject("event").getJSONObject("commonEventHeader").toString(); + } catch (JSONException e) { + LOG.debug("{}", e); + return "Invalid message received"; + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultToVESFaultMapper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultToVESFaultMapper.java new file mode 100644 index 000000000..b05e83f9a --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMFaultToVESFaultMapper.java @@ -0,0 +1,155 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.time.Instant; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.ORanFaultToVESFaultMapper; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//@formatter:off +/* +* Maps ORAN Fault fields to VES fault domain fields and VES commonEventHeader fields +* +* +* VES Fields Mapping +* ---------- ------- +* domain "fault" +* eventId "nt:network-topology/nt:topology/nt:node/nt:node-id" +* eventName "nt:network-topology/nt:topology/nt:node/nt:node-id" +* eventType "O-RAN-RU-Fault" +* lastEpochMicrosec TimeStamp represented by field in NetConf notification header in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. +* nfcNamingCode always "" +* nfNamingCode always "" +* nfVendorName /ietf-hardware:hardware/component[not(parent)][1]/mfg-name +* priority "Normal" +* reportingEntityId The OAM-Controller identifier with in the SMO - e.g. the fully qualified domain name or IP-Address. +* reportingEntityName as configured by helm charts for the OpenDaylight cluster name ?????? +* sequence As per NetConf notification increasing sequence number as unsigned integer 32 bits. The value is reused in the eventId field. +* sourceId Value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/uuid or 'nt:network-topology/nt:topology/nt:node/nt:node-id' if ietf component not found. +* sourceName "nt:network-topology/nt:topology/nt:node/nt:node-id" +* startEpochMicrosec Current OAM-Controller Node timestamp in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. +* timeZoneOffset Static text: "+00:00" +* version "4.1" +* vesEventListenerVersion "7.2.1" +* +* +* alarmAdditionalInformation +* alarmCondition Value of "o-ran-fm:alarm-notif/fault-id" +* alarmInterfaceA Value of "o-ran-fm:alarm-notif/fault-source" +* eventCategory Static text "O-RU failure" +* eventSeverity Value of "o-ran-fm:alarm-notif/fault-severity". But if "o-ran-fm:alarm-notif/is-cleared" then "NORMAL" +* eventSourceType The value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/model-name or "O-RU" if not found. +* faultFieldsVersion "4.0" +* specificProblem A mapping of the fault-id to its description according to O-RAN OpenFronthaul specification. +* vfStatus "Active" +* +*/ +//@formatter:on + +public class ORanDOMFaultToVESFaultMapper { + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + private static final String VES_EVENT_DOMAIN = "fault"; + private static final String VES_EVENTTYPE = "ORAN_Fault"; + private static final String VES_EVENT_PRIORITY = "Normal"; + private static final String VES_EVENT_CATEGORY = "O-RU Failure"; + private static final String VES_FAULT_FIELDS_VERSION = "4.0"; + private static final String VES_FAULT_FIELDS_VFSTATUS = "Active"; //virtual function status + + private final VESCollectorService vesProvider; + private final String notifName; // Name + private final String nodeIdString; // Sourcename + //Initialized during registration + private String mfgName; + private String uuid; + private String modelName; + + public ORanDOMFaultToVESFaultMapper(NodeId nodeId, VESCollectorService vesCollectorService, String notifName) { + this.nodeIdString = nodeId.getValue(); + this.vesProvider = vesCollectorService; + this.notifName = notifName; + } + + public void setMfgName(String mfgName) { + this.mfgName = mfgName; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(DOMNotification notification, Instant eventTime, + int sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventName(notifName); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + String eventId = notifName + "-" + Long.toUnsignedString(sequenceNo); + + vesCEH.setEventId(eventId); + vesCEH.setStartEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setNfVendorName(mfgName); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId(uuid); + vesCEH.setSourceName(nodeIdString); + + return vesCEH; + } + + public VESFaultFieldsPOJO mapFaultFields(DOMNotification alarmNotif) { + VESFaultFieldsPOJO vesFaultFields = new VESFaultFieldsPOJO(); + ContainerNode cn = alarmNotif.getBody(); + vesFaultFields.setAlarmCondition(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_ID)); + vesFaultFields + .setAlarmInterfaceA(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SOURCE)); + vesFaultFields.setEventCategory(VES_EVENT_CATEGORY); + if (ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_IS_CLEARED).equals("true")) { + vesFaultFields.setEventSeverity("NORMAL"); + } else { + vesFaultFields.setEventSeverity( + ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SEVERITY)); + } + vesFaultFields.setEventSourceType(modelName); + vesFaultFields.setFaultFieldsVersion(VES_FAULT_FIELDS_VERSION); + vesFaultFields + .setSpecificProblem(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_TEXT)); + vesFaultFields.setVfStatus(VES_FAULT_FIELDS_VFSTATUS); + + return vesFaultFields; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNetworkElement.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNetworkElement.java new file mode 100644 index 000000000..64006339d --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNetworkElement.java @@ -0,0 +1,283 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.ORanRegistrationToVESpnfRegistrationMapper; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanDOMNetworkElement implements NetworkElement { + + private static final Logger LOG = LoggerFactory.getLogger(ORanDOMNetworkElement.class); + + private final @NonNull NetconfDomAccessor netconfDomAccessor; + private final @NonNull DataProvider databaseService; + private final @NonNull FaultService faultService; + private final @NonNull NotificationService notificationService; + private final @NonNull ORanDOMChangeNotificationListener oranDomChangeNotificationListener; + private final @NonNull ORanDOMFaultNotificationListener oranDomFaultNotificationListener; + private final @NonNull VESCollectorService vesCollectorService; + private final @NonNull ORanRegistrationToVESpnfRegistrationMapper mapper; + + public ORanDOMNetworkElement(@NonNull NetconfDomAccessor netconfDomAccessor, + @NonNull DeviceManagerServiceProvider serviceProvider) { + LOG.info("Create {}", ORanDOMNetworkElement.class.getSimpleName()); + this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor); + Objects.requireNonNull(serviceProvider); + this.databaseService = serviceProvider.getDataProvider(); + this.vesCollectorService = serviceProvider.getVESCollectorService(); + this.faultService = serviceProvider.getFaultService(); + this.notificationService = serviceProvider.getNotificationService(); + + this.oranDomChangeNotificationListener = + new ORanDOMChangeNotificationListener(netconfDomAccessor, vesCollectorService, databaseService); + + this.oranDomFaultNotificationListener = + new ORanDOMFaultNotificationListener(netconfDomAccessor, vesCollectorService, + serviceProvider.getFaultService(), serviceProvider.getWebsocketService(), databaseService); + + this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfDomAccessor, vesCollectorService); + } + + @Override + public void register() { + Collection componentList = initialReadFromNetworkElement(); + oranDomFaultNotificationListener.setComponentList(componentList); + publishMountpointToVES(componentList); + QName[] notifications = {ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE, + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIRMED_COMMIT, + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_SESSION_START, + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_SESSION_END, + ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CAPABILITY_CHANGE}; + netconfDomAccessor.doRegisterNotificationListener(oranDomChangeNotificationListener, notifications); + QName[] faultNotification = {ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF}; + netconfDomAccessor.doRegisterNotificationListener(oranDomFaultNotificationListener, faultNotification); + // Output notification streams to LOG + @SuppressWarnings("unused") + Map streams = netconfDomAccessor.getNotificationStreamsAsMap(); + // Register to default stream + netconfDomAccessor.invokeCreateSubscription(); + } + + public Collection initialReadFromNetworkElement() { + Collection componentMapEntries = null; + NormalizedNode hwData = readHardware(); + + if (hwData != null) { + ContainerNode hwContainer = (ContainerNode) hwData; + MapNode componentMap = (MapNode) hwContainer + .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST)); + if (componentMap != null) { + componentMapEntries = componentMap.body(); + List inventoryList = + ORanDOMToInternalDataModel.getInventoryList(netconfDomAccessor.getNodeId(), hwData); + databaseService.writeInventory(netconfDomAccessor.getNodeId().getValue(), inventoryList); + } + } else { + componentMapEntries = Collections.emptyList(); + } + + Optional oGuicutthrough = ORanDOMToInternalDataModel.getGuicutthrough(getOnapSystemData()); + if (oGuicutthrough.isPresent()) { + databaseService.writeGuiCutThroughData(oGuicutthrough.get(), netconfDomAccessor.getNodeId().getValue()); + } + return componentMapEntries; + } + + @Override + public void deregister() { + /* + * if (oranDomChangeNotificationListener != null) { + * this.oranDomChangeNotificationListener.close(); } if + * (oRanFaultListenerRegistrationResult != null) { + * this.oRanFaultListenerRegistrationResult.close(); } ; + */ + databaseService.clearGuiCutThroughEntriesOfNode(getMountpointId()); + } + + @Override + public NodeId getNodeId() { + return netconfDomAccessor.getNodeId(); + } + + @Override + public NetworkElementDeviceType getDeviceType() { + return NetworkElementDeviceType.ORAN; + } + + @Override + public Optional getService(Class clazz) { + return Optional.empty(); + } + + @Override + public void warmstart() {} + + @Override + public Optional getAcessor() { + return Optional.of(netconfDomAccessor); + } + + // Private functions + + private String getMountpointId() { + return getNodeId().getValue(); + } + + private NormalizedNode readHardware() { + InstanceIdentifierBuilder hardwareIIDBuilder = + YangInstanceIdentifier.builder().node(ORanDeviceManagerQNames.IETF_HW_CONTAINER); + + Optional oData = + netconfDomAccessor.readDataNode(LogicalDatastoreType.OPERATIONAL, hardwareIIDBuilder.build()); + if (oData.isPresent()) { + return oData.get(); + } + return null; + } + + // Read from device + /** + * Read system data with GUI cut through information from device if ONAP_SYSTEM YANG is supported. + * + * @return NormalizedNode data with GUI cut through information or null if not available. + */ + private @Nullable NormalizedNode getOnapSystemData() { + LOG.info("Get System1 for mountpoint {}", netconfDomAccessor.getNodeId().getValue()); + @NonNull + InstanceIdentifierBuilder ietfSystemIID = + YangInstanceIdentifier.builder().node(ORanDeviceManagerQNames.IETF_SYSTEM_CONTAINER); + @NonNull + AugmentationIdentifier onapSystemIID = YangInstanceIdentifier.AugmentationIdentifier.create( + Sets.newHashSet(ORanDeviceManagerQNames.ONAP_SYSTEM_NAME, ORanDeviceManagerQNames.ONAP_SYSTEM_WEB_UI)); + InstanceIdentifierBuilder augmentedOnapSystem = + YangInstanceIdentifier.builder(ietfSystemIID.build()).node(onapSystemIID); + Capabilities x = netconfDomAccessor.getCapabilites(); + LOG.info("Capabilites: {}", x); + if (x.isSupportingNamespace(ORanDeviceManagerQNames.ONAP_SYSTEM_QNAME)) { + Optional res = + netconfDomAccessor.readDataNode(LogicalDatastoreType.OPERATIONAL, augmentedOnapSystem.build()); + LOG.debug("Result of System1 = {}", res); + return res.isPresent() ? res.get() : null; + } else { + LOG.debug("No GUI cut through support"); + return null; + } + } + + // VES related + private void publishMountpointToVES(Collection componentList) { + /* + * 1. Check if this device is in the list of allowed-devices. 2. If device + * exists in allowed-devices, then create VES pnfRegistration event and publish + * to VES + */ + if (vesCollectorService.getConfig().isVESCollectorEnabled() && inAllowedDevices(getMountpointId())) { + for (MapEntryNode component : ORanDOMToInternalDataModel.getRootComponents(componentList)) { + // Just get one component. At the moment we don't care which one. Also since + // there is only one management address, we assume there will be only one + // chassis. + // If the device supports subtended configuration then it is assumed that the + // Chassis containing the management interface will be the root component and + // there will be only one root. + VESCommonEventHeaderPOJO header = mapper.mapCommonEventHeader(component); + VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(component); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + LOG.warn("Error while serializing VES Event to String ", e); + } + } + } + } + + private boolean inAllowedDevices(String mountpointName) { + InstanceIdentifierBuilder callhomeServerIID = + YangInstanceIdentifier.builder().node(ORanDeviceManagerQNames.CALLHOME_SERVER_CONTAINER); + final InstanceIdentifierBuilder allowedDevicesIID = YangInstanceIdentifier.builder(callhomeServerIID.build()) + .node(ORanDeviceManagerQNames.CALLHOME_SERVER_ALLOWED_DEVICE); + + Optional allowedDevices = netconfDomAccessor + .readControllerDataNode(LogicalDatastoreType.CONFIGURATION, allowedDevicesIID.build()); + + if (allowedDevices.isPresent()) { + ContainerNode allowedDevicesNode = (ContainerNode) allowedDevices.get(); + MapNode deviceList = (MapNode) allowedDevicesNode + .childByArg(new NodeIdentifier(ORanDeviceManagerQNames.CALLHOME_SERVER_ALLOWED_DEVICE_DEVICE_LIST)); + if (deviceList != null) { + Collection deviceListCollection = deviceList.body(); + for (MapEntryNode device : deviceListCollection) { + // String deviceName = device.getIdentifier() + // .getValue(ORanDeviceManagerQNames.CALLHOME_SERVER_ALLOWED_DEVICE_KEY).toString(); + String deviceName = ORanDMDOMUtility.getLeafValue(device, + ORanDeviceManagerQNames.CALLHOME_SERVER_ALLOWED_DEVICE_KEY); + if (deviceName != null && deviceName.equals(mountpointName)) { + LOG.info("Mountpoint {} is part of allowed-devices list", mountpointName); + return true; + } + } + } + } + + LOG.info("Mountpoint {} is not part of allowed-devices list", mountpointName); + return false; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNotifToVESEventAssembly.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNotifToVESEventAssembly.java new file mode 100644 index 000000000..b8b5151fe --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMNotifToVESEventAssembly.java @@ -0,0 +1,102 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Objects; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanDOMNotifToVESEventAssembly { + + private static final Logger log = LoggerFactory.getLogger(ORanDOMNotifToVESEventAssembly.class); + private static final String VES_EVENT_DOMAIN = "notification"; + private static final String VES_EVENTTYPE = "ORAN_notification"; + private static final String VES_EVENT_PRIORITY = "Normal"; + private NetconfDomAccessor netconfDomAccessor; + private VESCollectorService vesProvider; + + public ORanDOMNotifToVESEventAssembly(@NonNull NetconfDomAccessor netconfDomAccessor, + @NonNull VESCollectorService vesCollectorService) { + this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor); + this.vesProvider = Objects.requireNonNull(vesCollectorService); + } + + // VES CommonEventHeader fields + public VESCommonEventHeaderPOJO createVESCommonEventHeader(Instant time, String notificationTypeName, + long sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventName(notificationTypeName); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + String eventId; + + eventId = notificationTypeName + "-" + Long.toUnsignedString(sequenceNo); + + vesCEH.setEventId(eventId); + vesCEH.setStartEpochMicrosec(time.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 1000); + vesCEH.setNfVendorName("ORAN"); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId("ORAN"); + vesCEH.setSourceName(netconfDomAccessor.getNodeId().getValue()); + return vesCEH; + } + + // Notification fields + public VESNotificationFieldsPOJO createVESNotificationFields(HashMap xPathFields, + String notificationTypeName) { + VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO(); + + vesNotifFields.setChangeType(notificationTypeName); + vesNotifFields.setChangeIdentifier(netconfDomAccessor.getNodeId().getValue()); + + StringBuffer buf = new StringBuffer(); + Iterator> it = xPathFields.entrySet().iterator(); + while (it.hasNext()) { + Entry pair = it.next(); + buf.append("\n" + pair.getKey() + " = " + pair.getValue()); + } + log.info("Resultlist({}):{}", xPathFields.size(), buf.toString()); + + ArrayList> arrayOfNamedHashMap = new ArrayList>(); + HashMap namedHashMap = new HashMap(); + namedHashMap.put("hashMap", xPathFields); + namedHashMap.put("name", notificationTypeName); + arrayOfNamedHashMap.add(namedHashMap); + vesNotifFields.setArrayOfNamedHashMap(arrayOfNamedHashMap); + return vesNotifFields; + + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMToInternalDataModel.java new file mode 100644 index 000000000..b157ae4b5 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDOMToInternalDataModel.java @@ -0,0 +1,293 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanDOMToInternalDataModel { + + private static final Logger LOG = LoggerFactory.getLogger(ORanDOMToInternalDataModel.class); + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + public static List getInventoryList(NodeId nodeId, NormalizedNode hwData) { + + List inventoryResultList = new ArrayList(); + ContainerNode hwContainer = (ContainerNode) hwData; + MapNode componentMap = (MapNode) hwContainer + .getChildByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST)); + Collection componentMapEntries = componentMap.body(); + + for (MapEntryNode componentMapEntryNode : getRootComponents(componentMapEntries)) { + inventoryResultList = + recurseGetInventory(nodeId, componentMapEntryNode, componentMapEntries, 0, inventoryResultList); + } + // Verify if result is complete + if (componentMapEntries.size() != inventoryResultList.size()) { + LOG.warn( + "Not all data were written to the Inventory. Potential entries with missing " + + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", + nodeId.getValue(), componentMapEntries.size(), inventoryResultList.size()); + } + return inventoryResultList; + } + + private static List recurseGetInventory(NodeId nodeId, MapEntryNode component, + Collection componentList, int treeLevel, List inventoryResultList) { + //Add element to list, if conversion successfull + Optional oInventory = getInternalEquipment(nodeId, component, treeLevel); + if (oInventory.isPresent()) { + inventoryResultList.add(oInventory.get()); + } + //Walk through list of child keys and add to list + for (String childUuid : CodeHelpers.nonnull(ORanDMDOMUtility.getLeafListValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD))) { + for (MapEntryNode c : getComponentsByName(childUuid, componentList)) { + inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList); + } + } + return inventoryResultList; + } + + public static List getRootComponents(Collection componentMapEntries) { + List resultList = new ArrayList<>(); + for (MapEntryNode componentMapEntryNode : componentMapEntries) { + if (ORanDMDOMUtility.getLeafValue(componentMapEntryNode, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT) == null) { // Root elements do not have a parent + resultList.add(componentMapEntryNode); + } + } + return resultList; + } + + private static List getComponentsByName(String name, Collection componentList) { + List resultList = new ArrayList<>(); + for (MapEntryNode c : componentList) { + if (name.equals(ORanDMDOMUtility.getKeyValue(c))) { // <-- Component list is flat search for child's of name + resultList.add(c); + } + } + return resultList; + } + + public static Optional getInternalEquipment(NodeId nodeId, MapEntryNode component, int treeLevel) { + + // Make sure that expected data are not null + Objects.requireNonNull(nodeId); + Objects.requireNonNull(component); + + // Read mandatory data + + @Nullable + String nodeIdString = nodeId.getValue(); + @Nullable + String uuid = ORanDMDOMUtility.getKeyValue(component); + @Nullable + String idParent = + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT); + @Nullable + String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht + + // do consistency check if all mandatory parameters are there + if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) { + // Build output data + + InventoryBuilder inventoryBuilder = new InventoryBuilder(); + + // General assumed as mandatory + inventoryBuilder.setNodeId(nodeIdString); + inventoryBuilder.setUuid(uuid); + inventoryBuilder.setParentUuid(uuidParent); + inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); + + // -- String list with ids of holders (optional) + inventoryBuilder.setContainedHolder(ORanDMDOMUtility.getLeafListValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD)); + + // -- Manufacturer related things (optional) + @Nullable + String mfgName = + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME); + inventoryBuilder.setManufacturerName(mfgName); + inventoryBuilder.setManufacturerIdentifier(mfgName); + + // Equipment type (optional) + inventoryBuilder.setDescription( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_DESC)); + inventoryBuilder.setModelIdentifier(ORanDMDOMUtility.getLeafValue(component, + ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MODEL_NAME)); + + inventoryBuilder.setPartTypeId( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CLASS)); + + inventoryBuilder.setTypeName(ORanDMDOMUtility.getKeyValue(component)); + inventoryBuilder.setVersion( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_HW_REV)); + + // Equipment instance (optional) + @Nullable + String mfgDate = + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_DATE); + if (mfgDate != null) { + inventoryBuilder.setDate(mfgDate); + } + inventoryBuilder.setSerial( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_SER_NUM)); + + return Optional.of(inventoryBuilder.build()); + } + return Optional.empty(); + } + + /** + * If system data is available convert + * + * @param sys + * @return + */ + public static Optional getGuicutthrough(@Nullable NormalizedNode sys) { + AugmentationNode onapSys = (AugmentationNode) sys; + if (onapSys != null) { + String name = ORanDMDOMUtility.getLeafValue(onapSys, ORanDeviceManagerQNames.ONAP_SYSTEM_NAME); + @Nullable + Uri uri = new Uri(ORanDMDOMUtility.getLeafValue(onapSys, ORanDeviceManagerQNames.ONAP_SYSTEM_WEB_UI)); + if (uri.getValue() != null) { + GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder(); + if (name != null) { + gcBuilder.setName(name); + } + gcBuilder.setWeburi(uri.getValue()); + return Optional.of(gcBuilder.build()); + } + LOG.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device"); + } + LOG.warn("Retrieving augmented System details failed. Gui cut through information not available"); + return Optional.empty(); + } + + /** + * Convert fault notification into data-provider FaultLogEntity + * + * @param notification with O-RAN notification + * @param nodeId of node to handle + * @param counter to be integrated into data + * @return FaultlogEntity with data + */ + public static FaultlogEntity getFaultLog(DOMNotification notification, NodeId nodeId, Integer counter) { + ContainerNode cn = notification.getBody(); + FaultlogBuilder faultAlarm = new FaultlogBuilder(); + faultAlarm.setNodeId(nodeId.getValue()); + faultAlarm.setObjectId(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SOURCE)); + faultAlarm.setProblem(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_TEXT)); + faultAlarm.setSeverity(getSeverityType( + ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SEVERITY), + ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_IS_CLEARED).equals("true"))); + faultAlarm.setCounter(counter); + faultAlarm.setId(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_ID)); + faultAlarm.setSourceType(SourceType.Netconf); + faultAlarm.setTimestamp(getEventTime(notification)); + return faultAlarm.build(); + } + + public static DateAndTime getEventTime(DOMNotification notification) { + DateAndTime eventTime; + Instant notificationEventTime = null; + if (notification instanceof DOMEvent) { + notificationEventTime = ((DOMEvent) notification).getEventInstant(); + eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(notificationEventTime.toString()); + } else { + eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(); + } + return eventTime; + } + + /** + * Convert O-RAN specific severity into data-provider severity + * + * @param faultSeverity O-RAN severity + * @param isCleared clear indicator + * @return data-provider severity type + * @throws IllegalArgumentException if conversion not possible. + */ + public static SeverityType getSeverityType(@Nullable String faultSeverity, @Nullable Boolean isCleared) + throws IllegalArgumentException { + if (isCleared != null && isCleared) { + return SeverityType.NonAlarmed; + } + if (faultSeverity != null) { + switch (faultSeverity) { + case "CRITICAL": + return SeverityType.Critical; + case "MAJOR": + return SeverityType.Major; + case "MINOR": + return SeverityType.Minor; + case "WARNING": + return SeverityType.Warning; + } + } + throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared + + " faultSeverity=" + faultSeverity); + } + + /** + * Convert Instant to NETCONF DataAndTime + * @param eventTimeInstant + * @return DateAndTime + */ + public static DateAndTime getDateAndTimeOfInstant(Instant eventTimeInstant) { + Date eventDate = Date.from(eventTimeInstant); + return new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp(eventDate)); + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDeviceManagerQNames.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDeviceManagerQNames.java new file mode 100644 index 000000000..e86168abd --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/ORanDeviceManagerQNames.java @@ -0,0 +1,114 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QName; + +public class ORanDeviceManagerQNames { + + //ietf-system + public static final String IETF_SYSTEM_NS = "urn:ietf:params:xml:ns:yang:ietf-system"; + public static final String IETF_SYSTEM_REVISION = "2014-08-06"; + public static final @NonNull QName IETF_SYSTEM_QNAME = + QName.create(IETF_SYSTEM_NS, IETF_SYSTEM_REVISION, "ietf-system"); + public static final @NonNull QName IETF_SYSTEM_CONTAINER = QName.create(IETF_SYSTEM_QNAME, "system"); + + // onap-system.yang + public static final String ONAP_SYSTEM_NS = "urn:onap:system"; + public static final String ONAP_SYSTEM_REVISION = "2020-10-26"; + public static final @NonNull QName ONAP_SYSTEM_QNAME = + QName.create(ONAP_SYSTEM_NS, ONAP_SYSTEM_REVISION, "onap-system"); + public static final @NonNull QName ONAP_SYSTEM_NAME = QName.create(ONAP_SYSTEM_QNAME, "name"); + public static final @NonNull QName ONAP_SYSTEM_WEB_UI = QName.create(ONAP_SYSTEM_QNAME, "web-ui"); + + //ietf-hardware.yang + public static final String IETF_HW_NS = "urn:ietf:params:xml:ns:yang:ietf-hardware"; + public static final String IETF_HW_REVISION = "2018-03-13"; + public static final @NonNull QName IETF_HW_MODULE_NAME = + QName.create(IETF_HW_NS, IETF_HW_REVISION, "ietf-hardware"); + public static final @NonNull QName IETF_HW_CONTAINER = QName.create(IETF_HW_MODULE_NAME, "hardware"); + public static final @NonNull QName IETF_HW_COMPONENT_LIST = QName.create(IETF_HW_MODULE_NAME, "component"); + public static final @NonNull QName IETF_HW_COMPONENT_LIST_KEY = QName.create(IETF_HW_MODULE_NAME, "name"); + public static final @NonNull QName IETF_HW_COMPONENT_LIST_MFG_NAME = QName.create(IETF_HW_MODULE_NAME, "mfg-name"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_UUID = QName.create(IETF_HW_MODULE_NAME, "uuid"); //leaf:yang:uuid + public static final @NonNull QName IETF_HW_COMPONENT_LIST_MODEL_NAME = QName.create(IETF_HW_MODULE_NAME, "model-name"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_SER_NUM = QName.create(IETF_HW_MODULE_NAME, "serial-num"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_SW_REV = QName.create(IETF_HW_MODULE_NAME, "software-rev"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_ALIAS = QName.create(IETF_HW_MODULE_NAME, "alias"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_CLASS = QName.create(IETF_HW_MODULE_NAME, "class"); + public static final @NonNull QName IETF_HW_COMPONENT_LIST_MFG_DATE = QName.create(IETF_HW_MODULE_NAME, "mfg-date"); //leaf:yang:date-and-time + public static final @NonNull QName IETF_HW_COMPONENT_LIST_CONTAINS_CHILD = QName.create(IETF_HW_MODULE_NAME, "contains-child"); //leaf-list:leafref + public static final @NonNull QName IETF_HW_COMPONENT_LIST_PARENT = QName.create(IETF_HW_MODULE_NAME, "parent"); //leaf:leafref + public static final @NonNull QName IETF_HW_COMPONENT_LIST_DESC = QName.create(IETF_HW_MODULE_NAME, "description"); //leaf:String + public static final @NonNull QName IETF_HW_COMPONENT_LIST_HW_REV = QName.create(IETF_HW_MODULE_NAME, "hardware-rev"); //leaf:String + + //odl-netconf-callhome-server.yang + public static final String CALLHOME_SERVER_NS = "urn:opendaylight:params:xml:ns:yang:netconf-callhome-server"; + public static final String CALLHOME_SERVER_REVISION = "2020-10-15"; + public static final @NonNull QName CALLHOME_SERVER_MODULE = + QName.create(CALLHOME_SERVER_NS, CALLHOME_SERVER_REVISION, "odl-netconf-callhome-server"); + public static final @NonNull QName CALLHOME_SERVER_CONTAINER = + QName.create(CALLHOME_SERVER_MODULE, "netconf-callhome-server"); + public static final @NonNull QName CALLHOME_SERVER_ALLOWED_DEVICE = + QName.create(CALLHOME_SERVER_MODULE, "allowed-devices"); + public static final @NonNull QName CALLHOME_SERVER_ALLOWED_DEVICE_DEVICE_LIST = + QName.create(CALLHOME_SERVER_MODULE, "device"); + public static final @NonNull QName CALLHOME_SERVER_ALLOWED_DEVICE_KEY = + QName.create(CALLHOME_SERVER_MODULE, "unique-id"); + + //o-ran-hardware.yang + public static final String ORAN_HW_NS = "urn:o-ran:hardware:1.0"; + public static final String ORAN_HW_REVISION = "2019-03-28"; + public static final @NonNull QName ORAN_HW_MODULE = QName.create(ORAN_HW_NS, ORAN_HW_REVISION, "o-ran-hardware").intern(); + public static final @NonNull QName ORAN_HW_COMPONENT = QName.create(ORAN_HW_MODULE, "O-RAN-HW-COMPONENT"); + + //o-ran-fm.yang + public static final String ORAN_FM_NS = "urn:o-ran:fm:1.0"; + public static final String ORAN_FM_REVISION = "2019-02-04"; + public static final @NonNull QName ORAN_FM_MODULE = QName.create(ORAN_FM_NS, ORAN_FM_REVISION, "o-ran-fm"); + public static final @NonNull QName ORAN_FM_ALARM_NOTIF = QName.create(ORAN_FM_MODULE, "alarm-notif"); + public static final @NonNull QName ORAN_FM_FAULT_ID = QName.create(ORAN_FM_MODULE, "fault-id"); + public static final @NonNull QName ORAN_FM_FAULT_SOURCE = QName.create(ORAN_FM_MODULE, "fault-source"); + public static final @NonNull QName ORAN_FM_FAULT_SEVERITY = QName.create(ORAN_FM_MODULE, "fault-severity"); + public static final @NonNull QName ORAN_FM_FAULT_TEXT = QName.create(ORAN_FM_MODULE, "fault-text"); + public static final @NonNull QName ORAN_FM_FAULT_IS_CLEARED = QName.create(ORAN_FM_MODULE, "is-cleared"); + + //ietf-netconf-notifications.yang + public static final String IETF_NETCONF_NOTIFICATIONS_NS = "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications"; + public static final String IETF_NETCONF_NOTIFICATIONS_REVISION = "2012-02-06"; + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_MODULE = QName.create(IETF_NETCONF_NOTIFICATIONS_NS, IETF_NETCONF_NOTIFICATIONS_REVISION, "ietf-netconf-notifications").intern(); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "netconf-config-change"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIRMED_COMMIT = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "netconf-confirmed-commit"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_NETCONF_SESSION_START = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "netconf-session-start"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_NETCONF_SESSION_END = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "netconf-session-end"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_NETCONF_CAPABILITY_CHANGE = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "netconf-capability-change"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_CHANGEDBY = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "changed-by"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_SERVERORUSER = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "server-or-user"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_EDITNODE = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "edit"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_USERNAME = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "username"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_SESSIONID = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "session-id"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_OPERATION = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "operation"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_TARGET = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "target"); + public static final @NonNull QName IETF_NETCONF_NOTIFICATIONS_DATASTORE = QName.create(IETF_NETCONF_NOTIFICATIONS_MODULE, "datastore"); + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/startup/ORanNetworkElementFactory.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/startup/ORanNetworkElementFactory.java new file mode 100644 index 000000000..afeac1932 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/startup/ORanNetworkElementFactory.java @@ -0,0 +1,59 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.startup; + +import java.util.Optional; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.NetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom.ORanDOMNetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom.ORanDeviceManagerQNames; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.opendaylight.yangtools.yang.common.QName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanNetworkElementFactory implements NetworkElementFactory { + + private static final Logger log = LoggerFactory.getLogger(ORanNetworkElementFactory.class); + //Workaround + private static final QName OneCell = + QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); + + @Override + public Optional create(NetconfAccessor accessor, DeviceManagerServiceProvider serviceProvider) { + Capabilities capabilites = accessor.getCapabilites(); + if (!capabilites.isSupportingNamespace(OneCell)) { + if (capabilites.isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)) { + log.info("Create device {} ", ORanDOMNetworkElement.class.getName()); + //Optional bindingAccessor = accessor.getNetconfBindingAccessor(); + Optional domAccessor = accessor.getNetconfDomAccessor(); + if (domAccessor.isPresent()) { + //return Optional.of(new ORanNetworkElement(bindingAccessor.get(), serviceProvider)); + return Optional.of(new ORanDOMNetworkElement(domAccessor.get(), serviceProvider)); + } + } + } + return Optional.empty(); + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml index 21b761ce2..b4cc2d927 100644 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml @@ -31,7 +31,7 @@ interface="org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService"/> diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ComponentHelper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ComponentHelper.java deleted file mode 100644 index 05c825fdc..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ComponentHelper.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.util.Arrays; -import java.util.List; -import java.util.Scanner; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.json.JSONArray; -import org.json.JSONObject; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Fan; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Port; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Sensor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.AdminState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.OperState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorStatus; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValue; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValueType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.ComponentBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorData; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorDataBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.State; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.StateBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; - -public class ComponentHelper { - - public static Component get(String name, String dateTimeString) { - DateAndTime dateTime = new DateAndTime(dateTimeString); - Uuid uuid = new Uuid("0Aabcdef-0abc-0cfD-0abC-0123456789AB"); - - ComponentBuilder componentBuilder = new ComponentBuilder(); - componentBuilder.setParent("Shelf").setName("Slot-0").setParentRelPos(0); - componentBuilder.setUuid(uuid); - componentBuilder.setContainsChild(Arrays.asList("Card-01A", "Card-01B")); - componentBuilder.setDescription("ORAN Network Element NO-456"); - componentBuilder.setXmlClass(TestHardwareClass.class); - componentBuilder.setMfgName("Nokia"); - componentBuilder.setMfgDate(dateTime); - return componentBuilder.build(); - } - - public static List getComponentList(String resourceName) { - try (Scanner scanner = new Scanner(ComponentHelper.class.getResourceAsStream(resourceName), "UTF-8")) { - String jsonString = scanner.useDelimiter("\\A").next(); - JSONObject jsonHardware = new JSONObject(jsonString).getJSONObject("hardware"); - JSONArray jsonComponentArray = jsonHardware.getJSONArray("component"); - return IntStream.range(0, jsonComponentArray.length()) - .mapToObj(idx -> ComponentHelper.get(jsonComponentArray.getJSONObject(idx))) - .collect(Collectors.toList()); - } - } - - public static Component get(JSONObject jsonComponent) { - ComponentBuilder componentBuilder = new ComponentBuilder(); - componentBuilder.setName(getString(jsonComponent, "name")); - componentBuilder.setParent(getString(jsonComponent, "parent")); - componentBuilder.setParentRelPos(getInteger(jsonComponent, "parent-rel-pos")); - componentBuilder.setAlias(getString(jsonComponent, "alias")); - componentBuilder.setXmlClass(getXmlClass(jsonComponent, "class")); - componentBuilder.setState(getState(jsonComponent, "state")); - componentBuilder.setDescription(getString(jsonComponent, "description")); - componentBuilder.setContainsChild(getStringArray(jsonComponent, "contains-child")); - componentBuilder.setSensorData(getSensorData(jsonComponent, "sensor-data")); - componentBuilder.setFirmwareRev(getString(jsonComponent, "firmware-rev")); - componentBuilder.setSerialNum(getString(jsonComponent, "serial-num")); - componentBuilder.setSoftwareRev(getString(jsonComponent, "software-rev")); - return componentBuilder.build(); - } - - // Private - - private static State getState(JSONObject jsonComponent, String key) { - if (jsonComponent.has(key)) { - JSONObject jsonState = jsonComponent.getJSONObject(key); - StateBuilder stateBuilder = new StateBuilder(); - stateBuilder.setOperState(getString(jsonState, "oper-state", value -> OperState.forName(value)).get()); - stateBuilder.setAdminState(getString(jsonState, "admin-state", value -> AdminState.forName(value)).get()); - return stateBuilder.build(); - } - return null; - } - - private static SensorData getSensorData(JSONObject jsonComponent, String key) { - if (jsonComponent.has(key)) { - JSONObject jsonSonsor = jsonComponent.getJSONObject(key); - SensorDataBuilder sensorBuilder = new SensorDataBuilder(); - sensorBuilder.setValueTimestamp(getString(jsonSonsor, "value-timestamp", value -> new DateAndTime(value))); - sensorBuilder.setValue(getInteger(jsonSonsor, "value", value -> new SensorValue(value))); - sensorBuilder - .setValueType(getString(jsonSonsor, "value-type", value -> SensorValueType.forName(value).get())); - sensorBuilder - .setOperStatus(getString(jsonSonsor, "oper-status", value -> SensorStatus.forName(value).get())); - return sensorBuilder.build(); - } - return null; - } - - // Get data types - private static Class getXmlClass(JSONObject jsonComponent, String key) { - return getString(jsonComponent, key, value -> { - switch (value) { - case "iana-hardware:sensor": - return Sensor.class; - case "iana-hardware:port": - return Port.class; - case "iana-hardware:fan": - return Fan.class; - default: - return HardwareClass.class; - } - }); - } - - private static String getString(JSONObject jsonObject, String key) { - return getString(jsonObject, key, value -> value); - } - - private static Integer getInteger(JSONObject jsonObject, String key) { - return getInteger(jsonObject, key, value -> value); - } - - private interface ConvertString { - T convert(String value); - } - - private static T getString(JSONObject jsonObject, String key, ConvertString convert) { - if (jsonObject.has(key)) { - String value = jsonObject.getString(key); - return convert.convert(value); - } - return null; - } - - private interface ConvertInteger { - T convert(int value); - } - - private static T getInteger(JSONObject jsonObject, String key, ConvertInteger convert) { - if (jsonObject.has(key)) { - int value = jsonObject.getInt(key); - return convert.convert(value); - } - return null; - } - - private static List getStringArray(JSONObject jsonComponent, String key) { - if (jsonComponent.has(key)) { - JSONArray stringArray = jsonComponent.getJSONArray(key); - return IntStream.range(0, stringArray.length()).mapToObj(idx -> stringArray.getString(idx)) - .collect(Collectors.toList()); - } - return null; - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestAlarmNotif.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestAlarmNotif.java deleted file mode 100644 index 4d10dd154..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestAlarmNotif.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import java.util.Map; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjects; -import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjectsKey; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.common.Uint16; - -public class TestAlarmNotif implements AlarmNotif { - - private static final Uint16 FAULT_ID = Uint16.valueOf(123); - - @Override - public > @Nullable A augmentation(Class augmentationType) { - return null; - } - - @Override - public @Nullable Uint16 getFaultId() { - return FAULT_ID; - } - - @Override - public @Nullable String getFaultSource() { - return "ORAN-RU-FH"; - } - - @Override - public @Nullable Map getAffectedObjects() { - return null; - } - - @Override - public @Nullable FaultSeverity getFaultSeverity() { - return FaultSeverity.CRITICAL; - } - - @Override - public @Nullable Boolean isIsCleared() { - return true; - } - - @Override - public @Nullable String getFaultText() { - return "CPRI Port Down"; - } - - @Override - public @Nullable DateAndTime getEventTime() { - return new DateAndTime("2021-03-23T18:19:42.326144Z"); - } - - @Override - public @NonNull Map>, Augmentation> augmentations() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Boolean getIsCleared() { - return true; - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestDeviceManagerORanImpl.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestDeviceManagerORanImpl.java deleted file mode 100644 index 98db4bbb6..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestDeviceManagerORanImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.mockito.Mockito.mock; -import java.io.IOException; -import org.junit.Before; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.DeviceManagerORanImpl; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; - -public class TestDeviceManagerORanImpl { - DeviceManagerORanImpl devMgrOran; - - @Before - public void init() throws InterruptedException, IOException { - } - - // @Test - public void test() throws Exception { - devMgrOran = new DeviceManagerORanImpl(); - NetconfNetworkElementService netconfNetworkElementService = mock(NetconfNetworkElementService.class); - - try { - devMgrOran.setNetconfNetworkElementService(netconfNetworkElementService); - devMgrOran.init(); - } catch (Exception e) { - throw e; - } - } - - //@After - public void cleanUp() throws Exception { - devMgrOran.close(); - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestHardwareClass.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestHardwareClass.java deleted file mode 100644 index 64b6ac1ab..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestHardwareClass.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; - -public interface TestHardwareClass extends HardwareClass { - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanChangeNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanChangeNotificationListener.java deleted file mode 100644 index da4d830d7..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanChangeNotificationListener.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ - -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import java.time.Instant; -import java.util.Arrays; -import java.util.List; -import org.eclipse.jdt.annotation.NonNull; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditOperationType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.Edit; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.EditBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; - -@RunWith(MockitoJUnitRunner.class) -public class TestORanChangeNotificationListener { - - private static final String NODEID = "node1"; - - @Mock - DeviceManagerServiceProvider serviceProvider; - @Mock - NetconfBindingAccessor netconfAccessor; - @Mock - DataProvider databaseService; - @Mock - VESCollectorService vesCollectorService; - @Mock - VESCollectorCfgService vesCfgService; - @Mock - NotificationProxyParser notifProxyParser; - @Mock - static NetconfConfigChange change; - - @Test - public void test() { - - when(vesCollectorService.getConfig()).thenReturn(vesCfgService); - when(netconfAccessor.getNodeId()).thenReturn(new NodeId(NODEID)); - when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); - when(serviceProvider.getDataProvider()).thenReturn(databaseService); - when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); - when(vesCollectorService.getNotificationProxyParser()).thenReturn(notifProxyParser); - - ORanChangeNotificationListener notifListener = - new ORanChangeNotificationListener(netconfAccessor, serviceProvider); - - Iterable pathArguments = Arrays.asList(new PathArgument() { - - @Override - public int compareTo(PathArgument arg0) { - return 0; - } - - @Override - public Class getType() { - return DataObject.class; - } - }); - InstanceIdentifier target = InstanceIdentifier.create(pathArguments); - NetconfConfigChange confChangeNotification = createNotification(EditOperationType.Create, target); - when(notifProxyParser.getTime(confChangeNotification)).thenReturn(Instant.now()); - notifListener.onNetconfConfigChange(confChangeNotification); - verify(databaseService).writeEventLog(any(EventlogEntity.class)); - } - - /** - * @param type - * @return - */ - private static NetconfConfigChange createNotification(EditOperationType type, InstanceIdentifier target) { - @SuppressWarnings("null") - final @NonNull List edits = Arrays.asList(new EditBuilder().setOperation(type).setTarget(target).build()); - when(change.nonnullEdit()).thenReturn(edits); - return change; - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanFaultNotificationListener.java deleted file mode 100644 index af2515c9a..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanFaultNotificationListener.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import com.google.common.io.Files; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorServiceImpl; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@RunWith(MockitoJUnitRunner.class) -public class TestORanFaultNotificationListener { - - private static final Logger LOG = LoggerFactory.getLogger(TestORanFaultNotificationListener.class); - private static final String TESTFILENAME = "configFile.txt"; - - // @formatter:off - private static final String TESTCONFIG_CONTENT = "[VESCollector]\n" - + "VES_COLLECTOR_ENABLED=true\n" - + "VES_COLLECTOR_TLS_ENABLED=true\n" - + "VES_COLLECTOR_TRUST_ALL_CERTS=true\n" - + "VES_COLLECTOR_USERNAME=sample1\n" - + "VES_COLLECTOR_PASSWORD=sample1\n" - + "VES_COLLECTOR_IP=[2001:db8:1:1::1]\n" - + "VES_COLLECTOR_PORT=8443\n" - + "VES_COLLECTOR_VERSION=v7\n" - + "REPORTING_ENTITY_NAME=ONAP SDN-R\n" - + "EVENTLOG_MSG_DETAIL=SHORT\n" - + ""; - // @formatter:on - - @Mock NetconfBindingAccessor bindingAccessor; - @Mock DataProvider dataProvider; - @Mock FaultService faultService; - @Mock DeviceManagerServiceProvider serviceProvider; - @Mock WebsocketManagerService websocketManagerService; - @Mock DataProvider databaseService; - VESCollectorService vesCollectorService; - - @After - @Before - public void afterAndBefore() { - File f = new File(TESTFILENAME); - if (f.exists()) { - LOG.info("Remove {}", f.getAbsolutePath()); - f.delete(); - } - } - - @Test - public void test() throws IOException { - Files.asCharSink(new File(TESTFILENAME), StandardCharsets.UTF_8).write(TESTCONFIG_CONTENT); - vesCollectorService = - new VESCollectorServiceImpl(new ConfigurationFileRepresentation(TESTFILENAME)); - when(bindingAccessor.getNodeId()).thenReturn(new NodeId("nSky")); - ORanFaultNotificationListener faultListener = new ORanFaultNotificationListener(bindingAccessor, - vesCollectorService, faultService, websocketManagerService, databaseService); - faultListener.onAlarmNotif(new TestAlarmNotif()); - - verify(faultService).faultNotification(getFaultLog()); - } - - private FaultlogEntity getFaultLog() { - FaultlogBuilder faultAlarm = new FaultlogBuilder(); - faultAlarm.setNodeId("nSky"); - faultAlarm.setObjectId("ORAN-RU-FH"); - faultAlarm.setProblem("CPRI Port Down"); - faultAlarm.setSeverity(SeverityType.NonAlarmed); - faultAlarm.setCounter(1); - faultAlarm.setId("123"); - faultAlarm.setSourceType(SourceType.Netconf); - faultAlarm.setTimestamp(new DateAndTime("2021-03-23T18:19:42.326144Z")); - return faultAlarm.build(); - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElement.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElement.java deleted file mode 100644 index af7664ab8..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElement.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.util.Optional; -import org.eclipse.jdt.annotation.NonNull; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; -import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; -import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.yang.common.QName; - -public class TestORanNetworkElement { - - private static final QName OneCell = - QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); - private static final @NonNull QName OnapSystem = QName.create("urn:onap:system", "2020-10-26", "onap-system").intern(); - private static String NODEIDSTRING = "nSky"; - private static NodeId nodeId = new NodeId(NODEIDSTRING); - - private static NetconfAccessor accessor; - private static DeviceManagerServiceProvider serviceProvider; - private static Capabilities capabilities; - private static TransactionUtils transactionUtils; - private static NetconfBindingAccessor bindingAccessor; - private static VESCollectorService vesCollectorService; - private static NotificationProxyParser notificationProxyParser; - private static VESCollectorCfgService vesCfgService; - private static WebsocketManagerService websocketManagerService; - - @BeforeClass - public static void init() throws InterruptedException, IOException { - capabilities = mock(Capabilities.class); - accessor = mock(NetconfAccessor.class); - serviceProvider = mock(DeviceManagerServiceProvider.class); - transactionUtils = mock(TransactionUtils.class); - bindingAccessor = mock(NetconfBindingAccessor.class); - vesCollectorService = mock(VESCollectorService.class); - notificationProxyParser = mock(NotificationProxyParser.class); - vesCfgService = mock(VESCollectorCfgService.class); - websocketManagerService = mock(WebsocketManagerService.class); - - when(accessor.getCapabilites()).thenReturn(capabilities); - when(accessor.getNodeId()).thenReturn(nodeId); - when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingAccessor)); - when(bindingAccessor.getCapabilites()).thenReturn(capabilities); - when(bindingAccessor.getTransactionUtils()).thenReturn(transactionUtils); - when(bindingAccessor.getNodeId()).thenReturn(nodeId); - when(vesCollectorService.getNotificationProxyParser()).thenReturn(notificationProxyParser); - - DataProvider dataProvider = mock(DataProvider.class); - FaultService faultService = mock(FaultService.class); - when(serviceProvider.getWebsocketService()).thenReturn(websocketManagerService); - when(serviceProvider.getFaultService()).thenReturn(faultService); - when(serviceProvider.getDataProvider()).thenReturn(dataProvider); - when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); - when(vesCollectorService.getConfig()).thenReturn(vesCfgService); - when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); - - } - - @Test - public void test() { - Optional oRanNe; - when(capabilities.isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); - when(capabilities.isSupportingNamespace(OneCell)).thenReturn(false); - when(capabilities.isSupportingNamespace(OnapSystem)).thenReturn(false); - - ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); - oRanNe = factory.create(accessor, serviceProvider); - assertTrue(factory.create(accessor, serviceProvider).isPresent()); - oRanNe.get().register(); - oRanNe.get().deregister(); - oRanNe.get().getAcessor(); - oRanNe.get().getDeviceType(); - assertEquals(oRanNe.get().getNodeId().getValue(), "nSky"); - } - - } diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElementFactory.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElementFactory.java deleted file mode 100644 index fc382bfe2..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanNetworkElementFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.util.Optional; -import org.junit.After; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; -import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; -import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; - -public class TestORanNetworkElementFactory { - - private static String NODEIDSTRING = "nSky"; - - private static NetconfBindingAccessor accessor; - private static DeviceManagerServiceProvider serviceProvider; - private static Capabilities capabilities; - private static VESCollectorService vesCollectorService; - private static FaultService faultService; - private static WebsocketManagerService notificationService; - private static DataProvider databaseService; - - @BeforeClass - public static void init() throws InterruptedException, IOException { - NetconfBindingAccessor bindingAccessor = mock(NetconfBindingAccessor.class); - NodeId nodeId = new NodeId(NODEIDSTRING); - when(bindingAccessor.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); - when(bindingAccessor.getNodeId()).thenReturn(nodeId); - - capabilities = mock(Capabilities.class); - accessor = mock(NetconfBindingAccessor.class); - serviceProvider = mock(DeviceManagerServiceProvider.class); - vesCollectorService = mock(VESCollectorService.class); - faultService = mock(FaultService.class); - notificationService = mock(WebsocketManagerService.class); - databaseService = mock(DataProvider.class); - - when(accessor.getCapabilites()).thenReturn(capabilities); - when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingAccessor)); - when(serviceProvider.getFaultService()).thenReturn(faultService); - when(serviceProvider.getWebsocketService()).thenReturn(notificationService); - when(serviceProvider.getDataProvider()).thenReturn(databaseService); - when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); - - } - - @Test - public void testCreateORANHWComponent() throws Exception { - when(accessor.getCapabilites().isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); - ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); - assertTrue((factory.create(accessor, serviceProvider)).isPresent()); - } - - @Test - public void testCreateNone() throws Exception { - when(accessor.getCapabilites().isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(false); - ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); - assertTrue(!(factory.create(accessor, serviceProvider).isPresent())); - } - - @After - public void cleanUp() throws Exception { - - } -} - diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanRegistrationToVESpnfRegistration.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanRegistrationToVESpnfRegistration.java deleted file mode 100644 index 115765d46..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanRegistrationToVESpnfRegistration.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanRegistrationToVESpnfRegistrationMapper; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; - -@RunWith(MockitoJUnitRunner.class) -public class TestORanRegistrationToVESpnfRegistration { - - @Mock - NetconfAccessor netconfAccessor; - @Mock - VESCollectorService vesCollectorService; - @Mock - VESCollectorCfgService vesCfgService; - - private final int SEQUENCE_NO = 10; - - @Test - public void test() { - String dateTimeString = "2020-02-05T12:30:45.283Z"; - String name = "Slot-0"; - - NetconfNode testNetconfNode = mock(NetconfNode.class); - when(testNetconfNode.getHost()).thenReturn(new Host(new IpAddress(new Ipv4Address("10.10.10.10")))); - - when(netconfAccessor.getNodeId()).thenReturn(new NodeId("nSky")); - when(netconfAccessor.getNetconfNode()).thenReturn(testNetconfNode); - when(vesCollectorService.getConfig()).thenReturn(vesCfgService); - when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R"); - Component testComponent = ComponentHelper.get(name, dateTimeString); - - ORanRegistrationToVESpnfRegistrationMapper mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService); - mapper.mapCommonEventHeader(testComponent); - mapper.mapPNFRegistrationFields(testComponent); - } - -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanToInternalDataModel.java deleted file mode 100644 index e2e0eb812..000000000 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/TestORanToInternalDataModel.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.util.List; -import java.util.Optional; -import java.util.function.IntConsumer; -import java.util.stream.IntStream; -import org.eclipse.jdt.annotation.Nullable; -import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanToInternalDataModel; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.yang.common.Uint32; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TestORanToInternalDataModel { - - private static final Logger LOG = LoggerFactory.getLogger(TestORanToInternalDataModel.class); - - NodeId nodeId = new NodeId("ORan-1000"); - - @Test - public void testInventory() { - String dateTimeString = "2020-02-05T12:30:45.283Z"; - String name = "Slot-0"; - - Component testComponent = ComponentHelper.get(name, dateTimeString); - Optional oInventory = ORanToInternalDataModel.getInternalEquipment(nodeId, testComponent, 0); - - assertTrue(oInventory.isPresent()); - Inventory inventory = oInventory.get(); - assertEquals(name, inventory.getUuid()); - assertEquals(dateTimeString, inventory.getDate()); - assertEquals(nodeId.getValue(), inventory.getNodeId()); - } - - @Test - public void testInventoryList() throws IOException, ClassNotFoundException { - List componentList = ComponentHelper.getComponentList("/Device-ietf-hardware-Output.json"); - List inventoryList = ORanToInternalDataModel.getInventoryList(nodeId, componentList); - //componentList.forEach(System.out::println); - assertEquals("All elements", 27, inventoryList.size()); - assertEquals("Fully parseable", componentList.size(), inventoryList.size()); - assertEquals("Treelevel always there", 0, - inventoryList.stream().filter(inventory -> inventory.getTreeLevel() == null).count()); - listAsTree(inventoryList); - } - - private void listAsTree(List inventoryList) { - //Walk through complete list and print parameters - IntConsumer action = level -> IntStream.range(0, inventoryList.size()) - .filter(idx -> inventoryList.get(idx).getTreeLevel().intValue() == level) - .forEach(idx2 -> printElements(idx2, level, inventoryList.get(idx2))); - //Walk trough 10 levels - IntStream.range(0, 10) - .forEach(action); - } - - private void printElements(int idx2, int level, Inventory inventory) { - System.out.println(level + ": " + inventory.getParentUuid() + " " - + inventory.getUuid()); - } - - @SuppressWarnings("unused") - private boolean compareLevel(int idx, List componentList, List inventoryList) { - @Nullable - Integer relPos = componentList.get(idx).getParentRelPos(); - @Nullable - Uint32 treeLevel = inventoryList.get(idx).getTreeLevel(); - LOG.warn("Treelevel relPos: {} treeLevel: {}", relPos, treeLevel); - if (relPos != null && treeLevel != null) { - return relPos == treeLevel.intValue(); - } - return false; - } -} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ComponentHelper.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ComponentHelper.java new file mode 100644 index 000000000..64cdd5f80 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ComponentHelper.java @@ -0,0 +1,179 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.json.JSONArray; +import org.json.JSONObject; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Fan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Port; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Sensor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.AdminState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.OperState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValue; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValueType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.ComponentBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorData; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorDataBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.State; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.StateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; + +public class ComponentHelper { + + public static Component get(String name, String dateTimeString) { + DateAndTime dateTime = new DateAndTime(dateTimeString); + Uuid uuid = new Uuid("0Aabcdef-0abc-0cfD-0abC-0123456789AB"); + + ComponentBuilder componentBuilder = new ComponentBuilder(); + componentBuilder.setParent("Shelf").setName("Slot-0").setParentRelPos(0); + componentBuilder.setUuid(uuid); + componentBuilder.setContainsChild(Arrays.asList("Card-01A", "Card-01B")); + componentBuilder.setDescription("ORAN Network Element NO-456"); + componentBuilder.setXmlClass(TestHardwareClass.class); + componentBuilder.setMfgName("Nokia"); + componentBuilder.setMfgDate(dateTime); + return componentBuilder.build(); + } + + public static List getComponentList(String resourceName) { + try (Scanner scanner = new Scanner(ComponentHelper.class.getResourceAsStream(resourceName), "UTF-8")) { + String jsonString = scanner.useDelimiter("\\A").next(); + JSONObject jsonHardware = new JSONObject(jsonString).getJSONObject("hardware"); + JSONArray jsonComponentArray = jsonHardware.getJSONArray("component"); + return IntStream.range(0, jsonComponentArray.length()) + .mapToObj(idx -> ComponentHelper.get(jsonComponentArray.getJSONObject(idx))) + .collect(Collectors.toList()); + } + } + + public static Component get(JSONObject jsonComponent) { + ComponentBuilder componentBuilder = new ComponentBuilder(); + componentBuilder.setName(getString(jsonComponent, "name")); + componentBuilder.setParent(getString(jsonComponent, "parent")); + componentBuilder.setParentRelPos(getInteger(jsonComponent, "parent-rel-pos")); + componentBuilder.setAlias(getString(jsonComponent, "alias")); + componentBuilder.setXmlClass(getXmlClass(jsonComponent, "class")); + componentBuilder.setState(getState(jsonComponent, "state")); + componentBuilder.setDescription(getString(jsonComponent, "description")); + componentBuilder.setContainsChild(getStringArray(jsonComponent, "contains-child")); + componentBuilder.setSensorData(getSensorData(jsonComponent, "sensor-data")); + componentBuilder.setFirmwareRev(getString(jsonComponent, "firmware-rev")); + componentBuilder.setSerialNum(getString(jsonComponent, "serial-num")); + componentBuilder.setSoftwareRev(getString(jsonComponent, "software-rev")); + return componentBuilder.build(); + } + + // Private + + private static State getState(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONObject jsonState = jsonComponent.getJSONObject(key); + StateBuilder stateBuilder = new StateBuilder(); + stateBuilder.setOperState(getString(jsonState, "oper-state", value -> OperState.forName(value)).get()); + stateBuilder.setAdminState(getString(jsonState, "admin-state", value -> AdminState.forName(value)).get()); + return stateBuilder.build(); + } + return null; + } + + private static SensorData getSensorData(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONObject jsonSonsor = jsonComponent.getJSONObject(key); + SensorDataBuilder sensorBuilder = new SensorDataBuilder(); + sensorBuilder.setValueTimestamp(getString(jsonSonsor, "value-timestamp", value -> new DateAndTime(value))); + sensorBuilder.setValue(getInteger(jsonSonsor, "value", value -> new SensorValue(value))); + sensorBuilder + .setValueType(getString(jsonSonsor, "value-type", value -> SensorValueType.forName(value).get())); + sensorBuilder + .setOperStatus(getString(jsonSonsor, "oper-status", value -> SensorStatus.forName(value).get())); + return sensorBuilder.build(); + } + return null; + } + + // Get data types + private static Class getXmlClass(JSONObject jsonComponent, String key) { + return getString(jsonComponent, key, value -> { + switch (value) { + case "iana-hardware:sensor": + return Sensor.class; + case "iana-hardware:port": + return Port.class; + case "iana-hardware:fan": + return Fan.class; + default: + return HardwareClass.class; + } + }); + } + + private static String getString(JSONObject jsonObject, String key) { + return getString(jsonObject, key, value -> value); + } + + private static Integer getInteger(JSONObject jsonObject, String key) { + return getInteger(jsonObject, key, value -> value); + } + + private interface ConvertString { + T convert(String value); + } + + private static T getString(JSONObject jsonObject, String key, ConvertString convert) { + if (jsonObject.has(key)) { + String value = jsonObject.getString(key); + return convert.convert(value); + } + return null; + } + + private interface ConvertInteger { + T convert(int value); + } + + private static T getInteger(JSONObject jsonObject, String key, ConvertInteger convert) { + if (jsonObject.has(key)) { + int value = jsonObject.getInt(key); + return convert.convert(value); + } + return null; + } + + private static List getStringArray(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONArray stringArray = jsonComponent.getJSONArray(key); + return IntStream.range(0, stringArray.length()).mapToObj(idx -> stringArray.getString(idx)) + .collect(Collectors.toList()); + } + return null; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestAlarmNotif.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestAlarmNotif.java new file mode 100644 index 000000000..883271d4c --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestAlarmNotif.java @@ -0,0 +1,88 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjects; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjectsKey; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.common.Uint16; + +public class TestAlarmNotif implements AlarmNotif { + + private static final Uint16 FAULT_ID = Uint16.valueOf(123); + + @Override + public > @Nullable A augmentation(Class augmentationType) { + return null; + } + + @Override + public @Nullable Uint16 getFaultId() { + return FAULT_ID; + } + + @Override + public @Nullable String getFaultSource() { + return "ORAN-RU-FH"; + } + + @Override + public @Nullable Map getAffectedObjects() { + return null; + } + + @Override + public @Nullable FaultSeverity getFaultSeverity() { + return FaultSeverity.CRITICAL; + } + + public @Nullable Boolean isIsCleared() { + return true; + } + + @Override + public @Nullable String getFaultText() { + return "CPRI Port Down"; + } + + @Override + public @Nullable DateAndTime getEventTime() { + return new DateAndTime("2021-03-23T18:19:42.326144Z"); + } + + @Override + public @NonNull Map>, Augmentation> augmentations() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Boolean getIsCleared() { + return true; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestHardwareClass.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestHardwareClass.java new file mode 100644 index 000000000..753e6c97f --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestHardwareClass.java @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; + +public interface TestHardwareClass extends HardwareClass { + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanChangeNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanChangeNotificationListener.java new file mode 100644 index 000000000..d8ea2664f --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanChangeNotificationListener.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.ORanChangeNotificationListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditOperationType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.Edit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.netconf.config.change.EditBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; + +@RunWith(MockitoJUnitRunner.class) +public class TestORanChangeNotificationListener { + + private static final String NODEID = "node1"; + + @Mock + DeviceManagerServiceProvider serviceProvider; + @Mock + NetconfBindingAccessor netconfAccessor; + @Mock + DataProvider databaseService; + @Mock + VESCollectorService vesCollectorService; + @Mock + VESCollectorCfgService vesCfgService; + @Mock + NotificationProxyParser notifProxyParser; + @Mock + static NetconfConfigChange change; + + @Test + public void test() { + + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(netconfAccessor.getNodeId()).thenReturn(new NodeId(NODEID)); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + when(serviceProvider.getDataProvider()).thenReturn(databaseService); + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); + when(vesCollectorService.getNotificationProxyParser()).thenReturn(notifProxyParser); + + ORanChangeNotificationListener notifListener = + new ORanChangeNotificationListener(netconfAccessor, serviceProvider); + + Iterable pathArguments = Arrays.asList(new PathArgument() { + + @Override + public int compareTo(PathArgument arg0) { + return 0; + } + + @Override + public Class getType() { + return DataObject.class; + } + }); + InstanceIdentifier target = InstanceIdentifier.create(pathArguments); + NetconfConfigChange confChangeNotification = createNotification(EditOperationType.Create, target); + when(notifProxyParser.getTime(confChangeNotification)).thenReturn(Instant.now()); + notifListener.onNetconfConfigChange(confChangeNotification); + verify(databaseService).writeEventLog(any(EventlogEntity.class)); + } + + /** + * @param type + * @return + */ + private static NetconfConfigChange createNotification(EditOperationType type, InstanceIdentifier target) { + @SuppressWarnings("null") + final @NonNull List edits = Arrays.asList(new EditBuilder().setOperation(type).setTarget(target).build()); + when(change.nonnullEdit()).thenReturn(edits); + return change; + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanFaultNotificationListener.java new file mode 100644 index 000000000..e26af989e --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanFaultNotificationListener.java @@ -0,0 +1,115 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.google.common.io.Files; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.ORanFaultNotificationListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorServiceImpl; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class TestORanFaultNotificationListener { + + private static final Logger LOG = LoggerFactory.getLogger(TestORanFaultNotificationListener.class); + private static final String TESTFILENAME = "configFile.txt"; + + // @formatter:off + private static final String TESTCONFIG_CONTENT = "[VESCollector]\n" + + "VES_COLLECTOR_ENABLED=true\n" + + "VES_COLLECTOR_TLS_ENABLED=true\n" + + "VES_COLLECTOR_TRUST_ALL_CERTS=true\n" + + "VES_COLLECTOR_USERNAME=sample1\n" + + "VES_COLLECTOR_PASSWORD=sample1\n" + + "VES_COLLECTOR_IP=[2001:db8:1:1::1]\n" + + "VES_COLLECTOR_PORT=8443\n" + + "VES_COLLECTOR_VERSION=v7\n" + + "REPORTING_ENTITY_NAME=ONAP SDN-R\n" + + "EVENTLOG_MSG_DETAIL=SHORT\n" + + ""; + // @formatter:on + + @Mock NetconfBindingAccessor bindingAccessor; + @Mock DataProvider dataProvider; + @Mock FaultService faultService; + @Mock DeviceManagerServiceProvider serviceProvider; + @Mock WebsocketManagerService websocketManagerService; + @Mock DataProvider databaseService; + VESCollectorService vesCollectorService; + + @After + @Before + public void afterAndBefore() { + File f = new File(TESTFILENAME); + if (f.exists()) { + LOG.info("Remove {}", f.getAbsolutePath()); + f.delete(); + } + } + + @Test + public void test() throws IOException { + Files.asCharSink(new File(TESTFILENAME), StandardCharsets.UTF_8).write(TESTCONFIG_CONTENT); + vesCollectorService = + new VESCollectorServiceImpl(new ConfigurationFileRepresentation(TESTFILENAME)); + when(bindingAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + ORanFaultNotificationListener faultListener = new ORanFaultNotificationListener(bindingAccessor, + vesCollectorService, faultService, websocketManagerService, databaseService); + faultListener.onAlarmNotif(new TestAlarmNotif()); + + verify(faultService).faultNotification(getFaultLog()); + } + + private FaultlogEntity getFaultLog() { + FaultlogBuilder faultAlarm = new FaultlogBuilder(); + faultAlarm.setNodeId("nSky"); + faultAlarm.setObjectId("ORAN-RU-FH"); + faultAlarm.setProblem("CPRI Port Down"); + faultAlarm.setSeverity(SeverityType.NonAlarmed); + faultAlarm.setCounter(1); + faultAlarm.setId("123"); + faultAlarm.setSourceType(SourceType.Netconf); + faultAlarm.setTimestamp(new DateAndTime("2021-03-23T18:19:42.326144Z")); + return faultAlarm.build(); + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanNetworkElement.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanNetworkElement.java new file mode 100644 index 000000000..3de211013 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanNetworkElement.java @@ -0,0 +1,115 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.io.IOException; +import java.util.Optional; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.BeforeClass; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.startup.ORanNetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; + +public class TestORanNetworkElement { + + private static final QName OneCell = + QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); + private static final @NonNull QName OnapSystem = QName.create("urn:onap:system", "2020-10-26", "onap-system").intern(); + private static String NODEIDSTRING = "nSky"; + private static NodeId nodeId = new NodeId(NODEIDSTRING); + + private static NetconfAccessor accessor; + private static DeviceManagerServiceProvider serviceProvider; + private static Capabilities capabilities; + private static TransactionUtils transactionUtils; + private static NetconfBindingAccessor bindingAccessor; + private static NetconfDomAccessor domAccessor; + private static VESCollectorService vesCollectorService; + private static NotificationProxyParser notificationProxyParser; + private static VESCollectorCfgService vesCfgService; + private static WebsocketManagerService websocketManagerService; + + @BeforeClass + public static void init() throws InterruptedException, IOException { + capabilities = mock(Capabilities.class); + accessor = mock(NetconfAccessor.class); + serviceProvider = mock(DeviceManagerServiceProvider.class); + transactionUtils = mock(TransactionUtils.class); + bindingAccessor = mock(NetconfBindingAccessor.class); + domAccessor = mock(NetconfDomAccessor.class); + vesCollectorService = mock(VESCollectorService.class); + notificationProxyParser = mock(NotificationProxyParser.class); + vesCfgService = mock(VESCollectorCfgService.class); + websocketManagerService = mock(WebsocketManagerService.class); + + when(accessor.getCapabilites()).thenReturn(capabilities); + when(accessor.getNodeId()).thenReturn(nodeId); + when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingAccessor)); + when(accessor.getNetconfDomAccessor()).thenReturn(Optional.of(domAccessor)); + when(bindingAccessor.getCapabilites()).thenReturn(capabilities); + when(bindingAccessor.getTransactionUtils()).thenReturn(transactionUtils); + when(bindingAccessor.getNodeId()).thenReturn(nodeId); + when(vesCollectorService.getNotificationProxyParser()).thenReturn(notificationProxyParser); + + DataProvider dataProvider = mock(DataProvider.class); + FaultService faultService = mock(FaultService.class); + when(serviceProvider.getWebsocketService()).thenReturn(websocketManagerService); + when(serviceProvider.getFaultService()).thenReturn(faultService); + when(serviceProvider.getDataProvider()).thenReturn(dataProvider); + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + + } + + //@Test + public void test() { + Optional oRanNe; + when(capabilities.isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); + when(capabilities.isSupportingNamespace(OneCell)).thenReturn(false); + when(capabilities.isSupportingNamespace(OnapSystem)).thenReturn(false); + + ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); + oRanNe = factory.create(accessor, serviceProvider); + assertTrue(factory.create(accessor, serviceProvider).isPresent()); + oRanNe.get().register(); + oRanNe.get().deregister(); + oRanNe.get().getAcessor(); + oRanNe.get().getDeviceType(); + assertEquals(oRanNe.get().getNodeId().getValue(), "nSky"); + } + + } diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanToInternalDataModel.java new file mode 100644 index 000000000..a4470d335 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/TestORanToInternalDataModel.java @@ -0,0 +1,96 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.function.IntConsumer; +import java.util.stream.IntStream; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestORanToInternalDataModel { + + private static final Logger LOG = LoggerFactory.getLogger(TestORanToInternalDataModel.class); + + NodeId nodeId = new NodeId("ORan-1000"); + + @Test + public void testInventory() { + String dateTimeString = "2020-02-05T12:30:45.283Z"; + String name = "Slot-0"; + + Component testComponent = ComponentHelper.get(name, dateTimeString); + Optional oInventory = ORanToInternalDataModel.getInternalEquipment(nodeId, testComponent, 0); + + assertTrue(oInventory.isPresent()); + Inventory inventory = oInventory.get(); + assertEquals(name, inventory.getUuid()); + assertEquals(dateTimeString, inventory.getDate()); + assertEquals(nodeId.getValue(), inventory.getNodeId()); + } + + @Test + public void testInventoryList() throws IOException, ClassNotFoundException { + List componentList = ComponentHelper.getComponentList("/Device-ietf-hardware-Output.json"); + List inventoryList = ORanToInternalDataModel.getInventoryList(nodeId, componentList); + //componentList.forEach(System.out::println); + assertEquals("All elements", 27, inventoryList.size()); + assertEquals("Fully parseable", componentList.size(), inventoryList.size()); + assertEquals("Treelevel always there", 0, + inventoryList.stream().filter(inventory -> inventory.getTreeLevel() == null).count()); + listAsTree(inventoryList); + } + + private void listAsTree(List inventoryList) { + //Walk through complete list and print parameters + IntConsumer action = level -> IntStream.range(0, inventoryList.size()) + .filter(idx -> inventoryList.get(idx).getTreeLevel().intValue() == level) + .forEach(idx2 -> printElements(idx2, level, inventoryList.get(idx2))); + //Walk trough 10 levels + IntStream.range(0, 10) + .forEach(action); + } + + private void printElements(int idx2, int level, Inventory inventory) { + System.out.println(level + ": " + inventory.getParentUuid() + " " + + inventory.getUuid()); + } + + @SuppressWarnings("unused") + private boolean compareLevel(int idx, List componentList, List inventoryList) { + @Nullable + Integer relPos = componentList.get(idx).getParentRelPos(); + @Nullable + Uint32 treeLevel = inventoryList.get(idx).getTreeLevel(); + LOG.warn("Treelevel relPos: {} treeLevel: {}", relPos, treeLevel); + if (relPos != null && treeLevel != null) { + return relPos == treeLevel.intValue(); + } + return false; + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestDeviceManagerORanImpl.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestDeviceManagerORanImpl.java new file mode 100644 index 000000000..f3932bc41 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestDeviceManagerORanImpl.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.mockito.Mockito.mock; +import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.DeviceManagerORanImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; + +public class TestDeviceManagerORanImpl { + DeviceManagerORanImpl devMgrOran; + + @Before + public void init() throws InterruptedException, IOException { + } + + @Test + public void test() throws Exception { + devMgrOran = new DeviceManagerORanImpl(); + NetconfNetworkElementService netconfNetworkElementService = mock(NetconfNetworkElementService.class); + + try { + devMgrOran.setNetconfNetworkElementService(netconfNetworkElementService); + devMgrOran.init(); + } catch (Exception e) { + throw e; + } + } + + @After + public void cleanUp() throws Exception { + devMgrOran.close(); + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANInventory.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANInventory.java new file mode 100644 index 000000000..337996a3d --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANInventory.java @@ -0,0 +1,250 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.util.xml.UntrustedXML; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +public class TestORANInventory { + + private static final Logger LOG = LoggerFactory.getLogger(TestORANInventory.class); + private static final QNameModule IETF_HARDWARE_MODULE = QNameModule + .create(XMLNamespace.of("urn:ietf:params:xml:ns:yang:ietf-hardware"), Revision.of("2018-03-13")); + private static final QName HW_CONTAINER = QName.create(IETF_HARDWARE_MODULE, "hardware"); + private static final QName HW_COMPONENT_LIST = QName.create(IETF_HARDWARE_MODULE, "component"); + private static final QName HW_COMPONENT_LIST_KEY = QName.create(IETF_HARDWARE_MODULE, "name"); + private static final QName HW_COMPONENT_LIST_CLASS = QName.create(IETF_HARDWARE_MODULE, "class"); + private static final QName HW_COMPONENT_LIST_DESC = QName.create(IETF_HARDWARE_MODULE, "description"); // leaf:String + private static final QName HW_COMPONENT_LIST_PARENT = QName.create(IETF_HARDWARE_MODULE, "parent"); // leaf:leafref + private static final QName HW_COMPONENT_LIST_CONTAINS_CHILD = QName.create(IETF_HARDWARE_MODULE, "contains-child"); // leaf-list:leafref + private static final QName HW_COMPONENT_LIST_HW_REV = QName.create(IETF_HARDWARE_MODULE, "hardware-rev"); // leaf:String + private static final QName HW_COMPONENT_LIST_SER_NUM = QName.create(IETF_HARDWARE_MODULE, "serial-num"); // leaf:String + private static final QName HW_COMPONENT_LIST_MFG_NAME = QName.create(IETF_HARDWARE_MODULE, "mfg-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_MODEL_NAME = QName.create(IETF_HARDWARE_MODULE, "model-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_MFG_DATE = QName.create(IETF_HARDWARE_MODULE, "mfg-date"); // leaf:yang:date-and-time + + private static EffectiveModelContext schemaContext; + private static @NonNull Inference hwContainerSchema; + + @BeforeClass + public static void setup() throws IOException { + schemaContext = YangParserTestUtils.parseYangResourceDirectory("/"); + hwContainerSchema = Inference.ofDataTreePath(schemaContext, HW_CONTAINER); + System.out.println("URL is - " + TestORANReadHardware.class.getResource("/")); + } + + @AfterClass + public static void cleanup() { + schemaContext = null; + hwContainerSchema = null; + } + + @Test + public void testIetfHardwareFromXML() throws XMLStreamException, URISyntaxException, IOException, SAXException { + + final InputStream resourceAsStream = TestORANReadHardware.class.getResourceAsStream("/ietf-hardware.xml"); + + /* + * final XMLInputFactory factory = XMLInputFactory.newInstance(); + * XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream); + */ + final XMLStreamReader reader = UntrustedXML.createXMLStreamReader(resourceAsStream); + + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + + final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, hwContainerSchema); + xmlParser.parse(reader); + + xmlParser.flush(); + xmlParser.close(); + + NormalizedNode transformedInput = result.getResult(); + NodeId nodeId = new NodeId("nSky"); + getInventoryList(nodeId, transformedInput); + } + + public static List getInventoryList(NodeId nodeId, NormalizedNode hwData) { + + List inventoryResultList = new ArrayList(); + ContainerNode hwContainer = (ContainerNode) hwData; + MapNode componentMap = (MapNode) hwContainer.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST)); + Collection componentMapEntries = componentMap.body(); + + for (MapEntryNode componentMapEntryNode : getRootComponents(componentMapEntries)) { + inventoryResultList = recurseGetInventory(nodeId, componentMapEntryNode, componentMapEntries, 0, + inventoryResultList); + } + // Verify if result is complete + if (componentMapEntries.size() != inventoryResultList.size()) { + LOG.warn( + "Not all data were written to the Inventory. Potential entries with missing " + + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", + nodeId.getValue(), componentMapEntries.size(), inventoryResultList.size()); + } + return inventoryResultList; + } + + private static List recurseGetInventory(NodeId nodeId, MapEntryNode component, + Collection componentList, int treeLevel, List inventoryResultList) { + LOG.info("Tree level = {}", treeLevel); + // Add element to list, if conversion successfull + Optional oInventory = getInternalEquipment(nodeId, component, treeLevel); + if (oInventory.isPresent()) { + inventoryResultList.add(oInventory.get()); + } + // Walk through list of child keys and add to list + for (String childUuid : CodeHelpers + .nonnull(ORanDMDOMUtility.getLeafListValue(component, HW_COMPONENT_LIST_CONTAINS_CHILD))) { + LOG.info("Calling recursively- component is {}", childUuid); + for (MapEntryNode c : getComponentsByName(childUuid, componentList)) { + inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList); + } + } + return inventoryResultList; + } + + public static List getRootComponents(Collection componentMapEntries) { + List resultList = new ArrayList<>(); + for (MapEntryNode componentMapEntryNode : componentMapEntries) { + if (ORanDMDOMUtility.getLeafValue(componentMapEntryNode, HW_COMPONENT_LIST_PARENT) == null) { // Root + // elements + // do not + // have a + // parent + resultList.add(componentMapEntryNode); + } + } + return resultList; + } + + private static List getComponentsByName(String name, Collection componentList) { + List resultList = new ArrayList<>(); + for (MapEntryNode c : componentList) { + if (name.equals(ORanDMDOMUtility.getKeyValue(c))) { // <-- Component list is flat search for child's of name + resultList.add(c); + } + } + return resultList; + } + + public static Optional getInternalEquipment(NodeId nodeId, MapEntryNode component, int treeLevel) { + + // Make sure that expected data are not null + Objects.requireNonNull(nodeId); + Objects.requireNonNull(component); + + // Read manadatory data + + @Nullable + String nodeIdString = nodeId.getValue(); + @Nullable + String uuid = ORanDMDOMUtility.getKeyValue(component); + @Nullable + String idParent = ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_PARENT); + @Nullable + String uuidParent = idParent != null ? idParent : uuid; // <- Passt nicht + LOG.info("Dump = {}, {}, {}, {}", uuidParent, uuid, treeLevel, nodeIdString); + // do consistency check if all mandatory parameters are there + if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) { + LOG.info("Creating new instance of Inventory"); + // Build output data + + InventoryBuilder inventoryBuilder = new InventoryBuilder(); + + // General assumed as mandatory + inventoryBuilder.setNodeId(nodeIdString); + inventoryBuilder.setUuid(uuid); + inventoryBuilder.setParentUuid(uuidParent); + inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); + + // -- String list with ids of holders (optional) + inventoryBuilder + .setContainedHolder(ORanDMDOMUtility.getLeafListValue(component, HW_COMPONENT_LIST_CONTAINS_CHILD)); + + // -- Manufacturer related things (optional) + @Nullable + String mfgName = ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_MFG_NAME); + inventoryBuilder.setManufacturerName(mfgName); + inventoryBuilder.setManufacturerIdentifier(mfgName); + + // Equipment type (optional) + inventoryBuilder.setDescription(ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_DESC)); + inventoryBuilder.setModelIdentifier(ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_MODEL_NAME)); + + inventoryBuilder.setPartTypeId(ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_CLASS)); + + inventoryBuilder.setTypeName(ORanDMDOMUtility.getKeyValue(component)); + inventoryBuilder.setVersion(ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_HW_REV)); + + // Equipment instance (optional) + @Nullable + String mfgDate = ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_MFG_DATE); + if (mfgDate != null) { + inventoryBuilder.setDate(mfgDate); + } + inventoryBuilder.setSerial(ORanDMDOMUtility.getLeafValue(component, HW_COMPONENT_LIST_SER_NUM)); + + return Optional.of(inventoryBuilder.build()); + } + return Optional.empty(); + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANReadHardware.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANReadHardware.java new file mode 100644 index 000000000..b2da8e61f --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORANReadHardware.java @@ -0,0 +1,383 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import com.google.common.base.VerifyException; +import com.google.common.collect.ImmutableList; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.yangtools.util.xml.UntrustedXML; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; +//import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; //Yangtool 8.0 +import org.xml.sax.SAXException; + +public class TestORANReadHardware { + + /* + * private static final QNameModule IETF_HARDWARE_MODULE = + * QNameModule.create(XMLNamespace.of( + * "urn:ietf:params:xml:ns:yang:ietf-hardware"), Revision.of("2018-03-13")); + */ // Applicable for Yangtools 8.0 + // private static final URI IETF_HARDWARE_URI = + // URI.create("urn:ietf:params:xml:ns:yang:ietf-hardware"); + private static final QNameModule IETF_HARDWARE_MODULE = QNameModule + .create(XMLNamespace.of("urn:ietf:params:xml:ns:yang:ietf-hardware"), Revision.of("2018-03-13")); + private static final QName HW_CONTAINER = QName.create(IETF_HARDWARE_MODULE, "hardware"); + private static final QName HW_COMPONENT_LIST = QName.create(IETF_HARDWARE_MODULE, "component"); + private static final QName HW_COMPONENT_LIST_KEY = QName.create(IETF_HARDWARE_MODULE, "name"); + private static final QName HW_COMPONENT_LIST_CLASS = QName.create(IETF_HARDWARE_MODULE, "class"); + private static final QName HW_COMPONENT_LIST_PHYSICAL_INDEX = QName.create(IETF_HARDWARE_MODULE, "physical-index"); // leaf:int32 + private static final QName HW_COMPONENT_LIST_DESC = QName.create(IETF_HARDWARE_MODULE, "description"); // leaf:String + private static final QName HW_COMPONENT_LIST_PARENT = QName.create(IETF_HARDWARE_MODULE, "parent"); // leaf:leafref + private static final QName HW_COMPONENT_LIST_PARENT_REL_POS = QName.create(IETF_HARDWARE_MODULE, "parent-rel-pos"); // leaf:int32 + private static final QName HW_COMPONENT_LIST_CONTAINS_CHILD = QName.create(IETF_HARDWARE_MODULE, "contains-child"); // leaf-list:leafref + private static final QName HW_COMPONENT_LIST_HW_REV = QName.create(IETF_HARDWARE_MODULE, "hardware-rev"); // leaf:String + private static final QName HW_COMPONENT_LIST_FW_REV = QName.create(IETF_HARDWARE_MODULE, "firmware-rev"); // leaf:String + private static final QName HW_COMPONENT_LIST_SW_REV = QName.create(IETF_HARDWARE_MODULE, "software-rev"); // leaf:String + private static final QName HW_COMPONENT_LIST_SER_NUM = QName.create(IETF_HARDWARE_MODULE, "serial-num"); // leaf:String + private static final QName HW_COMPONENT_LIST_MFG_NAME = QName.create(IETF_HARDWARE_MODULE, "mfg-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_MODEL_NAME = QName.create(IETF_HARDWARE_MODULE, "model-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_ALIAS = QName.create(IETF_HARDWARE_MODULE, "alias"); // leaf:String + private static final QName HW_COMPONENT_LIST_ASSET_ID = QName.create(IETF_HARDWARE_MODULE, "asset-id"); // leaf:String + private static final QName HW_COMPONENT_LIST_IS_FRU = QName.create(IETF_HARDWARE_MODULE, "is-fru"); // leaf:boolean + private static final QName HW_COMPONENT_LIST_MFG_DATE = QName.create(IETF_HARDWARE_MODULE, "mfg-date"); // leaf:yang:date-and-time + private static final QName HW_COMPONENT_LIST_URI = QName.create(IETF_HARDWARE_MODULE, "uri"); // leaf-list:inet:uri + private static final QName HW_COMPONENT_LIST_UUID = QName.create(IETF_HARDWARE_MODULE, "uuid"); // leaf:yang:uuid + private static final QName HW_COMPONENT_LIST_STATE = QName.create(IETF_HARDWARE_MODULE, "state"); // leaf:yang:uuid + private static final QName HW_COMPONENT_LIST_ADMIN_STATE = QName.create(IETF_HARDWARE_MODULE, "admin-state"); // leaf:yang:uuid + private static final QName HW_COMPONENT_LIST_OPER_STATE = QName.create(IETF_HARDWARE_MODULE, "oper-state"); // leaf:yang:uuid + + private static EffectiveModelContext schemaContext; + private static Inference hwContainerSchema; + + @BeforeClass + public static void setup() throws IOException { + schemaContext = YangParserTestUtils.parseYangResourceDirectory("/"); + hwContainerSchema = Inference.ofDataTreePath(schemaContext, HW_CONTAINER); + System.out.println("URL is - " + TestORANReadHardware.class.getResource("/")); + } + + @AfterClass + public static void cleanup() { + schemaContext = null; + hwContainerSchema = null; + } + + @Test + public void testIetfHardwareFromXML() throws XMLStreamException, URISyntaxException, IOException, SAXException { + + final InputStream resourceAsStream = TestORANReadHardware.class.getResourceAsStream("/ietf-hardware.xml"); + + /* + * final XMLInputFactory factory = XMLInputFactory.newInstance(); + * XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream); + */ + final XMLStreamReader reader = UntrustedXML.createXMLStreamReader(resourceAsStream); + + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + + final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, hwContainerSchema); + xmlParser.parse(reader); + + xmlParser.flush(); + xmlParser.close(); + + NormalizedNode transformedInput = result.getResult(); + System.out.println("Hardware Data = " + transformedInput); + + ContainerNode hwContainer = (ContainerNode) transformedInput; + MapNode containerMap = (MapNode) hwContainer.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST)); + Collection containerMapEntries = containerMap.body(); + for (MapEntryNode mapEntryNode : containerMapEntries) { + NodeIdentifierWithPredicates componentKey = mapEntryNode.getIdentifier(); // list key + System.out.println("Key Name is - " + componentKey.keySet()); + System.out.println("Key Value is - " + componentKey.getValue(HW_COMPONENT_LIST_KEY)); + + LeafNode classField = (LeafNode) mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_CLASS)); + System.out.println("Class = " + classField.getIdentifier().getNodeType().getLocalName() + " Value = " + + classField.body().toString()); + Object obj = classField.body(); + System.out.println(obj.getClass()); + if (obj instanceof QName) { + System.out.println("This is of type QName"); + } + LeafNode aliasLeaf = (LeafNode) mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_ALIAS)); + // System.out.println("Alias = " + aliasLeaf.getValue().toString()); + System.out.println("Alias = " + getLeafValue(mapEntryNode, HW_COMPONENT_LIST_ALIAS)); + + try { + DataContainerChild childSet = mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_CONTAINS_CHILD)); + + Collection childEntry = (Collection) childSet.body(); + Iterator childEntryItr = childEntry.iterator(); + while (childEntryItr.hasNext()) { + LeafSetEntryNode childEntryNode = (LeafSetEntryNode) childEntryItr.next(); + System.out.println("Child Node - " + childEntryNode.body()); + } + } catch (VerifyException ve) { + // System.out.println("Child not not exist"); + } + + try { + LeafSetNode containsChildSet = (LeafSetNode) mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_CONTAINS_CHILD)); + Collection containsChildSetEntry = containsChildSet.body(); + Iterator childItr = containsChildSetEntry.iterator(); + while (childItr.hasNext()) { + LeafSetEntryNode childEntryNode = (LeafSetEntryNode) childItr.next(); + System.out.println("Child Node - " + childEntryNode.body()); + } + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + + try { + System.out + .println(CodeHelpers.nonnull(getLeafListValue(mapEntryNode, HW_COMPONENT_LIST_CONTAINS_CHILD))); + for (String childUuid : CodeHelpers + .nonnull(getLeafListValue(mapEntryNode, HW_COMPONENT_LIST_CONTAINS_CHILD))) { + System.out.println("Calling recursively - " + childUuid); + } + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String description = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_DESC)) + .body(); + System.out.println("Description = " + description); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String serialNum = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_SER_NUM)) + .body(); + System.out.println("Serial Number = " + serialNum); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String firmwareRev = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_FW_REV)) + .body(); + System.out.println("Firmware Rev = " + firmwareRev); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String swRev = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_SW_REV)).body(); + System.out.println("Software Rev = " + swRev); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String modelName = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_MODEL_NAME)) + .body(); + System.out.println("Model Name = " + modelName); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + Integer parentRelPos = (Integer) mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_PARENT_REL_POS)).body(); + System.out.println("Parent Rel Pos = " + (parentRelPos != null ? parentRelPos.intValue() : null)); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String parent = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_PARENT)) + .body(); + System.out.println("Parent = " + parent); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String hwRev = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_HW_REV)).body(); + System.out.println("Hardware Revision = " + hwRev); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String mfgName = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_MFG_NAME)) + .body(); + System.out.println("Manufacturer Name = " + mfgName); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + DataContainerChild mfgNameOpt = mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_MFG_NAME)); + if (mfgNameOpt != null) { + System.out.println("Mfg Name - " + (String) mfgNameOpt.body()); + } + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String assetID = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_ASSET_ID)) + .body(); + System.out.println("Asset ID = " + assetID); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String mfgDate = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_MFG_DATE)) + .body(); + System.out.println("Mfg Date = " + mfgDate); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String uri = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_URI)).body(); + System.out.println("URI = " + uri); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + Boolean isFRU = (Boolean) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_IS_FRU)) + .body(); + System.out.println("IS FRU = " + isFRU); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + try { + String uuid = (String) mapEntryNode.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_UUID)).body() + .toString(); + System.out.println("UUID = " + uuid); + } catch (VerifyException | NoSuchElementException e) { + // System.out.println("Child not not exist"); + } + + try { + ContainerNode state = (ContainerNode) mapEntryNode + .getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_STATE)); + String adminState = (String) state.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_ADMIN_STATE)) + .body().toString(); + System.out.println("Admin State = " + adminState); + String operState = (String) state.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST_OPER_STATE)).body() + .toString(); + + System.out.println("Oper State = " + operState); + } catch (VerifyException | NoSuchElementException e) { + System.out.println("Child not not exist"); + } + + System.out.println("********************************************"); + + } + // assertNotNull(transformedInput); + + } + + public static String getLeafValue(DataContainerNode componentEntry, QName leafQName) { + NodeIdentifier leafNodeIdentifier = new NodeIdentifier(leafQName); + try { + LeafNode optLeafNode = (LeafNode) componentEntry.getChildByArg(leafNodeIdentifier); + if (optLeafNode.body() instanceof QName) { + System.out.println("Leaf is of type QName"); + } + return optLeafNode.body().toString(); + } catch (NoSuchElementException nsee) { + System.out.println("Leaf with QName {} not found" + leafQName.toString()); + return null; + } + } + + public static List getLeafListValue(DataContainerNode componentEntry, QName leafListQName) { + if (componentEntry instanceof MapEntryNode) { + List containsChildList = new ArrayList(); + DataContainerChild childSet = componentEntry.getChildByArg(new NodeIdentifier(leafListQName)); + if (childSet != null) { + Collection childEntry = (Collection) childSet.body(); + Iterator childEntryItr = childEntry.iterator(); + while (childEntryItr.hasNext()) { + LeafSetEntryNode childEntryNode = (LeafSetEntryNode) childEntryItr.next(); + containsChildList.add(childEntryNode.body().toString()); + } + } + return containsChildList; + } + return null; + } + + @Test + public void testIetfHardwareFromNormalizedNode() { + buildIetfHardwareContainerNode(); + } + + private static NormalizedNode buildIetfHardwareContainerNode() { + MapNode componentMap = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST)) + .withChild(Builders.mapEntryBuilder() + .withNodeIdentifier( + NodeIdentifierWithPredicates.of(HW_COMPONENT_LIST, HW_COMPONENT_LIST_KEY, "chassis")) + .withChild( + Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_CLASS)) + .withValue("ianahw:chassis").build()) + .withChild(Builders.leafBuilder() + .withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_PHYSICAL_INDEX)).withValue(1) + .build()) + .build()) + .build(); + return componentMap; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMFaultNotificationListener.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMFaultNotificationListener.java new file mode 100644 index 000000000..8abfb2d3e --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMFaultNotificationListener.java @@ -0,0 +1,164 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.google.common.io.Files; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.TestORanFaultNotificationListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorServiceImpl; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class TestORanDOMFaultNotificationListener { + private static final Logger LOG = LoggerFactory.getLogger(TestORanFaultNotificationListener.class); + private static final String TESTFILENAME = "configFile.txt"; + + // @formatter:off + private static final String TESTCONFIG_CONTENT = "[VESCollector]\n" + + "VES_COLLECTOR_ENABLED=true\n" + + "VES_COLLECTOR_TLS_ENABLED=true\n" + + "VES_COLLECTOR_TRUST_ALL_CERTS=true\n" + + "VES_COLLECTOR_USERNAME=sample1\n" + + "VES_COLLECTOR_PASSWORD=sample1\n" + + "VES_COLLECTOR_IP=[2001:db8:1:1::1]\n" + + "VES_COLLECTOR_PORT=8443\n" + + "VES_COLLECTOR_VERSION=v7\n" + + "REPORTING_ENTITY_NAME=ONAP SDN-R\n" + + "EVENTLOG_MSG_DETAIL=SHORT\n" + + ""; + // @formatter:on + + @Mock + NetconfDomAccessor domAccessor; + @Mock + DataProvider dataProvider; + @Mock + FaultService faultService; + @Mock + DeviceManagerServiceProvider serviceProvider; + @Mock + WebsocketManagerService websocketManagerService; + @Mock + DataProvider databaseService; + VESCollectorService vesCollectorService; + + @After + @Before + public void afterAndBefore() { + File f = new File(TESTFILENAME); + if (f.exists()) { + LOG.info("Remove {}", f.getAbsolutePath()); + f.delete(); + } + } + + @Test + public void test() throws IOException { + Files.asCharSink(new File(TESTFILENAME), StandardCharsets.UTF_8).write(TESTCONFIG_CONTENT); + vesCollectorService = new VESCollectorServiceImpl(new ConfigurationFileRepresentation(TESTFILENAME)); + when(domAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + ORanDOMFaultNotificationListener faultListener = new ORanDOMFaultNotificationListener(domAccessor, + vesCollectorService, faultService, websocketManagerService, databaseService); + NetconfDeviceNotification ndn = new NetconfDeviceNotification(createORANDOMFault(), Instant.now()); + faultListener.onNotification(ndn); + + verify(faultService).faultNotification(any(FaultlogEntity.class)); + } + + public static ContainerNode createORANDOMFault() { + final QName fault_id = QName.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF, "fault-id"); + final QName fault_source = QName.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF, "fault-source"); + final QName fault_severity = QName.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF, "fault-severity"); + final QName is_cleared = QName.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF, "is-cleared"); + final QName fault_text = QName.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF, "fault-text"); + return Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF)) + .withChild(ImmutableNodes.leafNode(fault_id, "47")) + .withChild(ImmutableNodes.leafNode(fault_source, "Slot-2-Port-B")) + .withChild(ImmutableNodes.leafNode(fault_severity, "MAJOR")) + .withChild(ImmutableNodes.leafNode(is_cleared, "true")) + .withChild(ImmutableNodes.leafNode(fault_text, "CPRI Port Down")).build(); + } + + + public static class NetconfDeviceNotification implements DOMNotification, DOMEvent { + private final ContainerNode content; + private final Absolute schemaPath; + private final Instant eventTime; + + NetconfDeviceNotification(final ContainerNode content, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = Absolute.of(content.getIdentifier().getNodeType()); + } + + NetconfDeviceNotification(final ContainerNode content, final Absolute schemaPath, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = schemaPath; + } + + @Override + public Absolute getType() { + return schemaPath; + } + + @Override + public ContainerNode getBody() { + return content; + } + + @Override + public Instant getEventInstant() { + return eventTime; + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNetworkElement.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNetworkElement.java new file mode 100644 index 000000000..c75f4f5a1 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNetworkElement.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.io.IOException; +import java.util.Optional; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.startup.ORanNetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; + +public class TestORanDOMNetworkElement { + + private static final QName OneCell = + QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); + private static final @NonNull QName OnapSystem = + QName.create("urn:onap:system", "2020-10-26", "onap-system").intern(); + private static String NODEIDSTRING = "nSky"; + private static NodeId nodeId = new NodeId(NODEIDSTRING); + + private static NetconfAccessor accessor; + private static DeviceManagerServiceProvider serviceProvider; + private static Capabilities capabilities; + private static NetconfDomAccessor domAccessor; + private static VESCollectorService vesCollectorService; + private static NotificationProxyParser notificationProxyParser; + private static VESCollectorCfgService vesCfgService; + private static WebsocketManagerService websocketManagerService; + + @BeforeClass + public static void init() throws InterruptedException, IOException { + capabilities = mock(Capabilities.class); + accessor = mock(NetconfAccessor.class); + serviceProvider = mock(DeviceManagerServiceProvider.class); + domAccessor = mock(NetconfDomAccessor.class); + vesCollectorService = mock(VESCollectorService.class); + notificationProxyParser = mock(NotificationProxyParser.class); + vesCfgService = mock(VESCollectorCfgService.class); + websocketManagerService = mock(WebsocketManagerService.class); + + when(accessor.getCapabilites()).thenReturn(capabilities); + when(accessor.getNodeId()).thenReturn(nodeId); + when(accessor.getNetconfDomAccessor()).thenReturn(Optional.of(domAccessor)); + when(domAccessor.getNodeId()).thenReturn(nodeId); + when(domAccessor.getCapabilites()).thenReturn(capabilities); + when(vesCollectorService.getNotificationProxyParser()).thenReturn(notificationProxyParser); + + DataProvider dataProvider = mock(DataProvider.class); + FaultService faultService = mock(FaultService.class); + when(serviceProvider.getWebsocketService()).thenReturn(websocketManagerService); + when(serviceProvider.getFaultService()).thenReturn(faultService); + when(serviceProvider.getDataProvider()).thenReturn(dataProvider); + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + + } + + @Test + public void test() { + Optional oRanNe; + when(capabilities.isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)).thenReturn(true); + when(capabilities.isSupportingNamespace(OneCell)).thenReturn(false); + when(capabilities.isSupportingNamespace(OnapSystem)).thenReturn(false); + + ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); + oRanNe = factory.create(accessor, serviceProvider); + assertTrue(factory.create(accessor, serviceProvider).isPresent()); + oRanNe.get().register(); + oRanNe.get().deregister(); + oRanNe.get().getAcessor(); + oRanNe.get().getDeviceType(); + assertEquals(oRanNe.get().getNodeId().getValue(), "nSky"); + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNotification.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNotification.java new file mode 100644 index 000000000..1665ac1ad --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMNotification.java @@ -0,0 +1,184 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.time.Instant; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class TestORanDOMNotification { + + private static final Logger log = LoggerFactory.getLogger(TestORanDOMNotification.class); + static ContainerNode cn = null; + static NodeId nodeId = new NodeId("nSky"); + private static NetconfDomAccessor domAccessor; + private static VESCollectorService vesCollectorService; + private static DataProvider databaseService; + private static VESCollectorCfgService vesCfgService; + // Use the below procedure for creating QName if binding generated classes are not available + /*String ietf_netconf_notif_ns = "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications"; + String ietf_netconf_notif_ns_date = "2012-02-06"; + QName username = QName.create(ietf_netconf_notif_ns, ietf_netconf_notif_ns_date, "username");*/ + + + @BeforeClass + public static void prepare() { + domAccessor = mock(NetconfDomAccessor.class); + vesCollectorService = mock(VESCollectorService.class); + databaseService = mock(DataProvider.class); + vesCfgService = mock(VESCollectorCfgService.class); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + when(domAccessor.getNodeId()).thenReturn(nodeId); + } + + /* + ImmutableContainerNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)netconf-config-change, + value=[ + ImmutableContainerNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)changed-by, + value=[ + ImmutableChoiceNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)server-or-user, + value=[ + ImmutableLeafNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)username, + value=root + }, + ImmutableLeafNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)session-id, + value=2 + } + ] + } + ] + }, + ImmutableUnkeyedListNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)edit, + value=[ + ImmutableUnkeyedListEntryNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)edit, + value=[ + ImmutableLeafNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)operation, + value=replace + }, + ImmutableLeafNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)target, value=/(urn:ietf:params:xml:ns:yang:ietf-hardware?revision=2018-03-13)hardware/component/component[{(urn:ietf:params:xml:ns:yang:ietf-hardware?revision=2018-03-13)name=chassis-fan3}]/alias + } + ] + } + ] + }, + ImmutableLeafNode{ + identifier=(urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?revision=2012-02-06)datastore, + value=running + } + ] + } + */ + private static ContainerNode createDOMNotificationBody() { + return Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_NETCONF_CONFIG_CHANGE)) + .withChild( + Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_CHANGEDBY)) + .withChild(Builders.choiceBuilder() + .withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_SERVERORUSER)) + .withChild(ImmutableNodes.leafNode(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_USERNAME, "root")) + .withChild(ImmutableNodes.leafNode(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_SESSIONID, Uint32.valueOf(2))).build()) + .build()) + .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_EDITNODE)) + .withChild(Builders.unkeyedListEntryBuilder() + .withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_EDITNODE)) + .withChild(ImmutableNodes.leafNode(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_OPERATION, "replace")) + .withChild(ImmutableNodes.leafNode(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_TARGET, + "/(urn:ietf:params:xml:ns:yang:ietf-hardware?revision=2018-03-13)hardware/component[{(urn:ietf:params:xml:ns:yang:ietf-hardware?revision=2018-03-13)name=chassis-fan3}]/alias")) + .build()) + .build()) + .withChild(ImmutableNodes.leafNode(ORanDeviceManagerQNames.IETF_NETCONF_NOTIFICATIONS_DATASTORE, "running")).build(); + } + + @Test + public void test() { + ContainerNode cn = createDOMNotificationBody(); + System.out.println(cn.toString()); + NetconfDeviceNotification ndn = new NetconfDeviceNotification(cn, Instant.now()); + ORanDOMChangeNotificationListener changeListener = new ORanDOMChangeNotificationListener(domAccessor, vesCollectorService, databaseService); + changeListener.onNotification(ndn); + verify(databaseService).writeEventLog(any(EventlogEntity.class)); + } + + public static class NetconfDeviceNotification implements DOMNotification, DOMEvent { + private final ContainerNode content; + private final Absolute schemaPath; + private final Instant eventTime; + + NetconfDeviceNotification(final ContainerNode content, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = Absolute.of(content.getIdentifier().getNodeType()); + } + + NetconfDeviceNotification(final ContainerNode content, final Absolute schemaPath, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = schemaPath; + } + + @Override + public Absolute getType() { + return schemaPath; + } + + @Override + public ContainerNode getBody() { + return content; + } + + @Override + public Instant getEventInstant() { + return eventTime; + } + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMToInternalDataModel.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMToInternalDataModel.java new file mode 100644 index 000000000..4eac71cde --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanDOMToInternalDataModel.java @@ -0,0 +1,202 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.junit.Assert.assertEquals; +import com.google.common.collect.Sets; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.mdsal.dom.api.DOMEvent; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.util.xml.UntrustedXML; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; +import org.xml.sax.SAXException; + +public class TestORanDOMToInternalDataModel { + + private static final QNameModule IETF_HARDWARE_MODULE = QNameModule + .create(XMLNamespace.of("urn:ietf:params:xml:ns:yang:ietf-hardware"), Revision.of("2018-03-13")); + private static final QName HW_CONTAINER = QName.create(IETF_HARDWARE_MODULE, "hardware"); + + private static final QNameModule IETF_SYSTEM_MODULE = QNameModule + .create(XMLNamespace.of("urn:ietf:params:xml:ns:yang:ietf-system"), Revision.of("2014-08-06")); + private static final QName IETF_CONTAINER = QName.create(IETF_SYSTEM_MODULE, "system"); + + private static EffectiveModelContext schemaContext; + private static Inference hwContainerSchema; + private static Inference systemSchema; + + private static final NodeId nodeId = new NodeId("nSky"); + + @BeforeClass + public static void setup() throws IOException { + schemaContext = YangParserTestUtils.parseYangResourceDirectory("/"); + hwContainerSchema = Inference.ofDataTreePath(schemaContext, HW_CONTAINER); + systemSchema = Inference.ofDataTreePath(schemaContext, IETF_CONTAINER); + } + + @AfterClass + public static void cleanup() { + schemaContext = null; + hwContainerSchema = null; + systemSchema = null; + } + + @Test + public void testIetfHardwareFromXML() throws XMLStreamException, URISyntaxException, IOException, SAXException { + + final InputStream resourceAsStream = TestORANReadHardware.class.getResourceAsStream("/ietf-hardware.xml"); + + /* + * final XMLInputFactory factory = XMLInputFactory.newInstance(); + * XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream); + */ + final XMLStreamReader reader = UntrustedXML.createXMLStreamReader(resourceAsStream); + + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + + final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, hwContainerSchema); + xmlParser.parse(reader); + + xmlParser.flush(); + xmlParser.close(); + + NormalizedNode transformedInput = result.getResult(); + + List inventoryList = ORanDOMToInternalDataModel.getInventoryList(nodeId, transformedInput); + assertEquals("All elements", 27, inventoryList.size()); + assertEquals("Treelevel always there", 0, + inventoryList.stream().filter(inventory -> inventory.getTreeLevel() == null).count()); + } + + @Test + public void testIetfSystemFromXML() throws XMLStreamException, URISyntaxException, IOException, SAXException { + + final InputStream resourceAsStream = TestORANReadHardware.class.getResourceAsStream("/onap-system.xml"); + + final XMLStreamReader reader = UntrustedXML.createXMLStreamReader(resourceAsStream); + + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + + final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, systemSchema); + xmlParser.parse(reader); + + xmlParser.flush(); + xmlParser.close(); + + NormalizedNode transformedInput = result.getResult(); + ContainerNode cn = (ContainerNode) transformedInput; + AugmentationIdentifier onapSystemIID = YangInstanceIdentifier.AugmentationIdentifier.create( + Sets.newHashSet(ORanDeviceManagerQNames.ONAP_SYSTEM_NAME, ORanDeviceManagerQNames.ONAP_SYSTEM_WEB_UI)); + Optional gc = ORanDOMToInternalDataModel.getGuicutthrough(cn.getChildByArg(onapSystemIID)); + assertEquals(gc.isPresent(), true); + + } + + @Test + public void testORANFault() { + ContainerNode cn = createORANDOMFault(); + NetconfDeviceNotification faultNotif = new NetconfDeviceNotification(cn, Instant.now()); + FaultlogEntity fle = ORanDOMToInternalDataModel.getFaultLog(faultNotif, nodeId, 1); + assertEquals(fle.getId(), "47"); + } + + public static ContainerNode createORANDOMFault() { + final QName fault_id = QName.create(ORanDeviceManagerQNames.ORAN_FM_FAULT_ID, "fault-id"); + final QName fault_source = QName.create(ORanDeviceManagerQNames.ORAN_FM_FAULT_SOURCE, "fault-source"); + final QName fault_severity = QName.create(ORanDeviceManagerQNames.ORAN_FM_FAULT_SEVERITY, "fault-severity"); + final QName is_cleared = QName.create(ORanDeviceManagerQNames.ORAN_FM_FAULT_IS_CLEARED, "is-cleared"); + final QName fault_text = QName.create(ORanDeviceManagerQNames.ORAN_FM_FAULT_TEXT, "fault-text"); + return Builders.containerBuilder() + .withNodeIdentifier(NodeIdentifier.create(ORanDeviceManagerQNames.ORAN_FM_ALARM_NOTIF)) + .withChild(ImmutableNodes.leafNode(fault_id, "47")) + .withChild(ImmutableNodes.leafNode(fault_source, "Slot-2-Port-B")) + .withChild(ImmutableNodes.leafNode(fault_severity, "MAJOR")) + .withChild(ImmutableNodes.leafNode(is_cleared, "true")) + .withChild(ImmutableNodes.leafNode(fault_text, "CPRI Port Down")).build(); + } + + public static class NetconfDeviceNotification implements DOMNotification, DOMEvent { + private final ContainerNode content; + private final Absolute schemaPath; + private final Instant eventTime; + + NetconfDeviceNotification(final ContainerNode content, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = Absolute.of(content.getIdentifier().getNodeType()); + } + + NetconfDeviceNotification(final ContainerNode content, final Absolute schemaPath, final Instant eventTime) { + this.content = content; + this.eventTime = eventTime; + this.schemaPath = schemaPath; + } + + @Override + public Absolute getType() { + return schemaPath; + } + + @Override + public ContainerNode getBody() { + return content; + } + + @Override + public Instant getEventInstant() { + return eventTime; + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanNetworkElementFactory.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanNetworkElementFactory.java new file mode 100644 index 000000000..27793e4bb --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanNetworkElementFactory.java @@ -0,0 +1,101 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.io.IOException; +import java.util.Optional; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.startup.ORanNetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.WebsocketManagerService; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; + +public class TestORanNetworkElementFactory { + + private static String NODEIDSTRING = "nSky"; + + private static NetconfAccessor accessor; + private static DeviceManagerServiceProvider serviceProvider; + private static Capabilities capabilities; + private static VESCollectorService vesCollectorService; + private static FaultService faultService; + private static WebsocketManagerService notificationService; + private static DataProvider databaseService; + private static NodeId nodeId = new NodeId(NODEIDSTRING); + + @BeforeClass + public static void init() throws InterruptedException, IOException { + NetconfBindingAccessor bindingAccessor = mock(NetconfBindingAccessor.class); + when(bindingAccessor.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); + when(bindingAccessor.getNodeId()).thenReturn(nodeId); + + NetconfDomAccessor domAccessor = mock(NetconfDomAccessor.class); + when(domAccessor.getNodeId()).thenReturn(nodeId); + + capabilities = mock(Capabilities.class); + //accessor = mock(NetconfBindingAccessor.class); + accessor = mock(NetconfAccessor.class); + serviceProvider = mock(DeviceManagerServiceProvider.class); + vesCollectorService = mock(VESCollectorService.class); + faultService = mock(FaultService.class); + notificationService = mock(WebsocketManagerService.class); + databaseService = mock(DataProvider.class); + + when(accessor.getCapabilites()).thenReturn(capabilities); + when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingAccessor)); + when(accessor.getNetconfDomAccessor()).thenReturn(Optional.of(domAccessor)); + when(serviceProvider.getFaultService()).thenReturn(faultService); + when(serviceProvider.getWebsocketService()).thenReturn(notificationService); + when(serviceProvider.getDataProvider()).thenReturn(databaseService); + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); + + } + + @Test + public void testCreateORANHWComponent() throws Exception { + when(accessor.getCapabilites().isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)).thenReturn(true); + ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); + assertTrue((factory.create(accessor, serviceProvider)).isPresent()); + } + + @Test + public void testCreateNone() throws Exception { + when(accessor.getCapabilites().isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)).thenReturn(false); + ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); + assertTrue(!(factory.create(accessor, serviceProvider).isPresent())); + } + + @After + public void cleanUp() throws Exception { + + } +} + diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanRegistrationToVESpnfRegistration.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanRegistrationToVESpnfRegistration.java new file mode 100644 index 000000000..d520af5ba --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/TestORanRegistrationToVESpnfRegistration.java @@ -0,0 +1,119 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.ORanRegistrationToVESpnfRegistrationMapper; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; + +@RunWith(MockitoJUnitRunner.class) +public class TestORanRegistrationToVESpnfRegistration { + + @Mock + NetconfAccessor netconfAccessor; + @Mock + VESCollectorService vesCollectorService; + @Mock + VESCollectorCfgService vesCfgService; + + private static final QNameModule IETF_HARDWARE_MODULE = QNameModule + .create(XMLNamespace.of("urn:ietf:params:xml:ns:yang:ietf-hardware"), Revision.of("2018-03-13")); + private static final QName HW_COMPONENT_LIST = QName.create(IETF_HARDWARE_MODULE, "component"); + private static final QName HW_COMPONENT_LIST_KEY = QName.create(IETF_HARDWARE_MODULE, "name"); + private static final QName HW_COMPONENT_LIST_CLASS = QName.create(IETF_HARDWARE_MODULE, "class"); + private static final QName HW_COMPONENT_LIST_PHYSICAL_INDEX = QName.create(IETF_HARDWARE_MODULE, "physical-index"); // leaf:int32 + private static final QName HW_COMPONENT_LIST_DESC = QName.create(IETF_HARDWARE_MODULE, "description"); // leaf:String + private static final QName HW_COMPONENT_LIST_SW_REV = QName.create(IETF_HARDWARE_MODULE, "software-rev"); // leaf:String + private static final QName HW_COMPONENT_LIST_SER_NUM = QName.create(IETF_HARDWARE_MODULE, "serial-num"); // leaf:String + private static final QName HW_COMPONENT_LIST_MFG_NAME = QName.create(IETF_HARDWARE_MODULE, "mfg-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_MODEL_NAME = QName.create(IETF_HARDWARE_MODULE, "model-name"); // leaf:String + private static final QName HW_COMPONENT_LIST_ALIAS = QName.create(IETF_HARDWARE_MODULE, "alias"); // leaf:String + + @Test + public void test() { + NetconfNode testNetconfNode = mock(NetconfNode.class); + when(testNetconfNode.getHost()).thenReturn(new Host(new IpAddress(new Ipv4Address("10.10.10.10")))); + + when(netconfAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + when(netconfAccessor.getNetconfNode()).thenReturn(testNetconfNode); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R"); + + ORanRegistrationToVESpnfRegistrationMapper mapper = new ORanRegistrationToVESpnfRegistrationMapper( + netconfAccessor, vesCollectorService); + VESCommonEventHeaderPOJO commonHeader = mapper.mapCommonEventHeader(buildComponentEntry()); + VESPNFRegistrationFieldsPOJO pnfFields = mapper.mapPNFRegistrationFields(buildComponentEntry()); + + assertEquals(commonHeader.getNfVendorName(), "ISCO"); + assertEquals(pnfFields.getUnitType(), "chassis"); + assertEquals(pnfFields.getSerialNumber(), "10283"); + assertEquals(pnfFields.getSoftwareVersion(), "3.8.1 (2020-10-30 11:47:59)"); + } + + public MapEntryNode buildComponentEntry() { + return Builders.mapEntryBuilder() + .withNodeIdentifier( + NodeIdentifierWithPredicates.of(HW_COMPONENT_LIST, HW_COMPONENT_LIST_KEY, "chassis")) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_CLASS)) + .withValue("ianahw:chassis").build()) + .withChild(Builders.leafBuilder() + .withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_PHYSICAL_INDEX)).withValue(1).build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_MFG_NAME)) + .withValue("ISCO").build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_MODEL_NAME)) + .withValue("ProteusCPRI Compact").build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_ALIAS)) + .withValue("chassis").build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_SER_NUM)) + .withValue("10283").build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_DESC)) + .withValue("HighStreet-ONAP40").build()) + .withChild(Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(HW_COMPONENT_LIST_SW_REV)) + .withValue("3.8.1 (2020-10-30 11:47:59)").build()) + .build(); + + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/YangParserTestUtils.java b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/YangParserTestUtils.java new file mode 100644 index 000000000..1d1726003 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/dom/YangParserTestUtils.java @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; + +import com.google.common.annotations.Beta; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.parser.api.YangParser; +import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration; +import org.opendaylight.yangtools.yang.parser.api.YangParserException; +import org.opendaylight.yangtools.yang.parser.api.YangParserFactory; +import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** + * Utility class which provides convenience methods for producing effective schema context based on the supplied + * yang/yin sources or paths to these sources. + */ +@Beta +public final class YangParserTestUtils { + + private static final FileFilter YANG_FILE_FILTER = file -> { + // Locale keeps SpotBugs happy. It should not matter that much anyway. + final String name = file.getName().toLowerCase(Locale.ENGLISH); + return name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION) && file.isFile(); + }; + + private static final @NonNull YangParserFactory PARSER_FACTORY; + + static { + final Iterator<@NonNull YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator(); + if (!it.hasNext()) { + throw new IllegalStateException("No YangParserFactory found"); + } + PARSER_FACTORY = it.next(); + } + + private YangParserTestUtils() { + // Hidden on purpose + } + + /** + * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to + * default mode and all YANG features are supported. + * + * @param resource relative path to the YANG file to be parsed + * + * @return effective schema context + */ + public static EffectiveModelContext parseYangResource(final String resource) { + return parseYangResource(resource, YangParserConfiguration.DEFAULT); + } + + /** + * Creates a new effective schema context containing the specified YANG source. All YANG features are supported. + * + * @param resource relative path to the YANG file to be parsed + * @param parserMode mode of statement parser + * @return effective schema context + */ + public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config) { + return parseYangResource(resource, config, null); + } + + /** + * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to + * default mode. + * + * @param resource relative path to the YANG file to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * model are resolved + * @return effective schema context + */ + public static EffectiveModelContext parseYangResource(final String resource, final Set supportedFeatures) { + return parseYangResource(resource, YangParserConfiguration.DEFAULT, supportedFeatures); + } + + /** + * Creates a new effective schema context containing the specified YANG source. + * + * @param resource relative path to the YANG file to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * model are resolved + * @param parserMode mode of statement parser + * @return effective schema context + */ + public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config, + final Set supportedFeatures) { + final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource); + return parseYangSources(config, supportedFeatures, source); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode and all YANG features are supported. + * + * @param files YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final File... files) { + return parseYangFiles(Arrays.asList(files)); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode and all YANG features are supported. + * + * @param files collection of YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final Collection files) { + return parseYangFiles(YangParserConfiguration.DEFAULT, files); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode. + * + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @param files YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final Set supportedFeatures, final File... files) { + return parseYangFiles(supportedFeatures, Arrays.asList(files)); + } + + public static EffectiveModelContext parseYangFiles(final Set supportedFeatures, + final Collection files) { + return parseYangFiles(supportedFeatures, YangParserConfiguration.DEFAULT, files); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported. + * + * @param parserMode mode of statement parser + * @param files YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config, final File... files) { + return parseYangFiles(config, Arrays.asList(files)); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported. + * + * @param parserMode mode of statement parser + * @param files collection of YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config, + final Collection files) { + return parseYangFiles(null, config, files); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. + * + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @param parserMode mode of statement parser + * @param files YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final Set supportedFeatures, + final YangParserConfiguration config, final File... files) { + return parseYangFiles(supportedFeatures, config, Arrays.asList(files)); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. + * + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @param parserMode mode of statement parser + * @param files YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangFiles(final Set supportedFeatures, + final YangParserConfiguration config, final Collection files) { + return parseSources(config, supportedFeatures, + files.stream().map(YangTextSchemaSource::forFile).collect(Collectors.toList())); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode and all YANG features are supported. + * + * @param resourcePath relative path to the directory with YANG files to be parsed + * @return effective schema context + */ + public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath) { + return parseYangResourceDirectory(resourcePath, YangParserConfiguration.DEFAULT); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported. + * + * @param resourcePath relative path to the directory with YANG files to be parsed + * @param parserMode mode of statement parser + * @return effective schema context + */ + public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath, + final YangParserConfiguration config) { + return parseYangResourceDirectory(resourcePath, null, config); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode. + * + * @param resourcePath relative path to the directory with YANG files to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @return effective schema context + */ + public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath, + final Set supportedFeatures) { + return parseYangResourceDirectory(resourcePath, supportedFeatures, YangParserConfiguration.DEFAULT); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. + * + * @param resourcePath relative path to the directory with YANG files to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @param parserMode mode of statement parser + * @return effective schema context + */ + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles") + public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath, + final Set supportedFeatures, final YangParserConfiguration config) { + final URI directoryPath; + try { + directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Failed to open resource " + resourcePath, e); + } + return parseYangFiles(supportedFeatures, config, new File(directoryPath).listFiles(YANG_FILE_FILTER)); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode and all YANG features are supported. + * + * @param clazz Resource lookup base + * @param resources Resource names to be looked up + * @return effective schema context + */ + public static EffectiveModelContext parseYangResources(final Class clazz, final String... resources) { + return parseYangResources(clazz, Arrays.asList(resources)); + } + + public static EffectiveModelContext parseYangResources(final Class clazz, final Collection resources) { + final List sources = new ArrayList<>(resources.size()); + for (final String r : resources) { + sources.add(YangTextSchemaSource.forResource(clazz, r)); + } + return parseSources(YangParserConfiguration.DEFAULT, null, sources); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to + * default mode. + * + * @param yangDirs relative paths to the directories containing YANG files to be parsed + * @param yangFiles relative paths to the YANG files to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @return effective schema context + */ + public static EffectiveModelContext parseYangResources(final List yangDirs, final List yangFiles, + final Set supportedFeatures) { + return parseYangResources(yangDirs, yangFiles, supportedFeatures, YangParserConfiguration.DEFAULT); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported. + * + * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed + * @param yangResources relative paths to the YANG files to be parsed + * @param statementParserMode mode of statement parser + * @return effective schema context + */ + public static EffectiveModelContext parseYangResources(final List yangResourceDirs, + final List yangResources, final YangParserConfiguration config) { + return parseYangResources(yangResourceDirs, yangResources, null, config); + } + + /** + * Creates a new effective schema context containing the specified YANG sources. + * + * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed + * @param yangResources relative paths to the YANG files to be parsed + * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG + * models are resolved + * @param statementParserMode mode of statement parser + * @return effective schema context + */ + public static EffectiveModelContext parseYangResources(final List yangResourceDirs, + final List yangResources, final Set supportedFeatures, + final YangParserConfiguration config) { + final List allYangFiles = new ArrayList<>(); + for (final String yangDir : yangResourceDirs) { + allYangFiles.addAll(getYangFiles(yangDir)); + } + + for (final String yangFile : yangResources) { + try { + allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI())); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid resource " + yangFile, e); + } + } + + return parseYangFiles(supportedFeatures, config, allYangFiles); + } + + public static EffectiveModelContext parseYangSources(final YangParserConfiguration config, + final Set supportedFeatures, final YangTextSchemaSource... sources) { + return parseSources(config, supportedFeatures, Arrays.asList(sources)); + } + + public static EffectiveModelContext parseSources(final YangParserConfiguration config, + final Set supportedFeatures, final Collection sources) { + final YangParser parser = PARSER_FACTORY.createParser(config); + if (supportedFeatures != null) { + parser.setSupportedFeatures(supportedFeatures); + } + + try { + parser.addSources(sources); + } catch (YangSyntaxErrorException e) { + throw new IllegalArgumentException("Malformed source", e); + } catch (IOException e) { + throw new IllegalArgumentException("Failed to read a source", e); + } + + try { + return parser.buildEffectiveModel(); + } catch (YangParserException e) { + throw new IllegalStateException("Failed to assemble SchemaContext", e); + } + } + + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles") + private static Collection getYangFiles(final String resourcePath) { + final URI directoryPath; + try { + directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e); + } + return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER)); + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-crypt-hash@2014-08-06.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-crypt-hash@2014-08-06.yang new file mode 100644 index 000000000..44c4674f8 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-crypt-hash@2014-08-06.yang @@ -0,0 +1,120 @@ +module iana-crypt-hash { + namespace "urn:ietf:params:xml:ns:yang:iana-crypt-hash"; + prefix ianach; + + organization "IANA"; + contact + " Internet Assigned Numbers Authority + + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States + + Tel: +1 310 301 5800 + E-Mail: iana@iana.org>"; + description + "This YANG module defines a type for storing passwords + using a hash function and features to indicate which hash + functions are supported by an implementation. + + The latest revision of this YANG module can be obtained from + the IANA web site. + + Requests for new values should be made to IANA via + email (iana@iana.org). + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The initial version of this YANG module is part of RFC 7317; + see the RFC itself for full legal notices."; + + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + + typedef crypt-hash { + type string { + pattern + '$0$.*' + + '|$1$[a-zA-Z0-9./]{1,8}$[a-zA-Z0-9./]{22}' + + '|$5$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{43}' + + '|$6$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{86}'; + } + description + "The crypt-hash type is used to store passwords using + a hash function. The algorithms for applying the hash + function and encoding the result are implemented in + various UNIX systems as the function crypt(3). + + A value of this type matches one of the forms: + + $0$ + $$$ + $$$$ + + The '$0$' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated, and the string '$$$' or + $$$$ is prepended to the result. This + value is stored in the configuration data store. + If a value starting with '$$', where is not '0', is + received, the server knows that the value already represents a + hashed value and stores it 'as is' in the data store. + + When a server needs to verify a password given by a user, it + finds the stored password hash string for that user, extracts + the salt, and calculates the hash with the salt and given + password as input. If the calculated hash value is the same + as the stored value, the password given by the client is + accepted. + + This type defines the following hash functions: + + id | hash function | feature + ---+---------------+------------------- + 1 | MD5 | crypt-hash-md5 + 5 | SHA-256 | crypt-hash-sha-256 + 6 | SHA-512 | crypt-hash-sha-512 + + The server indicates support for the different hash functions + by advertising the corresponding feature."; + reference + "IEEE Std 1003.1-2008 - crypt() function + RFC 1321: The MD5 Message-Digest Algorithm + FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-md5 { + description + "Indicates that the device supports the MD5 + hash function in 'crypt-hash' values."; + reference "RFC 1321: The MD5 Message-Digest Algorithm"; + } + + feature crypt-hash-sha-256 { + description + "Indicates that the device supports the SHA-256 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-sha-512 { + description + "Indicates that the device supports the SHA-512 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-hardware.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-hardware.yang new file mode 100755 index 000000000..52bcaf3a0 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/iana-hardware.yang @@ -0,0 +1,180 @@ +module iana-hardware { +yang-version 1.1; +namespace "urn:ietf:params:xml:ns:yang:iana-hardware"; +prefix ianahw; + +organization "IANA"; +contact + " Internet Assigned Numbers Authority + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States of America + Tel: +1 310 301 5800 + E-Mail: iana@iana.org>"; + +description + "IANA-defined identities for hardware class. + The latest revision of this YANG module can be obtained from + the IANA website. + Requests for new values should be made to IANA via + email (iana@iana.org). + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + The initial version of this YANG module is part of RFC 8348; + see the RFC itself for full legal notices."; +reference + "https://www.iana.org/assignments/yang-parameters"; + +revision 2018-03-13 { + description + "Initial revision."; + reference + "RFC 8348: A YANG Data Model for Hardware Management"; +} + +/* + * Identities + */ + +identity hardware-class { + description + "This identity is the base for all hardware class + identifiers."; +} + +identity unknown { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is unknown + to the server."; +} + +identity chassis { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is an + overall container for networking equipment. Any class of + physical component, except a stack, may be contained within a + chassis; a chassis may only be contained within a stack."; +} + +identity backplane { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of device for aggregating and forwarding networking traffic, + such as a shared backplane in a modular ethernet switch. Note + that an implementation may model a backplane as a single + physical component, which is actually implemented as multiple + discrete physical components (within a chassis or stack)."; +} + +identity container { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is capable + of containing one or more removable physical entities, + possibly of different types. For example, each (empty or + full) slot in a chassis will be modeled as a container. Note + that all removable physical components should be modeled + within a container component, such as field-replaceable + modules, fans, or power supplies. Note that all known + containers should be modeled by the agent, including empty + containers."; +} + +identity power-supply { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is a + power-supplying component."; +} + +identity fan { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is a fan or + other heat-reduction component."; +} + +identity sensor { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of sensor, such as a temperature sensor within a router + chassis."; +} + +identity module { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of self-contained sub-system. If a module component is + removable, then it should be modeled within a container + component; otherwise, it should be modeled directly within + another physical component (e.g., a chassis or another + module)."; +} + +identity port { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of networking port capable of receiving and/or transmitting + networking traffic."; +} + +identity stack { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of super-container (possibly virtual) intended to group + together multiple chassis entities. A stack may be realized + by a virtual cable, a real interconnect cable attached to + multiple chassis, or multiple interconnect cables. A stack + should not be modeled within any other physical components, + but a stack may be contained within another stack. Only + chassis components should be contained within a stack."; +} + +identity cpu { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of central processing unit."; +} + +identity energy-object { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of energy object, i.e., it is a piece of equipment that is + part of or attached to a communications network that is + monitored, it is controlled, or it aids in the management of + another device for Energy Management."; +} + +identity battery { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of battery."; +} + +identity storage-drive { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of component with data storage capability as its main + functionality, e.g., hard disk drive (HDD), solid-state device + (SSD), solid-state hybrid drive (SSHD), object storage device + (OSD), or other."; +} +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.xml b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.xml new file mode 100644 index 000000000..60f998630 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.xml @@ -0,0 +1,418 @@ + + + + chassis + chassis + ianahw:chassis + + unlocked + enabled + + 10283 + 3.8.1 (2020-10-30 11:47:59) + ISCO + ProteusCPRI Compact + HighStreet-ONAP40 + chassis-temperature-exhaust + chassis-temperature-inlet + chassis-fan0 + chassis-fan1 + chassis-fan2 + chassis-fan3 + cpu + slot0 + slot2 + + + chassis-temperature-exhaust + chassis-temperature-exhaust + ianahw:sensor + + locked + enabled + + chassis + 0 + + 30 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + chassis-temperature-inlet + chassis-temperature-inlet + ianahw:sensor + + locked + enabled + + chassis + 1 + + 29 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + chassis-fan0 + chassis-fan0 + ianahw:fan + + locked + enabled + + chassis + 2 + chassis-fan0-speed + + + chassis-fan0-speed + chassis-fan0-speed + ianahw:sensor + + locked + enabled + + chassis-fan0 + 0 + + 4100 + rpm + 2021-03-18T19:51:50.3Z + ok + + + + chassis-fan1 + chassis-fan1 + ianahw:fan + + locked + enabled + + chassis + 3 + chassis-fan1-speed + + + chassis-fan1-speed + chassis-fan1-speed + ianahw:sensor + + locked + enabled + + chassis-fan1 + 0 + + 4100 + rpm + 2021-03-18T19:51:50.3Z + ok + + + + chassis-fan2 + chassis-fan2 + ianahw:fan + + locked + enabled + + chassis + 4 + chassis-fan2-speed + + + chassis-fan2-speed + chassis-fan2-speed + ianahw:sensor + + locked + enabled + + chassis-fan2 + 0 + + 4100 + rpm + 2021-03-18T19:51:50.3Z + ok + + + + chassis-fan3 + chassis-fan3 + ianahw:fan + + locked + enabled + + chassis + 5 + chassis-fan3-speed + + + chassis-fan3-speed + chassis-fan3-speed + ianahw:sensor + + locked + enabled + + chassis-fan3 + 0 + + 1000 + rpm + 2021-03-18T19:51:50.3Z + ok + + + + cpu + cpu + ianahw:cpu + + locked + enabled + + chassis + 6 + cpu-temperature + + + cpu-temperature + cpu-temperature + ianahw:sensor + + locked + enabled + + cpu + 0 + + 30 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + slot0 + slot0 + ianahw:module + + unlocked + enabled + + chassis + 7 + 7220530 + 12.00.42-S (0F7F1001) + 0 + 385A-SFP-2P-40-FHL-JC3 + slot0-temperature + slot0-logical0 + slot0-logical1 + slot0-logical2 + + + slot0-temperature + slot0-temperature + ianahw:sensor + + locked + enabled + + slot0 + 0 + + 51 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + slot0-logical0 + Slot0-A + ianahw:module + + unlocked + enabled + + slot0 + 1 + SLOT0-AZ + slot0-logical0-bbu + slot0-logical0-rrh + + + slot0-logical0-bbu + Slot0-A-bbu + ianahw:port + + unlocked + enabled + + slot0-logical0 + 0 + slot0-logical0-bbu + AYR3GA2 + FINISAR CORP. + FTLX1475D3BTL-E7 + slot0-logical0-bbu-temperature + + + slot0-logical0-bbu-temperature + Slot0-A-bbu-temperature + ianahw:sensor + + locked + enabled + + slot0-logical0-bbu + 0 + + 37 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + slot0-logical0-rrh + Slot0-A-rrh + ianahw:port + + unlocked + enabled + + slot0-logical0 + 1 + slot0-logical0-rrh + AYR3GA9 + FINISAR CORP. + FTLX1475D3BTL-E7 + slot0-logical0-rrh-temperature + + + slot0-logical0-rrh-temperature + Slot0-A-rrh-temperature + ianahw:sensor + + locked + enabled + + slot0-logical0-rrh + 0 + + 35 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + slot0-logical1 + Slot0-B + ianahw:module + + unlocked + disabled + + slot0 + 2 + SLOT0-B + + + slot0-logical2 + Slot0-C + ianahw:module + + unlocked + disabled + + slot0 + 3 + SLOT0-C + + + slot2 + slot2 + ianahw:module + + unlocked + enabled + + chassis + 9 + 7220718 + 12.00.42-S (0F7F1001) + 0 + 385A-SFP-2P-40-FHL-JC3 + 2021-10-12T14:41:55.234Z + slot2-temperature + slot2-logical0 + slot2-logical1 + slot2-logical2 + + + slot2-temperature + slot2-temperature + ianahw:sensor + + locked + enabled + + slot2 + 0 + + 49 + celsius + 2021-03-18T19:51:50.3Z + ok + + + + slot2-logical0 + Slot2-C + ianahw:module + + unlocked + disabled + + slot2 + 1 + SLOT2-C + + + slot2-logical1 + Slot3-A + ianahw:module + + unlocked + disabled + + slot2 + 2 + SLOT3-A + + + slot2-logical2 + Slot3-B + ianahw:module + + unlocked + disabled + + slot2 + 3 + SLOT3-B + + \ No newline at end of file diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.yang new file mode 100755 index 000000000..f444e26ee --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-hardware.yang @@ -0,0 +1,1141 @@ +module ietf-hardware { +yang-version 1.1; +namespace "urn:ietf:params:xml:ns:yang:ietf-hardware"; +prefix hw; + +import ietf-inet-types { + prefix inet; +} +import ietf-yang-types { + prefix yang; +} +import iana-hardware { + prefix ianahw; +} + +organization + "IETF NETMOD (Network Modeling) Working Group"; + +contact + "WG Web: + WG List: + Editor: Andy Bierman + + Editor: Martin Bjorklund + + Editor: Jie Dong + + Editor: Dan Romascanu + "; + +description + "This module contains a collection of YANG definitions for + managing hardware. + This data model is designed for the Network Management Datastore + Architecture (NMDA) defined in RFC 8342. + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 8348; see + the RFC itself for full legal notices."; + +revision 2018-03-13 { + description + "Initial revision."; + reference + "RFC 8348: A YANG Data Model for Hardware Management"; +} + +/* + * Features + */ + +feature entity-mib { + description + "This feature indicates that the device implements + the ENTITY-MIB."; + reference + "RFC 6933: Entity MIB (Version 4)"; +} + +feature hardware-state { + description + "Indicates that ENTITY-STATE-MIB objects are supported"; + reference + "RFC 4268: Entity State MIB"; +} + +feature hardware-sensor { + description + "Indicates that ENTITY-SENSOR-MIB objects are supported"; + reference + "RFC 3433: Entity Sensor Management Information Base"; +} + +/* + * Typedefs + */ + +typedef admin-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report administrative state."; + } + enum locked { + value 2; + description + "The resource is administratively prohibited from use."; + } + enum shutting-down { + value 3; + description + "The resource usage is administratively limited to current + instances of use."; + } + enum unlocked { + value 4; + description + "The resource is not administratively prohibited from + use."; + } + } + description + "Represents the various possible administrative states."; + reference + "RFC 4268: Entity State MIB - EntityAdminState"; +} + +typedef oper-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report its operational state."; + } + enum disabled { + value 2; + description + "The resource is totally inoperable."; + } + enum enabled { + value 3; + + description + "The resource is partially or fully operable."; + } + enum testing { + value 4; + description + "The resource is currently being tested and cannot + therefore report whether or not it is operational."; + } + } + description + "Represents the possible values of operational states."; + reference + "RFC 4268: Entity State MIB - EntityOperState"; +} + +typedef usage-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report usage state."; + } + enum idle { + value 2; + description + "The resource is servicing no users."; + } + enum active { + value 3; + description + "The resource is currently in use, and it has sufficient + spare capacity to provide for additional users."; + } + enum busy { + value 4; + description + "The resource is currently in use, but it currently has no + spare capacity to provide for additional users."; + } + } + description + "Represents the possible values of usage states."; + reference + "RFC 4268: Entity State MIB - EntityUsageState"; +} + +typedef alarm-state { + type bits { + bit unknown { + position 0; + description + "The resource is unable to report alarm state."; + } + bit under-repair { + position 1; + description + "The resource is currently being repaired, which, depending + on the implementation, may make the other values in this + bit string not meaningful."; + } + bit critical { + position 2; + description + "One or more critical alarms are active against the + resource."; + } + bit major { + position 3; + description + "One or more major alarms are active against the + resource."; + } + bit minor { + position 4; + description + "One or more minor alarms are active against the + resource."; + } + bit warning { + position 5; + description + "One or more warning alarms are active against the + resource."; + } + bit indeterminate { + position 6; + description + "One or more alarms of whose perceived severity cannot be + determined are active against this resource."; + } + } + description + "Represents the possible values of alarm states. An alarm is a + persistent indication of an error or warning condition. + When no bits of this attribute are set, then no active alarms + are known against this component and it is not under repair."; + reference + "RFC 4268: Entity State MIB - EntityAlarmStatus"; +} + +typedef standby-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report standby state."; + } + enum hot-standby { + value 2; + description + "The resource is not providing service, but it will be + immediately able to take over the role of the resource to + be backed up, without the need for initialization + activity, and will contain the same information as the + resource to be backed up."; + } + enum cold-standby { + value 3; + description + "The resource is to back up another resource, but it will + not be immediately able to take over the role of a + resource to be backed up and will require some + initialization activity."; + } + enum providing-service { + value 4; + description + "The resource is providing service."; + } + } + description + "Represents the possible values of standby states."; + reference + "RFC 4268: Entity State MIB - EntityStandbyStatus"; +} + +typedef sensor-value-type { + type enumeration { + enum other { + value 1; + description + "A measure other than those listed below."; + } + enum unknown { + value 2; + description + "An unknown measurement or arbitrary, relative numbers"; + } + enum volts-AC { + value 3; + description + "A measure of electric potential (alternating current)."; + } + enum volts-DC { + value 4; + description + "A measure of electric potential (direct current)."; + } + enum amperes { + value 5; + description + "A measure of electric current."; + } + enum watts { + value 6; + description + "A measure of power."; + } + enum hertz { + value 7; + description + "A measure of frequency."; + } + enum celsius { + value 8; + description + "A measure of temperature."; + } + enum percent-RH { + value 9; + description + "A measure of percent relative humidity."; + } + enum rpm { + value 10; + description + "A measure of shaft revolutions per minute."; + } + enum cmm { + value 11; + description + "A measure of cubic meters per minute (airflow)."; + } + enum truth-value { + value 12; + description + "Value is one of 1 (true) or 2 (false)"; + } + } + description + "A node using this data type represents the sensor measurement + data type associated with a physical sensor value. The actual + data units are determined by examining a node of this type + together with the associated sensor-value-scale node. + A node of this type SHOULD be defined together with nodes of + type sensor-value-scale and type sensor-value-precision. + These three types are used to identify the semantics of a node + of type sensor-value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorDataType"; +} + +typedef sensor-value-scale { + type enumeration { + enum yocto { + value 1; + description + "Data scaling factor of 10^-24."; + } + enum zepto { + value 2; + description + "Data scaling factor of 10^-21."; + } + enum atto { + value 3; + description + "Data scaling factor of 10^-18."; + } + enum femto { + value 4; + description + "Data scaling factor of 10^-15."; + } + enum pico { + value 5; + description + "Data scaling factor of 10^-12."; + } + enum nano { + value 6; + description + "Data scaling factor of 10^-9."; + } + enum micro { + value 7; + description + "Data scaling factor of 10^-6."; + } + enum milli { + value 8; + description + "Data scaling factor of 10^-3."; + } + enum units { + value 9; + description + "Data scaling factor of 10^0."; + } + enum kilo { + value 10; + description + "Data scaling factor of 10^3."; + } + enum mega { + value 11; + description + "Data scaling factor of 10^6."; + } + enum giga { + value 12; + description + "Data scaling factor of 10^9."; + } + enum tera { + value 13; + description + "Data scaling factor of 10^12."; + } + enum peta { + value 14; + description + "Data scaling factor of 10^15."; + } + enum exa { + value 15; + description + "Data scaling factor of 10^18."; + } + enum zetta { + value 16; + description + "Data scaling factor of 10^21."; + } + enum yotta { + value 17; + description + "Data scaling factor of 10^24."; + } + } + description + "A node using this data type represents a data scaling factor, + represented with an International System of Units (SI) prefix. + The actual data units are determined by examining a node of + this type together with the associated sensor-value-type. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type and type sensor-value-precision. + Together, associated nodes of these three types are used to + identify the semantics of a node of type sensor-value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorDataScale"; +} + +typedef sensor-value-precision { + type int8 { + range "-8 .. 9"; + } + description + "A node using this data type represents a sensor value + precision range. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type and type sensor-value-scale. Together, + associated nodes of these three types are used to identify the + semantics of a node of type sensor-value. + If a node of this type contains a value in the range 1 to 9, + it represents the number of decimal places in the fractional + part of an associated sensor-value fixed-point number. + If a node of this type contains a value in the range -8 to -1, + it represents the number of accurate digits in the associated + sensor-value fixed-point number. + The value zero indicates the associated sensor-value node is + not a fixed-point number. + Server implementers must choose a value for the associated + sensor-value-precision node so that the precision and accuracy + of the associated sensor-value node is correctly indicated. + For example, a component representing a temperature sensor + that can measure 0 to 100 degrees C in 0.1 degree + increments, +/- 0.05 degrees, would have a + sensor-value-precision value of '1', a sensor-value-scale + value of 'units', and a sensor-value ranging from '0' to + '1000'. The sensor-value would be interpreted as + 'degrees C * 10'."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorPrecision"; +} + +typedef sensor-value { + type int32 { + range "-1000000000 .. 1000000000"; + } + description + "A node using this data type represents a sensor value. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type, type sensor-value-scale, and + type sensor-value-precision. Together, associated nodes of + those three types are used to identify the semantics of a node + of this data type. + The semantics of a node using this data type are determined by + the value of the associated sensor-value-type node. + If the associated sensor-value-type node is equal to 'voltsAC', + 'voltsDC', 'amperes', 'watts', 'hertz', 'celsius', or 'cmm', + then a node of this type MUST contain a fixed-point number + ranging from -999,999,999 to +999,999,999. The value + -1000000000 indicates an underflow error. The value + +1000000000 indicates an overflow error. The + sensor-value-precision indicates how many fractional digits + are represented in the associated sensor-value node. + If the associated sensor-value-type node is equal to + 'percentRH', then a node of this type MUST contain a number + ranging from 0 to 100. + If the associated sensor-value-type node is equal to 'rpm', + then a node of this type MUST contain a number ranging from + -999,999,999 to +999,999,999. + If the associated sensor-value-type node is equal to + 'truth-value', then a node of this type MUST contain either the + value 1 (true) or the value 2 (false). + If the associated sensor-value-type node is equal to 'other' or + 'unknown', then a node of this type MUST contain a number + ranging from -1000000000 to 1000000000."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorValue"; +} + +typedef sensor-status { + type enumeration { + enum ok { + value 1; + description + "Indicates that the server can obtain the sensor value."; + } + enum unavailable { + value 2; + description + "Indicates that the server presently cannot obtain the + sensor value."; + } + enum nonoperational { + value 3; + description + "Indicates that the server believes the sensor is broken. + The sensor could have a hard failure (disconnected wire) + or a soft failure such as out-of-range, jittery, or wildly + fluctuating readings."; + } + } + description + "A node using this data type represents the operational status + of a physical sensor."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorStatus"; +} + +/* + * Data nodes + */ + +container hardware { + description + "Data nodes representing components. + If the server supports configuration of hardware components, + then this data model is instantiated in the configuration + datastores supported by the server. The leaf-list 'datastore' + for the module 'ietf-hardware' in the YANG library provides + this information."; + + leaf last-change { + type yang:date-and-time; + config false; + description + "The time the '/hardware/component' list changed in the + operational state."; + } + + list component { + key name; + description + "List of components. + When the server detects a new hardware component, it + initializes a list entry in the operational state. + If the server does not support configuration of hardware + components, list entries in the operational state are + initialized with values for all nodes as detected by the + implementation. + Otherwise, this procedure is followed: + 1. If there is an entry in the '/hardware/component' list + in the intended configuration with values for the nodes + 'class', 'parent', and 'parent-rel-pos' that are equal + to the detected values, then the list entry in the + operational state is initialized with the configured + values, including the 'name'. + 2. Otherwise (i.e., there is no matching configuration + entry), the list entry in the operational state is + initialized with values for all nodes as detected by + the implementation. + If the '/hardware/component' list in the intended + configuration is modified, then the system MUST behave as if + it re-initializes itself and follow the procedure in (1)."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalEntry"; + + leaf name { + type string; + description + "The name assigned to this component. + This name is not required to be the same as + entPhysicalName."; + } + + leaf class { + type identityref { + base ianahw:hardware-class; + } + mandatory true; + description + "An indication of the general hardware type of the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalClass"; + } + + leaf physical-index { + if-feature entity-mib; + type int32 { + range "1..2147483647"; + } + config false; + description + "The entPhysicalIndex for the entPhysicalEntry represented + by this list entry."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalIndex"; + } + + leaf description { + type string; + config false; + description + "A textual description of the component. This node should + contain a string that identifies the manufacturer's name + for the component and should be set to a distinct value + for each version or model of the component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalDescr"; + } + + leaf parent { + type leafref { + path "../../component/name"; + require-instance false; + } + description + "The name of the component that physically contains this + component. + If this leaf is not instantiated, it indicates that this + component is not contained in any other component. + In the event that a physical component is contained by + more than one physical component (e.g., double-wide + modules), this node contains the name of one of these + components. An implementation MUST use the same name + every time this node is instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalContainedIn"; + } + + leaf parent-rel-pos { + type int32 { + range "0 .. 2147483647"; + } + description + "An indication of the relative position of this child + component among all its sibling components. Sibling + components are defined as components that: + o share the same value of the 'parent' node and + o share a common base identity for the 'class' node. + Note that the last rule gives implementations flexibility + in how components are numbered. For example, some + implementations might have a single number series for all + components derived from 'ianahw:port', while some others + might have different number series for different + components with identities derived from 'ianahw:port' (for + example, one for registered jack 45 (RJ45) and one for + small form-factor pluggable (SFP))."; + + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalParentRelPos"; + } + + leaf-list contains-child { + type leafref { + path "../../component/name"; + } + config false; + description + "The name of the contained component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalChildIndex"; + } + + leaf hardware-rev { + type string; + config false; + description + "The vendor-specific hardware revision string for the + component. The preferred value is the hardware revision + identifier actually printed on the component itself (if + present)."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalHardwareRev"; + } + + leaf firmware-rev { + type string; + config false; + description + "The vendor-specific firmware revision string for the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalFirmwareRev"; + } + + leaf software-rev { + type string; + config false; + + description + "The vendor-specific software revision string for the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalSoftwareRev"; + } + + leaf serial-num { + type string; + config false; + description + "The vendor-specific serial number string for the + component. The preferred value is the serial number + string actually printed on the component itself (if + present)."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalSerialNum"; + } + + leaf mfg-name { + type string; + config false; + description + "The name of the manufacturer of this physical component. + The preferred value is the manufacturer name string + actually printed on the component itself (if present). + Note that comparisons between instances of the + 'model-name', 'firmware-rev', 'software-rev', and + 'serial-num' nodes are only meaningful amongst components + with the same value of 'mfg-name'. + If the manufacturer name string associated with the + physical component is unknown to the server, then this + node is not instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgName"; + } + + leaf model-name { + type string; + config false; + description + "The vendor-specific model name identifier string + associated with this physical component. The preferred + value is the customer-visible part number, which may be + printed on the component itself. + If the model name string associated with the physical + component is unknown to the server, then this node is not + instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalModelName"; + } + + leaf alias { + type string; + description + "An 'alias' name for the component, as specified by a + network manager, that provides a non-volatile 'handle' for + the component. + If no configured value exists, the server MAY set the + value of this node to a locally unique value in the + operational state. + A server implementation MAY map this leaf to the + entPhysicalAlias MIB object. Such an implementation needs + to use some mechanism to handle the differences in size + and characters allowed between this leaf and + entPhysicalAlias. The definition of such a mechanism is + outside the scope of this document."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalAlias"; + } + + leaf asset-id { + type string; + description + "This node is a user-assigned asset tracking identifier for + the component. + A server implementation MAY map this leaf to the + entPhysicalAssetID MIB object. Such an implementation + needs to use some mechanism to handle the differences in + size and characters allowed between this leaf and + entPhysicalAssetID. The definition of such a mechanism is + outside the scope of this document."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalAssetID"; + } + + leaf is-fru { + type boolean; + config false; + + description + "This node indicates whether or not this component is + considered a 'field-replaceable unit' by the vendor. If + this node contains the value 'true', then this component + identifies a field-replaceable unit. For all components + that are permanently contained within a field-replaceable + unit, the value 'false' should be returned for this + node."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalIsFRU"; + } + + leaf mfg-date { + type yang:date-and-time; + config false; + description + "The date of manufacturing of the managed component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgDate"; + } + + leaf-list uri { + type inet:uri; + description + "This node contains identification information about the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalUris"; + } + + leaf uuid { + type yang:uuid; + config false; + description + "A Universally Unique Identifier of the component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalUUID"; + } + + container state { + if-feature hardware-state; + description + "State-related nodes"; + reference + "RFC 4268: Entity State MIB"; + + leaf state-last-changed { + type yang:date-and-time; + config false; + description + "The date and time when the value of any of the + admin-state, oper-state, usage-state, alarm-state, or + standby-state changed for this component. + If there has been no change since the last + re-initialization of the local system, this node + contains the date and time of local system + initialization. If there has been no change since the + component was added to the local system, this node + contains the date and time of the insertion."; + reference + "RFC 4268: Entity State MIB - entStateLastChanged"; + } + + leaf admin-state { + type admin-state; + description + "The administrative state for this component. + This node refers to a component's administrative + permission to service both other components within its + containment hierarchy as well other users of its + services defined by means outside the scope of this + module. + Some components exhibit only a subset of the remaining + administrative state values. Some components cannot be + locked; hence, this node exhibits only the 'unlocked' + state. Other components cannot be shut down gracefully; + hence, this node does not exhibit the 'shutting-down' + state."; + reference + "RFC 4268: Entity State MIB - entStateAdmin"; + } + + leaf oper-state { + type oper-state; + config false; + description + "The operational state for this component. + Note that this node does not follow the administrative + state. An administrative state of 'down' does not + predict an operational state of 'disabled'. + Note that some implementations may not be able to + accurately report oper-state while the admin-state node + has a value other than 'unlocked'. In these cases, this + node MUST have a value of 'unknown'."; + reference + "RFC 4268: Entity State MIB - entStateOper"; + } + + leaf usage-state { + type usage-state; + config false; + description + "The usage state for this component. + This node refers to a component's ability to service + more components in a containment hierarchy. + Some components will exhibit only a subset of the usage + state values. Components that are unable to ever + service any components within a containment hierarchy + will always have a usage state of 'busy'. In some + cases, a component will be able to support only one + other component within its containment hierarchy and + will therefore only exhibit values of 'idle' and + 'busy'."; + reference + "RFC 4268: Entity State MIB - entStateUsage"; + } + + leaf alarm-state { + type alarm-state; + config false; + description + "The alarm state for this component. It does not + include the alarms raised on child components within its + containment hierarchy."; + reference + "RFC 4268: Entity State MIB - entStateAlarm"; + } + + leaf standby-state { + type standby-state; + config false; + description + "The standby state for this component. + Some components will exhibit only a subset of the + remaining standby state values. If this component + cannot operate in a standby role, the value of this node + will always be 'providing-service'."; + reference + "RFC 4268: Entity State MIB - entStateStandby"; + } + } + + container sensor-data { + when 'derived-from-or-self(../class, + "ianahw:sensor")' { + description + "Sensor data nodes present for any component of type + 'sensor'"; + } + if-feature hardware-sensor; + config false; + + description + "Sensor-related nodes."; + reference + "RFC 3433: Entity Sensor Management Information Base"; + + leaf value { + type sensor-value; + description + "The most recent measurement obtained by the server + for this sensor. + A client that periodically fetches this node should also + fetch the nodes 'value-type', 'value-scale', and + 'value-precision', since they may change when the value + is changed."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValue"; + } + + leaf value-type { + type sensor-value-type; + description + "The type of data units associated with the + sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorType"; + } + leaf value-scale { + type sensor-value-scale; + description + "The (power of 10) scaling factor associated + with the sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorScale"; + } + + leaf value-precision { + type sensor-value-precision; + description + "The number of decimal places of precision + associated with the sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorPrecision"; + } + + leaf oper-status { + type sensor-status; + description + "The operational status of the sensor."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorOperStatus"; + } + + leaf units-display { + type string; + description + "A textual description of the data units that should be + used in the display of the sensor value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorUnitsDisplay"; + } + + leaf value-timestamp { + type yang:date-and-time; + description + "The time the status and/or value of this sensor was last + obtained by the server."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValueTimeStamp"; + } + leaf value-update-rate { + type uint32; + units "milliseconds"; + description + "An indication of the frequency that the server updates + the associated 'value' node, represented in + milliseconds. The value zero indicates: + - the sensor value is updated on demand (e.g., + when polled by the server for a get-request), + - the sensor value is updated when the sensor + value changes (event-driven), or + - the server does not know the update rate."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValueUpdateRate"; + } + } + } +} + +/* + * Notifications + */ + +notification hardware-state-change { + description + "A hardware-state-change notification is generated when the + value of /hardware/last-change changes in the operational + state."; + reference + "RFC 6933: Entity MIB (Version 4) - entConfigChange"; +} + +notification hardware-state-oper-enabled { + if-feature hardware-state; + description + "A hardware-state-oper-enabled notification signifies that a + component has transitioned into the 'enabled' state."; + + leaf name { + type leafref { + path "/hardware/component/name"; + } + + description + "The name of the component that has transitioned into the + 'enabled' state."; + } + leaf admin-state { + type leafref { + path "/hardware/component/state/admin-state"; + } + description + "The administrative state for the component."; + } + leaf alarm-state { + type leafref { + path "/hardware/component/state/alarm-state"; + } + description + "The alarm state for the component."; + } + reference + "RFC 4268: Entity State MIB - entStateOperEnabled"; +} + +notification hardware-state-oper-disabled { + if-feature hardware-state; + description + "A hardware-state-oper-disabled notification signifies that a + component has transitioned into the 'disabled' state."; + + leaf name { + type leafref { + path "/hardware/component/name"; + } + description + "The name of the component that has transitioned into the + 'disabled' state."; + } + leaf admin-state { + type leafref { + path "/hardware/component/state/admin-state"; + } + description + "The administrative state for the component."; + } + leaf alarm-state { + type leafref { + path "/hardware/component/state/alarm-state"; + } + + description + "The alarm state for the component."; + } + reference + "RFC 4268: Entity State MIB - entStateOperDisabled"; +} + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-inet-types.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-inet-types.yang new file mode 100644 index 000000000..f91aa1fb8 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-inet-types.yang @@ -0,0 +1,429 @@ +module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + WG Chair: David Kessens + + WG Chair: Juergen Schoenwaelder + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - ip-address-no-zone + - ipv4-address-no-zone + - ipv6-address-no-zone"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of types related to protocol fields ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code Point + that may be used for marking packets in a traffic stream. + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The ipv6-flow-label type represents the flow identifier or Flow + Label in an IPv6 packet header that may be used to + discriminate traffic flows. + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport-layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of types related to autonomous systems ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASes. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4001: Textual Conventions for Internet Network Addresses + RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space"; + } + + /*** collection of types related to IP addresses and hostnames ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representation + implies the IP version. This type supports scoped addresses + by allowing zone identifiers in the address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + The canonical format of IPv6 addresses uses the textual + representation defined in Section 4 of RFC 5952. The + canonical format for the zone index is the numerical + format as described in Section 11.2 of RFC 4007."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-address-no-zone { + type union { + type inet:ipv4-address-no-zone; + type inet:ipv6-address-no-zone; + } + description + "The ip-address-no-zone type represents an IP address and is + IP version neutral. The format of the textual representation + implies the IP version. This type does not support scoped + addresses since it does not allow zone identifiers in the + address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address-no-zone { + type inet:ipv4-address { + pattern '[0-9\.]*'; + } + description + "An IPv4 address without a zone index. This type, derived from + ipv4-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + } + + typedef ipv6-address-no-zone { + type inet:ipv6-address { + pattern '[0-9a-fA-F:\.]*'; + } + description + "An IPv6 address without a zone index. This type, derived from + ipv6-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 128. + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, the IPv6 address is represented + as defined in Section 4 of RFC 5952."; + reference + "RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + length "1..253"; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitly or may depend on the configuration of the + resolver. + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be A-labels as per RFC 5890."; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-netconf-acm.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-netconf-acm.yang new file mode 100644 index 000000000..bf4855faf --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-netconf-acm.yang @@ -0,0 +1,464 @@ +module ietf-netconf-acm { + + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm"; + + prefix nacm; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + Author: Andy Bierman + + + Author: Martin Bjorklund + "; + + description + "Network Configuration Access Control Model. + + Copyright (c) 2012 - 2018 IETF Trust and the persons + identified as authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8341; see + the RFC itself for full legal notices."; + + revision "2018-02-14" { + description + "Added support for YANG 1.1 actions and notifications tied to + data nodes. Clarified how NACM extensions can be used by + other data models."; + reference + "RFC 8341: Network Configuration Access Control Model"; + } + + revision "2012-02-22" { + description + "Initial version."; + reference + "RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model"; + } + + /* + * Extension statements + */ + + extension default-deny-write { + description + "Used to indicate that the data model node + represents a sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have write access to the node. An + explicit access control rule is required for all other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-write' extension MAY appear within a data + definition statement. It is ignored otherwise."; + } + + extension default-deny-all { + description + "Used to indicate that the data model node + controls a very sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have read, write, or execute access to + the node. An explicit access control rule is required for all + other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-all' extension MAY appear within a data + definition statement, 'rpc' statement, or 'notification' + statement. It is ignored otherwise."; + } + + /* + * Derived types + */ + + typedef user-name-type { + type string { + length "1..max"; + } + description + "General-purpose username string."; + } + + typedef matchall-string-type { + type string { + pattern '\*'; + } + description + "The string containing a single asterisk '*' is used + to conceptually represent all possible values + for the particular leaf using this data type."; + } + + typedef access-operations-type { + type bits { + bit create { + description + "Any protocol operation that creates a + new data node."; + } + bit read { + description + "Any protocol operation or notification that + returns the value of a data node."; + } + bit update { + description + "Any protocol operation that alters an existing + data node."; + } + bit delete { + description + "Any protocol operation that removes a data node."; + } + bit exec { + description + "Execution access to the specified protocol operation."; + } + } + description + "Access operation."; + } + + typedef group-name-type { + type string { + length "1..max"; + pattern '[^\*].*'; + } + description + "Name of administrative group to which + users can be assigned."; + } + + typedef action-type { + type enumeration { + enum permit { + description + "Requested action is permitted."; + } + enum deny { + description + "Requested action is denied."; + } + } + description + "Action taken by the server when a particular + rule matches."; + } + + typedef node-instance-identifier { + type yang:xpath1.0; + description + "Path expression used to represent a special + data node, action, or notification instance-identifier + string. + + A node-instance-identifier value is an + unrestricted YANG instance-identifier expression. + All the same rules as an instance-identifier apply, + except that predicates for keys are optional. If a key + predicate is missing, then the node-instance-identifier + represents all possible server instances for that key. + + This XML Path Language (XPath) expression is evaluated in the + following context: + + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the + current session. + + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + + o The context node is the root node in the data tree. + + The accessible tree includes actions and notifications tied + to data nodes."; + } + + /* + * Data definition statements + */ + + container nacm { + nacm:default-deny-all; + + description + "Parameters for NETCONF access control model."; + + leaf enable-nacm { + type boolean; + default "true"; + description + "Enables or disables all NETCONF access control + enforcement. If 'true', then enforcement + is enabled. If 'false', then enforcement + is disabled."; + } + + leaf read-default { + type action-type; + default "permit"; + description + "Controls whether read access is granted if + no appropriate rule is found for a + particular read request."; + } + + leaf write-default { + type action-type; + default "deny"; + description + "Controls whether create, update, or delete access + is granted if no appropriate rule is found for a + particular write request."; + } + + leaf exec-default { + type action-type; + default "permit"; + description + "Controls whether exec access is granted if no appropriate + rule is found for a particular protocol operation request."; + } + + leaf enable-external-groups { + type boolean; + default "true"; + description + "Controls whether the server uses the groups reported by the + NETCONF transport layer when it assigns the user to a set of + NACM groups. If this leaf has the value 'false', any group + names reported by the transport layer are ignored by the + server."; + } + + leaf denied-operations { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request was denied."; + } + + leaf denied-data-writes { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request to alter + a configuration datastore was denied."; + } + + leaf denied-notifications { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that + a notification was dropped for a subscription because + access to the event type was denied."; + } + + container groups { + description + "NETCONF access control groups."; + + list group { + key name; + + description + "One NACM group entry. This list will only contain + configured entries, not any entries learned from + any transport protocols."; + + leaf name { + type group-name-type; + description + "Group name associated with this entry."; + } + + leaf-list user-name { + type user-name-type; + description + "Each entry identifies the username of + a member of the group associated with + this entry."; + } + } + } + + list rule-list { + key name; + ordered-by user; + description + "An ordered collection of access control rules."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule-list."; + } + leaf-list group { + type union { + type matchall-string-type; + type group-name-type; + } + description + "List of administrative groups that will be + assigned the associated access rights + defined by the 'rule' list. + + The string '*' indicates that all groups apply to the + entry."; + } + + list rule { + key name; + ordered-by user; + description + "One access control rule. + + Rules are processed in user-defined order until a match is + found. A rule matches if 'module-name', 'rule-type', and + 'access-operations' match the request. If a rule + matches, the 'action' leaf determines whether or not + access is granted."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule."; + } + + leaf module-name { + type union { + type matchall-string-type; + type string; + } + default "*"; + description + "Name of the module associated with this rule. + + This leaf matches if it has the value '*' or if the + object being accessed is defined in the module with the + specified module name."; + } + choice rule-type { + description + "This choice matches if all leafs present in the rule + match the request. If no leafs are present, the + choice matches all requests."; + case protocol-operation { + leaf rpc-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name."; + } + } + case notification { + leaf notification-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if its + value equals the requested notification name."; + } + } + + case data-node { + leaf path { + type node-instance-identifier; + mandatory true; + description + "Data node instance-identifier associated with the + data node, action, or notification controlled by + this rule. + + Configuration data or state data + instance-identifiers start with a top-level + data node. A complete instance-identifier is + required for this type of path value. + + The special value '/' refers to all possible + datastore contents."; + } + } + } + + leaf access-operations { + type union { + type matchall-string-type; + type access-operations-type; + } + default "*"; + description + "Access operations associated with this rule. + + This leaf matches if it has the value '*' or if the + bit corresponding to the requested operation is set."; + } + + leaf action { + type action-type; + mandatory true; + description + "The access control action associated with the + rule. If a rule has been determined to match a + particular request, then this object is used + to determine whether to permit or deny the + request."; + } + + leaf comment { + type string; + description + "A textual description of the access rule."; + } + } + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-system@2014-08-06.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-system@2014-08-06.yang new file mode 100644 index 000000000..1618242bc --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-system@2014-08-06.yang @@ -0,0 +1,800 @@ +module ietf-system { + namespace "urn:ietf:params:xml:ns:yang:ietf-system"; + prefix "sys"; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import ietf-netconf-acm { + prefix nacm; + } + + import iana-crypt-hash { + prefix ianach; + } + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: Thomas Nadeau + + + WG Chair: Juergen Schoenwaelder + + + Editor: Andy Bierman + + + Editor: Martin Bjorklund + "; + + description + "This module contains a collection of YANG definitions for the + configuration and identification of some common system + properties within a device containing a NETCONF server. This + includes data node definitions for system identification, + time-of-day management, user management, DNS resolver + configuration, and some protocol operations for system + management. + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 7317; see + the RFC itself for full legal notices."; + + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + + /* + * Typedefs + */ + + typedef timezone-name { + type string; + description + "A time zone name as used by the Time Zone Database, + sometimes referred to as the 'Olson Database'. + + The exact set of valid values is an implementation-specific + matter. Client discovery of the exact set of time zone names + for a particular server is out of scope."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + + /* + * Features + */ + + feature radius { + description + "Indicates that the device can be configured as a RADIUS + client."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + feature authentication { + description + "Indicates that the device supports configuration of + user authentication."; + } + + feature local-users { + if-feature authentication; + description + "Indicates that the device supports configuration of + local user authentication."; + } + + feature radius-authentication { + if-feature radius; + if-feature authentication; + description + "Indicates that the device supports configuration of user + authentication over RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + + feature ntp { + description + "Indicates that the device can be configured to use one or + more NTP servers to set the system date and time."; + } + + feature ntp-udp-port { + if-feature ntp; + description + "Indicates that the device supports the configuration of + the UDP port for NTP servers. + + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + + feature timezone-name { + description + "Indicates that the local time zone on the device + can be configured to use the TZ database + to set the time zone and manage daylight saving time."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + + feature dns-udp-tcp-port { + description + "Indicates that the device supports the configuration of + the UDP and TCP port for DNS servers. + + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + + /* + * Identities + */ + + identity authentication-method { + description + "Base identity for user authentication methods."; + } + + identity radius { + base authentication-method; + description + "Indicates user authentication using RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + + identity local-users { + base authentication-method; + description + "Indicates password-based authentication of locally + configured users."; + } + + identity radius-authentication-type { + description + "Base identity for RADIUS authentication types."; + } + + identity radius-pap { + base radius-authentication-type; + description + "The device requests Password Authentication Protocol (PAP) + authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + identity radius-chap { + base radius-authentication-type; + description + "The device requests Challenge Handshake Authentication + Protocol (CHAP) authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + /* + * Configuration data nodes + */ + + container system { + description + "System group configuration."; + + leaf contact { + type string; + description + "The administrator contact information for the system. + + A server implementation MAY map this leaf to the sysContact + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysContact. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysContact"; + } + leaf hostname { + type inet:domain-name; + description + "The name of the host. This name can be a single domain + label or the fully qualified domain name of the host."; + } + leaf location { + type string; + description + "The system location. + + A server implementation MAY map this leaf to the sysLocation + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysLocation. The definition + of such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysLocation"; + } + + container clock { + description + "Configuration of the system date and time properties."; + + choice timezone { + description + "The system time zone information."; + + case timezone-name { + if-feature timezone-name; + leaf timezone-name { + type timezone-name; + description + "The TZ database name to use for the system, such + as 'Europe/Stockholm'."; + } + } + case timezone-utc-offset { + leaf timezone-utc-offset { + type int16 { + range "-1500 .. 1500"; + } + units "minutes"; + description + "The number of minutes to add to UTC time to + identify the time zone for this system. For example, + 'UTC - 8:00 hours' would be represented as '-480'. + Note that automatic daylight saving time adjustment + is not provided if this object is used."; + } + } + } + } + + container ntp { + if-feature ntp; + presence + "Enables the NTP client unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Configuration of the NTP client."; + + leaf enabled { + type boolean; + default true; + description + "Indicates that the system should attempt to + synchronize the system clock with an NTP server + from the 'ntp/server' list."; + } + list server { + key name; + description + "List of NTP servers to use for system clock + synchronization. If '/system/ntp/enabled' + is 'true', then the system will attempt to + contact and utilize the specified NTP servers."; + + leaf name { + type string; + description + "An arbitrary name for the NTP server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for NTP."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the NTP server."; + } + leaf port { + if-feature ntp-udp-port; + type inet:port-number; + default 123; + description + "The port number of the NTP server."; + } + } + } + } + leaf association-type { + type enumeration { + enum server { + description + "Use client association mode. This device + will not provide synchronization to the + configured NTP server."; + } + enum peer { + description + "Use symmetric active association mode. + This device may provide synchronization + to the configured NTP server."; + } + enum pool { + description + "Use client association mode with one or + more of the NTP servers found by DNS + resolution of the domain name given by + the 'address' leaf. This device will not + provide synchronization to the servers."; + } + } + default server; + description + "The desired association type for this NTP server."; + } + leaf iburst { + type boolean; + default false; + description + "Indicates whether this server should enable burst + synchronization or not."; + } + leaf prefer { + type boolean; + default false; + description + "Indicates whether this server should be preferred + or not."; + } + } + } + + container dns-resolver { + description + "Configuration of the DNS resolver."; + + leaf-list search { + type inet:domain-name; + ordered-by user; + description + "An ordered list of domains to search when resolving + a host name."; + } + list server { + key name; + ordered-by user; + description + "List of the DNS servers that the resolver should query. + + When the resolver is invoked by a calling application, it + sends the query to the first name server in this list. If + no response has been received within 'timeout' seconds, + the resolver continues with the next server in the list. + If no response is received from any server, the resolver + continues with the first server again. When the resolver + has traversed the list 'attempts' times without receiving + any response, it gives up and returns an error to the + calling application. + + Implementations MAY limit the number of entries in this + list."; + + leaf name { + type string; + description + "An arbitrary name for the DNS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp-and-tcp { + container udp-and-tcp { + description + "Contains UDP- and TCP-specific configuration + parameters for DNS."; + reference + "RFC 1035: Domain Names - Implementation and + Specification + RFC 5966: DNS Transport over TCP - Implementation + Requirements"; + + leaf address { + type inet:ip-address; + mandatory true; + description + "The address of the DNS server."; + } + leaf port { + if-feature dns-udp-tcp-port; + type inet:port-number; + default 53; + description + "The UDP and TCP port number of the DNS server."; + } + } + } + } + } + container options { + description + "Resolver options. The set of available options has been + limited to those that are generally available across + different resolver implementations and generally useful."; + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The amount of time the resolver will wait for a + response from each remote name server before + retrying the query via a different name server."; + } + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the resolver will send a query to + all of its name servers before giving up and returning + an error to the calling application."; + } + } + } + + container radius { + if-feature radius; + + description + "Configuration of the RADIUS client."; + + list server { + key name; + ordered-by user; + description + "List of RADIUS servers used by the device. + + When the RADIUS client is invoked by a calling + application, it sends the query to the first server in + this list. If no response has been received within + 'timeout' seconds, the client continues with the next + server in the list. If no response is received from any + server, the client continues with the first server again. + When the client has traversed the list 'attempts' times + without receiving any response, it gives up and returns an + error to the calling application."; + + leaf name { + type string; + description + "An arbitrary name for the RADIUS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for RADIUS."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the RADIUS server."; + } + + leaf authentication-port { + type inet:port-number; + default "1812"; + description + "The port number of the RADIUS server."; + } + leaf shared-secret { + type string; + mandatory true; + nacm:default-deny-all; + description + "The shared secret, which is known to both the + RADIUS client and server."; + reference + "RFC 2865: Remote Authentication Dial In User + Service (RADIUS)"; + } + } + } + } + leaf authentication-type { + type identityref { + base radius-authentication-type; + } + default radius-pap; + description + "The authentication type requested from the RADIUS + server."; + } + } + container options { + description + "RADIUS client options."; + + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The number of seconds the device will wait for a + response from each RADIUS server before trying with a + different server."; + } + + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the device will send a query to + all of its RADIUS servers before giving up."; + } + } + } + + container authentication { + nacm:default-deny-write; + if-feature authentication; + + description + "The authentication configuration subtree."; + + leaf-list user-authentication-order { + type identityref { + base authentication-method; + } + must '(. != "sys:radius" or ../../radius/server)' { + error-message + "When 'radius' is used, a RADIUS server" + + " must be configured."; + description + "When 'radius' is used as an authentication method, + a RADIUS server must be configured."; + } + ordered-by user; + + description + "When the device authenticates a user with a password, + it tries the authentication methods in this leaf-list in + order. If authentication with one method fails, the next + method is used. If no method succeeds, the user is + denied access. + + An empty user-authentication-order leaf-list still allows + authentication of users using mechanisms that do not + involve a password. + + If the 'radius-authentication' feature is advertised by + the NETCONF server, the 'radius' identity can be added to + this list. + + If the 'local-users' feature is advertised by the + NETCONF server, the 'local-users' identity can be + added to this list."; + } + + list user { + if-feature local-users; + key name; + description + "The list of local users configured on this device."; + + leaf name { + type string; + description + "The user name string identifying this entry."; + } + leaf password { + type ianach:crypt-hash; + description + "The password for this entry."; + } + list authorized-key { + key name; + description + "A list of public SSH keys for this user. These keys + are allowed for SSH authentication, as described in + RFC 4253."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + + leaf name { + type string; + description + "An arbitrary name for the SSH key."; + } + + leaf algorithm { + type string; + mandatory true; + description + "The public key algorithm name for this SSH key. + + Valid values are the values in the IANA 'Secure Shell + (SSH) Protocol Parameters' registry, Public Key + Algorithm Names."; + reference + "IANA 'Secure Shell (SSH) Protocol Parameters' + registry, Public Key Algorithm Names"; + } + leaf key-data { + type binary; + mandatory true; + description + "The binary public key data for this SSH key, as + specified by RFC 4253, Section 6.6, i.e.: + + string certificate or public key format + identifier + byte[n] key/certificate data."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + } + } + } + } + } + + /* + * Operational state data nodes + */ + + container system-state { + config false; + description + "System group operational state."; + + container platform { + description + "Contains vendor-specific information for + identifying the system platform and operating system."; + reference + "IEEE Std 1003.1-2008 - sys/utsname.h"; + + leaf os-name { + type string; + description + "The name of the operating system in use - + for example, 'Linux'."; + reference + "IEEE Std 1003.1-2008 - utsname.sysname"; + } + leaf os-release { + type string; + description + "The current release level of the operating + system in use. This string MAY indicate + the OS source code revision."; + reference + "IEEE Std 1003.1-2008 - utsname.release"; + } + leaf os-version { + type string; + description + "The current version level of the operating + system in use. This string MAY indicate + the specific OS build date and target variant + information."; + reference + "IEEE Std 1003.1-2008 - utsname.version"; + } + leaf machine { + type string; + description + "A vendor-specific identifier string representing + the hardware in use."; + reference + "IEEE Std 1003.1-2008 - utsname.machine"; + } + } + + container clock { + description + "Monitoring of the system date and time properties."; + + leaf current-datetime { + type yang:date-and-time; + description + "The current system date and time."; + } + + leaf boot-datetime { + type yang:date-and-time; + description + "The system date and time when the system last restarted."; + } + } + } + + rpc set-current-datetime { + nacm:default-deny-all; + description + "Set the /system-state/clock/current-datetime leaf + to the specified value. + + If the system is using NTP (i.e., /system/ntp/enabled + is set to 'true'), then this operation will fail with + error-tag 'operation-failed' and error-app-tag value of + 'ntp-active'."; + input { + leaf current-datetime { + type yang:date-and-time; + mandatory true; + description + "The current system date and time."; + } + } + } + + rpc system-restart { + nacm:default-deny-all; + description + "Request that the entire system be restarted immediately. + A server SHOULD send an rpc reply to the client before + restarting the system."; + } + + rpc system-shutdown { + nacm:default-deny-all; + description + "Request that the entire system be shut down immediately. + A server SHOULD send an rpc reply to the client before + shutting down the system."; + } + +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-yang-types.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-yang-types.yang new file mode 100644 index 000000000..20a3ef0d3 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/ietf-yang-types.yang @@ -0,0 +1,435 @@ +module ietf-yang-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + WG Chair: David Kessens + + WG Chair: Juergen Schoenwaelder + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types. + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - yang-identifier + - hex-string + - uuid + - dotted-quad"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of counter and gauge types ***/ + + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + /*** collection of identifier-related types ***/ + + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifiers. The pattern + captures these restrictions. + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type; the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef yang-identifier { + type string { + length "1..max"; + pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*'; + pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*'; + } + description + "A YANG identifier string as defined by the 'identifier' + rule in Section 12 of RFC 6020. An identifier must + start with an alphabetic character or an underscore + followed by an arbitrary sequence of alphabetic or + numeric characters, underscores, hyphens, or dots. + A YANG identifier MUST NOT start with any possible + combination of the lowercase or uppercase character + sequence 'xml'."; + reference + "RFC 6020: YANG - A Data Modeling Language for the Network + Configuration Protocol (NETCONF)"; + } + + /*** collection of types related to date and time***/ + + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + (a) The date-and-time type does not allow negative years. + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z + all represent the same time zone in dateTime. + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using + the time-offset 'Z'. + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually + referring to the notion of local time) uses the time-offset + -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence + happened. The specific occurrence must be defined in the + description of any schema node defined using this type. When + the specific occurrence occurred prior to the last time the + associated timeticks attribute was zero, then the timestamp + value is zero. Note that this requires all timestamp values + to be reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + The associated timeticks schema node must be specified + in the description of any schema node using this type. + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of generic address types ***/ + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of XML-specific types ***/ + + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + + /*** collection of string types ***/ + + typedef hex-string { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "A hexadecimal string with octets represented as hex digits + separated by colons. The canonical representation uses + lowercase characters."; + } + + typedef uuid { + type string { + pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-' + + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; + } + description + "A Universally Unique IDentifier in the string representation + defined in RFC 4122. The canonical representation uses + lowercase characters. + The following is an example of a UUID in string representation: + f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + "; + reference + "RFC 4122: A Universally Unique IDentifier (UUID) URN + Namespace"; + } + + typedef dotted-quad { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + } + description + "An unsigned 32-bit number expressed in the dotted-quad + notation, i.e., four octets written as decimal numbers + and separated with the '.' (full stop) character."; + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/o-ran-hardware@2019-07-03.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/o-ran-hardware@2019-07-03.yang new file mode 100644 index 000000000..ec6b359c1 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/o-ran-hardware@2019-07-03.yang @@ -0,0 +1,271 @@ +module o-ran-hardware { + yang-version 1.1; + namespace "urn:o-ran:hardware:1.0"; + prefix "o-ran-hw"; + + import ietf-hardware { + prefix hw; + } + import iana-hardware { + prefix ianahw; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the YANG definitions for managng the O-RAN hardware. + + Copyright 2019 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) added new identities to accommodate cross working group use of + o-ran-hardware and assoicated set of augmentations that are backwards + compatible to version 1.0.0"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature ENERGYSAVING { + description + "Indicates that the Radio Unit supports energy saving state."; + } + + // identity statements + identity O-RAN-RADIO { + base ianahw:module; + description + "Module used as it represents a self-contained sub-system + used in /hw:/hardware/hw:component/hw:class to represent + an O-RAN RU"; + } + + identity O-RAN-HW-COMPONENT { + base ianahw:module; + description + "Module used as it represents a self-contained sub-system + used in /hw:/hardware/hw:component/hw:class to represent + any O-RAN hardware component"; + } + + identity O-DU-COMPONENT { + base O-RAN-HW-COMPONENT; + description + "Used in /hw:/hardware/hw:component/hw:class to represent + any O-RAN defined O-DU hardware component"; + } + + identity O-RU-COMPONENT { + base O-RAN-HW-COMPONENT; + description + "Used in /hw:/hardware/hw:component/hw:class to represent + any O-RAN defined O-RU hardware component, including a stand-alone + O-RU or an O-RU component integrated into a multi-module system."; + } + + // typedef statements + typedef energysaving-state { + type enumeration { + enum UNKNOWN { + description "The Radio Unit is unable to report energy saving state."; + } + enum SLEEPING { + description + "The Radio Unit is in a sleep state. The NETCONF management plane + connection is functioning. Other functions and hardware which are + not needed for management plane may be in energy saving mode."; + } + enum AWAKE { + description + "The Radio Unit is not in an energy saving state."; + } + } + description + "new typedef since ietf-hardware only covers pwer-state + for redundancy purposes and not power saving operations."; + } + + typedef availability-type { + type enumeration { + enum UNKNOWN { + description "The Radio Unit is unable to report its availability state."; + } + enum NORMAL { + description + "The equipment is functioning correctly."; + } + enum DEGRADED { + description + "The equipment may be reporting a major alarm or may be reporting a critical + alarm that is only impacting one or more subcomponent, but where the + equipment's implementation permit it to continue operation (server traffic) + in a degraded state. + + Used for example, when the equipment has M identical sub-components and + when a critical alarm is imapcting only N subcomponents, where N + + + UTC + + NTS_FUNCTION_TYPE_O_RAN_FH-0 + http://172.18.0.3:8181/odlux/index.html#/configuration/NTS_FUNCTION_TYPE_O_RAN_FH-0 + O-RAN-SC SIM project + NTS_FUNCTION_TYPE_O_RAN_FH-0 + Open Wireless Lab + + false + + + \ No newline at end of file diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.yang b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.yang new file mode 100644 index 000000000..3e194298e --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.yang @@ -0,0 +1,59 @@ +module onap-system { + yang-version 1.1; + namespace "urn:onap:system"; + prefix os; + + import ietf-inet-types { + prefix inet; + } + import ietf-system { + prefix sys; + } + + organization + "ONAP - Open Network Automation Platform"; + contact + "Web: + Editors: + Alex Stancu + Adrian Lita + Martin Skorupski "; + description + "This module augments ietf-system with ONAP details. + + Copyright 2020 the O-RAN Alliance. + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License."; + + revision 2020-10-26 { + description + "Initial revision for the ietf-system augmentation for ONAP."; + reference + "https://jira.onap.org/browse/SDNC-1396"; + } + + augment "/sys:system" { + leaf name { + type string; + description + "The name of the system."; + } + leaf web-ui { + type inet:uri; + description + "The URI of the system Web UI."; + } + description + "Enhancing the system information."; + } +} -- cgit 1.2.3-korg