From 6188c03a3fd1b73da7184c26fdb81f02c8aa8825 Mon Sep 17 00:00:00 2001 From: Ravi Pendurty Date: Mon, 5 Apr 2021 11:04:55 +0200 Subject: Callhome to VES PNF Registration Callhome to VES PNF Registration Issue-ID: CCSDK-3160 Signed-off-by: Ravi Pendurty Change-Id: Ic5503ff7bb5bb77af3d5b4ad3ba6b09ccd10d87e Signed-off-by: Ravi Pendurty --- sdnr/wt/devicemanager-oran/provider/pom.xml | 5 + .../oran/impl/ORanNetworkElement.java | 66 +++++- ...ORanRegistrationToVESpnfRegistrationMapper.java | 87 ++++++++ .../oran/test/TestORanNetworkElementFactory.java | 9 +- .../TestORanRegistrationToVESpnfRegistration.java | 248 +++++++++++++++++++++ 5 files changed, 406 insertions(+), 9 deletions(-) create mode 100644 sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java create mode 100644 sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java (limited to 'sdnr/wt/devicemanager-oran') diff --git a/sdnr/wt/devicemanager-oran/provider/pom.xml b/sdnr/wt/devicemanager-oran/provider/pom.xml index 3b8583dad..e6ae4bfc2 100644 --- a/sdnr/wt/devicemanager-oran/provider/pom.xml +++ b/sdnr/wt/devicemanager-oran/provider/pom.xml @@ -90,6 +90,11 @@ sal-netconf-connector provided + + org.opendaylight.netconf + callhome-model + + org.opendaylight.mdsal mdsal-singleton-common-api diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java index 47ea3eadd..df81f60bf 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java @@ -41,6 +41,9 @@ import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.NetconfCallhomeServer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.netconf.callhome.server.AllowedDevices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.netconf.callhome.server.allowed.devices.Device; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -64,7 +67,9 @@ public class ORanNetworkElement implements NetworkElement { private ListenerRegistration oRanFaultListenerRegistrationResult; private @NonNull final ORanFaultNotificationListener oRanFaultListener; private final NotificationProxyParser notificationProxyParser; + private @NonNull ORanRegistrationToVESpnfRegistrationMapper mapper; private Collection componentList; + private static int sequenceNo = 0; ORanNetworkElement(NetconfBindingAccessor netconfAccess, DataProvider databaseService, VESCollectorService vesCollectorService) { @@ -89,7 +94,7 @@ public class ORanNetworkElement implements NetworkElement { componentList = YangHelper.getCollection(hardware.nonnullComponent()); List inventoryList = ORanToInternalDataModel.getInventoryList(netconfAccessor.getNodeId(), componentList); - inventoryList.forEach(databaseService::writeInventory); + inventoryList.forEach(databaseService::writeInventory); } Optional oGuicutthrough = ORanToInternalDataModel.getGuicutthrough(getOnapSystemData()); @@ -106,6 +111,8 @@ public class ORanNetworkElement implements NetworkElement { @Override public void register() { initialReadFromNetworkElement(); + // Publish the mountpoint to VES if enabled + publishMountpointToVES(); // Register call back class for receiving notifications Optional oNotifications = netconfAccessor.getNotificationAccessor(); if (oNotifications.isPresent()) { @@ -176,5 +183,60 @@ public class ORanNetworkElement implements NetworkElement { log.debug("Result of Hardware = {}", res); return res; } - + + private void publishMountpointToVES() { + log.debug("In publishMountpointToVES()"); + + /** + * 1. Check if this device is in the list of allowed-devices. + * 2. If device exists in allowed-devices, then create VES pnfRegistration event and publish to VES + */ + if (inAllowedDevices(netconfAccessor.getNodeId().getValue())) { + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + + for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { + //Just get one component. At the moment we don't care which one. Also since there is only one management address, we assume there will be only one chassis. + //If the device supports subtended configuration then it is assumed that the Chassis containing the management interface will be the root component and there will be only one root. + this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, + vesCollectorService, component); + VESCommonEventHeaderPOJO header = + mapper.mapCommonEventHeader(sequenceNo++); + VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + log.warn("Error while serializing VES Event to String ", e); + e.printStackTrace(); + } + + } + } + + } + + } + + private boolean inAllowedDevices(String mountpointName) { + final InstanceIdentifier ALL_DEVICES = + InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class); + + AllowedDevices allowedDevices; + allowedDevices = netconfAccessor.getTransactionUtils().readData( + netconfAccessor.getControllerBindingDataBroker(), LogicalDatastoreType.CONFIGURATION, ALL_DEVICES); + + if (allowedDevices != null) { + Collection deviceList = YangHelper.getCollection(allowedDevices.nonnullDevice()); + for (Device device : deviceList) { + log.info("Device in allowed-devices is - {}", device.getUniqueId()); + if (device.getUniqueId().equals(netconfAccessor.getNodeId().getValue())) { + log.info("Mountpoint is part of allowed-devices list"); + return true; + } + } + } + + log.info("Mountpoint {} is not part of allowed-devices list", mountpointName); + return false; + } + } diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java new file mode 100644 index 000000000..81605e450 --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; + +import java.time.Instant; +import org.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.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanRegistrationToVESpnfRegistrationMapper { + + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + //CommonEventHeader fields + private static final String VES_EVENT_DOMAIN = "pnfRegistration"; + private static final String VES_EVENTTYPE = "NetConf Callhome Registration"; + private static final String VES_EVENT_PRIORITY = "Normal"; + + private final VESCollectorService vesProvider; + private final @NonNull Component component; + private final NetconfAccessor netconfAccessor; + + public ORanRegistrationToVESpnfRegistrationMapper(NetconfAccessor netconfAccessor, + VESCollectorService vesCollectorService, Component component) { + this.netconfAccessor = netconfAccessor; + this.vesProvider = vesCollectorService; + this.component = component; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(int sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventId(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventName(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + vesCEH.setStartEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setNfVendorName(component.getMfgName()); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId(component.getUuid().toString()); + vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); + + return vesCEH; + } + + public VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields() { + VESPNFRegistrationFieldsPOJO vesPnfFields = new VESPNFRegistrationFieldsPOJO(); + vesPnfFields.setModelNumber(component.getModelName()); + vesPnfFields.setOamV4IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().toString()); + //vesPnfFields.setOamV6IpAddress(oamV6IpAddress); // Check if IP address in V6 format and then include it. Same with v4 address also + 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().toString()); + //vesPnfFields.setLastServiceDate(component.getLastChange()); + + return vesPnfFields; + } +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java index 05a2f9334..0da5ec1f4 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java @@ -22,7 +22,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.Optional; - import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; @@ -43,27 +42,23 @@ public class TestORanNetworkElementFactory { private static DeviceManagerServiceProvider serviceProvider; private static Capabilities capabilities; private static VESCollectorService vesCollectorService; - private static NetconfBindingAccessor bindingCommunicator; @BeforeClass public static void init() throws InterruptedException, IOException { - bindingCommunicator = mock(NetconfBindingAccessor.class); - vesCollectorService = mock(VESCollectorService.class); + NetconfBindingAccessor bindingCommunicator = mock(NetconfBindingAccessor.class); NodeId nodeId = new NodeId(NODEIDSTRING); when(bindingCommunicator.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); when(bindingCommunicator.getNodeId()).thenReturn(nodeId); - capabilities = mock(Capabilities.class); accessor = mock(NetconfBindingAccessor.class); serviceProvider = mock(DeviceManagerServiceProvider.class); + vesCollectorService = mock(VESCollectorService.class); when(accessor.getCapabilites()).thenReturn(capabilities); when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingCommunicator)); when(serviceProvider.getDataProvider()).thenReturn(null); when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); - - } @Test diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java new file mode 100644 index 000000000..781d333fe --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java @@ -0,0 +1,248 @@ +/* + * ============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.test; + +import static org.mockito.Mockito.when; +import java.math.BigDecimal; +import org.eclipse.jdt.annotation.Nullable; +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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.augmented.optional.fields.IgnoreMissingSchemaSources; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.NonModuleCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.OdlHelloMessageCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.YangModuleCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.PassThrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.schema.storage.YangLibrary; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; + +@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"; + + when(netconfAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + when(netconfAccessor.getNetconfNode()).thenReturn(new TestNetconfNode()); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R"); + Component testComponent = ComponentHelper.get(name, dateTimeString); + + ORanRegistrationToVESpnfRegistrationMapper mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService, testComponent); + mapper.mapCommonEventHeader(SEQUENCE_NO); + mapper.mapPNFRegistrationFields(); + } + + public class TestNetconfNode implements NetconfNode { + + @Override + public @Nullable Credentials getCredentials() { + return null; + } + + @Override + public @Nullable Host getHost() { + return new Host(new IpAddress(new Ipv4Address("10.10.10.10"))); + } + + @Override + public @Nullable PortNumber getPort() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isTcpOnly() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Protocol getProtocol() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isSchemaless() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable YangModuleCapabilities getYangModuleCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable NonModuleCapabilities getNonModuleCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isReconnectOnChangedSchema() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getConnectionTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getDefaultRequestTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getMaxConnectionAttempts() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getBetweenAttemptsTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable BigDecimal getSleepFactor() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getKeepaliveDelay() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getConcurrentRpcLimit() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getActorResponseWaitTime() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable OdlHelloMessageCapabilities getOdlHelloMessageCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable ConnectionStatus getConnectionStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable ClusteredConnectionStatus getClusteredConnectionStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable String getConnectedMessage() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable AvailableCapabilities getAvailableCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable UnavailableCapabilities getUnavailableCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable PassThrough getPassThrough() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable String getSchemaCacheDirectory() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable YangLibrary getYangLibrary() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable IgnoreMissingSchemaSources getIgnoreMissingSchemaSources() { + // TODO Auto-generated method stub + return null; + } + + } + +} -- cgit 1.2.3-korg