UUIDs be gone.
[groupbasedpolicy.git] / neutron-ovsdb / src / main / java / org / opendaylight / groupbasedpolicy / neutron / ovsdb / NodeDataChangeListener.java
index 3494d8450fe5a89cbed3523a696d093c30a6d0a8..2bd1334e8e6b478346ffd28091f8a7dd0c85d483 100644 (file)
@@ -14,16 +14,21 @@ import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelp
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.NeutronOvsdbIidFactory.ovsdbNodeAugmentationIid;
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getNodeFromBridgeRef;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 
 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.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
@@ -37,13 +42,18 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Strings;
+
+import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.removeIfExists;
+import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.submitToDs;
+
 public class NodeDataChangeListener implements DataChangeListener, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(NodeDataChangeListener.class);
     private static final String NEUTRON_PROVIDER_MAPPINGS_KEY = "provider_mappings";
     private static final String INVENTORY_PREFIX = "openflow:";
     private final ListenerRegistration<DataChangeListener> registration;
-    private final DataBroker dataBroker;
+    private static DataBroker dataBroker;
 
     public NodeDataChangeListener(DataBroker dataBroker) {
         this.dataBroker = checkNotNull(dataBroker);
@@ -52,7 +62,14 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         LOG.trace("NodeDataChangeListener started");
     }
 
+    /*
+     * When vSwitch is deleted, we loose data in operational DS to determine Iid of
+     * corresponding ExternalInterfaces.
+     */
+    public static final Map<InstanceIdentifier<OvsdbNodeAugmentation>, InstanceIdentifier<ExternalInterfaces>> nodeIdByExtInterface = new HashMap<>();
+
     @Override
+    @SuppressWarnings("unchecked")
     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
 
         /*
@@ -62,7 +79,11 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbNodeAugmentation) {
                 OvsdbNodeAugmentation ovsdbNode = (OvsdbNodeAugmentation) entry.getValue();
-                processNodeNotification(ovsdbNode);
+                InstanceIdentifier<OvsdbNodeAugmentation> key = (InstanceIdentifier<OvsdbNodeAugmentation>) entry.getKey();
+                InstanceIdentifier<ExternalInterfaces> extInterfacesIid = processNodeNotification(ovsdbNode);
+                if (extInterfacesIid != null) {
+                    nodeIdByExtInterface.put(key, extInterfacesIid);
+                }
             }
         }
 
@@ -72,7 +93,9 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getUpdatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbNodeAugmentation) {
                 OvsdbNodeAugmentation ovsdbNode = (OvsdbNodeAugmentation) entry.getValue();
-                processNodeNotification(ovsdbNode);
+                if (Strings.isNullOrEmpty(getProviderMapping(ovsdbNode))) {
+                    removeExternalInterfaces((InstanceIdentifier<OvsdbNodeAugmentation>) entry.getKey());
+                }
             }
         }
 
@@ -80,10 +103,10 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
          * Deletions
          */
         for (InstanceIdentifier<?> iid : change.getRemovedPaths()) {
-            if (iid instanceof OvsdbTerminationPointAugmentation) {
-                /*
-                 * Remove the state from OfOverlay?
-                 */
+            if (iid.getTargetType().equals(OvsdbNodeAugmentation.class)) {
+                if (nodeIdByExtInterface.get(iid) != null) {
+                    removeExternalInterfaces((InstanceIdentifier<OvsdbNodeAugmentation>) iid);
+                }
             }
         }
     }
@@ -93,7 +116,7 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         registration.close();
     }
 
-    private void processNodeNotification(OvsdbNodeAugmentation ovsdbNode) {
+    public static InstanceIdentifier<ExternalInterfaces> processNodeNotification(OvsdbNodeAugmentation ovsdbNode) {
         LOG.trace("Search for provider mapping on node {}", ovsdbNode);
         String providerPortName = getProviderMapping(ovsdbNode);
         if (providerPortName != null) {
@@ -104,16 +127,25 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
                 String[] elements = nodeConnectorIdString.split(":");
                 String nodeIdString = elements[0] + ":" + elements[1];
                 NodeConnectorId ncid = getNodeConnectorId(nodeConnectorIdString);
-                addOfOverlayExternalPort(nodeIdString, ncid, dataBroker);
+                return addOfOverlayExternalPort(new NodeId(nodeIdString), ncid, dataBroker);
             }
         }
+        return null;
+    }
+
+    private void removeExternalInterfaces(InstanceIdentifier<OvsdbNodeAugmentation> iidOvsdbNodeAug){
+        InstanceIdentifier<ExternalInterfaces> iidExtInterface = nodeIdByExtInterface.get(iidOvsdbNodeAug);
+        ReadWriteTransaction wTx = dataBroker.newReadWriteTransaction();
+        removeIfExists(LogicalDatastoreType.CONFIGURATION, iidExtInterface, wTx);
+        submitToDs(wTx);
+        nodeIdByExtInterface.remove(iidOvsdbNodeAug);
     }
 
-    private NodeConnectorId getNodeConnectorId(String nodeConnectorIdString) {
+    private static NodeConnectorId getNodeConnectorId(String nodeConnectorIdString) {
         return new NodeConnectorId(nodeConnectorIdString);
     }
 
-    private String getProviderMapping(OvsdbNodeAugmentation ovsdbNode) {
+    public static String getProviderMapping(OvsdbNodeAugmentation ovsdbNode) {
         if (ovsdbNode.getOpenvswitchOtherConfigs() != null) {
             for (OpenvswitchOtherConfigs config : ovsdbNode.getOpenvswitchOtherConfigs()) {
                 if (config.getOtherConfigKey() == null || config.getOtherConfigValue() == null) {
@@ -137,11 +169,13 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
      * Get the DPID and OpenFlow port of the bridge that owns the {@link TerminationPoint} in the
      * provider mapping
      *
-     * @return
+     * @return the DPID and OpenFlow port of the bridge that owns the {@link TerminationPoint} in
+     * the provider mapping
      */
-    private String getInventoryNodeId(OvsdbNodeAugmentation ovsdbNode, String externalPortName) {
+    private static String getInventoryNodeId(OvsdbNodeAugmentation ovsdbNode, String externalPortName) {
         List<ManagedNodeEntry> ovsdbNodes = ovsdbNode.getManagedNodeEntry();
         if (ovsdbNodes == null) {
+            LOG.trace("No ManagedNodeEntry was found on {}", ovsdbNode);
             return null;
         }
         for (ManagedNodeEntry managedNode : ovsdbNodes) {
@@ -158,6 +192,7 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
                 }
                 OvsdbBridgeAugmentation ovsdbBridge = node.getAugmentation(OvsdbBridgeAugmentation.class);
                 if (ovsdbBridge == null) {
+                    LOG.trace("OVSDB Node {} does not contain OvsdbBridgeAugmentation. {}", node.getKey(), node);
                     continue;
                 }
                 for (TerminationPoint tp : node.getTerminationPoint()) {
@@ -174,7 +209,7 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         return null;
     }
 
-    private String buildInventoryNcid(OvsdbBridgeAugmentation ovsdbBridge,
+    private static String buildInventoryNcid(OvsdbBridgeAugmentation ovsdbBridge,
             OvsdbTerminationPointAugmentation terminationPoint) {
         Long macLong = getLongFromDpid(ovsdbBridge.getDatapathId().getValue());
         return INVENTORY_PREFIX + String.valueOf(macLong) + ":" + String.valueOf(terminationPoint.getOfport());