Convert to JobCoordinator in interfacemanager
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / listeners / InterfaceTopologyStateListener.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.genius.interfacemanager.listeners;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.List;
12 import java.util.concurrent.Callable;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
18 import org.opendaylight.genius.interfacemanager.IfmConstants;
19 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
20 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
21 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper;
22 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
23 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
24 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
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.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 @Singleton
35 public class InterfaceTopologyStateListener
36         extends AsyncClusteredDataTreeChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
37     private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class);
38     private final DataBroker dataBroker;
39     private final InterfacemgrProvider interfaceMgrProvider;
40     private final EntityOwnershipUtils entityOwnershipUtils;
41     private final JobCoordinator coordinator;
42     private final OvsInterfaceTopologyStateUpdateHelper ovsInterfaceTopologyStateUpdateHelper;
43
44     @Inject
45     public InterfaceTopologyStateListener(final DataBroker dataBroker, final InterfacemgrProvider interfaceMgrProvider,
46             final EntityOwnershipUtils entityOwnershipUtils, final JobCoordinator coordinator) {
47         super(OvsdbBridgeAugmentation.class, InterfaceTopologyStateListener.class);
48         this.dataBroker = dataBroker;
49         this.interfaceMgrProvider = interfaceMgrProvider;
50         this.entityOwnershipUtils = entityOwnershipUtils;
51         this.coordinator = coordinator;
52         this.ovsInterfaceTopologyStateUpdateHelper = new OvsInterfaceTopologyStateUpdateHelper(dataBroker,
53                 entityOwnershipUtils, coordinator);
54         this.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
55     }
56
57     @Override
58     protected InstanceIdentifier<OvsdbBridgeAugmentation> getWildCardPath() {
59         return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(Node.class)
60                 .augmentation(OvsdbBridgeAugmentation.class).build();
61     }
62
63     @Override
64     protected InterfaceTopologyStateListener getDataTreeChangeListener() {
65         return InterfaceTopologyStateListener.this;
66     }
67
68     private void runOnlyInOwnerNode(String jobDesc, Runnable job) {
69         entityOwnershipUtils.runOnlyInOwnerNode(IfmConstants.INTERFACE_CONFIG_ENTITY,
70                 IfmConstants.INTERFACE_CONFIG_ENTITY, coordinator, jobDesc, job);
71     }
72
73     @Override
74     protected void remove(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld) {
75         LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
76                 identifier, bridgeOld);
77
78         InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
79         interfaceMgrProvider.removeBridgeForNodeIid(nodeIid);
80
81         runOnlyInOwnerNode("OVSDB bridge removed", () -> {
82             RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(identifier, bridgeOld);
83             coordinator.enqueueJob(bridgeOld.getBridgeName().getValue(), rendererStateRemoveWorker,
84                 IfmConstants.JOB_MAX_RETRIES);
85         });
86     }
87
88     @Override
89     protected void update(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld,
90             OvsdbBridgeAugmentation bridgeNew) {
91         LOG.debug(
92                 "Received Update DataChange Notification for identifier: {}, ovsdbBridgeAugmentation old: {}, new: {}.",
93                 identifier, bridgeOld, bridgeNew);
94
95         InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
96         interfaceMgrProvider.addBridgeForNodeIid(nodeIid, bridgeNew);
97
98         runOnlyInOwnerNode("OVSDB bridge updated", () -> {
99             DatapathId oldDpid = bridgeOld.getDatapathId();
100             DatapathId newDpid = bridgeNew.getDatapathId();
101             if (oldDpid == null && newDpid != null) {
102                 RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
103                 coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
104                         IfmConstants.JOB_MAX_RETRIES);
105             } else if (oldDpid != null && !oldDpid.equals(newDpid)) {
106                 RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(identifier, bridgeNew,
107                         bridgeOld);
108                 coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
109                         IfmConstants.JOB_MAX_RETRIES);
110             }
111         });
112     }
113
114     @Override
115     protected void add(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeNew) {
116         LOG.debug("Received Add DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
117                 identifier, bridgeNew);
118
119         InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
120         interfaceMgrProvider.addBridgeForNodeIid(nodeIid, bridgeNew);
121
122         runOnlyInOwnerNode("OVSDB bridge added", () -> {
123             RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
124             coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
125                 IfmConstants.JOB_MAX_RETRIES);
126         });
127     }
128
129     private class RendererStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
130         InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
131         OvsdbBridgeAugmentation bridgeNew;
132
133         RendererStateAddWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
134                 OvsdbBridgeAugmentation bridgeNew) {
135             this.instanceIdentifier = instanceIdentifier;
136             this.bridgeNew = bridgeNew;
137         }
138
139         @Override
140         public List<ListenableFuture<Void>> call() {
141             return OvsInterfaceTopologyStateAddHelper.addPortToBridge(instanceIdentifier, bridgeNew, dataBroker);
142         }
143     }
144
145     private class RendererStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
146         InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
147         OvsdbBridgeAugmentation bridgeNew;
148
149         RendererStateRemoveWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
150                 OvsdbBridgeAugmentation bridgeNew) {
151             this.instanceIdentifier = instanceIdentifier;
152             this.bridgeNew = bridgeNew;
153         }
154
155         @Override
156         public List<ListenableFuture<Void>> call() {
157             return OvsInterfaceTopologyStateRemoveHelper.removePortFromBridge(instanceIdentifier, bridgeNew,
158                     dataBroker);
159         }
160     }
161
162     private class RendererStateUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
163         InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
164         OvsdbBridgeAugmentation bridgeNew;
165         OvsdbBridgeAugmentation bridgeOld;
166
167         RendererStateUpdateWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
168                 OvsdbBridgeAugmentation bridgeNew, OvsdbBridgeAugmentation bridgeOld) {
169             this.instanceIdentifier = instanceIdentifier;
170             this.bridgeNew = bridgeNew;
171             this.bridgeOld = bridgeOld;
172         }
173
174         @Override
175         public List<ListenableFuture<Void>> call() {
176             return ovsInterfaceTopologyStateUpdateHelper.updateBridgeRefEntry(instanceIdentifier, bridgeNew, bridgeOld);
177         }
178     }
179 }