2 * Copyright (c) 2014 Cisco Systems, 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.controller.sample.l2switch.md.topology;
10 import com.google.common.base.Preconditions;
11 import org.opendaylight.controller.sample.l2switch.md.util.InstanceIdentifierUtils;
12 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
13 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
14 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
15 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
16 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
17 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
18 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
19 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
20 import org.opendaylight.yangtools.yang.binding.DataObject;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import java.util.List;
27 import java.util.concurrent.Executors;
28 import java.util.concurrent.ScheduledExecutorService;
29 import java.util.concurrent.TimeUnit;
32 * Listens to data change events on topology links
33 * {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
34 * and maintains a topology graph using provided NetworkGraphService
35 * {@link org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService}.
36 * It refreshes the graph after a delay(default 10 sec) to accommodate burst of change events if they come in bulk.
37 * This is to avoid continuous refresh of graph on a series of change events in short time.
39 public class TopologyLinkDataChangeHandler implements DataChangeListener {
40 private static final Logger _logger = LoggerFactory.getLogger(TopologyLinkDataChangeHandler.class);
41 private static final String DEFAULT_TOPOLOGY_ID = "flow:1";
43 private boolean networkGraphRefreshScheduled = false;
44 private final ScheduledExecutorService networkGraphRefreshScheduler = Executors.newScheduledThreadPool(1);
45 private final long DEFAULT_GRAPH_REFRESH_DELAY = 10;
46 private final long graphRefreshDelayInSec;
48 private final NetworkGraphService networkGraphService;
49 private final DataBrokerService dataBrokerService;
52 * Uses default delay to refresh topology graph if this constructor is used.
53 * @param dataBrokerService
54 * @param networkGraphService
56 public TopologyLinkDataChangeHandler(DataBrokerService dataBrokerService, NetworkGraphService networkGraphService) {
57 Preconditions.checkNotNull(dataBrokerService, "dataBrokerService should not be null.");
58 Preconditions.checkNotNull(networkGraphService, "networkGraphService should not be null.");
59 this.dataBrokerService = dataBrokerService;
60 this.networkGraphService = networkGraphService;
61 this.graphRefreshDelayInSec = DEFAULT_GRAPH_REFRESH_DELAY;
66 * @param dataBrokerService
67 * @param networkGraphService
68 * @param graphRefreshDelayInSec
70 public TopologyLinkDataChangeHandler(DataBrokerService dataBrokerService, NetworkGraphService networkGraphService,
71 long graphRefreshDelayInSec) {
72 Preconditions.checkNotNull(dataBrokerService, "dataBrokerService should not be null.");
73 Preconditions.checkNotNull(networkGraphService, "networkGraphService should not be null.");
74 this.dataBrokerService = dataBrokerService;
75 this.networkGraphService = networkGraphService;
76 this.graphRefreshDelayInSec = graphRefreshDelayInSec;
80 * Based on if links have been added or removed in topology data store, schedules a refresh of network graph.
81 * @param dataChangeEvent
84 public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> dataChangeEvent) {
85 if(dataChangeEvent == null) {
86 _logger.info("In onDataChanged: No Processing done as dataChangeEvent is null.");
88 Map<InstanceIdentifier<?>, DataObject> linkOriginalData = dataChangeEvent.getOriginalOperationalData();
89 Map<InstanceIdentifier<?>, DataObject> linkUpdatedData = dataChangeEvent.getUpdatedOperationalData();
90 // change this logic, once MD-SAL start populating DeletedOperationData Set
91 if(linkOriginalData != null && linkUpdatedData != null
92 && (linkOriginalData.size() != 0 || linkUpdatedData.size() != 0)
93 && !networkGraphRefreshScheduled) {
94 networkGraphRefreshScheduled = linkOriginalData.size() != linkUpdatedData.size();
95 if(networkGraphRefreshScheduled) {
96 networkGraphRefreshScheduler.schedule(new NetworkGraphRefresher(), graphRefreshDelayInSec, TimeUnit.SECONDS);
103 * Registers as a data listener to receive changes done to
104 * {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
105 * under {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology}
106 * operation data root.
109 public void registerAsDataChangeListener() {
110 InstanceIdentifier<Link> linkInstance = InstanceIdentifier.builder(NetworkTopology.class)
111 .child(Topology.class, new TopologyKey(new TopologyId(DEFAULT_TOPOLOGY_ID))).child(Link.class).toInstance();
112 dataBrokerService.registerDataChangeListener(linkInstance, this);
118 private class NetworkGraphRefresher implements Runnable {
124 networkGraphRefreshScheduled = false;
125 //TODO: it should refer to changed links only from DataChangeEvent above.
126 List<Link> links = getLinksFromTopology(DEFAULT_TOPOLOGY_ID);
127 networkGraphService.clear();// can remove this once changed links are addressed
128 if(links != null && !links.isEmpty()) {
129 networkGraphService.addLinks(links);
137 private List<Link> getLinksFromTopology(String topologyId) {
138 InstanceIdentifier<Topology> topologyInstanceIdentifier = InstanceIdentifierUtils.generateTopologyInstanceIdentifier(topologyId);
139 Topology topology = (Topology) dataBrokerService.readOperationalData(topologyInstanceIdentifier);
140 return topology.getLink();