2 * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.openstack.netvirt.impl;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
14 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryListener;
19 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
20 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
21 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TransactUtils;
22 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
30 import org.opendaylight.yangtools.concepts.ListenerRegistration;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * MDSAL dataChangeListener for the OVSDB Southbound
40 * @author Sam Hague (shague@redhat.com)
42 public class OvsdbDataChangeListener implements DataChangeListener, AutoCloseable {
43 private static final Logger LOG = LoggerFactory.getLogger(OvsdbDataChangeListener.class);
44 private DataBroker dataBroker = null;
45 private ListenerRegistration<DataChangeListener> registration;
46 private NodeCacheManager nodeCacheManager = null;
48 public OvsdbDataChangeListener (DataBroker dataBroker) {
49 LOG.info(">>>>> Registering OvsdbNodeDataChangeListener: dataBroker= {}", dataBroker);
50 this.dataBroker = dataBroker;
51 InstanceIdentifier<Node> path = InstanceIdentifier
52 .create(NetworkTopology.class)
53 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
55 registration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, path, this,
56 DataChangeScope.SUBTREE);
57 LOG.info("netvirt OvsdbDataChangeListener: registration= {}", registration);
61 public void close () throws Exception {
66 * Recognize when netvirt added a bridge to config and then the operational update comes in
67 * can it be ignored or just viewed as a new switch? ports and interfaces can likely be mapped
68 * to the old path where there were updates for them for update and insert row.
71 public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
72 LOG.info(">>>>> onDataChanged: {}", changes);
74 updateConnections(changes);
75 updateOpenflowConnections(changes);
78 private void updateConnections(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
79 for (Map.Entry<InstanceIdentifier<?>, DataObject> created : changes.getCreatedData().entrySet()) {
80 LOG.info("updateConnections created: {}", created);
81 if (created.getValue() instanceof OvsdbNodeAugmentation) {
82 Node ovsdbNode = getNode(changes, created);
83 LOG.info("ovsdbNode: {}", ovsdbNode);
84 notifyNodeAdded(ovsdbNode);
89 private void updateOpenflowConnections(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
90 for (Map.Entry<InstanceIdentifier<?>, DataObject> created : changes.getCreatedData().entrySet()) {
91 LOG.info("updateOpenflowConnections created: {}", created);
92 if (created.getValue() instanceof OvsdbBridgeAugmentation) {
93 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = (OvsdbBridgeAugmentation)created.getValue();
94 // This value is not being set right now - OvsdbBridgeupdateCommand
95 //if (ovsdbBridgeAugmentation.getBridgeOpenflowNodeRef() != null) {
96 nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
97 nodeCacheManager.nodeAdded(getNode(changes, created));
101 for (Map.Entry<InstanceIdentifier<?>, DataObject> created : changes.getUpdatedData().entrySet()) {
102 LOG.info("updateOpenflowConnections updated: {}", created);
103 if (created.getValue() instanceof OvsdbBridgeAugmentation) {
104 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = (OvsdbBridgeAugmentation)created.getValue();
105 // This value is not being set right now - OvsdbBridgeupdateCommand
106 // if (ovsdbBridgeAugmentation.getBridgeOpenflowNodeRef() != null) {
107 nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
108 nodeCacheManager.nodeAdded(getNode(changes, created));
114 private Node getNode(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
115 Map.Entry<InstanceIdentifier<?>, DataObject> created) {
116 InstanceIdentifier<Node> nodeInstanceIdentifier = created.getKey().firstIdentifierOf(Node.class);
117 return (Node)changes.getCreatedData().get(nodeInstanceIdentifier);
120 private void notifyNodeAdded(Node node) {
121 Set<OvsdbInventoryListener> mdsalConsumerListeners = OvsdbInventoryServiceImpl.getMdsalConsumerListeners();
122 for (OvsdbInventoryListener mdsalConsumerListener : mdsalConsumerListeners) {
123 mdsalConsumerListener.ovsdbNodeAdded(node);