e7c68e724f80d342422d0c92613d47b04152b6d5
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkNodeListener.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.netvirt.vpnmanager.intervpnlink;
9
10 import java.math.BigInteger;
11 import java.util.List;
12 import javax.annotation.PostConstruct;
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.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
19 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
20 import org.opendaylight.netvirt.vpnmanager.VpnFootprintService;
21 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
22 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
23 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
24 import org.opendaylight.netvirt.vpnmanager.intervpnlink.tasks.InterVpnLinkCleanedCheckerTask;
25 import org.opendaylight.netvirt.vpnmanager.intervpnlink.tasks.InterVpnLinkCreatorTask;
26 import org.opendaylight.netvirt.vpnmanager.intervpnlink.tasks.InterVpnLinkRemoverTask;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Listens for Nodes going down, in order to check if the InterVpnLink must be
41  * moved to some other DPN.
42  */
43 @Singleton
44 public class InterVpnLinkNodeListener extends AsyncDataTreeChangeListenerBase<Node, InterVpnLinkNodeListener> {
45     private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkNodeListener.class);
46
47     public static final TopologyId FLOW_TOPOLOGY_ID = new TopologyId(new Uri("flow:1"));
48
49     private final DataBroker dataBroker;
50     private final IMdsalApiManager mdsalManager;
51     private final VpnFootprintService vpnFootprintService;
52     private final JobCoordinator jobCoordinator;
53     private final InterVpnLinkCache interVpnLinkCache;
54     private final VpnUtil vpnUtil;
55     private final InterVpnLinkUtil interVpnLinkUtil;
56
57     @Inject
58     public InterVpnLinkNodeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalMgr,
59                                     final VpnFootprintService vpnFootprintService,
60                                     final JobCoordinator jobCoordinator, final InterVpnLinkCache interVpnLinkCache,
61                                     VpnUtil vpnUtil, InterVpnLinkUtil interVpnLinkUtil) {
62         this.dataBroker = dataBroker;
63         this.mdsalManager = mdsalMgr;
64         this.vpnFootprintService = vpnFootprintService;
65         this.jobCoordinator = jobCoordinator;
66         this.interVpnLinkCache = interVpnLinkCache;
67         this.vpnUtil = vpnUtil;
68         this.interVpnLinkUtil = interVpnLinkUtil;
69     }
70
71     @PostConstruct
72     public void start() {
73         LOG.info("{} start", getClass().getSimpleName());
74         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
75     }
76
77     @Override
78     protected InstanceIdentifier<Node> getWildCardPath() {
79         return InstanceIdentifier.create(NetworkTopology.class)
80             .child(Topology.class, new TopologyKey(FLOW_TOPOLOGY_ID))
81             .child(Node.class);
82     }
83
84     @Override
85     protected InterVpnLinkNodeListener getDataTreeChangeListener() {
86         return InterVpnLinkNodeListener.this;
87     }
88
89     @Override
90     protected void add(InstanceIdentifier<Node> identifier, Node add) {
91         NodeId nodeId = add.getNodeId();
92         String[] node = nodeId.getValue().split(":");
93         if (node.length < 2) {
94             LOG.warn("Unexpected nodeId {}", nodeId.getValue());
95             return;
96         }
97         BigInteger dpId = new BigInteger(node[1]);
98         jobCoordinator.enqueueJob("IVpnLink" + dpId.toString(),
99             new InterVpnLinkNodeAddTask(dataBroker, mdsalManager, vpnFootprintService, dpId, interVpnLinkCache,
100                     vpnUtil, interVpnLinkUtil));
101     }
102
103     @Override
104     protected void remove(InstanceIdentifier<Node> identifier, Node del) {
105         LOG.trace("Node {} has been deleted", identifier.firstKeyOf(Node.class).toString());
106         NodeId nodeId = del.getNodeId();
107         String[] node = nodeId.getValue().split(":");
108         if (node.length < 2) {
109             LOG.warn("Unexpected nodeId {}", nodeId.getValue());
110             return;
111         }
112         BigInteger dpId = new BigInteger(node[1]);
113         List<InterVpnLinkDataComposite> allInterVpnLinks = interVpnLinkCache.getAllInterVpnLinks();
114         allInterVpnLinks.stream()
115                         .filter(ivl -> ivl.stepsOnDpn(dpId))           // Only those affected by DPN going down
116                         .forEach(this::reinstallInterVpnLink);         // Move them somewhere else
117     }
118
119     private void reinstallInterVpnLink(InterVpnLinkDataComposite ivl) {
120         String ivlName = ivl.getInterVpnLinkName();
121         LOG.debug("Reinstalling InterVpnLink {} affected by node going down", ivlName);
122         // Lets move the InterVpnLink to some other place. Basically, remove it and create it again
123         InstanceIdentifier<InterVpnLink> interVpnLinkIid = InterVpnLinkUtil.getInterVpnLinkPath(ivlName);
124         String specificJobKey = "InterVpnLink.update." + ivlName;
125         InterVpnLink interVpnLink = ivl.getInterVpnLinkConfig();
126         jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkRemoverTask(dataBroker, interVpnLinkIid));
127         jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkCleanedCheckerTask(dataBroker, interVpnLink,
128                 interVpnLinkUtil, vpnUtil));
129         jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkCreatorTask(dataBroker, interVpnLink));
130     }
131
132     @Override
133     protected void update(InstanceIdentifier<Node> identifier, Node original, Node update) {
134     }
135 }