description "Per Logical Switch tunnel key";
type string;
}
+ leaf logical-switch-managed-by {
+ description "The hwvtep global node to which this logical switch belongs to";
+ type hwvtep-global-ref;
+ }
}
grouping hwvtep-physical-port-attributes {
if (transactInvokers == null) {
try {
transactInvokers = new HashMap<>();
- List<String> databases = getDatabases().get();
- for (String database : databases) {
- DatabaseSchema dbSchema = getSchema(database).get();
- if (dbSchema != null) {
- transactInvokers.put(dbSchema, new TransactInvokerImpl(this,dbSchema));
- }
+ DatabaseSchema dbSchema = getSchema(HwvtepSchemaConstants.databaseName).get();
+ if(dbSchema != null) {
+ transactInvokers.put(dbSchema, new TransactInvokerImpl(this,dbSchema));
}
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception attempting to createTransactionInvokers {}: {}",connectionInfo,e);
hcm.handleOwnershipChanged(ownershipChange);
}
}
-
}
package org.opendaylight.ovsdb.hwvtepsouthbound;
import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.HwvtepOperationalState;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommandAggregator;
import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
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.HwvtepLogicalSwitchAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfoBuilder;
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;
Node node = getCreated(mod);
if (node != null) {
HwvtepGlobalAugmentation hwvtepGlobal = node.getAugmentation(HwvtepGlobalAugmentation.class);
- ConnectionInfo connection = hwvtepGlobal.getConnectionInfo();
- InstanceIdentifier<Node> iid = hcm.getInstanceIdentifier(connection);
- if (iid != null) {
- LOG.warn("Connection to device {} already exists. Plugin does not allow multiple connections "
- + "to same device, hence dropping the request {}", connection, hwvtepGlobal);
- } else {
- try {
- hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId()), hwvtepGlobal);
- } catch (UnknownHostException e) {
- LOG.warn("Failed to connect to OVSDB node", e);
+ if (hwvtepGlobal != null) {
+ ConnectionInfo connection = hwvtepGlobal.getConnectionInfo();
+ InstanceIdentifier<Node> iid = hcm.getInstanceIdentifier(connection);
+ if (iid != null) {
+ LOG.warn("Connection to device {} already exists. Plugin does not allow multiple connections "
+ + "to same device, hence dropping the request {}", connection, hwvtepGlobal);
+ } else {
+ try {
+ hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId()), hwvtepGlobal);
+ } catch (UnknownHostException e) {
+ LOG.warn("Failed to connect to OVSDB node", e);
+ }
}
}
}
}
-
}
private void updateConnections(Collection<DataTreeModification<Node>> changes) {
Node original = getOriginal(mod);
HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
HwvtepGlobalAugmentation hgOriginal = original.getAugmentation(HwvtepGlobalAugmentation.class);
- OvsdbClient client = hcm.getClient(hgUpdated.getConnectionInfo());
- if (client == null) {
- try {
- hcm.disconnect(hgOriginal);
- hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(original.getNodeId()), hgUpdated);
- } catch (UnknownHostException e) {
- LOG.warn("Failed to update connection on OVSDB Node", e);
+ if (hgUpdated != null && hgOriginal != null) {
+ OvsdbClient client = hcm.getClient(hgUpdated.getConnectionInfo());
+ if (client == null) {
+ try {
+ hcm.disconnect(hgOriginal);
+ hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(original.getNodeId()), hgUpdated);
+ } catch (UnknownHostException e) {
+ LOG.warn("Failed to update connection on OVSDB Node", e);
+ }
}
}
}
}
-
}
private void updateData(Collection<DataTreeModification<Node>> changes) {
* Update data for each connection
* Requires Command patterns. TBD.
*/
- connectionInstancesFromChanges(changes);
- /*for (Entry<InstanceIdentifier<Node>, HwvtepConnectionInstance> connectionInstanceEntry :
- connectionInstancesFromChanges(changes).entrySet()) {
-
- }*/
+ for (Entry<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> changesEntry :
+ changesByConnectionInstance(changes).entrySet()) {
+ HwvtepConnectionInstance connectionInstance = changesEntry.getKey();
+ connectionInstance.transact(new TransactCommandAggregator(
+ new HwvtepOperationalState(db, changesEntry.getValue()),changesEntry.getValue()));
+ }
}
private void disconnect(Collection<DataTreeModification<Node>> changes) {
Node deleted = getRemoved(mod);
if (deleted != null) {
HwvtepGlobalAugmentation hgDeleted = deleted.getAugmentation(HwvtepGlobalAugmentation.class);
- try {
- hcm.disconnect(hgDeleted);
- } catch (UnknownHostException e) {
- LOG.warn("Failed to disconnect OVSDB Node", e);
+ if (hgDeleted != null) {
+ try {
+ hcm.disconnect(hgDeleted);
+ } catch (UnknownHostException e) {
+ LOG.warn("Failed to disconnect OVSDB Node", e);
+ }
}
}
}
}
private Node getCreated(DataObjectModification<Node> mod) {
- if((mod.getModificationType() == ModificationType.WRITE)
+ if((mod.getModificationType() == ModificationType.WRITE)
&& (mod.getDataBefore() == null)){
return mod.getDataAfter();
}
return path;
}
- public Map<InstanceIdentifier<Node>, HwvtepConnectionInstance> connectionInstancesFromChanges(
- Collection<DataTreeModification<Node>> changes) {
- Map<InstanceIdentifier<Node>, HwvtepConnectionInstance> result =
- new HashMap<InstanceIdentifier<Node>, HwvtepConnectionInstance>();
+ private Map<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> changesByConnectionInstance(
+ Collection<DataTreeModification<Node>> changes) {
+ Map<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> result =
+ new HashMap<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>>();
for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
final DataObjectModification<Node> mod = change.getRootNode();
- Node created = getCreated(mod);
- Node updated = getUpdated(mod);
- Node original = getOriginal(mod);
- Node deleted = getRemoved(mod);
-
- if((original != null) && (deleted == null)) {
- result.put(key, getConnectionInstance(original));
- }
- if(created != null) {
- result.put(key, getConnectionInstance(created));
- } else if(updated != null) {
- result.put(key, getConnectionInstance(updated));
+ //From original node to get connection instance
+ Node node = mod.getDataBefore()!=null ? mod.getDataBefore() : mod.getDataAfter();
+ HwvtepConnectionInstance connection = hcm.getConnectionInstance(node);
+ if (connection != null) {
+ if (!result.containsKey(connection)) {
+ List<DataTreeModification<Node>> tempChanges= new ArrayList<DataTreeModification<Node>>();
+ tempChanges.add(change);
+ result.put(connection, tempChanges);
+ } else {
+ result.get(connection).add(change);
+ }
+ } else {
+ LOG.warn("Failed to get the connection of changed node: {}", node);
}
}
- LOG.trace("Connection Instance Map: {}", result);
+ LOG.trace("Connection Change Map: {}", result);
return result;
}
-
- private HwvtepConnectionInstance getConnectionInstance(Node node) {
- // TODO Auto-generated method stub
- return null;
- }
-
-
-}
+}
\ No newline at end of file
HwvtepLogicalSwitchAttributes lNode) {
Preconditions.checkNotNull(lNode);
Optional<HwvtepGlobalAugmentation> result = null;
- // TODO: Add managed-by to hwvtep-logical-switch-attributes in
- // hwvtep.yang
- /*
- * HwvtepGlobalRef ref = lNode.getManagedBy(); if (ref != null &&
- * ref.getValue() != null) { result = getManagingNode(db, ref); } else {
- * LOG.warn(
- * "Cannot find client for LogicalSwitch without a specified ManagedBy {}"
- * , pNode); return Optional.absent(); } if(!result.isPresent()) {
- * LOG.warn("Failed to find managing node for PhysicalSwitch {}",
- * pNode); } return result;
- */
- return Optional.absent(); // TODO: Delete this once yang is updated
+
+ HwvtepGlobalRef ref = lNode.getLogicalSwitchManagedBy();
+ if (ref != null && ref.getValue() != null) {
+ result = getManagingNode(db, ref);
+ } else {
+ LOG.warn("Cannot find client for LogicalSwitch without a specified ManagedBy {}", lNode);
+ return Optional.absent();
+ }
+ if(!result.isPresent()) {
+ LOG.warn("Failed to find managing node for PhysicalSwitch {}",lNode);
+ }
+ return result;
}
private static Optional<HwvtepGlobalAugmentation> getManagingNode(DataBroker db, HwvtepGlobalRef ref) {
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+
+public abstract class AbstractTransactCommand implements TransactCommand {
+
+ private HwvtepOperationalState operationalState;
+ private Collection<DataTreeModification<Node>> changes;
+
+ protected AbstractTransactCommand() {
+ // NO OP
+ }
+
+ public AbstractTransactCommand(HwvtepOperationalState state, Collection<DataTreeModification<Node>> changes) {
+ this.operationalState = state;
+ this.changes = changes;
+ }
+
+ public HwvtepOperationalState getOperationalState() {
+ return operationalState;
+ }
+
+ public Collection<DataTreeModification<Node>> getChanges() {
+ return changes;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorSetAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+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.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+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.util.concurrent.CheckedFuture;
+
+public class HwvtepOperationalState {
+ private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
+ private Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
+
+ public HwvtepOperationalState(DataBroker db, Collection<DataTreeModification<Node>> changes) {
+ ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
+ Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
+ extractCreatedOrUpdatedOrRemoved(changes, Node.class);
+ //TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, Node.class);
+ if (nodeCreateOrUpdate != null) {
+ for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
+ CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture =
+ transaction.read(LogicalDatastoreType.OPERATIONAL, entry.getKey());
+ try {
+ Optional<Node> nodeOptional = nodeFuture.get();
+ if (nodeOptional.isPresent()) {
+ operationalNodes.put(entry.getKey(), nodeOptional.get());
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Error reading from datastore",e);
+ }
+ }
+ }
+ transaction.close();
+ }
+
+ private Node getCreated(DataObjectModification<Node> mod) {
+ if((mod.getModificationType() == ModificationType.WRITE)
+ && (mod.getDataBefore() == null)){
+ return mod.getDataAfter();
+ }
+ return null;
+ }
+
+ private Node getRemoved(DataObjectModification<Node> mod) {
+ if(mod.getModificationType() == ModificationType.DELETE){
+ return mod.getDataBefore();
+ }
+ return null;
+ }
+
+ private Node getUpdated(DataObjectModification<Node> mod) {
+ Node node = null;
+ switch(mod.getModificationType()) {
+ case SUBTREE_MODIFIED:
+ node = mod.getDataAfter();
+ break;
+ case WRITE:
+ if(mod.getDataBefore() != null) {
+ node = mod.getDataAfter();
+ }
+ break;
+ default:
+ break;
+ }
+ return node;
+ }
+
+ private Node getOriginal(DataObjectModification<Node> mod) {
+ Node node = null;
+ switch(mod.getModificationType()) {
+ case SUBTREE_MODIFIED:
+ node = mod.getDataBefore();
+ break;
+ case WRITE:
+ if(mod.getDataBefore() != null) {
+ node = mod.getDataBefore();
+ }
+ break;
+ case DELETE:
+ node = mod.getDataBefore();
+ break;
+ default:
+ break;
+ }
+ return node;
+ }
+
+ private Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
+ Collection<DataTreeModification<Node>> changes, Class<Node> class1) {
+ // TODO Auto-generated method stub
+ Map<InstanceIdentifier<Node>, Node> result = new HashMap<InstanceIdentifier<Node>, Node>();
+ for (DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ Node created = getCreated(mod);
+ result.put(key, created);
+ Node updated = getUpdated(mod);
+ result.put(key, updated);
+ Node deleted = getRemoved(mod);
+ result.put(key, deleted);
+ }
+ return result;
+ }
+
+ public Optional<Node> getGlobalNode(InstanceIdentifier<?> iid) {
+ InstanceIdentifier<Node> nodeIid = iid.firstIdentifierOf(Node.class);
+ return Optional.fromNullable(operationalNodes.get(nodeIid));
+ }
+
+ public Optional<HwvtepLogicalSwitchAugmentation> getLogicalSwitchAugmentation(InstanceIdentifier<?> iid) {
+ Optional<Node> nodeOptional = getGlobalNode(iid);
+ if (nodeOptional.isPresent()) {
+ return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepLogicalSwitchAugmentation.class));
+ }
+ return Optional.absent();
+ }
+
+ public Optional<PhysicalSwitchAugmentation> getPhysicalSwitchAugmentation(InstanceIdentifier<?> iid) {
+ Optional<Node> nodeOptional = getGlobalNode(iid);
+ if (nodeOptional.isPresent()) {
+ return Optional.fromNullable(nodeOptional.get().getAugmentation(PhysicalSwitchAugmentation.class));
+ }
+ return Optional.absent();
+ }
+
+ public Optional<HwvtepPhysicalLocatorSetAugmentation> getPhysicalLocatorSetAugmentation(InstanceIdentifier<?> iid) {
+ Optional<Node> nodeOptional = getGlobalNode(iid);
+ if (nodeOptional.isPresent()) {
+ return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepPhysicalLocatorSetAugmentation.class));
+ }
+ return Optional.absent();
+ }
+
+ public Optional<TerminationPoint> getHwvtepTerminationPoint(InstanceIdentifier<?> iid) {
+ if (iid != null) {
+ Optional<Node> nodeOptional = getGlobalNode(iid);
+ if (nodeOptional.isPresent() && nodeOptional.get().getTerminationPoint() != null) {
+ TerminationPointKey key = iid.firstKeyOf(TerminationPoint.class, TerminationPointKey.class);
+ if (key != null) {
+ for (TerminationPoint tp:nodeOptional.get().getTerminationPoint()) {
+ if (tp.getKey().equals(key)) {
+ return Optional.of(tp);
+ }
+ }
+ }
+ }
+ }
+ return Optional.absent();
+ }
+
+ public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<?> iid) {
+ Optional<TerminationPoint> nodeOptional = getHwvtepTerminationPoint(iid);
+ if (nodeOptional.isPresent()) {
+ return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class));
+ }
+ return Optional.absent();
+ }
+
+ public Optional<HwvtepPhysicalPortAugmentation> getPhysycalPortAugmentation(InstanceIdentifier<?> iid) {
+ Optional<TerminationPoint> tpOptional = getHwvtepTerminationPoint(iid);
+ if (tpOptional.isPresent()) {
+ return Optional.fromNullable(tpOptional.get().getAugmentation(HwvtepPhysicalPortAugmentation.class));
+ }
+ return Optional.absent();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+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.hardwarevtep.Global;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+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 LogicalSwitchRemoveCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
+
+ public LogicalSwitchRemoveCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ //TODO
+ /*Set<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>> removeds =
+ TransactUtils.extractRemoved(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+ Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> originals
+ = TransactUtils.extractOriginal(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+ for (InstanceIdentifier<HwvtepLogicalSwitchAugmentation> removed: removeds) {
+ LOG.info("Received request to delete ovsdb node {}",removed);
+ HwvtepLogicalSwitchAugmentation original = originals.get(removed);
+ LogicalSwitch bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class, null);
+ Optional<HwvtepLogicalSwitchAugmentation> lsAugmentationOptional = getOperationalState()
+ .getLogicalSwitchAugmentation(removed);
+ if (lsAugmentationOptional.isPresent() && lsAugmentationOptional.get().getHwvtepLogicalSwitchExternalId() != null) {
+ UUID lsUuid = new UUID(lsAugmentationOptional.get().getHwvtepLogicalSwitchExternalId().getValue());
+ Global ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
+ Global.class,null);
+ transaction.add(op.delete(bridge.getSchema())
+ .where(bridge.getUuidColumn().getSchema().opEqual(lsUuid)).build());
+ transaction.add(op.comment("Logical Switch: Deleting " + original.getHwvtepNodeName()));
+ } else {
+ LOG.warn("Unable to delete logical switch {} because it was not found in the operational store, "
+ + "and thus we cannot retrieve its UUID", removed);
+ }
+
+ }*/
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.Collection;
+import java.util.HashMap;
+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.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+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 LogicalSwitchUpdateCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class);
+
+ public LogicalSwitchUpdateCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> created =
+ extractCreated(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+ if(created != null) {
+ for(Entry<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> logicalSwitchEntry:
+ created.entrySet()) {
+ updateLogicalSwitch(transaction, logicalSwitchEntry.getKey(), logicalSwitchEntry.getValue());
+ }
+ }
+ }
+
+
+ private void updateLogicalSwitch(TransactionBuilder transaction,
+ InstanceIdentifier<HwvtepLogicalSwitchAugmentation> iid, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation) {
+ LOG.debug("Creating a logical switch named: {}", logicalSwitchAugmentation.getHwvtepNodeName());
+ Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional =
+ getOperationalState().getLogicalSwitchAugmentation(iid);
+ DatabaseSchema dbSchema = transaction.getDatabaseSchema();
+ LogicalSwitch logicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
+ if(!operationalLogicalSwitchOptional.isPresent()) {
+ setName(logicalSwitch, logicalSwitchAugmentation, operationalLogicalSwitchOptional);
+ setTunnelKey(logicalSwitch, logicalSwitchAugmentation, operationalLogicalSwitchOptional);
+ transaction.add(op.insert(logicalSwitch));
+ } else {
+ String existingLogicalSwitchName = operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue();
+ // Name is immutable, and so we *can't* update it. So we use extraBridge for the schema stuff
+ LogicalSwitch extraLogicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
+ extraLogicalSwitch.setName("");
+ transaction.add(op.update(logicalSwitch)
+ .where(extraLogicalSwitch.getNameColumn().getSchema().opEqual(existingLogicalSwitchName))
+ .build());
+ //stampInstanceIdentifier(transaction, iid.firstIdentifierOf(Node.class),existingBridgeName);
+ }
+ }
+
+ private void setName(LogicalSwitch logicalSwitch, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation,
+ Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional) {
+ if(logicalSwitchAugmentation.getHwvtepNodeName() != null) {
+ logicalSwitch.setName(logicalSwitchAugmentation.getHwvtepNodeName().getValue());
+ } else if(operationalLogicalSwitchOptional.isPresent() && operationalLogicalSwitchOptional.get().getHwvtepNodeName() != null) {
+ logicalSwitch.setName(operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue());
+ }
+ }
+
+ private void setTunnelKey(LogicalSwitch logicalSwitch, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation,
+ Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional) {
+ if(logicalSwitchAugmentation.getTunnelKey() != null) {
+ Set<Long> tunnel = new HashSet<Long>();
+ tunnel.add(Long.valueOf(logicalSwitchAugmentation.getTunnelKey()));
+ logicalSwitch.setTunnelKey(tunnel);
+ } else if(operationalLogicalSwitchOptional.isPresent() && operationalLogicalSwitchOptional.get().getTunnelKey() != null) {
+ Set<Long> tunnel = new HashSet<Long>();
+ tunnel.add(Long.valueOf(operationalLogicalSwitchOptional.get().getTunnelKey()));
+ logicalSwitch.setTunnelKey(tunnel);
+ }
+ }
+
+ private Node getCreated(DataObjectModification<Node> mod) {
+ if((mod.getModificationType() == ModificationType.WRITE)
+ && (mod.getDataBefore() == null)){
+ return mod.getDataAfter();
+ }
+ return null;
+ }
+
+ private Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> extractCreated(
+ Collection<DataTreeModification<Node>> changes, Class<HwvtepLogicalSwitchAugmentation> class1) {
+ Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> result
+ = new HashMap<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation>();
+ if(changes != null && !changes.isEmpty()) {
+ for(DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ Node created = getCreated(mod);
+ if(created != null) {
+ HwvtepLogicalSwitchAugmentation logicalSwitch = created.getAugmentation(HwvtepLogicalSwitchAugmentation.class);
+ InstanceIdentifier<HwvtepLogicalSwitchAugmentation> iid = change.getRootPath().getRootIdentifier().augmentation(HwvtepLogicalSwitchAugmentation.class);
+ if(logicalSwitch != null) {
+ result.put(iid, logicalSwitch);
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorRemoveCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorRemoveCommand.class);
+
+ public PhysicalLocatorRemoveCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ //TODO
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorUpdateCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorUpdateCommand.class);
+
+ public PhysicalLocatorUpdateCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ //TODO
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalPortRemoveCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortRemoveCommand.class);
+
+ public PhysicalPortRemoveCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ //TODO
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
+
+ public PhysicalPortUpdateCommand(HwvtepOperationalState state,
+ Collection<DataTreeModification<Node>> changes) {
+ super(state, changes);
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ //TODO
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+
+public class TransactCommandAggregator implements TransactCommand {
+
+ private List<TransactCommand> commands = new ArrayList<TransactCommand>();
+
+ public TransactCommandAggregator(HwvtepOperationalState state, Collection<DataTreeModification<Node>> changes) {
+ commands.add(new LogicalSwitchUpdateCommand(state,changes));
+ commands.add(new LogicalSwitchRemoveCommand(state,changes));
+ commands.add(new PhysicalLocatorUpdateCommand(state,changes));
+ commands.add(new PhysicalLocatorRemoveCommand(state,changes));
+ commands.add(new PhysicalPortUpdateCommand(state,changes));
+ commands.add(new PhysicalPortRemoveCommand(state,changes));
+ }
+
+ @Override
+ public void execute(TransactionBuilder transaction) {
+ for (TransactCommand command:commands) {
+ command.execute(transaction);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+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.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TransactUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
+
+ public static Node getCreated(DataObjectModification<Node> mod) {
+ if((mod.getModificationType() == ModificationType.WRITE)
+ && (mod.getDataBefore() == null)){
+ return mod.getDataAfter();
+ }
+ return null;
+ }
+
+ public static Node getRemoved(DataObjectModification<Node> mod) {
+ if(mod.getModificationType() == ModificationType.DELETE){
+ return mod.getDataBefore();
+ }
+ return null;
+ }
+
+ public static Node getUpdated(DataObjectModification<Node> mod) {
+ Node node = null;
+ switch(mod.getModificationType()) {
+ case SUBTREE_MODIFIED:
+ node = mod.getDataAfter();
+ break;
+ case WRITE:
+ if(mod.getDataBefore() != null) {
+ node = mod.getDataAfter();
+ }
+ break;
+ default:
+ break;
+ }
+ return node;
+ }
+
+ public static Node getOriginal(DataObjectModification<Node> mod) {
+ Node node = null;
+ switch(mod.getModificationType()) {
+ case SUBTREE_MODIFIED:
+ node = mod.getDataBefore();
+ break;
+ case WRITE:
+ if(mod.getDataBefore() != null) {
+ node = mod.getDataBefore();
+ }
+ break;
+ case DELETE:
+ node = mod.getDataBefore();
+ break;
+ default:
+ break;
+ }
+ return node;
+ }
+
+ public static Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
+ Collection<DataTreeModification<Node>> changes, Class<Node> class1) {
+ // TODO Auto-generated method stub
+ Map<InstanceIdentifier<Node>, Node> result = new HashMap<InstanceIdentifier<Node>, Node>();
+ for(DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ Node created = getCreated(mod);
+ result.put(key, created);
+ Node updated = getUpdated(mod);
+ result.put(key, updated);
+ Node deleted = getRemoved(mod);
+ result.put(key, deleted);
+ }
+ return null;
+ }
+
+ /*
+ public static <T extends Augmentation<Node>> Map<InstanceIdentifier<? extends DataObject>, T> extractCreated(
+ Collection<DataTreeModification<Node>> changes, Class<T> class1) {
+ // TODO Auto-generated method stub
+ Map<InstanceIdentifier<?>, T> result =
+ new HashMap<InstanceIdentifier<?>, T>();
+ if(changes != null && !changes.isEmpty()) {
+ for(DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ Node created = getCreated(mod);
+ if(created != null) {
+ T logicalSwitch = created.getAugmentation(class1);
+ created.getKey().getNodeId().get
+ logicalSwitch.
+ InstanceIdentifier<?> iid = change.getRootPath().getRootIdentifier()..augmentation(class1);
+ if(logicalSwitch != null) {
+ result.put(iid, logicalSwitch);
+ }
+ }
+ }
+ }
+ return result;
+ }
+ */
+
+}