599f70380f12b18ab36c76ea206378bed0b5ed61
[vpnservice.git] / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / vpnservice / InterfaceStateChangeListener.java
1 /*
2  * Copyright (c) 2015 - 2016 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.vpnservice;
9
10 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
11 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
12 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.vpnservice.utilities.InterfaceUtils;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
20 import org.opendaylight.yangtools.concepts.ListenerRegistration;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import java.math.BigInteger;
26
27 public class InterfaceStateChangeListener extends AbstractDataChangeListener<Interface> implements AutoCloseable {
28     private static final Logger LOG = LoggerFactory.getLogger(InterfaceStateChangeListener.class);
29
30     private ListenerRegistration<DataChangeListener> listenerRegistration;
31     private final DataBroker broker;
32     private VpnInterfaceManager vpnInterfaceManager;
33     private OdlInterfaceRpcService interfaceManager;
34
35
36     public InterfaceStateChangeListener(final DataBroker db, VpnInterfaceManager vpnInterfaceManager) {
37         super(Interface.class);
38         broker = db;
39         this.vpnInterfaceManager = vpnInterfaceManager;
40         registerListener(db);
41     }
42
43     public void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {
44       this.interfaceManager = interfaceManager;
45   }
46
47     @Override
48     public void close() throws Exception {
49         if (listenerRegistration != null) {
50             try {
51                 listenerRegistration.close();
52             } catch (final Exception e) {
53                 LOG.error("Error when cleaning up DataChangeListener.", e);
54             }
55             listenerRegistration = null;
56         }
57         LOG.info("Interface listener Closed");
58     }
59
60
61     private void registerListener(final DataBroker db) {
62         try {
63             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
64                                                                  getWildCardPath(), InterfaceStateChangeListener.this, DataChangeScope.SUBTREE);
65         } catch (final Exception e) {
66             LOG.error("Interface DataChange listener registration failed", e);
67             throw new IllegalStateException("Nexthop Manager registration Listener failed.", e);
68         }
69     }
70
71     @Override
72     protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
73       LOG.trace("Received interface {} up event", intrf);
74       try {
75         String interfaceName = intrf.getName();
76         LOG.info("Received port UP event for interface {} ", interfaceName);
77         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
78             configInterface = InterfaceUtils.getInterface(broker, interfaceName);
79         if (configInterface != null && configInterface.getType().equals(Tunnel.class)) {
80           BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
81           if(intrf.getOperStatus().equals(Interface.OperStatus.Up)) {
82             //advertise all prefixes in all vpns for this dpn to bgp
83             vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
84           }
85         } else {
86           vpnInterfaceManager.processVpnInterfaceUp(interfaceName, intrf.getIfIndex());
87         }
88       } catch (Exception e) {
89         LOG.error("Exception caught in Interface Operational State Up event", e);
90       }
91     }
92
93
94     private InstanceIdentifier<Interface> getWildCardPath() {
95         return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
96     }
97
98     @Override
99     protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
100       LOG.trace("Received interface {} down event", intrf);
101       try {
102         String interfaceName = intrf.getName();
103         LOG.info("Received port DOWN event for interface {} ", interfaceName);
104         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
105             intf = InterfaceUtils.getInterface(broker, interfaceName);
106         if (intf != null && intf.getType().equals(Tunnel.class)) {
107           // Get the dpId from del reference itself. Because interfaceManager.getDpnForInterface returns
108           // NPE because entry is already deleted in operational data store
109           BigInteger dpId = getDpIdFromInterface(intrf);
110           if (dpId == null) {
111             return;
112           }
113           if(intrf.getOperStatus().equals(Interface.OperStatus.Down)) {
114             //withdraw all prefixes in all vpns for this dpn from bgp
115             vpnInterfaceManager.updatePrefixesForDPN(dpId, VpnInterfaceManager.UpdateRouteAction.WITHDRAW_ROUTE);
116           }
117         } else {
118           if (VpnUtil.isVpnInterfaceConfigured(broker, interfaceName)) {
119             vpnInterfaceManager.processVpnInterfaceDown(interfaceName, intrf.getIfIndex(), true);
120           }
121         }
122       } catch (Exception e) {
123         LOG.error("Exception caught in onVlanInterfaceOperationalStateDown", e);
124       }
125     }
126
127     @Override
128     protected void update(InstanceIdentifier<Interface> identifier,
129             Interface original, Interface update) {
130       LOG.trace("Operation Interface update event - Old: {}, New: {}", original, update);
131       String interfaceName = update.getName();
132       org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
133           intf = InterfaceUtils.getInterface(broker, interfaceName);
134       if (intf != null && intf.getType().equals(Tunnel.class)) {
135         BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
136         if(update.getOperStatus().equals(Interface.OperStatus.Up)) {
137           //advertise all prefixes in all vpns for this dpn to bgp
138           vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
139         } else if(update.getOperStatus().equals(Interface.OperStatus.Down)) {
140           //withdraw all prefixes in all vpns for this dpn from bgp
141           vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.WITHDRAW_ROUTE);
142         }
143       }
144
145     }
146
147   public BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface infState) {
148     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
149         InterfaceUtils.getInterfaceStateFromOperDS(broker, infState.getName());
150     String lowerLayerIf = ifState.getLowerLayerIf().get(0);
151     NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
152     return new BigInteger(InterfaceUtils.getDpnFromNodeConnectorId(nodeConnectorId));
153   }
154
155 }