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;
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())));
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) {
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);
}
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);
}
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);
}
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()
}
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();
try {
return devFuture.checkedGet();
} catch (ReadFailedException e) {
- return null;
+ return Optional.absent();
}
}
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) {
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 =
private List<Device> getDevicesAsList() {
AllowedDevices devices = getDevices();
- return (devices == null) ? new ArrayList<Device>() : devices.getDevice();
+ return devices == null ? new ArrayList<>() : devices.getDevice();
}
@Override
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;