1 package org.opendaylight.ovsdb.southbound;
3 import java.net.UnknownHostException;
4 import java.util.HashSet;
6 import java.util.Map.Entry;
9 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
10 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
11 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
12 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.ovsdb.lib.OvsdbClient;
15 import org.opendaylight.ovsdb.southbound.ovsdb.transact.BridgeOperationalState;
16 import org.opendaylight.ovsdb.southbound.ovsdb.transact.DataChangesManagedByOvsdbNodeEvent;
17 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TransactCommandAggregator;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
20 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
21 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.yang.binding.DataObject;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 import com.google.common.base.Preconditions;
31 import com.google.common.base.Predicates;
32 import com.google.common.collect.Maps;
34 public class OvsdbDataChangeListener implements DataChangeListener, AutoCloseable {
36 private ListenerRegistration<DataChangeListener> registration;
37 private OvsdbConnectionManager cm;
38 private DataBroker db;
39 private static final Logger LOG = LoggerFactory.getLogger(OvsdbDataChangeListener.class);
41 OvsdbDataChangeListener(DataBroker db, OvsdbConnectionManager cm) {
42 LOG.info("Registering OvsdbNodeDataChangeListener");
45 InstanceIdentifier<Node> path = InstanceIdentifier
46 .create(NetworkTopology.class)
47 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
50 db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.SUBTREE);
55 public void close() throws Exception {
60 public void onDataChanged(
61 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
62 // Connect first if we have to:
65 // Second update connections if we have to
66 updateConnections(changes);
68 // Then handle updates to the actual data
71 // Finally disconnect if we need to
76 private void updateData(
77 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
78 for (OvsdbConnectionInstance connectionInstance : connectionInstancesFromChanges(changes)) {
79 connectionInstance.transact(new TransactCommandAggregator(
80 new BridgeOperationalState(db, changes),
81 new DataChangesManagedByOvsdbNodeEvent(
82 SouthboundMapper.createInstanceIdentifier(connectionInstance.getKey()),
87 private void disconnect(
88 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
89 Map<InstanceIdentifier<?>, DataObject> originalDataObject = changes.getOriginalData();
90 Set<InstanceIdentifier<?>> iiD = changes.getRemovedPaths();
91 for (InstanceIdentifier instanceIdentifier : iiD) {
92 if (originalDataObject.get(instanceIdentifier) instanceof OvsdbNodeAugmentation) {
94 cm.disconnect((OvsdbNodeAugmentation) originalDataObject.get(instanceIdentifier));
95 } catch (UnknownHostException e) {
96 LOG.warn("Failed to disconnect ovsdbNode", e);
102 private void updateConnections(
103 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
104 for (Entry<InstanceIdentifier<?>, DataObject> updated : changes.getUpdatedData().entrySet()) {
105 if (updated.getValue() instanceof OvsdbNodeAugmentation) {
106 OvsdbNodeAugmentation value = (OvsdbNodeAugmentation) updated.getValue();
107 OvsdbClient client = cm.getClient(value.getConnectionInfo());
108 if (client == null) {
109 for (Entry<InstanceIdentifier<?>, DataObject> original : changes.getOriginalData().entrySet()) {
110 if (original.getValue() instanceof OvsdbNodeAugmentation) {
112 cm.disconnect((OvsdbNodeAugmentation) original.getValue());
114 } catch (UnknownHostException e) {
115 LOG.warn("Failed to disconnect to ovsdbNode", e);
124 private void connect(
125 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
126 for (Entry<InstanceIdentifier<?>, DataObject> created : changes.getCreatedData().entrySet()) {
127 // TODO validate we have the correct kind of InstanceIdentifier
128 if (created.getValue() instanceof OvsdbNodeAugmentation) {
130 cm.connect((OvsdbNodeAugmentation) created.getValue());
131 } catch (UnknownHostException e) {
132 LOG.warn("Failed to connect to ovsdbNode", e);
138 public Set<OvsdbConnectionInstance> connectionInstancesFromChanges(
139 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
140 Set<OvsdbConnectionInstance> result = new HashSet<OvsdbConnectionInstance>();
141 result.addAll(connectionInstancesFromMap(changes.getCreatedData()));
142 result.addAll(connectionInstancesFromMap(changes.getUpdatedData()));
143 result.addAll(connectionInstancesFromMap(
144 Maps.filterKeys(changes.getOriginalData(), Predicates.in(changes.getRemovedPaths()))));
148 public Set<OvsdbConnectionInstance> connectionInstancesFromMap(Map<InstanceIdentifier<?>, DataObject> map) {
149 Preconditions.checkNotNull(map);
150 Set<OvsdbConnectionInstance> result = new HashSet<OvsdbConnectionInstance>();
151 for ( Entry<InstanceIdentifier<?>, DataObject> created : map.entrySet()) {
152 if (created.getValue() instanceof Node) {
153 LOG.debug("Received request to create {}",created.getValue());
154 OvsdbBridgeAugmentation bridge =
155 ((Node)created.getValue()).getAugmentation(OvsdbBridgeAugmentation.class);
156 if (bridge != null) {
157 OvsdbConnectionInstance client = cm.getConnectionInstance(bridge);
158 if (client != null) {
159 LOG.debug("Found client for {}", created.getValue());
162 LOG.debug("Did not find client for {}",created.getValue());
165 OvsdbNodeAugmentation ovsNode =
166 ((Node)created.getValue()).getAugmentation(OvsdbNodeAugmentation.class);
167 if (ovsNode != null && ovsNode.getConnectionInfo() != null) {
168 OvsdbConnectionInstance client = cm.getConnectionInstance(ovsNode.getConnectionInfo());
169 if (client != null) {
170 LOG.debug("Found client for {}", created.getValue());
173 LOG.debug("Did not find client for {}",created.getValue());