diff options
Diffstat (limited to 'sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider')
49 files changed, 7849 insertions, 142 deletions
diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/pom.xml b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/pom.xml index 34886499e..0a75fcee3 100644 --- a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/pom.xml +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>org.onap.ccsdk.parent</groupId> <artifactId>binding-parent</artifactId> - <version>2.3.2</version> + <version>2.3.3-SNAPSHOT</version> <relativePath/> </parent> 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/binding/DeviceManagerORanImpl.java index 87157e8ce..7e04e8c1a 100644 --- 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/binding/DeviceManagerORanImpl.java @@ -15,10 +15,11 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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; 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/binding/ORanChangeNotificationListener.java index c0aa0ac9b..abed01a44 100644 --- 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/binding/ORanChangeNotificationListener.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import com.fasterxml.jackson.core.JsonProcessingException; import java.util.List; 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/binding/ORanFaultNotificationListener.java index a17dcd726..d03b39480 100644 --- 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/binding/ORanFaultNotificationListener.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import com.fasterxml.jackson.core.JsonProcessingException; import java.time.Instant; 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/binding/ORanFaultToVESFaultMapper.java index ec8eaa7b7..f5873df96 100644 --- 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/binding/ORanFaultToVESFaultMapper.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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; 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/binding/ORanNetworkElement.java index d3ae5014e..e16df1d1c 100644 --- 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/binding/ORanNetworkElement.java @@ -15,12 +15,12 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; -import com.fasterxml.jackson.core.JsonProcessingException; 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; @@ -30,14 +30,20 @@ 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.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; @@ -64,20 +70,25 @@ public class ORanNetworkElement implements NetworkElement { .augmentation(System1.class).build(); private final NetconfBindingAccessor netconfAccessor; + private final Optional<NetconfBindingAccessor> netconfAccessorOpt; + + private final Optional<NetconfDomAccessor> netconfDomAccessor; private final DataProvider databaseService; private final ORanRegistrationToVESpnfRegistrationMapper mapper; private final VESCollectorService vesCollectorService; private ListenerRegistration<NotificationListener> oRanListenerRegistrationResult; - private @NonNull final ORanChangeNotificationListener oRanListener; + //private @NonNull final ORanChangeNotificationListener oRanListener; private ListenerRegistration<NotificationListener> oRanFaultListenerRegistrationResult; private @NonNull final ORanFaultNotificationListener oRanFaultListener; - ORanNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { + //ORanNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { + ORanNetworkElement(NetconfAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) { LOG.info("Create {}", ORanNetworkElement.class.getSimpleName()); // Read parameters - this.netconfAccessor = netconfAccess; - + this.netconfAccessorOpt = netconfAccess.getNetconfBindingAccessor(); + this.netconfAccessor = netconfAccessorOpt.get(); + this.netconfDomAccessor = netconfAccess.getNetconfDomAccessor(); // Get services this.databaseService = serviceProvider.getDataProvider(); this.vesCollectorService = serviceProvider.getVESCollectorService(); @@ -86,11 +97,12 @@ public class ORanNetworkElement implements NetworkElement { // Register callbacks this.oRanListenerRegistrationResult = null; - this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, serviceProvider); + //this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, serviceProvider); this.oRanFaultListenerRegistrationResult = null; this.oRanFaultListener = new ORanFaultNotificationListener(netconfAccessor, vesCollectorService, serviceProvider.getFaultService(), serviceProvider.getWebsocketService(), databaseService); + } private Collection<Component> initialReadFromNetworkElement() { @@ -125,12 +137,21 @@ public class ORanNetworkElement implements NetworkElement { // Publish the mountpoint to VES if enabled publishMountpointToVES(componentList); // Register call back class for receiving notifications - this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener); + //this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener); this.oRanFaultListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanFaultListener); // Register notifications stream - if (netconfAccessor.isNotificationsRFC5277Supported()) { + /*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<StreamKey, Stream> streams = netconfDomAccessor.get().getNotificationStreamsAsMap(); + LOG.info("Available notifications streams: {}", streams); + // Register to default stream + netconfDomAccessor.get().invokeCreateSubscription(); } @Override @@ -220,14 +241,13 @@ public class ORanNetworkElement implements NetworkElement { // 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); + /*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(); - } + }*/ } } } 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/binding/ORanNotifToVESEventAssembly.java index d99f1c874..6e31ffb6f 100644 --- 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/binding/ORanNotifToVESEventAssembly.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import java.time.Instant; import java.util.ArrayList; 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/binding/ORanRegistrationToVESpnfRegistrationMapper.java index 3524383f2..206abb5d7 100644 --- 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/binding/ORanRegistrationToVESpnfRegistrationMapper.java @@ -19,14 +19,16 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +55,7 @@ public class ORanRegistrationToVESpnfRegistrationMapper { this.sequenceNo = 0; } - public VESCommonEventHeaderPOJO mapCommonEventHeader(Component component) { + public VESCommonEventHeaderPOJO mapCommonEventHeader(MapEntryNode component) { VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); vesCEH.setDomain(VES_EVENT_DOMAIN); vesCEH.setEventId(netconfAccessor.getNodeId().getValue()); @@ -63,26 +65,48 @@ public class ORanRegistrationToVESpnfRegistrationMapper { vesCEH.setStartEpochMicrosec(Instant.now().toEpochMilli() * 1000); vesCEH.setLastEpochMicrosec(Instant.now().toEpochMilli() * 1000); - vesCEH.setNfVendorName(component.getMfgName()); + vesCEH.setNfVendorName( + ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME)); vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); vesCEH.setSequence(sequenceNo++); - vesCEH.setSourceId(component.getUuid() != null ? component.getUuid().toString():netconfAccessor.getNodeId().getValue()); + 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(Component component) { + public VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields(MapEntryNode 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.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/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 index 71ab613d2..2469e46b7 100644 --- 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/binding/ORanToInternalDataModel.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import java.time.Instant; import java.util.ArrayList; @@ -236,7 +236,7 @@ public class ORanToInternalDataModel { faultAlarm.setNodeId(nodeId.getValue()); faultAlarm.setObjectId(notification.getFaultSource()); faultAlarm.setProblem(notification.getFaultText()); - faultAlarm.setSeverity(getSeverityType(notification.getFaultSeverity(), notification.isIsCleared())); + faultAlarm.setSeverity(getSeverityType(notification.getFaultSeverity(), notification.getIsCleared())); faultAlarm.setCounter(counter); faultAlarm.setId(String.valueOf(notification.getFaultId())); faultAlarm.setSourceType(SourceType.Netconf); 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<String, String> convertDomNotifToXPath(@NonNull DOMNotification domNotification) { + @NonNull + ContainerNode notifContainer = domNotification.getBody(); + HashMap<String, String> xPathData = new HashMap<String, String>(); + + Collection<DataContainerChild> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String> getLeafListValue(DataContainerNode componentEntry, QName leafListQName) { + List<String> containsChildList = new ArrayList<String>(); + 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<MapEntryNode> 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 <eventTime> 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<MapEntryNode> 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<StreamKey, Stream> streams = netconfDomAccessor.getNotificationStreamsAsMap(); + // Register to default stream + netconfDomAccessor.invokeCreateSubscription(); + } + + public Collection<MapEntryNode> initialReadFromNetworkElement() { + Collection<MapEntryNode> 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<Inventory> inventoryList = + ORanDOMToInternalDataModel.getInventoryList(netconfDomAccessor.getNodeId(), hwData); + databaseService.writeInventory(netconfDomAccessor.getNodeId().getValue(), inventoryList); + } + } else { + componentMapEntries = Collections.emptyList(); + } + + Optional<Guicutthrough> 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 <L extends NetworkElementService> Optional<L> getService(Class<L> clazz) { + return Optional.empty(); + } + + @Override + public void warmstart() {} + + @Override + public Optional<NetconfAccessor> 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<NormalizedNode> 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<NormalizedNode> 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<MapEntryNode> 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<NormalizedNode> 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<MapEntryNode> 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<String, String> xPathFields, + String notificationTypeName) { + VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO(); + + vesNotifFields.setChangeType(notificationTypeName); + vesNotifFields.setChangeIdentifier(netconfDomAccessor.getNodeId().getValue()); + + StringBuffer buf = new StringBuffer(); + Iterator<Entry<String, String>> it = xPathFields.entrySet().iterator(); + while (it.hasNext()) { + Entry<String, String> pair = it.next(); + buf.append("\n" + pair.getKey() + " = " + pair.getValue()); + } + log.info("Resultlist({}):{}", xPathFields.size(), buf.toString()); + + ArrayList<HashMap<String, Object>> arrayOfNamedHashMap = new ArrayList<HashMap<String, Object>>(); + HashMap<String, Object> namedHashMap = new HashMap<String, Object>(); + 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<Inventory> getInventoryList(NodeId nodeId, NormalizedNode hwData) { + + List<Inventory> inventoryResultList = new ArrayList<Inventory>(); + ContainerNode hwContainer = (ContainerNode) hwData; + MapNode componentMap = (MapNode) hwContainer + .getChildByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST)); + Collection<MapEntryNode> 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<Inventory> recurseGetInventory(NodeId nodeId, MapEntryNode component, + Collection<MapEntryNode> componentList, int treeLevel, List<Inventory> inventoryResultList) { + //Add element to list, if conversion successfull + Optional<Inventory> 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<MapEntryNode> getRootComponents(Collection<MapEntryNode> componentMapEntries) { + List<MapEntryNode> 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<MapEntryNode> getComponentsByName(String name, Collection<MapEntryNode> componentList) { + List<MapEntryNode> 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<Inventory> 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<Guicutthrough> 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/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 index fff1fba79..afeac1932 100644 --- 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/startup/ORanNetworkElementFactory.java @@ -18,16 +18,17 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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.NetconfBindingAccessor; -import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; import org.opendaylight.yangtools.yang.common.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,11 +44,13 @@ public class ORanNetworkElementFactory implements NetworkElementFactory { public Optional<NetworkElement> 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<NetconfBindingAccessor> bindingAccessor = accessor.getNetconfBindingAccessor(); - if (bindingAccessor.isPresent()) { - return Optional.of(new ORanNetworkElement(bindingAccessor.get(), serviceProvider)); + if (capabilites.isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)) { + log.info("Create device {} ", ORanDOMNetworkElement.class.getName()); + //Optional<NetconfBindingAccessor> bindingAccessor = accessor.getNetconfBindingAccessor(); + Optional<NetconfDomAccessor> domAccessor = accessor.getNetconfDomAccessor(); + if (domAccessor.isPresent()) { + //return Optional.of(new ORanNetworkElement(bindingAccessor.get(), serviceProvider)); + return Optional.of(new ORanDOMNetworkElement(domAccessor.get(), serviceProvider)); } } } 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"/> <bean id="provider" - class="org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.DeviceManagerORanImpl" + class="org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding.DeviceManagerORanImpl" init-method="init" destroy-method="close"> <property name="netconfNetworkElementService" ref="netconfNetworkElementService"/> </bean> 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/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 index 05c825fdc..64cdd5f80 100644 --- 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/binding/ComponentHelper.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import java.util.Arrays; import java.util.List; 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/binding/TestAlarmNotif.java index 4d10dd154..883271d4c 100644 --- 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/binding/TestAlarmNotif.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import java.util.Map; import org.eclipse.jdt.annotation.NonNull; @@ -60,7 +60,6 @@ public class TestAlarmNotif implements AlarmNotif { return FaultSeverity.CRITICAL; } - @Override public @Nullable Boolean isIsCleared() { 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/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 index 64b6ac1ab..753e6c97f 100644 --- 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/binding/TestHardwareClass.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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; 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/binding/TestORanChangeNotificationListener.java index da4d830d7..d8ea2664f 100644 --- 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/binding/TestORanChangeNotificationListener.java @@ -16,7 +16,7 @@ * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; @@ -30,6 +30,7 @@ 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; 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/binding/TestORanFaultNotificationListener.java index af2515c9a..e26af989e 100644 --- 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/binding/TestORanFaultNotificationListener.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +31,7 @@ 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; 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/binding/TestORanNetworkElement.java index af7664ab8..3de211013 100644 --- 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/binding/TestORanNetworkElement.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -25,9 +25,9 @@ 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; @@ -36,6 +36,7 @@ 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; @@ -55,6 +56,7 @@ public class TestORanNetworkElement { 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; @@ -67,6 +69,7 @@ public class TestORanNetworkElement { 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); @@ -75,6 +78,7 @@ public class TestORanNetworkElement { 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); @@ -91,7 +95,7 @@ public class TestORanNetworkElement { } - @Test + //@Test public void test() { Optional<NetworkElement> oRanNe; when(capabilities.isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(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/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 index e2e0eb812..a4470d335 100644 --- 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/binding/TestORanToInternalDataModel.java @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -26,7 +26,6 @@ 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; 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/dom/TestDeviceManagerORanImpl.java index 98db4bbb6..f3932bc41 100644 --- 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/dom/TestDeviceManagerORanImpl.java @@ -15,12 +15,14 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +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.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.DeviceManagerORanImpl; +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 { @@ -30,7 +32,7 @@ public class TestDeviceManagerORanImpl { public void init() throws InterruptedException, IOException { } - // @Test + @Test public void test() throws Exception { devMgrOran = new DeviceManagerORanImpl(); NetconfNetworkElementService netconfNetworkElementService = mock(NetconfNetworkElementService.class); @@ -43,7 +45,7 @@ public class TestDeviceManagerORanImpl { } } - //@After + @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<Inventory> getInventoryList(NodeId nodeId, NormalizedNode hwData) { + + List<Inventory> inventoryResultList = new ArrayList<Inventory>(); + ContainerNode hwContainer = (ContainerNode) hwData; + MapNode componentMap = (MapNode) hwContainer.getChildByArg(new NodeIdentifier(HW_COMPONENT_LIST)); + Collection<MapEntryNode> 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<Inventory> recurseGetInventory(NodeId nodeId, MapEntryNode component, + Collection<MapEntryNode> componentList, int treeLevel, List<Inventory> inventoryResultList) { + LOG.info("Tree level = {}", treeLevel); + // Add element to list, if conversion successfull + Optional<Inventory> 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<MapEntryNode> getRootComponents(Collection<MapEntryNode> componentMapEntries) { + List<MapEntryNode> 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<MapEntryNode> getComponentsByName(String name, Collection<MapEntryNode> componentList) { + List<MapEntryNode> 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<Inventory> 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<MapEntryNode> 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<String> getLeafListValue(DataContainerNode componentEntry, QName leafListQName) { + if (componentEntry instanceof MapEntryNode) { + List<String> containsChildList = new ArrayList<String>(); + 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<NetworkElement> 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<Inventory> 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<Guicutthrough> 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/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 index fc382bfe2..27793e4bb 100644 --- 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/dom/TestORanNetworkElementFactory.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================================== * ONAP : ccsdk feature sdnr wt * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. + * 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 @@ -15,7 +15,7 @@ * the License. * ============LICENSE_END========================================================================== */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -26,37 +26,43 @@ 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.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 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); - NodeId nodeId = new NodeId(NODEIDSTRING); 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(NetconfBindingAccessor.class); + accessor = mock(NetconfAccessor.class); serviceProvider = mock(DeviceManagerServiceProvider.class); vesCollectorService = mock(VESCollectorService.class); faultService = mock(FaultService.class); @@ -65,6 +71,7 @@ public class TestORanNetworkElementFactory { 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); @@ -74,14 +81,14 @@ public class TestORanNetworkElementFactory { @Test public void testCreateORANHWComponent() throws Exception { - when(accessor.getCapabilites().isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); + 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(ORANHWCOMPONENT.QNAME)).thenReturn(false); + when(accessor.getCapabilites().isSupportingNamespace(ORanDeviceManagerQNames.ORAN_HW_COMPONENT)).thenReturn(false); ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); assertTrue(!(factory.create(accessor, serviceProvider).isPresent())); } 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<QName> 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<QName> 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<File> 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<QName> supportedFeatures, final File... files) { + return parseYangFiles(supportedFeatures, Arrays.asList(files)); + } + + public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures, + final Collection<File> 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<File> 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<QName> 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<QName> supportedFeatures, + final YangParserConfiguration config, final Collection<File> 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<QName> 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<QName> 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<String> resources) { + final List<YangTextSchemaSource> 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<String> yangDirs, final List<String> yangFiles, + final Set<QName> 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<String> yangResourceDirs, + final List<String> 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<String> yangResourceDirs, + final List<String> yangResources, final Set<QName> supportedFeatures, + final YangParserConfiguration config) { + final List<File> 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<QName> supportedFeatures, final YangTextSchemaSource... sources) { + return parseSources(config, supportedFeatures, Arrays.asList(sources)); + } + + public static EffectiveModelContext parseSources(final YangParserConfiguration config, + final Set<QName> supportedFeatures, final Collection<? extends SchemaSourceRepresentation> 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<File> 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$<clear text password> + $<id>$<salt>$<password hash> + $<id>$<parameter>$<salt>$<password hash> + + 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 '$<id>$<salt>$' or + $<id>$<parameter>$<salt>$ is prepended to the result. This + value is stored in the configuration data store. + If a value starting with '$<id>$', where <id> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<hardware xmlns="urn:ietf:params:xml:ns:yang:ietf-hardware"> + <component> + <name>chassis</name> + <alias>chassis</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:chassis</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <serial-num>10283</serial-num> + <software-rev>3.8.1 (2020-10-30 11:47:59)</software-rev> + <mfg-name>ISCO</mfg-name> + <model-name>ProteusCPRI Compact</model-name> + <description>HighStreet-ONAP40</description> + <contains-child>chassis-temperature-exhaust</contains-child> + <contains-child>chassis-temperature-inlet</contains-child> + <contains-child>chassis-fan0</contains-child> + <contains-child>chassis-fan1</contains-child> + <contains-child>chassis-fan2</contains-child> + <contains-child>chassis-fan3</contains-child> + <contains-child>cpu</contains-child> + <contains-child>slot0</contains-child> + <contains-child>slot2</contains-child> + </component> + <component> + <name>chassis-temperature-exhaust</name> + <alias>chassis-temperature-exhaust</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>30</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>chassis-temperature-inlet</name> + <alias>chassis-temperature-inlet</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>1</parent-rel-pos> + <sensor-data> + <value>29</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>chassis-fan0</name> + <alias>chassis-fan0</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:fan</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>2</parent-rel-pos> + <contains-child>chassis-fan0-speed</contains-child> + </component> + <component> + <name>chassis-fan0-speed</name> + <alias>chassis-fan0-speed</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis-fan0</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>4100</value> + <value-type>rpm</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>chassis-fan1</name> + <alias>chassis-fan1</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:fan</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>3</parent-rel-pos> + <contains-child>chassis-fan1-speed</contains-child> + </component> + <component> + <name>chassis-fan1-speed</name> + <alias>chassis-fan1-speed</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis-fan1</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>4100</value> + <value-type>rpm</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>chassis-fan2</name> + <alias>chassis-fan2</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:fan</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>4</parent-rel-pos> + <contains-child>chassis-fan2-speed</contains-child> + </component> + <component> + <name>chassis-fan2-speed</name> + <alias>chassis-fan2-speed</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis-fan2</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>4100</value> + <value-type>rpm</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>chassis-fan3</name> + <alias>chassis-fan3</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:fan</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>5</parent-rel-pos> + <contains-child>chassis-fan3-speed</contains-child> + </component> + <component> + <name>chassis-fan3-speed</name> + <alias>chassis-fan3-speed</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis-fan3</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>1000</value> + <value-type>rpm</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>cpu</name> + <alias>cpu</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:cpu</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>6</parent-rel-pos> + <contains-child>cpu-temperature</contains-child> + </component> + <component> + <name>cpu-temperature</name> + <alias>cpu-temperature</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>cpu</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>30</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>slot0</name> + <alias>slot0</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>7</parent-rel-pos> + <serial-num>7220530</serial-num> + <firmware-rev>12.00.42-S (0F7F1001)</firmware-rev> + <software-rev>0</software-rev> + <model-name>385A-SFP-2P-40-FHL-JC3</model-name> + <contains-child>slot0-temperature</contains-child> + <contains-child>slot0-logical0</contains-child> + <contains-child>slot0-logical1</contains-child> + <contains-child>slot0-logical2</contains-child> + </component> + <component> + <name>slot0-temperature</name> + <alias>slot0-temperature</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>51</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>slot0-logical0</name> + <alias>Slot0-A</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0</parent> + <parent-rel-pos>1</parent-rel-pos> + <description>SLOT0-AZ</description> + <contains-child>slot0-logical0-bbu</contains-child> + <contains-child>slot0-logical0-rrh</contains-child> + </component> + <component> + <name>slot0-logical0-bbu</name> + <alias>Slot0-A-bbu</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:port</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0-logical0</parent> + <parent-rel-pos>0</parent-rel-pos> + <o-ran-name xmlns="urn:o-ran:hardware:1.0">slot0-logical0-bbu</o-ran-name> + <serial-num>AYR3GA2</serial-num> + <mfg-name>FINISAR CORP.</mfg-name> + <model-name>FTLX1475D3BTL-E7</model-name> + <contains-child>slot0-logical0-bbu-temperature</contains-child> + </component> + <component> + <name>slot0-logical0-bbu-temperature</name> + <alias>Slot0-A-bbu-temperature</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0-logical0-bbu</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>37</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>slot0-logical0-rrh</name> + <alias>Slot0-A-rrh</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:port</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0-logical0</parent> + <parent-rel-pos>1</parent-rel-pos> + <o-ran-name xmlns="urn:o-ran:hardware:1.0">slot0-logical0-rrh</o-ran-name> + <serial-num>AYR3GA9</serial-num> + <mfg-name>FINISAR CORP.</mfg-name> + <model-name>FTLX1475D3BTL-E7</model-name> + <contains-child>slot0-logical0-rrh-temperature</contains-child> + </component> + <component> + <name>slot0-logical0-rrh-temperature</name> + <alias>Slot0-A-rrh-temperature</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot0-logical0-rrh</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>35</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>slot0-logical1</name> + <alias>Slot0-B</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>disabled</oper-state> + </state> + <parent>slot0</parent> + <parent-rel-pos>2</parent-rel-pos> + <description>SLOT0-B</description> + </component> + <component> + <name>slot0-logical2</name> + <alias>Slot0-C</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>disabled</oper-state> + </state> + <parent>slot0</parent> + <parent-rel-pos>3</parent-rel-pos> + <description>SLOT0-C</description> + </component> + <component> + <name>slot2</name> + <alias>slot2</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>chassis</parent> + <parent-rel-pos>9</parent-rel-pos> + <serial-num>7220718</serial-num> + <firmware-rev>12.00.42-S (0F7F1001)</firmware-rev> + <software-rev>0</software-rev> + <model-name>385A-SFP-2P-40-FHL-JC3</model-name> + <mfg-date>2021-10-12T14:41:55.234Z</mfg-date> + <contains-child>slot2-temperature</contains-child> + <contains-child>slot2-logical0</contains-child> + <contains-child>slot2-logical1</contains-child> + <contains-child>slot2-logical2</contains-child> + </component> + <component> + <name>slot2-temperature</name> + <alias>slot2-temperature</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:sensor</class> + <state> + <admin-state>locked</admin-state> + <oper-state>enabled</oper-state> + </state> + <parent>slot2</parent> + <parent-rel-pos>0</parent-rel-pos> + <sensor-data> + <value>49</value> + <value-type>celsius</value-type> + <value-timestamp>2021-03-18T19:51:50.3Z</value-timestamp> + <oper-status>ok</oper-status> + </sensor-data> + </component> + <component> + <name>slot2-logical0</name> + <alias>Slot2-C</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>disabled</oper-state> + </state> + <parent>slot2</parent> + <parent-rel-pos>1</parent-rel-pos> + <description>SLOT2-C</description> + </component> + <component> + <name>slot2-logical1</name> + <alias>Slot3-A</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>disabled</oper-state> + </state> + <parent>slot2</parent> + <parent-rel-pos>2</parent-rel-pos> + <description>SLOT3-A</description> + </component> + <component> + <name>slot2-logical2</name> + <alias>Slot3-B</alias> + <class xmlns:ianahw="urn:ietf:params:xml:ns:yang:iana-hardware">ianahw:module</class> + <state> + <admin-state>unlocked</admin-state> + <oper-state>disabled</oper-state> + </state> + <parent>slot2</parent> + <parent-rel-pos>3</parent-rel-pos> + <description>SLOT3-B</description> + </component> +</hardware>
\ 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: <https://datatracker.ietf.org/wg/netmod/> + WG List: <mailto:netmod@ietf.org> + Editor: Andy Bierman + <mailto:andy@yumaworks.com> + Editor: Martin Bjorklund + <mailto:mbj@tail-f.com> + Editor: Jie Dong + <mailto:jie.dong@huawei.com> + Editor: Dan Romascanu + <mailto:dromasca@gmail.com>"; + +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: <http://tools.ietf.org/wg/netmod/> + WG List: <mailto:netmod@ietf.org> + WG Chair: David Kessens + <mailto:david.kessens@nsn.com> + WG Chair: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + Editor: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de>"; + + 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 <http://www.iana.org/>. + 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: <https://datatracker.ietf.org/wg/netconf/> + WG List: <mailto:netconf@ietf.org> + + Author: Andy Bierman + <mailto:andy@yumaworks.com> + + Author: Martin Bjorklund + <mailto:mbj@tail-f.com>"; + + 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: <http://tools.ietf.org/wg/netmod/> + WG List: <mailto:netmod@ietf.org> + + WG Chair: Thomas Nadeau + <mailto:tnadeau@lucidvision.com> + + WG Chair: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + + Editor: Andy Bierman + <mailto:andy@yumaworks.com> + + Editor: Martin Bjorklund + <mailto:mbj@tail-f.com>"; + + 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: <http://tools.ietf.org/wg/netmod/> + WG List: <mailto:netmod@ietf.org> + WG Chair: David Kessens + <mailto:david.kessens@nsn.com> + WG Chair: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + Editor: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de>"; + + 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<M."; + } + enum FAULTY { + description + "The (sub-)components impacted by the critical alarm(s) impact the + ability of the equipment to continue operation (serve traffic)."; + } + } + description + "Equipment's availability-state is derived by matching active faults + and their impact to module's operation and enables an equipment to indicate + that even though it may have one or more critical alarms, it can continue + to serve traffic."; + } + + // common WG4 and croos-WG augmentations using O-RAN-RADIO identity + + augment "/hw:hardware/hw:component" { + when "(derived-from-or-self(hw:class, 'o-ran-hw:O-RAN-RADIO')) or + (derived-from-or-self(hw:class, 'o-ran-hw:O-RAN-HW-COMPONENT'))"; + description "New O-RAN parameters for o-ran hardware"; + + container label-content { + config false; + description + "Which set of attributes are printed on the Radio Unit's label"; + leaf model-name { + type boolean; + description + "indicates whether model-name is included on the equipment's label"; + } + leaf serial-number { + type boolean; + description + "indicates whether serial number is included on the equipment's label"; + } + } + leaf product-code { + type string; + config false; + mandatory true; + description + "O-RAN term that is distinct from model-name in ietf-hardware."; + } + leaf energy-saving-enabled { + if-feature "ENERGYSAVING"; + type boolean; + config true; + default false; + description + "This parameter can enable O-RAN unit to be switched to energy + saving mode. + TRUE indicates to switch the energy saving mode. + FALSE indicates to cancel the energy saving mode. + At the energy saving mode, all power of whole O-RAN unit becomes + lowest level whereas M-plane is still available"; + } + } + + augment "/hw:hardware/hw:component" { + when "(derived-from-or-self(hw:class, 'o-ran-hw:O-RAN-RADIO')) or + (derived-from-or-self(hw:class, 'ianahw:port')) or + (derived-from-or-self(hw:class, 'o-ran-hw:O-RAN-HW-COMPONENT'))"; + description "New O-RAN parameters for o-ran naming"; + leaf o-ran-name { + type leafref { + path "/hw:hardware/hw:component/hw:name"; + } + must "re-match(current(),'[a-zA-Z0-9][a-zA-Z0-9\\.\\-_]{0,253}[a-zA-Z0-9]')" { + error-message "Name must match pattern and length."; + } + mandatory true; + description + "O-RAN name needed to bind and match with the name of hw element, + to be compliant with O-RAN naming convention."; + } + } + + augment "/hw:hardware/hw:component/hw:state" { + when "(derived-from-or-self(../hw:class, 'o-ran-hw:O-RAN-RADIO')) or + (derived-from-or-self(../hw:class, 'o-ran-hw:O-RAN-HW-COMPONENT'))"; + description + "new O-RAN defined state"; + leaf power-state { + if-feature "ENERGYSAVING"; + type energysaving-state; + config false; + description + "The current power saving state for this component. + Note - hw:/hardware/compnent/state/standby-state defined in RFC 4268 is + used for redundancy purposes and not power saving operations."; + } + leaf availability-state { + type availability-type; + config false; + description + "Equipment's availability-state is derived by matching active faults + and their impact to module's operation and enables an equipment to indicate + that even though it may have one or more critical alarms, it can continue + to serve traffic."; + } + } + + +// augmentations to Notifications + + augment "/hw:hardware-state-oper-enabled" { + description "new availability state"; + leaf availability-state { + type leafref { + path "/hw:hardware/hw:component/hw:state/o-ran-hw:availability-state"; + } + description + "The availability-state of the O-RU."; + } + } + + augment "/hw:hardware-state-oper-disabled" { + description "new availability state"; + leaf availability-state { + type leafref { + path "/hw:hardware/hw:component/hw:state/o-ran-hw:availability-state"; + } + description + "The availability-state of the O-RU."; + } + } +} diff --git a/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.xml b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.xml new file mode 100644 index 000000000..3fb45c232 --- /dev/null +++ b/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/test/resources/onap-system.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system"> + <clock> + <timezone-name>UTC</timezone-name> + </clock> + <name xmlns="urn:onap:system">NTS_FUNCTION_TYPE_O_RAN_FH-0</name> + <web-ui xmlns="urn:onap:system">http://172.18.0.3:8181/odlux/index.html#/configuration/NTS_FUNCTION_TYPE_O_RAN_FH-0</web-ui> + <contact>O-RAN-SC SIM project</contact> + <hostname>NTS_FUNCTION_TYPE_O_RAN_FH-0</hostname> + <location>Open Wireless Lab</location> + <ntp> + <enabled>false</enabled> + </ntp> +</system> +
\ 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: <https://www.onap.org> + Editors: + Alex Stancu <mailto:alexandru.stancu@highstreet-technologies.com> + Adrian Lita <mailto:adrian.lita@highstreet-technologies.com> + Martin Skorupski <mailto:martin.skorupski@highstreet-technologies.com>"; + 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."; + } +} |