NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / ha / listeners / HAConfigNodeListener.java
1 /*
2  * Copyright (c) 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.netvirt.elan.l2gw.ha.listeners;
9
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
11
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.Optional;
15 import java.util.Set;
16 import java.util.concurrent.ExecutionException;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.opendaylight.genius.infra.Datastore.Configuration;
20 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
21 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
22 import org.opendaylight.infrautils.metrics.MetricProvider;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.DataObjectModification;
25 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
26 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.HAEventHandler;
27 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.IHAEventHandler;
28 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.NodeCopier;
29 import org.opendaylight.netvirt.elan.l2gw.recovery.impl.L2GatewayServiceRecoveryHandler;
30 import org.opendaylight.serviceutils.srm.RecoverableListener;
31 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 @Singleton
38 public class HAConfigNodeListener extends HwvtepNodeBaseListener<Configuration> implements RecoverableListener {
39
40     private static final Logger LOG = LoggerFactory.getLogger(HAConfigNodeListener.class);
41
42     private final IHAEventHandler haEventHandler;
43     private final NodeCopier nodeCopier;
44
45     @Inject
46     public HAConfigNodeListener(DataBroker db, HAEventHandler haEventHandler,
47                                 NodeCopier nodeCopier, HwvtepNodeHACache hwvtepNodeHACache,
48                                 MetricProvider metricProvider,
49                                 final L2GatewayServiceRecoveryHandler l2GatewayServiceRecoveryHandler,
50                                 final ServiceRecoveryRegistry serviceRecoveryRegistry) throws Exception {
51         super(CONFIGURATION, db, hwvtepNodeHACache, metricProvider, true);
52         this.haEventHandler = haEventHandler;
53         this.nodeCopier = nodeCopier;
54         serviceRecoveryRegistry.addRecoverableListener(l2GatewayServiceRecoveryHandler.buildServiceRegistryKey(), this);
55     }
56
57     @Override
58     @SuppressWarnings("all")
59     public void registerListener() {
60         try {
61             LOG.info("Registering HAConfigNodeListener");
62             registerListener(CONFIGURATION, getDataBroker());
63         } catch (Exception e) {
64             LOG.error("HA Config Node register listener error.");
65         }
66     }
67
68     public void deregisterListener() {
69         LOG.info("Deregistering HAConfigNodeListener");
70         super.close();
71     }
72
73     @Override
74     void onPsNodeAdd(InstanceIdentifier<Node> haPsPath,
75                      Node haPSNode,
76                      TypedReadWriteTransaction<Configuration> tx)
77              throws ExecutionException, InterruptedException {
78         //copy the ps node data to children
79         String psId = haPSNode.getNodeId().getValue();
80         Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
81         if (childSwitchIds.isEmpty()) {
82             LOG.error("Failed to find any ha children {}", haPsPath);
83             return;
84         }
85         for (InstanceIdentifier<Node> childPsPath : childSwitchIds) {
86             String nodeId =
87                     HwvtepHAUtil.convertToGlobalNodeId(childPsPath.firstKeyOf(Node.class).getNodeId().getValue());
88             InstanceIdentifier<Node> childGlobalPath = HwvtepHAUtil.convertToInstanceIdentifier(nodeId);
89             nodeCopier.copyPSNode(Optional.ofNullable(haPSNode), haPsPath, childPsPath, childGlobalPath,
90                     CONFIGURATION, tx);
91         }
92         LOG.trace("Handle config ps node add {}", psId);
93     }
94
95     @Override
96     void onPsNodeUpdate(Node haPSUpdated,
97         DataObjectModification<Node> mod,
98         TypedReadWriteTransaction<Configuration> tx) {
99         //copy the ps node data to children
100         String psId = haPSUpdated.getNodeId().getValue();
101         Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
102         for (InstanceIdentifier<Node> childSwitchId : childSwitchIds) {
103             haEventHandler.copyHAPSUpdateToChild(childSwitchId, mod, tx);
104         }
105     }
106
107     @Override
108     void onGlobalNodeUpdate(InstanceIdentifier<Node> key,
109                             Node haUpdated,
110                             Node haOriginal,
111                             DataObjectModification<Node> mod,
112                             TypedReadWriteTransaction<Configuration> tx) {
113         Set<InstanceIdentifier<Node>> childNodeIds = getHwvtepNodeHACache().getChildrenForHANode(key);
114         for (InstanceIdentifier<Node> haChildNodeId : childNodeIds) {
115             haEventHandler.copyHAGlobalUpdateToChild(haChildNodeId, mod, tx);
116         }
117     }
118
119     @Override
120     void onPsNodeDelete(InstanceIdentifier<Node> key,
121                         Node deletedPsNode,
122                         TypedReadWriteTransaction<Configuration> tx)
123             throws ExecutionException, InterruptedException {
124         //delete ps children nodes
125         String psId = deletedPsNode.getNodeId().getValue();
126         Set<InstanceIdentifier<Node>> childPsIds = getPSChildrenIdsForHAPSNode(psId);
127         for (InstanceIdentifier<Node> childPsId : childPsIds) {
128             HwvtepHAUtil.deleteNodeIfPresent(tx, childPsId);
129         }
130     }
131
132     @Override
133     void onGlobalNodeDelete(InstanceIdentifier<Node> key,
134                             Node haNode,
135                             TypedReadWriteTransaction<Configuration> tx)
136             throws ExecutionException, InterruptedException {
137         //delete child nodes
138         Set<InstanceIdentifier<Node>> children = getHwvtepNodeHACache().getChildrenForHANode(key);
139         for (InstanceIdentifier<Node> childId : children) {
140             HwvtepHAUtil.deleteNodeIfPresent(tx, childId);
141         }
142         HwvtepHAUtil.deletePSNodesOfNode(key, haNode, tx);
143     }
144
145     private Set<InstanceIdentifier<Node>> getPSChildrenIdsForHAPSNode(String psNodId) {
146         if (!psNodId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
147             return Collections.emptySet();
148         }
149         String nodeId = HwvtepHAUtil.convertToGlobalNodeId(psNodId);
150         InstanceIdentifier<Node> iid = HwvtepHAUtil.convertToInstanceIdentifier(nodeId);
151         if (getHwvtepNodeHACache().isHAParentNode(iid)) {
152             Set<InstanceIdentifier<Node>> childSwitchIds = new HashSet<>();
153             Set<InstanceIdentifier<Node>> childGlobalIds = getHwvtepNodeHACache().getChildrenForHANode(iid);
154             final String append = psNodId.substring(psNodId.indexOf(HwvtepHAUtil.PHYSICALSWITCH));
155             for (InstanceIdentifier<Node> childId : childGlobalIds) {
156                 String childIdVal = childId.firstKeyOf(Node.class).getNodeId().getValue();
157                 childSwitchIds.add(HwvtepHAUtil.convertToInstanceIdentifier(childIdVal + append));
158             }
159             return childSwitchIds;
160         }
161         return Collections.emptySet();
162     }
163 }