Convert callhome DCLs to DTCLs
[netconf.git] / netconf / callhome-provider / src / main / java / org / opendaylight / netconf / callhome / mount / CallhomeStatusReporter.java
index 016bd57de29601452938ea2f272a992f7eab71a6..a9da3f3d7cc5025b7449fd3fa33476d97f36e5c3 100644 (file)
@@ -10,23 +10,23 @@ package org.opendaylight.netconf.callhome.mount;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
-
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.PublicKey;
 import java.security.spec.InvalidKeySpecException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
-import java.util.Map;
-
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.netconf.callhome.protocol.AuthorizedKeysDecoder;
@@ -49,13 +49,11 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
-class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, AutoCloseable {
+class CallhomeStatusReporter implements DataTreeChangeListener<Node>, StatusRecorder, AutoCloseable {
     private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
             InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
                     new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
@@ -63,37 +61,46 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
     private static final Logger LOG = LoggerFactory.getLogger(CallhomeStatusReporter.class);
 
     private final DataBroker dataBroker;
-    private final ListenerRegistration<DataChangeListener> reg;
+    private final ListenerRegistration<CallhomeStatusReporter> reg;
 
     CallhomeStatusReporter(DataBroker broker) {
         this.dataBroker = broker;
-        this.reg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, NETCONF_TOPO_IID.child(Node.class),
-                this, AsyncDataBroker.DataChangeScope.SUBTREE);
+        this.reg = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+            NETCONF_TOPO_IID.child(Node.class)), this);
     }
 
     @Override
-    public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
-        for (InstanceIdentifier<?> removedPath : change.getRemovedPaths()) {
-            if(removedPath.getTargetType() != NetconfNode.class)
-                continue;
-
-            final NodeId nodeId = getNodeId(removedPath);
-            if (nodeId != null) {
-                handleDisconnectedNetconfNode(nodeId);
-                return;
+    public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
+        for (DataTreeModification<Node> change: changes) {
+            final DataObjectModification<Node> rootNode = change.getRootNode();
+            final InstanceIdentifier<Node> identifier = change.getRootPath().getRootIdentifier();
+            switch (rootNode.getModificationType()) {
+                case WRITE:
+                case SUBTREE_MODIFIED:
+                    if (isNetconfNode(rootNode.getDataAfter())) {
+                        NodeId nodeId = getNodeId(identifier);
+                        if (nodeId != null) {
+                            NetconfNode nnode = rootNode.getDataAfter().getAugmentation(NetconfNode.class);
+                            handledNetconfNode(nodeId, nnode);
+                        }
+                    }
+                    break;
+                case DELETE:
+                    if (isNetconfNode(rootNode.getDataBefore())) {
+                        final NodeId nodeId = getNodeId(identifier);
+                        if (nodeId != null) {
+                            handleDisconnectedNetconfNode(nodeId);
+                        }
+                    }
+                    break;
+                default:
+                    break;
             }
         }
+    }
 
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : change.getUpdatedData().entrySet()) {
-            if (entry.getKey().getTargetType() == NetconfNode.class) {
-                NodeId nodeId = getNodeId(entry.getKey());
-                if (nodeId != null) {
-                    NetconfNode nnode = (NetconfNode) entry.getValue();
-                    handledNetconfNode(nodeId, nnode);
-                    return;
-                }
-            }
-        }
+    private boolean isNetconfNode(Node node) {
+        return node.getAugmentation(NetconfNode.class) != null;
     }
 
     private NodeId getNodeId(final InstanceIdentifier<?> path) {
@@ -127,8 +134,9 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
             LOG.warn("No corresponding callhome device found - exiting.");
         } else {
             Device modifiedDevice = withConnectedStatus(opDev);
-            if(modifiedDevice == null)
-                return ;
+            if (modifiedDevice == null) {
+                return;
+            }
             LOG.info("Setting successful status for callhome device id:{}.", nodeId);
             writeDevice(nodeId, modifiedDevice);
         }
@@ -142,8 +150,9 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
             LOG.warn("No corresponding callhome device found - exiting.");
         } else {
             Device modifiedDevice = withDisconnectedStatus(opDev);
-            if(modifiedDevice == null)
+            if (modifiedDevice == null) {
                 return;
+            }
             LOG.info("Setting disconnected status for callhome device id:{}.", nodeId);
             writeDevice(nodeId, modifiedDevice);
         }
@@ -160,8 +169,9 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
             LOG.warn("No corresponding callhome device found - exiting.");
         } else {
             Device modifiedDevice = withFailedStatus(opDev);
-            if(modifiedDevice == null)
+            if (modifiedDevice == null) {
                 return;
+            }
             LOG.info("Setting failed status for callhome device id:{}.", nodeId);
             writeDevice(nodeId, modifiedDevice);
         }
@@ -184,8 +194,7 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
         try {
             sshEncodedKey = AuthorizedKeysDecoder.encodePublicKey(serverKey);
         } catch (IOException e) {
-            e.printStackTrace();
-            LOG.warn("Unable to encode public key to ssh format.");
+            LOG.warn("Unable to encode public key to ssh format.", e);
         }
         Device1 d1 = new Device1Builder().setDeviceStatus(Device1.DeviceStatus.FAILEDNOTALLOWED).build();
         DeviceBuilder builder = new DeviceBuilder()
@@ -198,16 +207,10 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
     }
 
     private Device readAndGetDevice(NodeId nodeId) {
-        Optional<Device> opDevGet = readDevice(nodeId);
-        if (opDevGet != null) {
-            if (opDevGet.isPresent()) {
-                return opDevGet.get();
-            }
-        }
-
-        return null;
+        return readDevice(nodeId).orNull();
     }
 
+    @Nonnull
     private Optional<Device> readDevice(NodeId nodeId) {
         ReadOnlyTransaction opTx = dataBroker.newReadOnlyTransaction();
 
@@ -218,7 +221,7 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
         try {
             return devFuture.checkedGet();
         } catch (ReadFailedException e) {
-            return null;
+            return Optional.absent();
         }
     }
 
@@ -237,7 +240,7 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
     private Device withConnectedStatus(Device opDev) {
         Device1 status = new Device1Builder().setDeviceStatus(Device1.DeviceStatus.CONNECTED).build();
         return new DeviceBuilder().addAugmentation(Device1.class, status).setUniqueId(opDev.getUniqueId())
-            .setSshHostKey(opDev.getSshHostKey()).build();
+                .setSshHostKey(opDev.getSshHostKey()).build();
     }
 
     private Device withFailedStatus(Device opDev) {
@@ -255,21 +258,20 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
     private Device withFailedAuthStatus(Device opDev) {
         Device1 status = new Device1Builder().setDeviceStatus(Device1.DeviceStatus.FAILEDAUTHFAILURE).build();
         return new DeviceBuilder().addAugmentation(Device1.class, status).setUniqueId(opDev.getUniqueId())
-               .setSshHostKey(opDev.getSshHostKey()).build();
+                .setSshHostKey(opDev.getSshHostKey()).build();
     }
 
     private void setDeviceStatus(Device device) {
         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
-        InstanceIdentifier<Device> Device_IID =
+        InstanceIdentifier<Device> deviceIId =
                 InstanceIdentifier.create(NetconfCallhomeServer.class)
                         .child(AllowedDevices.class)
                         .child(Device.class, device.getKey());
 
-        tx.merge(LogicalDatastoreType.OPERATIONAL, Device_IID, device);
+        tx.merge(LogicalDatastoreType.OPERATIONAL, deviceIId, device);
         tx.submit();
     }
 
-
     private AllowedDevices getDevices() {
         ReadOnlyTransaction rxTransaction = dataBroker.newReadOnlyTransaction();
         CheckedFuture<Optional<AllowedDevices>, ReadFailedException> devicesFuture =
@@ -290,7 +292,7 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
 
     private List<Device> getDevicesAsList() {
         AllowedDevices devices = getDevices();
-        return (devices == null) ? new ArrayList<Device>() : devices.getDevice();
+        return devices == null ? new ArrayList<>() : devices.getDevice();
     }
 
     @Override
@@ -304,8 +306,9 @@ class CallhomeStatusReporter implements DataChangeListener, StatusRecorder, Auto
                 PublicKey pubKey = decoder.decodePublicKey(keyString);
                 if (sshKey.getAlgorithm().equals(pubKey.getAlgorithm()) && sshKey.equals(pubKey)) {
                     Device failedDevice = withFailedAuthStatus(device);
-                    if(failedDevice==null)
+                    if (failedDevice == null) {
                         return;
+                    }
                     LOG.info("Setting auth failed status for callhome device id:{}.", failedDevice.getUniqueId());
                     setDeviceStatus(failedDevice);
                     return;