Support of several NetConf notification streams 24/116224/1
authorRavi Pendurty <ravi.pendurty@highstreet-technologies.com>
Tue, 8 Dec 2020 16:48:09 +0000 (17:48 +0100)
committerRavi Pendurty <ravi.pendurty@highstreet-technologies.com>
Tue, 8 Dec 2020 16:49:01 +0000 (17:49 +0100)
Support of several NetConf notification streams

Issue-ID: SDNC-1369
Change-Id: I75b9ba06aed159992444cce3e60384a1cdb91625
Signed-off-by: Ravi Pendurty <ravi.pendurty@highstreet-technologies.com>
21 files changed:
sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/NetconfAccessorMock.java
sdnr/wt/devicemanager-onf14/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/onf14/test/mock/NetconfAccessorMock.java
sdnr/wt/devicemanager-openroadm/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/openroadm/test/mock/NetconfAccessorMock.java
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElementFactory.java
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotificationMapper.java [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESCommonEventHeaderPOJO.java [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESEvent.java [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESNotificationFieldsPOJO.java [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/main/yang/nc-notifications@2008-07-14.yang [new file with mode: 0644]
sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanChangeNotificationListener.java
sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElement.java
sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java
sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/NetconfAccessorMock.java [deleted file]
sdnr/wt/mountpoint-state-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/test/mock/NetconfAccessorMock.java
sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/Capabilities.java
sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfAccessor.java
sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java
sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java

index fa0a9cb..91f5c43 100644 (file)
@@ -18,6 +18,7 @@
 package org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
@@ -25,6 +26,7 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.concepts.ListenerRegistration;
@@ -89,4 +91,22 @@ public class NetconfAccessorMock implements NetconfAccessor {
         return null;
     }
 
+    @Override
+    public void registerNotificationsStream(List<Stream> streamList) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean isNCNotificationsSupported() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<Stream> getNotificationStreams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index 138aa94..8324854 100644 (file)
@@ -18,6 +18,7 @@
 package org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.test.mock;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
@@ -25,6 +26,7 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.concepts.ListenerRegistration;
@@ -89,4 +91,22 @@ public class NetconfAccessorMock implements NetconfAccessor {
         return null;
     }
 
+    @Override
+    public void registerNotificationsStream(List<Stream> streamList) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean isNCNotificationsSupported() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<Stream> getNotificationStreams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index 8b13b00..d225a1e 100644 (file)
@@ -22,6 +22,7 @@
 package org.onap.ccsdk.features.sdnr.wt.devicemanager.openroadm.test.mock;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
@@ -29,6 +30,7 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.concepts.ListenerRegistration;
@@ -93,4 +95,18 @@ public class NetconfAccessorMock implements NetconfAccessor {
         return null;
     }
 
+    @Override
+    public void registerNotificationsStream(List<Stream> streamList) {
+    }
+
+    @Override
+    public boolean isNCNotificationsSupported() {
+        return false;
+    }
+
+    @Override
+    public List<Stream> getNotificationStreams() {
+        return null;
+    }
+
 }
index 76e06de..75b4bf5 100644 (file)
  */
 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl;
 
+import java.time.Instant;
+import java.util.HashMap;
 import java.util.List;
 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
+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.netconf.notifications.rev120206.IetfNetconfNotificationsListener;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
@@ -42,10 +45,14 @@ public class ORanChangeNotificationListener implements IetfNetconfNotificationsL
 
     private final NetconfAccessor netconfAccessor;
     private final DataProvider databaseService;
+    private final VESCollectorService vesCollectorService;
 
-    public ORanChangeNotificationListener(NetconfAccessor netconfAccessor, DataProvider databaseService) {
+    private static int sequenceNo = 0;
+
+    public ORanChangeNotificationListener(NetconfAccessor netconfAccessor, DataProvider databaseService, VESCollectorService vesCollectorService) {
         this.netconfAccessor = netconfAccessor;
         this.databaseService = databaseService;
+        this.vesCollectorService = vesCollectorService;
     }
 
     @Override
@@ -71,6 +78,7 @@ public class ORanChangeNotificationListener implements IetfNetconfNotificationsL
     @Override
     public void onNetconfConfigChange(NetconfConfigChange notification) {
         log.info("onNetconfConfigChange (1) {}", notification);
+        sequenceNo++;
         StringBuffer sb = new StringBuffer();
         List<Edit> editList = notification.nonnullEdit();
         for (Edit edit : editList) {
@@ -94,6 +102,17 @@ public class ORanChangeNotificationListener implements IetfNetconfNotificationsL
             databaseService.writeEventLog(eventlogBuilder.build());
         }
         log.info("onNetconfConfigChange (2) {}", sb);
+        ORanNotificationMapper mapper = new ORanNotificationMapper();
+        HashMap<String, String> xPathFieldsMap = mapper.performMapping(notification);
+        log.info("MappingInfo after mapping notification - {}", xPathFieldsMap);
+        Instant instant = mapper.getTime(notification);
+
+        ORanNotifToVESEventAssembly oranVESEventAssembly = new ORanNotifToVESEventAssembly(netconfAccessor, vesCollectorService);
+        String data = oranVESEventAssembly.performAssembly(xPathFieldsMap, instant, NetconfConfigChange.class.getSimpleName(),
+                sequenceNo);
+        vesCollectorService.publishVESMessage(data);
+
+
     }
 
 }
index 09978c2..3f69e18 100644 (file)
@@ -25,8 +25,13 @@ import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement;
 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+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.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.inet.types.rev130715.Uri;
@@ -50,6 +55,8 @@ public class ORanNetworkElement implements NetworkElement {
 
     private final DataProvider databaseService;
 
+    private final VESCollectorService vesCollectorService;
+
     private final ORanToInternalDataModel oRanMapper;
 
     private ListenerRegistration<NotificationListener> oRanListenerRegistrationResult;
@@ -57,13 +64,15 @@ public class ORanNetworkElement implements NetworkElement {
     private ListenerRegistration<NotificationListener> oRanFaultListenerRegistrationResult;
     private @NonNull final ORanFaultNotificationListener oRanFaultListener;
 
-    ORanNetworkElement(NetconfAccessor netconfAccess, DataProvider databaseService) {
+    ORanNetworkElement(NetconfAccessor netconfAccess, DataProvider databaseService,
+            VESCollectorService vesCollectorService) {
         log.info("Create {}", ORanNetworkElement.class.getSimpleName());
         this.netconfAccessor = netconfAccess;
         this.databaseService = databaseService;
+        this.vesCollectorService = vesCollectorService;
 
         this.oRanListenerRegistrationResult = null;
-        this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, databaseService);
+        this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService);
 
         this.oRanFaultListenerRegistrationResult = null;
         this.oRanFaultListener = new ORanFaultNotificationListener();
@@ -128,8 +137,14 @@ public class ORanNetworkElement implements NetworkElement {
         // Register call back class for receiving notifications
         this.oRanListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanListener);
         this.oRanFaultListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(oRanFaultListener);
-       // Register netconf stream
-        netconfAccessor.registerNotificationsStream(NetconfAccessor.DefaultNotificationsStream);
+        // Register notifications stream
+        if (netconfAccessor.isNCNotificationsSupported()) {
+            List<Stream> streamList = netconfAccessor.getNotificationStreams();
+            netconfAccessor.registerNotificationsStream(NetconfAccessor.DefaultNotificationsStream); // Always register first to default stream
+            netconfAccessor.registerNotificationsStream(streamList);
+        } else {
+            netconfAccessor.registerNotificationsStream(NetconfAccessor.DefaultNotificationsStream);
+        }
     }
 
     @Override
index 173b74a..3e5171c 100644 (file)
@@ -1,21 +1,23 @@
 /*
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * ============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
+ *     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==========================================================================
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
  */
-
 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl;
 
 import java.util.Optional;
@@ -42,7 +44,7 @@ public class ORanNetworkElementFactory implements NetworkElementFactory {
         if (!capabilites.isSupportingNamespace(OneCell)) {
             if (capabilites.isSupportingNamespace(ORANHWCOMPONENT.QNAME)) {
                 log.info("Create device {} ", ORanNetworkElement.class.getName());
-                return Optional.of(new ORanNetworkElement(acessor, serviceProvider.getDataProvider()));
+                return Optional.of(new ORanNetworkElement(acessor, serviceProvider.getDataProvider(), serviceProvider.getVESCollectorService()));
             }
         }
         return Optional.empty();
diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java
new file mode 100644 (file)
index 0000000..2cb15c5
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * ============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 com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESCommonEventHeaderPOJO;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESEvent;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESNotificationFieldsPOJO;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ORanNotifToVESEventAssembly {
+
+    private static final Logger log = LoggerFactory.getLogger(ORanNotifToVESEventAssembly.class);
+    private static final String VES_EVENT_DOMAIN = "notification";
+    private static final String VES_EVENTTYPE = "ORAN_notification";
+    private static final String VES_EVENT_PRIORITY = "Normal";
+    private NetconfAccessor netconfAccessor;
+    private VESCollectorService vesProvider;
+
+    public ORanNotifToVESEventAssembly(NetconfAccessor netconfAccessor, VESCollectorService vesProvider) {
+        this.netconfAccessor = netconfAccessor;
+        this.vesProvider = vesProvider;
+    }
+
+    public String performAssembly(HashMap<String, String> xPathFieldsMap, Instant instant, String notificationTypeName,
+            long sequenceNo) {
+        VESEvent data = assembleVESEventMsg(xPathFieldsMap, instant, notificationTypeName, sequenceNo);
+        return createVESEventJSON(data);
+    }
+
+    public VESEvent assembleVESEventMsg(HashMap<String, String> xPathFieldsMap, Instant instant,
+            String notificationTypeName, long sequenceNo) {
+        VESCommonEventHeaderPOJO vesCEH = createVESCommonEventHeader(instant, notificationTypeName, sequenceNo);
+        VESNotificationFieldsPOJO vesNotifFields = createVESNotificationFields(xPathFieldsMap, notificationTypeName);
+
+        VESEvent vesEvent = new VESEvent();
+        vesEvent.addEventObjects(vesCEH);
+        vesEvent.addEventObjects(vesNotifFields);
+
+        return vesEvent;
+    }
+
+    public String createVESEventJSON(VESEvent vesEvent) {
+        String oranVESMsg = "";
+        try {
+            ObjectMapper objMapper = new ObjectMapper();
+            oranVESMsg = objMapper.writeValueAsString(vesEvent);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        log.debug("VES Message generated from ORAN Netconf Notification is - {}", oranVESMsg);
+        return oranVESMsg;
+    }
+
+    // VES CommonEventHeader fields
+    private 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() * 100);
+        vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 100);
+        vesCEH.setNfVendorName("ORAN");
+        vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName());
+        vesCEH.setSequence(sequenceNo);
+        vesCEH.setSourceId("ORAN");
+        vesCEH.setSourceName(netconfAccessor.getNodeId().getValue());
+        return vesCEH;
+    }
+
+    // Notification fields
+    private VESNotificationFieldsPOJO createVESNotificationFields(HashMap<String, String> xPathFields,
+            String notificationTypeName) {
+        VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO();
+
+        vesNotifFields.setChangeType(notificationTypeName);
+        vesNotifFields.setChangeIdentifier(netconfAccessor.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-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotificationMapper.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotificationMapper.java
new file mode 100644 (file)
index 0000000..ccb1ac0
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.EventInstantAware;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ORanNotificationMapper {
+
+    /*
+     *  Converter of TR069 notifications to VES key, value hashmap.
+     *  Notifications are received as cascade if proxy object.
+     *  References: https://stackoverflow.com/questions/19633534/what-is-com-sun-proxy-proxy
+     *
+     *  Attributes are provided by getters starting with "get", "is", "key".
+     *  Proxy received: "com.sun.proxy.$ProxyNN". NN is a number.
+     *
+     *  Example result:
+     *
+     * Expected output via VES in JSON
+     *    {
+     *      "event": {
+     *         "commonEventHeader": {
+     *            "domain": "notification",
+     *            "eventId": "ABCD",
+     *            "eventName": "Notification_LTE_Enterprise_C-RANSC_Cntrl-ACME",
+     *            "eventType": "TR069_RAN_notification",
+     *            "sequence": 0,
+     *            "priority": "High",
+     *            "reportingEntityId": "0005B942CDB4",
+     *            "reportingEntityName": "ABCD",
+     *            "sourceId": "0005B942CDB4",
+     *            "sourceName": "ABCD",
+     *            "startEpochMicrosec": 1569579510211,
+     *            "lastEpochMicrosec": 1569579510211,
+     *            "nfcNamingCode": "",
+     *            "nfNamingCode": "",
+     *            "nfVendorName": "",
+     *            "timeZoneOffset": "+00:00",
+     *            "version": "4.0.1",
+     *            "vesEventListenerVersion": "7.0.1"
+     *         },
+     *         "notificationFields": {
+     *         "arrayOfNamedHashMap": [
+     *          {
+     *           "name": "VALUECHANGE",
+     *           "hashMap": {
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/serial-number": "0005B94238A0",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/software-version": "4.3.00.244",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/hardware-version": "1",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/provisioning-code": "",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/manufacturer": "ACME",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/product-class": "LTE_Enterprise_C-RANSC_Cntrl",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/manufacturer-oui": "0005B9",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[1]/index": "1",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[1]/fap-control/lte/rf-tx-status": "false",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[1]/fap-control/lte/op-state": "true",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[2]/index": "2",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[2]/fap-control/lte/rf-tx-status": "false",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[2]/fap-control/lte/op-state": "true",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/services/fap-service[2]/cell-config/lte/ran/rf/phy-cell-id": "201",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/management-server/connection-request-url": "http://10.220.68.2/acscall",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/management-server/parameter-key": "none",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/management-server/connection-request-password": "password",
+     *               "/notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/management-server/connection-request-username": "0005B9-LTE_Enterprise_C-RANSC_Cntrl-0005B94238A0"
+     *           },
+     *          }
+     *         ],
+     *         "changeContact": "",
+     *         "changeIdentifier": "SessionID",
+     *         "changeType": "ValueChange",
+     *         "newState": "",
+     *         "oldState": "",
+     *         "stateInterface": "",
+     *         "notificationFieldsVersion": "2.0",
+     *         }
+     *      }
+     *    }
+     *
+     */
+        private static final Logger log = LoggerFactory.getLogger(ORanNotificationMapper.class);
+        private Notification notification;
+
+        public HashMap<String, String> performMapping(Notification notification)
+        /*throws ORanNotificationMapperException*/ {
+
+            try {
+                return extractFields(notification);
+            } catch (IllegalArgumentException | SecurityException | NoSuchFieldException | IllegalAccessException
+                    | InvocationTargetException e) {
+                //throw new ORanNotificationMapperException("Mapping/JSON Creation problem", e);
+                log.info("Exception in performMapping method {}",e);
+                return null;
+            }
+
+        }
+
+        private HashMap<String, String> extractFields(Object o) throws IllegalAccessException, IllegalArgumentException,
+                InvocationTargetException, NoSuchFieldException, SecurityException {
+            String start = "/notification/" + getExtendedInterfaceName(Notification.class, o) + getXmlNameSpace(o);
+            return recurseExtractData(o, start, 0, new HashMap<String, String>());
+        }
+
+        private HashMap<String, String> recurseExtractData(Object o, String namePath, int level,
+                HashMap<String, String> result)
+                throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+            log.debug("In recurseExtractData - {} {} {}", namePath, level, log.isTraceEnabled() ? result : result.size());
+            if (level > 20) {
+                log.warn("Level to deep protection ended the recusive loop.");
+            } else {
+                if (o != null) {
+                    Class<?> classz = o.getClass();
+                    //notification/VALUECHANGE$$$eventInstantAware[@xmlns=urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notificationon] 0 {}
+                    //org.opendaylight.yang.gen.v1.urn.org.onap.ccsdk.features.sdnr.northbound.onecell.notification.rev200622.VALUECHANGE$$$eventInstantAware
+                    //if (Proxy.isProxyClass(classz)) {
+                    handleInterface(classz, o, namePath, level, result);
+                    //}
+                } else {
+                    log.warn("Null not expected here.");
+                }
+            }
+            return result;
+        }
+
+        private void handleInterface(Class<?> clazz, Object o, String namePath, int level, HashMap<String, String> result)
+                throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+            log.debug("In extract Interface {}", clazz);
+            if (clazz == null) {
+                log.warn("Loop with null class");
+                return;
+            }
+            if (level > 20) {
+                log.warn("Level to deep protection ended the recusive loop.");
+            }
+            if (clazz.getName().contentEquals("org.opendaylight.mdsal.binding.dom.codec.impl.AugmentableCodecDataObject")) {
+                log.trace("Leave AugmentableCodecDataObject");
+                return;
+            }
+
+            Method[] methods = clazz.getDeclaredMethods();
+            if (methods != null) {
+                for (Method method : methods) {
+                    String methodName = method.getName();
+                    log.trace("Method {}", methodName);
+                    if (methodName.startsWith("get")) {
+                        if (!methodName.equals("getImplementedInterface")) {
+                            handleGetterValue(method, methodName.substring(3), namePath, o, level, result);
+                        }
+                    } else if (methodName.startsWith("is")) {
+                        handleGetterValue(method, methodName.substring(2), namePath, o, level, result);
+                    } else if (methodName.equals("key")) {
+                        handleGetterValue(method, methodName, namePath, o, level, result);
+                    }
+                }
+            }
+            Class<?> sc = clazz.getSuperclass();  //Sodium
+            log.trace("Superclass is - {}", sc);
+            if (sc != null && !(sc.getName().contains("java.lang.reflect.Proxy")) && !Proxy.isProxyClass(sc)) {
+                handleInterface(sc, o, namePath, level + 1, result);
+            }
+        }
+
+        private void handleGetterValue(Method method, String name, String namePath, Object o, int level,
+                HashMap<String, String> result)
+                throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+            log.debug("Begin: {}-{}-{}-{}", method.getName(), name, namePath, level);
+            if (!method.isAccessible()) {
+                method.setAccessible(true);
+            }
+            Object value = method.invoke(o);
+            namePath += "/" + convertCamelToKebabCase(name);
+            log.trace("Namepath {}", namePath);
+            if (value != null) {
+                Class<?> type = value.getClass();
+                log.trace("Class {}", type.getSimpleName());
+                if (List.class.isAssignableFrom(type)) {
+                    int idx = 0;
+                    String keyString;
+                    for (Object listObject : (List<?>) value) {
+                        if (listObject != null) {
+                            if (Identifiable.class.isAssignableFrom(listObject.getClass())) {
+                                keyString = getKeyString((Identifiable<?>) listObject);
+                            } else {
+                                keyString = String.valueOf(idx);
+                            }
+                            recurseExtractData(listObject, namePath + "[" + keyString + "]", level + 1, result);
+                        } else {
+                            log.warn("Null value received {} {} {}", namePath, idx, name);
+                        }
+                        idx++;
+                    }
+                } else if (DataObject.class.isAssignableFrom(type)) {
+                    recurseExtractData(value, namePath, level + 1, result);
+                } else if (Proxy.isProxyClass(type)) {
+                    recurseExtractData(value, namePath, level + 1, result);
+                } else if (Identifier.class.isAssignableFrom(type)) {
+                    //don't put the key
+                } else {
+                    result.put(namePath, value.toString());
+                }
+            } else {
+                log.trace("Null value");
+            }
+        }
+
+        private String getExtendedInterfaceName(Class<?> assignableClazz, Object o) {
+            Class<?> interfaces[] = o.getClass().getInterfaces();
+            for (Class<?> oneInterface : interfaces) {
+                log.trace("In getExtendedInterfaceName, oneInterface = {}", oneInterface.getClass().getName());
+                if (assignableClazz.isAssignableFrom(oneInterface)) {
+                    return oneInterface.getSimpleName().contains("eventInstantAware")?oneInterface.getSimpleName().substring(0, oneInterface.getSimpleName().indexOf("$")):oneInterface.getSimpleName();
+                }
+            }
+            log.trace("In getExtendedInterfaceName, o.getClass().getName() = {}", o.getClass().getName());
+            return o.getClass().getSimpleName().contains("eventInstantAware")?o.getClass().getSimpleName().substring(0, o.getClass().getSimpleName().indexOf("$")):o.getClass().getSimpleName();
+        }
+
+        private String getXmlNameSpace(Object o)
+                throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
+            Field f = o.getClass().getField("QNAME");
+            Object couldQName = f.get(o);
+            if (couldQName instanceof QName) {
+                QName qname = (QName) couldQName;
+                return "[@xmlns=" + qname.getNamespace().toString() + "]";
+            }
+            return "";
+        }
+
+        /*private String convertCamelToKebabCase(String camel) {
+            KebabCaseStrategy kbCase = new KebabCaseStrategy();
+            return kbCase.translate(camel);
+            //return camel.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase();
+        } */
+
+        /**
+         * @param input string in Camel Case
+         * @return String in Kebab case
+         * Inspiration from KebabCaseStrategy class of com.fasterxml.jackson.databind with an additional condition to handle numbers as well
+         * Using QNAME would have been a more fool proof solution, however it can lead to performance problems due to usage of Java reflection
+         */
+        public String convertCamelToKebabCase(String input)
+        {
+            if (input == null) return input; // garbage in, garbage out
+            int length = input.length();
+            if (length == 0) {
+                return input;
+            }
+
+            StringBuilder result = new StringBuilder(length + (length >> 1));
+
+            int upperCount = 0;
+
+            for (int i = 0; i < length; ++i) {
+                char ch = input.charAt(i);
+                char lc = Character.toLowerCase(ch);
+
+                if (lc == ch) { // lower-case letter means we can get new word
+                    // but need to check for multi-letter upper-case (acronym), where assumption
+                    // is that the last upper-case char is start of a new word
+                    if ((upperCount > 1)  ){
+                        // so insert hyphen before the last character now
+                        result.insert(result.length() - 1, '-');
+                    } else if ((upperCount == 1) && Character.isDigit(ch) && i != length-1) {
+                        result.append('-');
+                    }
+                    upperCount = 0;
+                } else {
+                    // Otherwise starts new word, unless beginning of string
+                    if ((upperCount == 0) && (i > 0)) {
+                        result.append('-');
+                    }
+                    ++upperCount;
+                }
+                result.append(lc);
+            }
+            return result.toString();
+        }
+
+        /**
+         * Key format like this: "FapServiceKey{_index=2}"
+         *
+         * @return
+         */
+        private String getKeyString(Identifiable<?> indentifiableObject) {
+            String keyString = (indentifiableObject.key()).toString();
+            int start = keyString.indexOf("=") + 1;
+            int end = keyString.length() - 1;
+            if (start > 0 && start < end)
+                return keyString.substring(keyString.indexOf("=") + 1, keyString.length() - 1);
+            else
+                throw new IllegalArgumentException("indentifiable object without key");
+        }
+
+        public Instant getTime(Notification notification2) {
+            @NonNull
+            Instant time;
+            if (notification instanceof EventInstantAware) { // If notification class extends/implements the EventInstantAware
+                time = ((EventInstantAware) notification).eventInstant();
+                log.info("Event time {}", time);
+            } else {
+                time = Instant.now();
+                log.info("Defaulting to actual time of processing the notification - {}", time);
+            }
+            return time;
+        }
+}
diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESCommonEventHeaderPOJO.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESCommonEventHeaderPOJO.java
new file mode 100644 (file)
index 0000000..730c63b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * ============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 com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonPropertyOrder({"domain", "eventId", "eventName", "eventType", "lastEpochMicrosec", "nfcNamingCode", "nfNamingCode",
+        "nfVendorName", "priority", "reportingEntityId", "reportingEntityName", "sequence", "sourceId", "sourceName",
+        "startEpochMicrosec", "timeZoneOffset", "version", "vesEventListenerVersion"})
+
+public class VESCommonEventHeaderPOJO {
+
+    private String domain = "";
+    private String eventId = "";
+    private String eventName = "";
+    private String eventType = "";
+    private long sequence = 0L;
+    private String priority = "";
+    @JsonIgnore
+    private String reportingEntityId = "";
+    private String reportingEntityName = "";
+    private String sourceId = "";
+    private String sourceName = "";
+    private long startEpochMicrosec = 0L;
+    private long lastEpochMicrosec = 0L;
+    private String nfcNamingCode = "";
+    private String nfNamingCode = "";
+    private String nfVendorName = "";
+    private String timeZoneOffset = "+00:00";
+    private String version = "4.1";
+    private String vesEventListenerVersion = "7.1.1";
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getEventId() {
+        return eventId;
+    }
+
+    public void setEventId(String eventId) {
+        this.eventId = eventId;
+    }
+
+    public String getEventName() {
+        return eventName;
+    }
+
+    public void setEventName(String eventName) {
+        this.eventName = eventName;
+    }
+
+    public String getEventType() {
+        return eventType;
+    }
+
+    public void setEventType(String eventType) {
+        this.eventType = eventType;
+    }
+
+    public Long getSequence() {
+        return sequence;
+    }
+
+    public void setSequence(long sequenceNo) {
+        this.sequence = sequenceNo;
+    }
+
+    public String getPriority() {
+        return priority;
+    }
+
+    public void setPriority(String priority) {
+        this.priority = priority;
+    }
+
+    public String getReportingEntityId() {
+        return reportingEntityId;
+    }
+
+    public void setReportingEntityId(String reportingEntityId) {
+        this.reportingEntityId = reportingEntityId;
+    }
+
+    public String getReportingEntityName() {
+        return reportingEntityName;
+    }
+
+    public void setReportingEntityName(String reportingEntityName) {
+        this.reportingEntityName = reportingEntityName;
+    }
+
+    public String getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(String sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+
+    public long getStartEpochMicrosec() {
+        return startEpochMicrosec;
+    }
+
+    public void setStartEpochMicrosec(long startEpochMicrosec) {
+        this.startEpochMicrosec = startEpochMicrosec;
+    }
+
+    public long getLastEpochMicrosec() {
+        return lastEpochMicrosec;
+    }
+
+    public void setLastEpochMicrosec(long lastEpochMicrosec) {
+        this.lastEpochMicrosec = lastEpochMicrosec;
+    }
+
+    public String getNfcNamingCode() {
+        return nfcNamingCode;
+    }
+
+    public void setNfcNamingCode(String nfcNamingCode) {
+        this.nfcNamingCode = nfcNamingCode;
+    }
+
+    public String getNfNamingCode() {
+        return nfNamingCode;
+    }
+
+    public void setNfNamingCode(String nfNamingCode) {
+        this.nfNamingCode = nfNamingCode;
+    }
+
+    public String getNfVendorName() {
+        return nfVendorName;
+    }
+
+    public void setNfVendorName(String nfVendorName) {
+        this.nfVendorName = nfVendorName;
+    }
+
+    public String getTimeZoneOffset() {
+        return timeZoneOffset;
+    }
+
+    public void setTimeZoneOffset(String timeZoneOffset) {
+        this.timeZoneOffset = timeZoneOffset;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getVesEventListenerVersion() {
+        return vesEventListenerVersion;
+    }
+
+    public void setVesEventListenerVersion(String vesEventListenerVersion) {
+        this.vesEventListenerVersion = vesEventListenerVersion;
+    }
+}
diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESEvent.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESEvent.java
new file mode 100644 (file)
index 0000000..1117565
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VESEvent {
+
+    public Map<String, Object> event = new HashMap<String, Object>();
+
+    public void addEventObjects(Object eventObject) {
+        if (eventObject instanceof VESCommonEventHeaderPOJO)
+            event.put("commonEventHeader", eventObject);
+        else if (eventObject instanceof VESNotificationFieldsPOJO)
+            event.put("notificationFields", eventObject);
+
+    }
+
+    public Map<String, Object> getEvent() {
+        return event;
+    }
+}
+
+
diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESNotificationFieldsPOJO.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESNotificationFieldsPOJO.java
new file mode 100644 (file)
index 0000000..09aa6dd
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * ============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 com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+@JsonPropertyOrder({"arrayOfNamedHashMap", "changeContact", "changeIdentifier", "changeType", "newState", "oldState",
+        "notificationFieldsVersion"})
+
+public class VESNotificationFieldsPOJO {
+
+    private ArrayList<HashMap<String, Object>> arrayOfNamedHashMap = new ArrayList<HashMap<String, Object>>();
+    @JsonIgnore
+    private HashMap<String, Object> namedHashMap = new HashMap<String, Object>();
+    @JsonIgnore
+    private HashMap<String, String> hashMap = new HashMap<String, String>();
+    @JsonIgnore
+    private String changeContact = "";
+    private String changeIdentifier = "";
+    private String changeType = "";
+    @JsonIgnore
+    private String newState = "";
+    @JsonIgnore
+    private String oldState = "";
+    @JsonIgnore
+    private String stateInterface = "";
+    private String notificationFieldsVersion = "2.0";
+
+    public ArrayList<HashMap<String, Object>> getArrayOfNamedHashMap() {
+        return arrayOfNamedHashMap;
+    }
+
+    public void setArrayOfNamedHashMap(ArrayList<HashMap<String, Object>> arrayOfNamedHashMap) {
+        this.arrayOfNamedHashMap = arrayOfNamedHashMap;
+    }
+
+    public String getChangeContact() {
+        return changeContact;
+    }
+
+    public void setChangeContact(String changeContact) {
+        this.changeContact = changeContact;
+    }
+
+    public String getChangeIdentifier() {
+        return changeIdentifier;
+    }
+
+    public void setChangeIdentifier(String changeIdentifier) {
+        this.changeIdentifier = changeIdentifier;
+    }
+
+    public String getChangeType() {
+        return changeType;
+    }
+
+    public void setChangeType(String changeType) {
+        this.changeType = changeType;
+    }
+
+    public String getNewState() {
+        return newState;
+    }
+
+    public void setNewState(String newState) {
+        this.newState = newState;
+    }
+
+    public String getOldState() {
+        return oldState;
+    }
+
+    public void setOldState(String oldState) {
+        this.oldState = oldState;
+    }
+
+    public String getStateInterface() {
+        return stateInterface;
+    }
+
+    public void setStateInterface(String stateInterface) {
+        this.stateInterface = stateInterface;
+    }
+
+    public String getNotificationFieldsVersion() {
+        return notificationFieldsVersion;
+    }
+
+    public void setNotificationFieldsVersion(String notificationFieldsVersion) {
+        this.notificationFieldsVersion = notificationFieldsVersion;
+    }
+
+
+}
diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/yang/nc-notifications@2008-07-14.yang b/sdnr/wt/devicemanager-oran/provider/src/main/yang/nc-notifications@2008-07-14.yang
new file mode 100644 (file)
index 0000000..9ef5ed0
--- /dev/null
@@ -0,0 +1,95 @@
+module nc-notifications {
+
+    namespace "urn:ietf:params:xml:ns:netmod:notification";
+    prefix "manageEvent";
+
+    import ietf-yang-types{ prefix yang; }
+    import notifications { prefix ncEvent; }
+
+    organization
+      "IETF NETCONF WG";
+
+    contact
+      "netconf@ietf.org";
+
+    description
+      "Conversion of the 'manageEvent' XSD in the NETCONF
+       Notifications RFC.";
+
+    reference
+      "RFC 5277";
+
+    revision 2008-07-14 {
+      description "RFC 5277 version.";
+    }
+
+    container netconf {
+      description "Top-level element in the notification namespace";
+
+      config false;
+
+      container streams {
+        description 
+          "The list of event streams supported by the system. When
+           a query is issued, the returned set of streams is 
+           determined based on user privileges.";
+
+        list stream {
+          description 
+            "Stream name, description and other information.";
+          key name;
+          min-elements 1;
+
+          leaf name {
+            description
+              "The name of the event stream. If this is the default
+               NETCONF stream, this must have the value 'NETCONF'.";
+            type ncEvent:streamNameType;
+          }
+
+          leaf description {
+            description
+              "A description of the event stream, including such
+               information as the type of events that are sent over
+               this stream.";
+            type string;
+            mandatory true;
+          }
+
+          leaf replaySupport {
+            description
+              "A description of the event stream, including such
+               information as the type of events that are sent over
+               this stream.";
+            type boolean;
+            mandatory true;
+          }
+
+          leaf replayLogCreationTime {
+            description
+              "The timestamp of the creation of the log used to support
+               the replay function on this stream. Note that this might
+               be earlier then the earliest available notification in
+               the log. This object is updated if the log resets for 
+               some reason.  This object MUST be present if replay is
+               supported.";
+            type yang:date-and-time;   // xsd:dateTime is wrong!
+          }
+        }
+      }
+    }
+
+    notification replayComplete {
+      description
+        "This notification is sent to signal the end of a replay
+         portion of a subscription.";
+    }
+
+    notification notificationComplete {
+      description
+        "This notification is sent to signal the end of a notification
+         subscription. It is sent in the case that stopTime was
+         specified during the creation of the subscription..";
+    }
+
+}
\ No newline at end of file
index 39816b6..59fb727 100644 (file)
@@ -27,6 +27,8 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.junit.Test;
 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanChangeNotificationListener;
+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.netconf.base._1._0.rev110601.EditOperationType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange;
@@ -48,8 +50,13 @@ public class TestORanChangeNotificationListener {
 
         NetconfAccessor netconfAccessor = mock(NetconfAccessor.class);
         DataProvider databaseService = mock(DataProvider.class);
+        VESCollectorService vesCollectorService = mock(VESCollectorService.class);
+        VESCollectorCfgService vesCfgService = mock(VESCollectorCfgService.class);
+
+        when(vesCollectorService.getConfig()).thenReturn(vesCfgService);
+        when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R");
         ORanChangeNotificationListener notifListener =
-                new ORanChangeNotificationListener(netconfAccessor, databaseService);
+                new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService);
         when(netconfAccessor.getNodeId()).thenReturn(new NodeId(NODEID));
         Iterable<? extends PathArgument> pathArguments = Arrays.asList(new PathArgument() {
 
index 8e0a24c..be3cde2 100644 (file)
@@ -20,7 +20,6 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 import java.io.IOException;
 import java.util.Optional;
@@ -30,17 +29,17 @@ 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.ORanNetworkElementFactory;
-import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock.NetconfAccessorMock;
 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock.TransactionUtilsMock;
 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.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yangtools.yang.common.QName;
 
 public class TestORanNetworkElement {
 
-    static NetconfAccessorMock accessor;
+    static NetconfAccessor accessor;
     static DeviceManagerServiceProvider serviceProvider;
     static Capabilities capabilities;
     QName qCapability;
@@ -48,8 +47,7 @@ public class TestORanNetworkElement {
     @BeforeClass
     public static void init() throws InterruptedException, IOException {
         capabilities = mock(Capabilities.class);
-        //accessor = mock(NetconfAccessorMock.class);
-        accessor = spy(new NetconfAccessorMock(null, null, null, null));
+        accessor = mock(NetconfAccessor.class);
         serviceProvider = mock(DeviceManagerServiceProvider.class);
 
         NodeId nNodeId = new NodeId("nSky");
index d9b48e4..a349598 100644 (file)
@@ -25,7 +25,6 @@ import org.junit.After;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanNetworkElementFactory;
-import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock.NetconfAccessorMock;
 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;
@@ -42,7 +41,7 @@ public class TestORanNetworkElementFactory {
     @BeforeClass
     public static void init() throws InterruptedException, IOException {
         capabilities = mock(Capabilities.class);
-        accessor = mock(NetconfAccessorMock.class);
+        accessor = mock(NetconfAccessor.class);
         serviceProvider = mock(DeviceManagerServiceProvider.class);
 
         when(accessor.getCapabilites()).thenReturn(capabilities);
diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/NetconfAccessorMock.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/NetconfAccessorMock.java
deleted file mode 100644 (file)
index 108f5ec..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import org.eclipse.jdt.annotation.NonNull;
-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.TransactionUtils;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.MountPoint;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
-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.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-/**
- */
-public class NetconfAccessorMock implements NetconfAccessor {
-
-    private final NodeId nNodeId;
-    private final NetconfNode netconfNode;
-    private final MountPoint mountpoint;
-    private final DataBroker netconfNodeDataBroker;
-
-    public NetconfAccessorMock(NodeId nNodeId, NetconfNode netconfNode, MountPoint mountpoint,
-            DataBroker netconfNodeDataBroker) {
-        this.nNodeId = nNodeId;
-        this.netconfNode = netconfNode;
-        this.mountpoint = mountpoint;
-        this.netconfNodeDataBroker = netconfNodeDataBroker;
-    }
-
-    @Override
-    public NodeId getNodeId() {
-        return nNodeId;
-    }
-
-    @Override
-    public NetconfNode getNetconfNode() {
-        return netconfNode;
-    }
-
-    @Override
-    public Capabilities getCapabilites() {
-        return null;
-    }
-
-    @Override
-    public DataBroker getDataBroker() {
-        return netconfNodeDataBroker;
-    }
-
-    @Override
-    public MountPoint getMountpoint() {
-        return mountpoint;
-    }
-
-    @Override
-    public TransactionUtils getTransactionUtils() {
-        return null;
-    }
-
-    @Override
-    public <T extends NotificationListener> ListenerRegistration<NotificationListener> doRegisterNotificationListener(
-            @NonNull T listener) {
-        return null;
-    }
-
-    @Override
-    public ListenableFuture<RpcResult<CreateSubscriptionOutput>> registerNotificationsStream(String streamName) {
-        return null;
-    }
-
-}
index 328e9a3..ee32a43 100644 (file)
@@ -18,6 +18,7 @@
 package org.onap.ccsdk.features.sdnr.wt.mountpointstateprovider.test.mock;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
@@ -25,6 +26,7 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.concepts.ListenerRegistration;
@@ -84,4 +86,22 @@ public class NetconfAccessorMock implements NetconfAccessor {
         return null;
     }
 
+    @Override
+    public void registerNotificationsStream(List<Stream> streamList) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean isNCNotificationsSupported() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<Stream> getNotificationStreams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index a348b29..cd5339a 100644 (file)
@@ -164,7 +164,7 @@ public class Capabilities {
      * @param revision request or null for any revision
      * @return true if existing
      */
-    private boolean isSupportingNamespaceAndRevision(String namespace, @Nullable String revision) {
+    public boolean isSupportingNamespaceAndRevision(String namespace, @Nullable String revision) {
         LOG.trace("isSupportingNamespaceAndRevision: Model namespace {}?[revision {}]", namespace, revision);
         for (String capability : capabilities) {
             if (capability.contains(namespace) && (revision == null || capability.contains(revision))) {
index 1161681..cca7145 100644 (file)
 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.concepts.ListenerRegistration;
@@ -78,11 +80,34 @@ public interface NetconfAccessor {
 
     /**
      * Register notifications stream for the connection.
-     * 
+     *
      * @param streamName that should be "NETCONF" as default.
      * @return progress indication
      */
     ListenableFuture<RpcResult<CreateSubscriptionOutput>> registerNotificationsStream(String streamName);
 
+    /**
+     * Register notifications stream for the connection
+     *
+     * @param streamList that contains a list of streams to be subscribed for notifications
+     * @return progress indication
+     */
+    void registerNotificationsStream(List<Stream> streamList);
+
+    /**
+     * check if the device supports notifications.yang
+     * @return true if notifications.yang is supported
+     */
+//    boolean isNotificationsSupported();
 
+    /**
+     * check if the device supports notifications.yang
+     * @return true if nc-notifications.yang is supported
+     */
+    boolean isNCNotificationsSupported();
+    /**
+     * Get all notification streams
+     * @return stream list
+     */
+    List<Stream> getNotificationStreams();
 }
index 275da39..65b8e6f 100644 (file)
@@ -19,8 +19,10 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
+import java.util.List;
 import java.util.Optional;
 import javax.annotation.Nonnull;
+import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
 import org.eclipse.jdt.annotation.NonNull;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
@@ -29,11 +31,15 @@ import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.MountPoint;
 import org.opendaylight.mdsal.binding.api.NotificationService;
 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
 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.NetconfNodeConnectionStatus.ConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
@@ -183,5 +189,36 @@ public class NetconfAccessorImpl implements NetconfAccessor {
         return res;
     }
 
+    @Override
+    public void registerNotificationsStream(List<Stream> streamList) {
+        for (Stream stream : streamList) {
+            log.info("Stream Name = {}, Stream Description = {}", stream.getName().getValue(), stream.getDescription());
+            if (!(stream.getName().getValue().equals(NetconfAccessor.DefaultNotificationsStream))) // Since this stream is already registered
+                registerNotificationsStream(stream.getName().getValue());
+        }
+    }
+
+    /**
+     * check if nc-notifications.yang is supported by the device
+     */
+    @Override
+    public boolean isNCNotificationsSupported() {
+        Capabilities capabilities = getCapabilites();
+        if (capabilities.isSupportingNamespace(Netconf.QNAME)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public List<Stream> getNotificationStreams() {
+        final Class<Netconf> netconfClazz = Netconf.class;
+        InstanceIdentifier<Netconf> streamsIID = InstanceIdentifier.builder(netconfClazz).build();
+
+        Netconf res = getTransactionUtils().readData(getDataBroker(), LogicalDatastoreType.OPERATIONAL, streamsIID);
+        Streams streams = res.getStreams();
+        return YangHelper.getList(streams.getStream());
+    }
+
 
 }
index b2560a2..ad410dd 100644 (file)
@@ -1,17 +1,22 @@
 /*
- * ============LICENSE_START======================================================= ONAP : ccsdk
- * feature sdnr wt ================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * ================================================================================ Licensed under
- * the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
+ * ============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
+ *     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=========================================================
+ * 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.netconfnodestateservice.test;