*/
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;
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;
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
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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
+
+ }
+
+}
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;
@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);
+ }
+ }
}
}
}
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;
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
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) {