--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.schema.openvswitch;
+
+import java.util.Map;
+
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.MethodType;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedColumn;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
+
+/**
+ * This class is a typed interface to the AutoAttach Table
+ */
+@TypedTable(name="AutoAttach", database="Open_vSwitch", fromVersion="7.11.2")
+public interface AutoAttach extends TypedBaseTable<GenericTableSchema> {
+
+ @TypedColumn(name="system_name", method=MethodType.GETCOLUMN, fromVersion="7.11.2")
+ Column<GenericTableSchema, String> getSystemNameColumn();
+ @TypedColumn(name="system_name", method=MethodType.SETDATA, fromVersion="7.11.2")
+ void setSystemName(String systemName);
+
+ @TypedColumn(name="system_description", method=MethodType.GETCOLUMN, fromVersion="7.11.2")
+ Column<GenericTableSchema, String> getSystemDescriptionColumn();
+ @TypedColumn(name="system_description", method=MethodType.SETDATA, fromVersion="7.11.2")
+ void setSystemDescription(String systemDescription);
+
+ @TypedColumn(name="mappings", method=MethodType.GETCOLUMN, fromVersion="7.11.2")
+ Column<GenericTableSchema, Map<Long, Long>> getMappingsColumn();
+ @TypedColumn(name="mappings", method=MethodType.SETDATA, fromVersion="7.11.2")
+ void setMappings(Map<Long, Long> mappings);
+
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// @TypedColumn (name="external_ids", method= MethodType.GETCOLUMN, fromVersion="7.11.2")
+// Column<GenericTableSchema, Map<String, String>> getExternalIdsColumn();
+// @TypedColumn (name="external_ids", method= MethodType.SETDATA, fromVersion="7.11.2")
+// void setExternalIds(Map<String, String> externalIds);
+
+}
@TypedColumn(name="flow_tables", method=MethodType.SETDATA, fromVersion="6.5.0")
void setFlowTables(Map<Long, UUID> flowTables);
+ @TypedColumn(name="auto_attach", method=MethodType.GETCOLUMN, fromVersion="7.11.2")
+ Column<GenericTableSchema, Set<UUID>> getAutoAttachColumn();
+
+ @TypedColumn(name="auto_attach", method=MethodType.SETDATA, fromVersion="7.11.2")
+ void setAutoAttach(Set<UUID> autoAttach);
}
description "An identifier used for AutoAttach table in the MD-SAL.";
type inet:uri;
}
+ leaf bridge-id {
+ description "Node-id of the Bridge table from where Autoattach table can be referenced.";
+ type inet:uri;
+ }
leaf autoattach-uuid {
description "The unique identifier of the autoattach table.";
type yang:uuid;
}
}
}
+ list autoattach-external-ids {
+ description
+ "Key-value pairs for use by external frameworks that integrate with
+ Open vSwitch, rather than by Open vSwitch itself.";
+
+ key "autoattach-external-id-key";
+ leaf autoattach-external-id-key {
+ description "external-id name/key";
+ type string;
+ mandatory true;
+ }
+ leaf autoattach-external-id-value {
+ description "autoattach-external-id value";
+ type string;
+ mandatory true;
+ }
+ }
}
}
MIRROR("Mirror", "Bridge", "mirrors"),
MANAGER("Manager", "Open_vSwitch", "manager_options"),
CONTROLLER("Controller", "Bridge", "controller"),
- FLOWSAMPLECOLLECTORSET("Flow_Sample_Collector_Set",null,null);
+ FLOWSAMPLECOLLECTORSET("Flow_Sample_Collector_Set",null,null),
+ AUTOATTACH("AutoAttach", "Bridge", "auto_attach");
private final String tableName;
private final String parentTableName;
public static final String TP_URI_PREFIX = "terminationpoint";
public static final String QOS_URI_PREFIX = "qos";
public static final String QUEUE_URI_PREFIX = "queue";
+ public static final String AUTOATTACH_URI_PREFIX = "autoattach";
public static final Integer DEFAULT_OVSDB_PORT = 6640;
public static final String DEFAULT_OPENFLOW_PORT = "6653";
public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
public static final String IID_EXTERNAL_ID_KEY = "opendaylight-iid";
public static final String QOS_ID_EXTERNAL_ID_KEY = "opendaylight-qos-id";
public static final String QUEUE_ID_EXTERNAL_ID_KEY = "opendaylight-queue-id";
+ public static final String AUTOATTACH_ID_EXTERNAL_ID_KEY = "opendaylight-autoattach-id";
public enum VLANMODES {
ACCESS("access"),
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+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.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.southbound.SouthboundProvider;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+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.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
+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.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.base.Preconditions;
+import com.google.common.collect.Sets;
+
+public class AutoAttachRemovedCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(AutoAttachRemovedCommand.class);
+
+ public AutoAttachRemovedCommand(BridgeOperationalState state,
+ AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+
+ // FIXME: Remove if loop after ovs community supports external_ids column in AutoAttach Table
+ if (true) {
+ try {
+ throw new UnsupportedOperationException("CRUD operations not supported from ODL for auto_attach column for"
+ + " this version of ovsdb schema due to missing external_ids column");
+ } catch (UnsupportedOperationException e) {
+ LOG.debug(e.getMessage());
+ }
+ return;
+ }
+
+ @SuppressWarnings("unused")
+ Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> original =
+ TransactUtils.extractOriginal(getChanges(), OvsdbNodeAugmentation.class);
+
+ Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> deleted =
+ TransactUtils.extractUpdated(getChanges(), OvsdbNodeAugmentation.class);
+
+ for (Map.Entry<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> originalEntry : original.entrySet()) {
+ InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid = originalEntry.getKey();
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = originalEntry.getValue();
+ OvsdbNodeAugmentation deletedOvsdbNodeAugmentation = deleted.get(ovsdbNodeIid);
+
+ if (ovsdbNodeAugmentation != null && deletedOvsdbNodeAugmentation != null) {
+ List<Autoattach> origAutoattachList = ovsdbNodeAugmentation.getAutoattach();
+ List<Autoattach> deletedAutoattachList = deletedOvsdbNodeAugmentation.getAutoattach();
+ if(origAutoattachList != null && !origAutoattachList.isEmpty() &&
+ (deletedAutoattachList == null || deletedAutoattachList.isEmpty())) {
+
+ OvsdbNodeAugmentation currentOvsdbNode =
+ getOperationalState().getBridgeNode(ovsdbNodeIid).get().getAugmentation(OvsdbNodeAugmentation.class);
+ List<Autoattach> currentAutoAttach = currentOvsdbNode.getAutoattach();
+ for (Autoattach origAutoattach : origAutoattachList) {
+ Uri autoAttachId = origAutoattach.getAutoattachId();
+ deleteAutoAttach(transaction, ovsdbNodeIid, getAutoAttachUuid(currentAutoAttach, autoAttachId));
+ }
+ }
+ }
+ }
+ }
+
+ private void deleteAutoAttach(TransactionBuilder transaction,
+ InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid,
+ Uuid autoattachUuid) {
+
+ LOG.debug("Received request to delete Autoattach entry {}", autoattachUuid);
+ OvsdbBridgeAugmentation bridgeAugmentation = getBridge(ovsdbNodeIid, autoattachUuid);
+ if (autoattachUuid != null && bridgeAugmentation != null) {
+ UUID uuid = new UUID(autoattachUuid.getValue());
+ AutoAttach autoattach = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), AutoAttach.class, null);
+ transaction.add(op.delete(autoattach.getSchema())
+ .where(autoattach.getUuidColumn().getSchema().opEqual(uuid))
+ .build());
+ transaction.add(op.comment("AutoAttach: Deleting {} " + uuid
+ + " attached to " + bridgeAugmentation.getBridgeName().getValue()));
+
+ Bridge bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
+ Bridge.class,null);
+
+ transaction.add(op.mutate(bridge.getSchema())
+ .addMutation(bridge.getAutoAttachColumn().getSchema(),
+ Mutator.DELETE, Sets.newHashSet(uuid))
+ .where(bridge.getNameColumn().getSchema()
+ .opEqual(bridgeAugmentation.getBridgeName().getValue())).build());
+
+ transaction.add(op.comment("Bridge: Mutating " + bridgeAugmentation.getBridgeName().getValue()
+ + " to remove autoattach column " + uuid));
+ } else {
+ LOG.debug("Unable to delete AutoAttach {} for node {} because it was not found in the operational store, "
+ + "and thus we cannot retrieve its UUID", autoattachUuid, ovsdbNodeIid);
+ }
+ }
+
+ private Uuid getAutoAttachUuid(List<Autoattach> currentAutoAttach, Uri autoAttachId) {
+ if (currentAutoAttach != null && !currentAutoAttach.isEmpty()) {
+ for (Autoattach autoAttach : currentAutoAttach) {
+ if (autoAttach.getAutoattachId().equals(autoAttachId)) {
+ return autoAttach.getAutoattachUuid();
+ }
+ }
+ }
+ return null;
+ }
+
+ private OvsdbBridgeAugmentation getBridge(InstanceIdentifier<OvsdbNodeAugmentation> key, Uuid aaUuid) {
+ Preconditions.checkNotNull(aaUuid);
+ OvsdbBridgeAugmentation bridge = null;
+ InstanceIdentifier<Node> nodeIid = key.firstIdentifierOf(Node.class);
+ try (ReadOnlyTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction()) {
+ Optional<Node> nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, nodeIid).get();
+ if (nodeOptional.isPresent()) {
+ List<ManagedNodeEntry> managedNodes = nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
+ for (ManagedNodeEntry managedNode : managedNodes) {
+ OvsdbBridgeRef ovsdbBridgeRef = managedNode.getBridgeRef();
+ InstanceIdentifier<OvsdbBridgeAugmentation> brIid = ovsdbBridgeRef.getValue()
+ .firstIdentifierOf(Node.class).augmentation(OvsdbBridgeAugmentation.class);
+ Optional<OvsdbBridgeAugmentation> optionalBridge = transaction.read(LogicalDatastoreType.OPERATIONAL, brIid).get();
+ bridge = optionalBridge.orNull();
+ if(bridge != null && bridge.getAutoAttach() != null
+ && bridge.getAutoAttach().equals(aaUuid)) {
+ return bridge;
+ }
+ }
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Error reading from datastore",e);
+ }
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+
+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.Mutator;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundProvider;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.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.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+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.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.ImmutableMap;
+import com.google.common.collect.Sets;
+
+public class AutoAttachUpdateCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(AutoAttachUpdateCommand.class);
+
+ public AutoAttachUpdateCommand(BridgeOperationalState state, AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+
+ // FIXME: Fix if loop after ovs community supports external_ids column in AutoAttach Table
+ if (true) {
+ try {
+ throw new UnsupportedOperationException("CRUD operations not supported from ODL for auto_attach column for"
+ + " this version of ovsdb schema due to missing external_ids column");
+ } catch (UnsupportedOperationException e) {
+ LOG.debug(e.getMessage());
+ }
+ return;
+ }
+
+ @SuppressWarnings("unused")
+ Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> createdOrUpdated =
+ TransactUtils.extractCreatedOrUpdated(getChanges(), OvsdbNodeAugmentation.class);
+ for (Entry<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> ovsdbNodeEntry
+ : createdOrUpdated.entrySet()) {
+ updateAutoAttach(transaction, ovsdbNodeEntry.getKey(), ovsdbNodeEntry.getValue());
+ }
+ }
+
+ private void updateAutoAttach(TransactionBuilder transaction,
+ InstanceIdentifier<OvsdbNodeAugmentation> iid,
+ OvsdbNodeAugmentation ovsdbNode) {
+
+ List<Autoattach> autoAttachList = ovsdbNode.getAutoattach();
+ if (!getOperationalState().getBridgeNode(iid).isPresent()) {
+ return;
+ }
+ OvsdbNodeAugmentation currentOvsdbNode = getOperationalState().getBridgeNode(iid).get().getAugmentation(OvsdbNodeAugmentation.class);
+ List<Autoattach> currentAutoAttach = currentOvsdbNode.getAutoattach();
+
+ if (autoAttachList != null) {
+ for (Autoattach autoAttach : autoAttachList) {
+ AutoAttach autoAttachWrapper = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), AutoAttach.class);
+ if (autoAttach.getSystemName() != null) {
+ autoAttachWrapper.setSystemName(autoAttach.getSystemName());
+ }
+ if (autoAttach.getSystemDescription() != null) {
+ autoAttachWrapper.setSystemDescription(autoAttach.getSystemDescription());
+ }
+
+ List<Mappings> mappingsList = autoAttach.getMappings();
+ if (mappingsList != null && !mappingsList.isEmpty()) {
+ Map<Long, Long> newMappings = new HashMap<>();
+ for (Mappings mappings : mappingsList) {
+ Long mappingsValue = new Long(mappings.getMappingsValue().toString());
+ newMappings.put(mappings.getMappingsKey(), mappingsValue);
+ }
+ autoAttachWrapper.setMappings(newMappings);
+ }
+
+ List<AutoattachExternalIds> externalIds = autoAttach.getAutoattachExternalIds();
+ Map<String, String> externalIdsMap = new HashMap<>();
+ if (externalIds != null) {
+ for (AutoattachExternalIds externalId : externalIds) {
+ externalIdsMap.put(externalId.getAutoattachExternalIdKey(), externalId.getAutoattachExternalIdValue());
+ }
+ }
+ externalIdsMap.put(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY, autoAttach.getAutoattachId().getValue());
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// try {
+// autoAttachWrapper.setExternalIds(ImmutableMap.copyOf(externalIdsMap));
+// } catch (NullPointerException e) {
+// LOG.warn("Incomplete AutoAttach external IDs");
+// }
+
+ Uuid aaUuid = getAutoAttachUuid(currentAutoAttach, autoAttach.getAutoattachId());
+ if (aaUuid != null) {
+ UUID uuid = new UUID(aaUuid.getValue());
+ AutoAttach newAutoAttach = TyperUtils.getTypedRowWrapper(
+ transaction.getDatabaseSchema(), AutoAttach.class, null);
+ newAutoAttach.getUuidColumn().setData(uuid);
+ LOG.trace("Updating autoattach table entries {}", uuid);
+ transaction.add(op.update(autoAttachWrapper)
+ .where(newAutoAttach.getUuidColumn().getSchema().opEqual(uuid)).build());
+ transaction.add(op.comment("Updating AutoAttach table: " + uuid));
+ } else {
+ Uri bridgeUri = autoAttach.getBridgeId();
+ String namedUuid = SouthboundMapper.getRandomUUID();
+ Bridge bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), Bridge.class);
+ transaction.add(op.insert(autoAttachWrapper).withId(namedUuid));
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = getBridge(iid, bridgeUri);
+ if (ovsdbBridgeAugmentation != null) {
+ bridge.setName(ovsdbBridgeAugmentation.getBridgeName().getValue());
+ bridge.setAutoAttach(Sets.newHashSet(new UUID(namedUuid)));
+ LOG.trace("Create Autoattach table {}, "
+ + "and mutate the bridge {}", autoAttach.getAutoattachId(), getBridge(iid, bridgeUri).getBridgeName().getValue());
+ transaction.add(op.mutate(bridge)
+ .addMutation(bridge.getAutoAttachColumn().getSchema(),
+ Mutator.INSERT,bridge.getAutoAttachColumn().getData())
+ .where(bridge.getNameColumn().getSchema()
+ .opEqual(bridge.getNameColumn().getData())).build());
+ transaction.add(op.comment("Bridge: Mutating " + ovsdbBridgeAugmentation.getBridgeName().getValue()
+ + " to add autoattach column " + namedUuid));
+ }
+ }
+ }
+ }
+ }
+
+ private OvsdbBridgeAugmentation getBridge(InstanceIdentifier<OvsdbNodeAugmentation> key,
+ Uri bridgeUri) {
+ InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class, new NodeKey(new NodeId(bridgeUri)))
+ .augmentation(OvsdbBridgeAugmentation.class);
+
+ OvsdbBridgeAugmentation bridge = null;
+ try (ReadOnlyTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction()) {
+ Optional<OvsdbBridgeAugmentation> bridgeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, bridgeIid).get();
+ if (bridgeOptional.isPresent()) {
+ bridge = bridgeOptional.get();
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Error reading from datastore", e);
+ }
+ return bridge;
+ }
+
+ private Uuid getAutoAttachUuid(List<Autoattach> currentAutoAttach, Uri autoattachId) {
+ if (currentAutoAttach != null && !currentAutoAttach.isEmpty()) {
+ for (Autoattach autoAttach : currentAutoAttach) {
+ if (autoAttach.getAutoattachId().equals(autoattachId)) {
+ return autoAttach.getAutoattachUuid();
+ }
+ }
+ }
+ return null;
+ }
+}
commands.add(new TerminationPointCreateCommand(state,changes));
commands.add(new TerminationPointDeleteCommand(state, changes));
commands.add(new OvsdbNodeUpdateCommand(changes));
+ commands.add(new AutoAttachUpdateCommand(state, changes));
+ commands.add(new AutoAttachRemovedCommand(state, changes));
commands.add(new QosUpdateCommand(state, changes));
commands.add(new QosRemovedCommand(state, changes));
commands.add(new QueueUpdateCommand(state, changes));
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.transactions.md;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+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.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
+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.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class OvsdbAutoAttachRemovedCommand extends AbstractTransactionCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsdbQueueUpdateCommand.class);
+
+ private Map<UUID, AutoAttach> removedAutoAttachRows;
+
+ public OvsdbAutoAttachRemovedCommand(OvsdbConnectionInstance key,
+ TableUpdates updates, DatabaseSchema dbSchema) {
+ super(key, updates, dbSchema);
+ removedAutoAttachRows = TyperUtils.extractRowsRemoved(AutoAttach.class, getUpdates(), getDbSchema());
+ }
+
+ @Override
+ public void execute(ReadWriteTransaction transaction) {
+ final InstanceIdentifier<Node> nodeIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+ final Optional<Node> ovsdbNode = SouthboundUtil.readNode(transaction, nodeIId);
+ if (ovsdbNode.isPresent() && removedAutoAttachRows != null && !removedAutoAttachRows.isEmpty()) {
+ InstanceIdentifier<Node> ovsdbNodeIid =
+ SouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance().getNodeId());
+ // FIXME: Iterate on external_ids instead of uuid when Open vSwitch supports external_ids column
+ for (UUID autoAttachUuid : removedAutoAttachRows.keySet()) {
+ AutoattachKey autoAttachKey = getAutoAttachKeyToRemove(ovsdbNode.get(), autoAttachUuid);
+ if (autoAttachKey != null) {
+ InstanceIdentifier<Autoattach> iid = ovsdbNodeIid
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Autoattach.class, autoAttachKey);
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, iid);
+ LOG.debug("AutoAttach table {} for Ovsdb Node {} is deleted", autoAttachUuid.toString(),
+ ovsdbNode.get().getNodeId());
+ } else {
+ LOG.warn("AutoAttach table {} not found for Ovsdb Node {} to delete", autoAttachUuid.toString(),
+ ovsdbNode.get().getNodeId());
+ }
+ }
+ }
+ }
+
+ private AutoattachKey getAutoAttachKeyToRemove(Node node, UUID autoAttachUuid) {
+ List<Autoattach> autoAttachList = node.getAugmentation(OvsdbNodeAugmentation.class).getAutoattach();
+ if (autoAttachList == null || autoAttachList.isEmpty()) {
+ return null;
+ }
+ for (Autoattach autoAttach : autoAttachList) {
+ if (autoAttach.getAutoattachUuid()
+ .equals(new Uuid(autoAttachUuid.toString()))) {
+ return autoAttach.getKey();
+ }
+ }
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsKey;
+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.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class OvsdbAutoAttachUpdateCommand extends AbstractTransactionCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsdbAutoAttachUpdateCommand.class);
+
+ private Map<UUID, AutoAttach> updatedAutoAttachRows;
+ private Map<UUID, AutoAttach> oldAutoAttachRows;
+
+ public OvsdbAutoAttachUpdateCommand(OvsdbConnectionInstance key,
+ TableUpdates updates, DatabaseSchema dbSchema) {
+ super(key, updates, dbSchema);
+ updatedAutoAttachRows = TyperUtils.extractRowsUpdated(AutoAttach.class,getUpdates(), getDbSchema());
+ oldAutoAttachRows = TyperUtils.extractRowsOld(AutoAttach.class, getUpdates(), getDbSchema());
+ }
+
+ @Override
+ public void execute(ReadWriteTransaction transaction) {
+ if (updatedAutoAttachRows != null && !updatedAutoAttachRows.isEmpty()) {
+ updateAutoAttach(transaction, updatedAutoAttachRows);
+ }
+ }
+
+ private void updateAutoAttach(ReadWriteTransaction transaction,
+ Map<UUID, AutoAttach> updatedAutoAttachRows) {
+
+ final InstanceIdentifier<Node> nodeIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+ final Optional<Node> ovsdbNode = SouthboundUtil.readNode(transaction, nodeIId);
+ if (ovsdbNode.isPresent()) {
+ for (Entry<UUID, AutoAttach> entry : updatedAutoAttachRows.entrySet()) {
+ AutoAttach autoAttach = entry.getValue();
+ AutoAttach oldAutoAttach = oldAutoAttachRows.get(entry.getKey());
+ Uri uri = new Uri(SouthboundConstants.AUTOATTACH_URI_PREFIX + "://" + autoAttach.getUuid().toString());
+
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// Uri uri = new Uri(getAutoAttachId(autoAttach));
+
+ Autoattach currentAutoattach = null;
+ try {
+ InstanceIdentifier<Autoattach> currentIid = nodeIId
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Autoattach.class, new AutoattachKey(new Uri(oldAutoAttach
+ .getUuidColumn().getData().toString())));
+ // FIXME: To be uncommented and replaced to currentIid when Open vSwitch supports external_ids column
+// InstanceIdentifier<Autoattach> currentIid = nodeIId
+// .augmentation(OvsdbNodeAugmentation.class)
+// .child(Autoattach.class, new AutoattachKey(new Uri(oldAutoAttach
+// .getExternalIdsColumn().getData()
+// .get(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY))));
+ Optional<Autoattach> optionalAutoattach =
+ transaction.read(LogicalDatastoreType.OPERATIONAL, currentIid).checkedGet();
+ if (optionalAutoattach.isPresent()) {
+ currentAutoattach = optionalAutoattach.get();
+ }
+ } catch (Exception e) {
+ LOG.warn("AutoAttach table entries not found in operational datastore, need to create it.", e);
+ }
+
+ AutoattachBuilder autoAttachBuilder = (currentAutoattach != null) ? new AutoattachBuilder(currentAutoattach)
+ : new AutoattachBuilder()
+ .setAutoattachUuid(new Uuid(entry.getKey().toString()))
+ .setAutoattachId(uri)
+ .setKey(new AutoattachKey(uri));
+
+ if (autoAttach.getSystemNameColumn() != null
+ && autoAttach.getSystemNameColumn().getData() != null
+ && !autoAttach.getSystemNameColumn().getData().isEmpty()) {
+ autoAttachBuilder.setSystemName(autoAttach.getSystemNameColumn().getData());
+ }
+ if (autoAttach.getSystemDescriptionColumn() != null
+ && autoAttach.getSystemDescriptionColumn().getData() != null
+ && !autoAttach.getSystemDescriptionColumn().getData().isEmpty()) {
+ autoAttachBuilder.setSystemDescription(autoAttach.getSystemDescriptionColumn().getData());
+ }
+ if (autoAttach.getMappingsColumn() != null
+ && autoAttach.getMappingsColumn().getData() != null
+ && !autoAttach.getMappingsColumn().getData().isEmpty()) {
+ setMappings(autoAttachBuilder, autoAttach);
+ }
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// setExternalIds(autoAttachBuilder, autoAttach);
+
+ Autoattach autoAttachEntry = autoAttachBuilder.build();
+ LOG.trace("Update Ovsdb Node {} with AutoAttach table entries {}",
+ ovsdbNode.get().getNodeId(), autoAttachEntry);
+ InstanceIdentifier<Autoattach> iid = nodeIId
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Autoattach.class, autoAttachEntry.getKey());
+ transaction.put(LogicalDatastoreType.OPERATIONAL,
+ iid, autoAttachEntry);
+ }
+ }
+ }
+
+ private void setMappings (AutoattachBuilder autoAttachBuilder,
+ AutoAttach autoAttach) {
+ Map<Long, Long> mappings = autoAttach.getMappingsColumn().getData();
+ Set<Long> mappingsKeys = mappings.keySet();
+ List<Mappings> mappingsList = new ArrayList<>();
+ for (Long mappingsKey : mappingsKeys) {
+ Integer mappingsValue = new Integer(mappings.get(mappingsKey).toString());
+ if (mappingsKey != null && mappingsValue != null) {
+ mappingsList.add(new MappingsBuilder()
+ .setKey(new MappingsKey(mappingsKey))
+ .setMappingsKey(mappingsKey)
+ .setMappingsValue(mappingsValue)
+ .build());
+ }
+ autoAttachBuilder.setMappings(mappingsList);
+ }
+ }
+
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// private String getAutoAttachId(AutoAttach autoAttach) {
+// if (autoAttach.getExternalIdsColumn() != null
+// && autoAttach.getExternalIdsColumn().getData() != null
+// && autoAttach.getExternalIdsColumn().getData().containsKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY)) {
+// return autoAttach.getExternalIdsColumn().getData().get(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY);
+// } else {
+// return SouthboundConstants.AUTOATTACH_URI_PREFIX + "://" + autoAttach.getUuid().toString();
+// }
+// }
+//
+// private void setExternalIds(AutoattachBuilder autoAttachBuilder,
+// AutoAttach autoAttach) {
+// List<AutoattachExternalIds> externalIdsList = new ArrayList<>();
+// if (autoAttach.getExternalIdsColumn() != null
+// && autoAttach.getExternalIdsColumn().getData() != null
+// && !autoAttach.getExternalIdsColumn().getData().isEmpty()) {
+// Map<String, String> externalIds = autoAttach.getExternalIdsColumn().getData();
+// Set<String> externalIdsKeys = externalIds.keySet();
+//
+// String extIdValue;
+// for (String extIdKey : externalIdsKeys) {
+// extIdValue = externalIds.get(extIdKey);
+// if (extIdKey != null && extIdValue != null) {
+// externalIdsList.add(new AutoattachExternalIdsBuilder().setAutoattachExternalIdKey(extIdKey)
+// .setAutoattachExternalIdValue(extIdValue).build());
+// }
+// }
+// } else {
+// externalIdsList.add(new AutoattachExternalIdsBuilder().setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY)
+// .setAutoattachExternalIdValue(autoAttach.getUuid().toString()).build());
+// }
+// autoAttachBuilder.setAutoattachExternalIds(externalIdsList);
+// }
+}
setFailMode(ovsdbBridgeAugmentationBuilder, bridge);
setOpenFlowNodeRef(ovsdbBridgeAugmentationBuilder, bridge);
setManagedBy(ovsdbBridgeAugmentationBuilder);
+ setAutoAttach(ovsdbBridgeAugmentationBuilder, bridge);
bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
LOG.debug("Built with the intent to store bridge data {}",
return bridgeNodeBuilder.build();
}
+ private void setAutoAttach(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
+ Bridge bridge) {
+ try {
+ if (bridge.getAutoAttachColumn() != null
+ && bridge.getAutoAttachColumn().getData() != null
+ && !bridge.getAutoAttachColumn().getData().isEmpty()) {
+ Set<UUID> uuids = bridge.getAutoAttachColumn().getData();
+ for (UUID uuid : uuids) {
+ ovsdbBridgeAugmentationBuilder.setAutoAttach(new Uuid(uuid.toString()));
+ }
+ }
+ } catch (SchemaVersionMismatchException e) {
+ LOG.debug("auto_attach column for Bridge Table unsupported for this version of ovsdb schema. {}", e);
+ }
+ }
+
private void setManagedBy(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder) {
InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
commands.add(new OvsdbControllerRemovedCommand(key, updates, dbSchema));
commands.add(new OvsdbPortUpdateCommand(key, updates, dbSchema));
commands.add(new OvsdbPortRemoveCommand(key, updates, dbSchema));
+ commands.add(new OvsdbAutoAttachUpdateCommand(key, updates, dbSchema));
+ commands.add(new OvsdbAutoAttachRemovedCommand(key, updates, dbSchema));
}
@Override
@PrepareForTest({})
@RunWith(PowerMockRunner.class)
public class TransactCommandAggregatorTest {
- private static final int NUMBER_OF_COMMANDS = 15;
+ private static final int NUMBER_OF_COMMANDS = 17;
private List<TransactCommand> commands = new ArrayList<>();
private TransactCommandAggregator transactCommandAggregator;
@Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
commands.add(mock(TerminationPointCreateCommand.class));
commands.add(mock(TerminationPointDeleteCommand.class));
commands.add(mock(OvsdbNodeUpdateCommand.class));
+ commands.add(mock(AutoAttachUpdateCommand.class));
+ commands.add(mock(AutoAttachRemovedCommand.class));
commands.add(mock(QosUpdateCommand.class));
commands.add(mock(QosRemovedCommand.class));
commands.add(mock(QueueUpdateCommand.class));
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.transactions.md;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+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.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.base.Optional;
+
+@PrepareForTest({OvsdbAutoAttachRemovedCommand.class, SouthboundMapper.class, SouthboundUtil.class})
+@RunWith(PowerMockRunner.class)
+public class OvsdbAutoAttachRemovedCommandTest {
+
+ private Map<UUID, AutoAttach> removedAutoAttachRows = new HashMap<>();
+ private OvsdbAutoAttachRemovedCommand ovsdbAutoAttachRemovedCommand;
+ private ReadWriteTransaction transaction;
+ private InstanceIdentifier<Autoattach> aaIid;
+
+ private static final UUID AUTOATTACH_UUID = new UUID("798f35d8-f40a-449a-94d3-c860f5547f9a");
+ private static final String CONNECTED_NODE_ID = "10.0.0.1";
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setUp() throws Exception {
+ ovsdbAutoAttachRemovedCommand = mock(OvsdbAutoAttachRemovedCommand.class, Mockito.CALLS_REAL_METHODS);
+
+ AutoAttach autoAttach = mock(AutoAttach.class);
+ removedAutoAttachRows.put(AUTOATTACH_UUID, autoAttach);
+ MemberModifier.field(OvsdbAutoAttachRemovedCommand.class, "removedAutoAttachRows").set(ovsdbAutoAttachRemovedCommand, removedAutoAttachRows);
+
+ OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
+ when(ovsdbAutoAttachRemovedCommand.getOvsdbConnectionInstance()).thenReturn(ovsdbConnectionInstance);
+ AutoattachKey aaKey = new AutoattachKey(new Uri(SouthboundConstants.AUTOATTACH_URI_PREFIX + "://" + AUTOATTACH_UUID.toString()));
+ aaIid = InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class, new NodeKey(new NodeId(CONNECTED_NODE_ID)))
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Autoattach.class, aaKey);
+ InstanceIdentifier<Node> nodeIid = aaIid.firstIdentifierOf(Node.class);
+ when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(nodeIid);
+
+ PowerMockito.mockStatic(SouthboundUtil.class);
+ Optional<Node> ovsdbNode = mock(Optional.class);
+ transaction = mock(ReadWriteTransaction.class);
+ PowerMockito.when(SouthboundUtil.readNode(transaction, nodeIid)).thenReturn(ovsdbNode);
+ when(ovsdbNode.isPresent()).thenReturn(true);
+ Node node = mock(Node.class);
+ when(ovsdbNode.get()).thenReturn(node);
+ NodeId nodeId = mock(NodeId.class);
+ when(node.getNodeId()).thenReturn(nodeId);
+
+ PowerMockito.mockStatic(SouthboundMapper.class);
+ when(ovsdbConnectionInstance.getNodeId()).thenReturn(nodeId);
+ when(SouthboundMapper.createInstanceIdentifier(nodeId)).thenReturn(nodeIid);
+
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = mock(OvsdbNodeAugmentation.class);
+ when(node.getAugmentation(OvsdbNodeAugmentation.class)).thenReturn(ovsdbNodeAugmentation);
+ List<Autoattach> autoAttachList = new ArrayList<>();
+ Autoattach aaEntry = mock(Autoattach.class);
+ autoAttachList.add(aaEntry);
+ when(aaEntry.getAutoattachUuid()).thenReturn(new Uuid(AUTOATTACH_UUID.toString()));
+ when(ovsdbNodeAugmentation.getAutoattach()).thenReturn(autoAttachList);
+ when(aaEntry.getKey()).thenReturn(aaKey);
+
+ doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+ }
+
+ @Test
+ public void testExecute() {
+ ovsdbAutoAttachRemovedCommand.execute(transaction);
+ verify(transaction).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(aaIid));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.transactions.md;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.ovsdb.node.attributes.Autoattach;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+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.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+
+@PrepareForTest({OvsdbAutoAttachUpdateCommand.class, SouthboundUtil.class})
+@RunWith(PowerMockRunner.class)
+public class OvsdbAutoAttachUpdateCommandTest {
+
+ private static final String AUTOATTACH_SYSTEM_INFO = "AutoAttach Test";
+ private static final Map<Long, Long> AUTOATTACH_MAPPINGS = ImmutableMap.of(100L, 200L);
+ private static final UUID AUTOATTACH_UUID = new UUID("798f35d8-f40a-449a-94d3-c860f5547f9a");
+ private static final String CONNECTED_NODE_ID = "10.0.0.2";
+ private static final Map<String, String> AUTOATTACH_EXTERNAL_IDS =
+ ImmutableMap.of("opendaylight-autoattach-id", "autoattach://798f35d8-f40a-449a-94d3-c860f5547f9a");
+ private Map<UUID, AutoAttach> updatedAutoAttachRows = new HashMap<>();
+ private Map<UUID, AutoAttach> oldAutoAttachRows = new HashMap<>();
+ private OvsdbAutoAttachUpdateCommand ovsdbAutoAttachUpdateCommand;
+ private ReadWriteTransaction transaction;
+ private InstanceIdentifier<Autoattach> aaIid;
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setUp() throws Exception {
+ ovsdbAutoAttachUpdateCommand = mock(OvsdbAutoAttachUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+
+ AutoAttach autoAttach = mock(AutoAttach.class);
+ updatedAutoAttachRows.put(AUTOATTACH_UUID, autoAttach);
+ oldAutoAttachRows.put(AUTOATTACH_UUID, autoAttach);
+
+ Column<GenericTableSchema, String> aaColumn = mock(Column.class);
+ when(autoAttach.getSystemNameColumn()).thenReturn(aaColumn);
+ when(autoAttach.getSystemDescriptionColumn()).thenReturn(aaColumn);
+ when(aaColumn.getData()).thenReturn(AUTOATTACH_SYSTEM_INFO);
+ Column<GenericTableSchema, Map<Long, Long>> aaMappingColumn = mock(Column.class);
+ when(autoAttach.getMappingsColumn()).thenReturn(aaMappingColumn);
+ when(aaMappingColumn.getData()).thenReturn(AUTOATTACH_MAPPINGS);
+
+ // FIXME: To be uncommented when Open vSwitch supports external_ids column
+// Column<GenericTableSchema, Map<String, String>> aaExternalIdsColumn = mock(Column.class);
+// when(autoAttach.getExternalIdsColumn()).thenReturn(aaExternalIdsColumn);
+// when(aaExternalIdsColumn.getData()).thenReturn(AUTOATTACH_EXTERNAL_IDS);
+ when(autoAttach.getUuid()).thenReturn(AUTOATTACH_UUID);
+
+ OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
+ when(ovsdbAutoAttachUpdateCommand.getOvsdbConnectionInstance()).thenReturn(ovsdbConnectionInstance);
+ aaIid = InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class, new NodeKey(new NodeId(CONNECTED_NODE_ID)))
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Autoattach.class, new AutoattachKey
+ (new Uri(SouthboundConstants.AUTOATTACH_URI_PREFIX + "://" + AUTOATTACH_UUID.toString())));
+ InstanceIdentifier<Node> connectionIid = aaIid.firstIdentifierOf(Node.class);
+ when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(connectionIid);
+ transaction = mock(ReadWriteTransaction.class);
+ doNothing().when(transaction).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Autoattach.class));
+ doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+
+ PowerMockito.mockStatic(SouthboundUtil.class);
+ Optional<Node> ovsdbNode = mock(Optional.class);
+ PowerMockito.when(SouthboundUtil.readNode(transaction, connectionIid)).thenReturn(ovsdbNode);
+ when(ovsdbNode.isPresent()).thenReturn(true);
+ Node node = mock(Node.class);
+ when(ovsdbNode.get()).thenReturn(node);
+ NodeId nodeId = mock(NodeId.class);
+ when(node.getNodeId()).thenReturn(nodeId);
+
+ MemberModifier.field(OvsdbAutoAttachUpdateCommand.class, "updatedAutoAttachRows").set(ovsdbAutoAttachUpdateCommand, updatedAutoAttachRows);
+ MemberModifier.field(OvsdbAutoAttachUpdateCommand.class, "oldAutoAttachRows").set(ovsdbAutoAttachUpdateCommand, oldAutoAttachRows);
+ }
+
+ @Test
+ public void testExecute() {
+ ovsdbAutoAttachUpdateCommand.execute(transaction);
+ verify(transaction).put(eq(LogicalDatastoreType.OPERATIONAL), eq(aaIid), any(Autoattach.class));
+ }
+}
@PrepareForTest({})
@RunWith(PowerMockRunner.class)
public class OvsdbOperationalCommandAggregatorTest {
- private static final int NUMBER_OF_COMMANDS = 13;
+ private static final int NUMBER_OF_COMMANDS = 15;
private List<TransactionCommand> commands = new ArrayList<>();
private OvsdbOperationalCommandAggregator ovsdbOperationalCommandAggregator;
commands.add(mock(OpenVSwitchUpdateCommand.class));
commands.add(mock(OvsdbManagersUpdateCommand.class));
commands.add(mock(OvsdbManagersRemovedCommand.class));
+ commands.add(mock(OvsdbAutoAttachUpdateCommand.class));
+ commands.add(mock(OvsdbAutoAttachRemovedCommand.class));
commands.add(mock(OvsdbQosUpdateCommand.class));
commands.add(mock(OvsdbQosRemovedCommand.class));
commands.add(mock(OvsdbQueueUpdateCommand.class));