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 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.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
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.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+
public class HwvtepDataChangeListener implements DataTreeChangeListener<Node>, AutoCloseable {
private ListenerRegistration<HwvtepDataChangeListener> registration;
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);
+ // We can only connect if user configured connection info
+ if (hwvtepGlobal != null && hwvtepGlobal.getConnectionInfo() != 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);
+ // Check if user has updated connection information
+ if (hgUpdated != null && hgOriginal != null && hgUpdated.getConnectionInfo() != 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.
*/
-
+ 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();
}
.child(Node.class);
return path;
}
+
+ 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 DataObjectModification<Node> mod = change.getRootNode();
+ //From original node to get connection instance
+ Node node = mod.getDataBefore()!=null ? mod.getDataBefore() : mod.getDataAfter();
+ HwvtepConnectionInstance connection = hcm.getConnectionInstance(node);
+ if(connection == null) {
+ //Let us try getting it from Operational DS
+ final ReadWriteTransaction transaction = db.newReadWriteTransaction();
+ InstanceIdentifier<Node> connectionIid = HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId());
+ Optional<Node> optionalNode = HwvtepSouthboundUtil.readNode(transaction, connectionIid);
+ LOG.trace("Node in Operational DataStore for user node {} is {}", node, optionalNode);
+ if(optionalNode.isPresent()) {
+ connection = hcm.getConnectionInstance(optionalNode.get());
+ }
+ }
+ 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 Change Map: {}", result);
+ return result;
+ }
}