Upgrade to Neon base platform
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / HwvtepPhysicalSwitchUpdateCommand.java
index 8dbe89382d1af556240fb4f513e0ce231f350b8e..9a3fd7ff26c1aa52364479f5cb5ded443753fc05 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -8,10 +8,16 @@
 
 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
@@ -24,6 +30,7 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
@@ -37,6 +44,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hw
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatusBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatusKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
@@ -44,67 +54,107 @@ 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.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-
 public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
 
     private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchUpdateCommand.class);
-    private Map<UUID, PhysicalSwitch> updatedPSRows;
+    private final Map<UUID, PhysicalSwitch> updatedPSRows;
     private Map<UUID, Tunnel> updatedTunnelRows;
+    private final Map<UUID, PhysicalSwitch> oldPSRows;
 
-    public HwvtepPhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
+    public HwvtepPhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
         super(key, updates, dbSchema);
         updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(), getDbSchema());
+        oldPSRows = TyperUtils.extractRowsOld(PhysicalSwitch.class, getUpdates(), getDbSchema());
         try {
             updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
         } catch (IllegalArgumentException e) {
-            LOG.debug("Tunnel Table not supported on this HWVTEP device", e.getMessage());
+            LOG.debug("Tunnel Table not supported on this HWVTEP device", e);
         }
     }
 
     @Override
     public void execute(ReadWriteTransaction transaction) {
-        for (PhysicalSwitch physicalSwitch : updatedPSRows.values()) {
-            updatePhysicalSwitch(transaction, physicalSwitch);
+        for (Map.Entry<UUID, PhysicalSwitch> entry : updatedPSRows.entrySet()) {
+            updatePhysicalSwitch(transaction, entry.getKey(), entry.getValue());
         }
     }
 
-    private void updatePhysicalSwitch(ReadWriteTransaction transaction, PhysicalSwitch pSwitch) {
+    private void updatePhysicalSwitch(ReadWriteTransaction transaction, UUID uuid, PhysicalSwitch phySwitch) {
         final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+        //TODO remove this read
         Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
         if (connection.isPresent()) {
             LOG.debug("Connection {} is present", connection);
             // Update the connection node to let it know it manages this
             // Physical Switch
-            Node connectionNode = buildConnectionNode(pSwitch);
+            Node connectionNode = buildConnectionNode(phySwitch);
             transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
 
             // Update the Physical Switch with whatever data we are getting
-            InstanceIdentifier<Node> psIid = getInstanceIdentifier(pSwitch);
-            Node psNode = buildPhysicalSwitchNode(connection.get(), pSwitch);
+            InstanceIdentifier<Node> psIid = getInstanceIdentifier(phySwitch);
+            Node psNode = buildPhysicalSwitchNode(connection.get(), phySwitch);
             transaction.merge(LogicalDatastoreType.OPERATIONAL, psIid, psNode);
-            getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitch(pSwitch.getUuid(), pSwitch);
+
+            PhysicalSwitch oldPSwitch = oldPSRows.get(uuid);
+            updateTunnelIps(phySwitch, oldPSwitch, transaction);
+
+            getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitch(phySwitch.getUuid(), phySwitch);
+            getDeviceInfo().updateDeviceOperData(Node.class, psIid, phySwitch.getUuid(), phySwitch);
             // TODO: Delete entries that are no longer needed
             // TODO: Deletion of tunnels
             // TODO: Deletion of Tunnel BFD config and params
+            //Deleting old switch fault status entries
+            deleteEntries(transaction, getSwitchFaultStatusToRemove(psIid,phySwitch));
+        }
+    }
+
+    private InstanceIdentifier<TunnelIps> getTunnelIpIid(final String tunnelIp,
+            final InstanceIdentifier<Node> psIid) {
+        IpAddress ip = IpAddressBuilder.getDefaultInstance(tunnelIp);
+        TunnelIps tunnelIps = new TunnelIpsBuilder().withKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build();
+        return psIid.augmentation(PhysicalSwitchAugmentation.class).child(TunnelIps.class, tunnelIps.key());
+    }
+
+    private void updateTunnelIps(@Nonnull final PhysicalSwitch newPSwitch, @Nullable final PhysicalSwitch oldPSwitch,
+                                 final ReadWriteTransaction transaction) {
+        Set<String> oldTunnelIps = oldPSwitch != null && oldPSwitch.getTunnelIpsColumn() != null ? oldPSwitch
+                .getTunnelIpsColumn().getData() : Collections.emptySet();
+        Set<String> newTunelIps = newPSwitch.getTunnelIpsColumn() != null ? newPSwitch
+                .getTunnelIpsColumn().getData() : Collections.emptySet();
+
+        Set<String> addedTunnelIps = Sets.difference(newTunelIps, oldTunnelIps);
+        Set<String> removedTunnelIps = Sets.difference(oldTunnelIps, newTunelIps);
+
+        InstanceIdentifier<Node> psIid = getInstanceIdentifier(newPSwitch);
+        for (String tunnelIp : removedTunnelIps) {
+            InstanceIdentifier<TunnelIps> tunnelIpsInstanceIdentifier = getTunnelIpIid(tunnelIp, psIid);
+            transaction.delete(LogicalDatastoreType.OPERATIONAL, tunnelIpsInstanceIdentifier);
+        }
+        for (String tunnelIp : addedTunnelIps) {
+            IpAddress ip = IpAddressBuilder.getDefaultInstance(tunnelIp);
+            InstanceIdentifier<TunnelIps> tunnelIpsInstanceIdentifier = getTunnelIpIid(tunnelIp, psIid);
+            TunnelIps tunnelIps = new TunnelIpsBuilder().withKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build();
+            transaction.put(LogicalDatastoreType.OPERATIONAL, tunnelIpsInstanceIdentifier, tunnelIps, true);
         }
     }
 
-    private Node buildPhysicalSwitchNode(Node node, PhysicalSwitch pSwitch) {
+    private Node buildPhysicalSwitchNode(Node node, PhysicalSwitch phySwitch) {
         NodeBuilder psNodeBuilder = new NodeBuilder();
-        NodeId psNodeId = getNodeId(pSwitch);
+        NodeId psNodeId = getNodeId(phySwitch);
         psNodeBuilder.setNodeId(psNodeId);
         PhysicalSwitchAugmentationBuilder psAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
-        psAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(pSwitch.getUuid().toString()));
+        psAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(phySwitch.getUuid().toString()));
         setManagedBy(psAugmentationBuilder);
-        setPhysicalSwitchId(psAugmentationBuilder, pSwitch);
-        setManagementIps(psAugmentationBuilder, pSwitch);
-        setTunnelIps(psAugmentationBuilder, pSwitch);
-        setTunnels(psAugmentationBuilder, pSwitch);
+        setPhysicalSwitchId(psAugmentationBuilder, phySwitch);
+        setManagementIps(psAugmentationBuilder, phySwitch);
+        setTunnels(psAugmentationBuilder, phySwitch);
+        setSwitchFaultStatus(psAugmentationBuilder, phySwitch);
 
         psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugmentationBuilder.build());
 
@@ -112,12 +162,12 @@ public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionComman
         return psNodeBuilder.build();
     }
 
-    private void setTunnels(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
-        if (updatedTunnelRows != null && pSwitch.getTunnels() != null && pSwitch.getTunnels().getData() != null
-                && !pSwitch.getTunnels().getData().isEmpty()) {
+    private void setTunnels(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch phySwitch) {
+        if (updatedTunnelRows != null && phySwitch.getTunnels() != null && phySwitch.getTunnels().getData() != null
+                && !phySwitch.getTunnels().getData().isEmpty()) {
             // Nothing to do but update deviceInfo cache
-            for(UUID uuid: pSwitch.getTunnels().getData()) {
-                getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitchForTunnel(uuid, pSwitch.getUuid());
+            for (UUID uuid: phySwitch.getTunnels().getData()) {
+                getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitchForTunnel(uuid, phySwitch.getUuid());
             }
         }
     }
@@ -127,41 +177,31 @@ public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionComman
         psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
     }
 
-    private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
-        if (pSwitch.getName() != null) {
-            psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
+    private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder,
+            PhysicalSwitch phySwitch) {
+        if (phySwitch.getName() != null) {
+            psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(phySwitch.getName()));
         }
-        if (pSwitch.getDescription() != null) {
-            psAugmentationBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
+        if (phySwitch.getDescription() != null) {
+            psAugmentationBuilder.setHwvtepNodeDescription(phySwitch.getDescription());
         }
     }
 
-    private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
-        if (pSwitch.getManagementIpsColumn() != null && pSwitch.getManagementIpsColumn().getData() != null
-                && !pSwitch.getManagementIpsColumn().getData().isEmpty()) {
+    private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder,
+            PhysicalSwitch phySwitch) {
+        if (phySwitch.getManagementIpsColumn() != null && phySwitch.getManagementIpsColumn().getData() != null
+                && !phySwitch.getManagementIpsColumn().getData().isEmpty()) {
             List<ManagementIps> mgmtIps = new ArrayList<>();
-            for (String mgmtIp : pSwitch.getManagementIpsColumn().getData()) {
-                IpAddress ip = new IpAddress(mgmtIp.toCharArray());
+            for (String mgmtIp : phySwitch.getManagementIpsColumn().getData()) {
+                IpAddress ip = IpAddressBuilder.getDefaultInstance(mgmtIp);
                 mgmtIps.add(
-                        new ManagementIpsBuilder().setKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
+                        new ManagementIpsBuilder().withKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
             }
             psAugmentationBuilder.setManagementIps(mgmtIps);
         }
     }
 
-    private void setTunnelIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
-        if (pSwitch.getTunnelIpsColumn() != null && pSwitch.getTunnelIpsColumn().getData() != null
-                && !pSwitch.getTunnelIpsColumn().getData().isEmpty()) {
-            List<TunnelIps> tunnelIps = new ArrayList<>();
-            for (String tunnelIp : pSwitch.getTunnelIpsColumn().getData()) {
-                IpAddress ip = new IpAddress(tunnelIp.toCharArray());
-                tunnelIps.add(new TunnelIpsBuilder().setKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
-            }
-            psAugmentationBuilder.setTunnelIps(tunnelIps);
-        }
-    }
-
-    private Node buildConnectionNode(PhysicalSwitch pSwitch) {
+    private Node buildConnectionNode(PhysicalSwitch phySwitch) {
         // Update node with PhysicalSwitch reference
         NodeBuilder connectionNode = new NodeBuilder();
         connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
@@ -169,7 +209,7 @@ public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionComman
         HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
         List<Switches> switches = new ArrayList<>();
         InstanceIdentifier<Node> switchIid =
-                HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
+                HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), phySwitch);
         hgAugmentationBuilder.setSwitches(switches);
         Switches physicalSwitch = new SwitchesBuilder().setSwitchRef(new HwvtepPhysicalSwitchRef(switchIid)).build();
         switches.add(physicalSwitch);
@@ -180,13 +220,52 @@ public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionComman
         return connectionNode.build();
     }
 
-    private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
-        return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
+    private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch phySwitch) {
+        return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), phySwitch);
     }
 
-    private NodeId getNodeId(PhysicalSwitch pSwitch) {
-        NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class);
+    private NodeId getNodeId(PhysicalSwitch phySwitch) {
+        NodeKey nodeKey = getInstanceIdentifier(phySwitch).firstKeyOf(Node.class);
         return nodeKey.getNodeId();
     }
 
+    private <T extends DataObject> void deleteEntries(ReadWriteTransaction transaction,
+            List<InstanceIdentifier<T>> entryIids) {
+        for (InstanceIdentifier<T> entryIid : entryIids) {
+            transaction.delete(LogicalDatastoreType.OPERATIONAL, entryIid);
+        }
+    }
+
+    private List<InstanceIdentifier<SwitchFaultStatus>> getSwitchFaultStatusToRemove(InstanceIdentifier<Node> psIid,
+            PhysicalSwitch phySwitch) {
+        Preconditions.checkNotNull(psIid);
+        Preconditions.checkNotNull(phySwitch);
+        List<InstanceIdentifier<SwitchFaultStatus>> result = new ArrayList<>();
+        PhysicalSwitch oldSwitch = oldPSRows.get(phySwitch.getUuid());
+        if (oldSwitch != null && oldSwitch.getSwitchFaultStatusColumn() != null) {
+            for (String switchFltStat : oldSwitch.getSwitchFaultStatusColumn().getData()) {
+                if (phySwitch.getSwitchFaultStatusColumn() == null
+                        || !phySwitch.getSwitchFaultStatusColumn().getData().contains(switchFltStat)) {
+                    InstanceIdentifier<SwitchFaultStatus> iid = psIid.augmentation(PhysicalSwitchAugmentation.class)
+                            .child(SwitchFaultStatus.class, new SwitchFaultStatusKey(switchFltStat));
+                    result.add(iid);
+                }
+            }
+        }
+        return result;
+    }
+
+    private void setSwitchFaultStatus(PhysicalSwitchAugmentationBuilder psAugmentationBuilder,
+            PhysicalSwitch phySwitch) {
+        if (phySwitch.getSwitchFaultStatusColumn() != null && phySwitch.getSwitchFaultStatusColumn().getData() != null
+                && !phySwitch.getSwitchFaultStatusColumn().getData().isEmpty()) {
+            List<SwitchFaultStatus> switchFaultStatusLst = new ArrayList<>();
+            for (String switchFaultStatus : phySwitch.getSwitchFaultStatusColumn().getData()) {
+                switchFaultStatusLst
+                        .add(new SwitchFaultStatusBuilder().withKey(new SwitchFaultStatusKey(switchFaultStatus))
+                                .setSwitchFaultStatusKey(switchFaultStatus).build());
+            }
+            psAugmentationBuilder.setSwitchFaultStatus(switchFaultStatusLst);
+        }
+    }
 }