BridgeRemovedCommand 14/17114/3
authorEd Warnicke <eaw@cisco.com>
Wed, 25 Mar 2015 15:11:34 +0000 (11:11 -0400)
committerEd Warnicke <eaw@cisco.com>
Wed, 25 Mar 2015 22:42:52 +0000 (18:42 -0400)
We can now delete bridges

Change-Id: I2c89b65c5410172cdb4f5e103bfa0da5b6ab8915
Signed-off-by: Ed Warnicke <eaw@cisco.com>
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbManagedNodeDataChangeListener.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommand.java [new file with mode: 0644]
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommand.java [new file with mode: 0644]
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/DataChangesManagedByOvsdbNodeEvent.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactCommandAggregator.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtils.java

index 3b81497b17bda8a6ab5e81a0c137f0399cb94fac..59e4f9c8664e861a365c71ae656fc99bc25fc4d9 100644 (file)
@@ -7,7 +7,10 @@
  */
 package org.opendaylight.ovsdb.southbound;
 
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
@@ -27,6 +30,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Maps;
+
 public class OvsdbManagedNodeDataChangeListener implements DataChangeListener, AutoCloseable {
 
     private ListenerRegistration<DataChangeListener> registration;
@@ -51,25 +60,40 @@ public class OvsdbManagedNodeDataChangeListener implements DataChangeListener, A
     public void onDataChanged(
             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
        LOG.info("Received change to ovsdbManagedNode: {}", changes);
-       for( Entry<InstanceIdentifier<?>, DataObject> created : changes.getCreatedData().entrySet()) {
-           // TODO validate we have the correct kind of InstanceIdentifier
-           if(created.getValue() instanceof OvsdbBridgeAugmentation) {
-               LOG.debug("Received request to create {}",created.getValue());
-               OvsdbConnectionInstance client = cm.getConnectionInstance((OvsdbBridgeAugmentation)created.getValue());
-               if(client != null) {
-                   LOG.debug("Found client for {}", created.getValue());
-                   client.transact(new TransactCommandAggregator(
-                           new DataChangesManagedByOvsdbNodeEvent(
-                                   SouthboundMapper.createInstanceIdentifier(client.getKey()),
-                                   changes)));
-               } else {
-                   LOG.debug("Did not find client for {}",created.getValue());
-               }
-               // TODO - translate the OvsdbBridgeAugmentation to libary/ transacts to create the node
-           }
+       for(OvsdbConnectionInstance connectionInstance: connectionInstancesFromChanges(changes)) {
+           connectionInstance.transact(new TransactCommandAggregator(
+                   db,
+                   new DataChangesManagedByOvsdbNodeEvent(
+                           SouthboundMapper.createInstanceIdentifier(connectionInstance.getKey()),
+                           changes)));
        }
-       // TODO handle case of updates to ovsdb managed nodes as needed
-       // TODO handle case of delete to ovsdb managed nodes as needed
+    }
+
+    public Set<OvsdbConnectionInstance> connectionInstancesFromChanges(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        Set<OvsdbConnectionInstance> result = new HashSet<OvsdbConnectionInstance>();
+        result.addAll(connectionInstancesFromMap(changes.getCreatedData()));
+        result.addAll(connectionInstancesFromMap(changes.getUpdatedData()));
+        result.addAll(connectionInstancesFromMap(
+                Maps.filterKeys(changes.getOriginalData(), Predicates.in(changes.getRemovedPaths()))));
+        return result;
+    }
+
+    public Set<OvsdbConnectionInstance> connectionInstancesFromMap(Map<InstanceIdentifier<?>, DataObject> map) {
+        Preconditions.checkNotNull(map);
+        Set<OvsdbConnectionInstance> result = new HashSet<OvsdbConnectionInstance>();
+        for( Entry<InstanceIdentifier<?>, DataObject> created : map.entrySet()) {
+            if(created.getValue() instanceof OvsdbBridgeAugmentation) {
+                LOG.debug("Received request to create {}",created.getValue());
+                OvsdbConnectionInstance client = cm.getConnectionInstance((OvsdbBridgeAugmentation)created.getValue());
+                if(client != null) {
+                    LOG.debug("Found client for {}", created.getValue());
+                    result.add(client);
+                } else {
+                    LOG.debug("Did not find client for {}",created.getValue());
+                }
+            }
+        }
+        return result;
     }
 
     @Override
diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommand.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommand.java
new file mode 100644 (file)
index 0000000..520c265
--- /dev/null
@@ -0,0 +1,92 @@
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+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.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+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;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class BridgeRemovedCommand implements TransactCommand{
+    private static final Logger LOG = LoggerFactory.getLogger(BridgeRemovedCommand.class);
+    private AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes;
+    private DataBroker db;
+
+    public BridgeRemovedCommand(DataBroker db,AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes) {
+        this.db = db;
+        this.changes = changes;
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        Set<InstanceIdentifier<Node>> removed = TransactUtils.extractOvsdbManagedNodeRemoved(changes);
+        Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> originals = TransactUtils.extractOvsdbManagedNodeOriginal(changes);
+        for(InstanceIdentifier<Node> ovsdbManagedNodeIid: removed) {
+            LOG.info("Received request to delete ovsdb node {}",ovsdbManagedNodeIid);
+            OvsdbBridgeAugmentation original = originals.get(ovsdbManagedNodeIid);
+            Bridge bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), Bridge.class,null);
+            Optional<UUID> bridgeUuidOptional = getBridgeUUID(ovsdbManagedNodeIid);
+            if(bridgeUuidOptional.isPresent()) {
+                UUID bridgeUuid = bridgeUuidOptional.get();
+                OpenVSwitch ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), OpenVSwitch.class,null);
+                transaction.add(op.delete(bridge.getSchema())
+                        .where(bridge.getUuidColumn().getSchema().opEqual(bridgeUuid)).build());
+                transaction.add(op.comment("Bridge: Deleting " + original.getBridgeName()));
+                transaction.add(op.mutate(ovs.getSchema())
+                        .addMutation(ovs.getBridgesColumn().getSchema(), Mutator.DELETE,
+                                Sets.newHashSet(bridgeUuid)));
+                transaction.add(op.comment("Open_vSwitch: Mutating " + original.getBridgeName() + " " + bridgeUuid));
+             } else {
+                 LOG.warn("Unable to delete bridge {} because it was not found in the operational store, and thus we cannot retrieve its UUID", ovsdbManagedNodeIid);
+             }
+
+        }
+    }
+
+    private Optional<UUID> getBridgeUUID(InstanceIdentifier<Node> ovsdbManagedNodeIid) {
+        Optional<UUID> result = Optional.absent();
+        ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
+        CheckedFuture<Optional<Node>, ReadFailedException> future = transaction.read(LogicalDatastoreType.OPERATIONAL, ovsdbManagedNodeIid);
+        Optional<Node> optional;
+        try {
+            optional = future.get();
+            if(optional.isPresent()) {
+                OvsdbBridgeAugmentation bridge = (OvsdbBridgeAugmentation) optional.get();
+                if(bridge != null && bridge.getBridgeUuid() != null) {
+                    result = Optional.of(new UUID(bridge.getBridgeUuid().getValue()));
+                }
+            }
+        } catch (InterruptedException e) {
+            LOG.warn("Unable to retrieve bridge from operational store",e);
+        } catch (ExecutionException e) {
+            LOG.warn("Unable to retrieve bridge from operational store",e);
+        }
+        return result;
+    }
+
+}
diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommand.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommand.java
new file mode 100644 (file)
index 0000000..d66644e
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.southbound.transactions.md.TransactionCommand;
+
+public class BridgeUpdateCommand implements TransactionCommand {
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
index cd07033125e23fcc2b6996a5bd3c58824dd35d93..7d40b5e52041cac3e14bcd694ebe2ac4a748f912 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Set;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 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.OvsdbNodeRef;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -67,14 +68,20 @@ public class DataChangesManagedByOvsdbNodeEvent implements
 
     @Override
     public Set<InstanceIdentifier<?>> getRemovedPaths() {
-        if(this.removedPaths != null) {
+        if(this.removedPaths == null) {
             this.removedPaths = new HashSet<InstanceIdentifier<?>>();
             for(InstanceIdentifier<?> path: event.getRemovedPaths()) {
                 DataObject original = this.event.getOriginalData().get(path);
                 if(original != null
-                        && original instanceof OvsdbBridgeAugmentation
-                        && ((OvsdbBridgeAugmentation)original).getManagedBy().equals(this.iid)) {
-                    this.removedPaths.add(path);
+                        && original instanceof OvsdbBridgeAugmentation) {
+                    OvsdbBridgeAugmentation ovsdbBridgeNode = (OvsdbBridgeAugmentation)original;
+                    OvsdbNodeRef ovsdbNodeRef = ovsdbBridgeNode.getManagedBy();
+                    if(ovsdbNodeRef != null) {
+                        InstanceIdentifier<?> ovsdbNodeIid = ovsdbNodeRef.getValue();
+                        if(ovsdbNodeIid.equals(this.iid)){
+                            this.removedPaths.add(path);
+                        }
+                    }
                 }
             }
         }
index 2bc99bc31a831a4de3564929c44763d2cb2a6dbc..9431a15481933833dbd847c71c50a774ff7cfa31 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.southbound.ovsdb.transact;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
@@ -19,10 +20,13 @@ public class TransactCommandAggregator implements TransactCommand {
 
     private List<TransactCommand> commands = new ArrayList<TransactCommand>();
     private AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes;
+    private DataBroker db;
 
-    public TransactCommandAggregator(AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes) {
+    public TransactCommandAggregator(DataBroker db,AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes) {
+        this.db = db;
         this.changes=changes;
         commands.add(new BridgeCreateCommand(changes));
+        commands.add(new BridgeRemovedCommand(db,changes));
     }
 
     @Override
index 124837d71fc609fa7fa6b670d17f5231bdb2ed17..d8ad5555ed88cdeb37f2db15dec129f4942ee44e 100644 (file)
@@ -45,6 +45,10 @@ public class TransactUtils {
         return result;
     }
 
+    public static Map<InstanceIdentifier<Node>,OvsdbBridgeAugmentation> extractOvsdbManagedNodeOriginal(AsyncDataChangeEvent<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes)  {
+        return extractOvsdbManagedNode(changes.getOriginalData());
+    }
+
 
     public static Map<InstanceIdentifier<Node>,OvsdbBridgeAugmentation> extractOvsdbManagedNode(
             Map<InstanceIdentifier<?>, OvsdbBridgeAugmentation> changes) {