Merge "Multiple fixes related to VPN concurrency"
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / BgpManager.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
9 package org.opendaylight.netvirt.bgpmanager;
10
11 import java.lang.management.ManagementFactory;
12 import java.util.*;
13 import java.util.concurrent.CountDownLatch;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.TimeoutException;
16 import javax.management.*;
17
18 import com.google.common.base.*;
19 import com.google.common.base.Optional;
20 import org.apache.thrift.TException;
21 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
22 import org.opendaylight.netvirt.bgpmanager.commands.Commands;
23 import org.opendaylight.netvirt.bgpmanager.oam.*;
24 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
25 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
30 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
31 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
32 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
33 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpManager {
39
40     private static final Logger LOGGER = LoggerFactory.getLogger(BgpManager.class);
41     private BgpConfigurationManager bcm;
42     private FibDSWriter fibDSWriter;
43     //private IITMProvider        itmProvider;
44     private DataBroker dataBroker;
45     private BgpAlarmBroadcaster     qbgpAlarmProducer = null;
46     private MBeanServer qbgpAlarmServer = null;
47     private NotificationFilter  qbgpAlarmFilter = null;
48     final static int DEFAULT_STALEPATH_TIME = 210;
49     final static boolean DEFAULT_FBIT = true;
50
51     private long qBGPrestartTS = 0;
52
53     EntityOwnershipService entityOwnershipService;
54     public BgpCounters bgpCounters;
55     public Timer bgpCountersTimer;
56
57     @Override
58     public void onSessionInitiated(ProviderContext session) {
59         try {
60             dataBroker = session.getSALService(DataBroker.class);
61             fibDSWriter = new FibDSWriter(dataBroker);
62             BgpUtil.setBroker(dataBroker);
63             bcm = new BgpConfigurationManager(this);
64             bcm.setEntityOwnershipService(entityOwnershipService);
65             Commands commands = new Commands(this);
66             ConfigureBgpCli.setBgpManager(this);
67             LOGGER.info("BgpManager started");
68         } catch (Exception e) {
69             LOGGER.error("Failed to start BgpManager: "+e);
70         }
71
72         // Set up the Infra for Posting BGP Alarms as JMX notifications.
73         try {
74             qbgpAlarmProducer = new BgpAlarmBroadcaster();
75             MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
76             ObjectName alarmObj = new ObjectName("SDNC.FM:name=BgpAlarmObj");
77             mbs.registerMBean(qbgpAlarmProducer, alarmObj);
78         } catch (JMException e) {
79             LOGGER.error("Adding a NotificationBroadcaster failed." + e.toString());
80             e.printStackTrace();
81         }
82     }
83
84     public void setEntityOwnershipService(EntityOwnershipService entityOwnershipService) {
85         this.entityOwnershipService = entityOwnershipService;
86     }
87
88     @Override
89     public void close() throws Exception {
90         bcm.close();
91         LOGGER.info("BgpManager Closed");
92     }
93
94     /*public void setITMProvider(IITMProvider itmProvider) {
95         this.itmProvider = itmProvider;
96     }
97
98     public IITMProvider getItmProvider() { return this.itmProvider; } */
99
100     public Bgp getConfig() {
101         //TODO cleanup this cache code
102         try {
103             Optional<Bgp> optional = BgpUtil.read(dataBroker,
104                     LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Bgp.class));
105             return optional.get();
106         } catch (Exception e) {
107             //LOGGER.error("failed to get bgp config",e);
108         }
109         return null;
110     }
111
112     public void configureGR(int stalepathTime) throws TException {
113         bcm.addGracefulRestart(stalepathTime);
114     }
115
116     public void delGracefulRestart() throws Exception {
117         bcm.delGracefulRestart();
118     }
119
120     public void addNeighbor(String ipAddress, long asNum) throws TException {
121         bcm.addNeighbor(ipAddress, (int) asNum);
122     }
123
124     public void addEbgpMultihop(String ipAddress, int nhops) throws TException {
125         bcm.addEbgpMultihop(ipAddress, nhops);
126     }
127
128     public void addUpdateSource(String ipAddress, String srcIp) throws TException {
129         bcm.addUpdateSource(ipAddress, srcIp);
130     }
131
132     public void addAddressFamily(String ipAddress, af_afi afi, af_safi safi) throws TException {
133         bcm.addAddressFamily(ipAddress, afi.getValue(), safi.getValue());
134     }
135
136     public void deleteNeighbor(String ipAddress) throws TException {
137         bcm.delNeighbor(ipAddress);
138     }
139
140     @Override
141     public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception {
142         bcm.addVrf(rd, new ArrayList<String>(importRts), new ArrayList<String>(exportRts));
143     }
144
145     @Override
146     public void deleteVrf(String rd, boolean removeFibTable) throws Exception {
147         if (removeFibTable) {
148             fibDSWriter.removeVrfFromDS(rd);
149         }
150         bcm.delVrf(rd);
151     }
152
153     @Override
154     public void addPrefix(String rd, String prefix, List<String> nextHopList, int vpnLabel, RouteOrigin origin) throws Exception {
155         fibDSWriter.addFibEntryToDS(rd, prefix, nextHopList, vpnLabel, origin);
156         bcm.addPrefix(rd, prefix, nextHopList, vpnLabel);
157     }
158
159     @Override
160     public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel, RouteOrigin origin) throws Exception {
161         addPrefix(rd, prefix, Arrays.asList(nextHop), vpnLabel, origin);
162     }
163
164     @Override
165     public void deletePrefix(String rd, String prefix) throws Exception {
166         fibDSWriter.removeFibEntryFromDS(rd, prefix);
167         bcm.delPrefix(rd, prefix);
168     }
169
170     @Override
171     public void advertisePrefix(String rd, String prefix, List<String> nextHopList, int vpnLabel) throws Exception {
172         bcm.addPrefix(rd, prefix, nextHopList, vpnLabel);
173     }
174
175     @Override
176     public void advertisePrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception {
177         LOGGER.info("ADVERTISE: Adding Prefix rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, vpnLabel);
178         bcm.addPrefix(rd, prefix, Arrays.asList(nextHop), vpnLabel);
179         LOGGER.info("ADVERTISE: Added Prefix rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, vpnLabel);
180     }
181
182     @Override
183     public void withdrawPrefix(String rd, String prefix) throws Exception {
184         LOGGER.info("WITHDRAW: Removing Prefix rd {} prefix {}", rd, prefix);
185         bcm.delPrefix(rd, prefix);
186         LOGGER.info("WITHDRAW: Removed Prefix rd {} prefix {}", rd, prefix);
187     }
188
189     public void setQbgpLog(String fileName, String debugLevel) throws Exception {
190         bcm.addLogging(fileName, debugLevel);
191     }
192
193     public void delLogging() throws Exception {
194         bcm.delLogging();
195     }
196
197     public void startBgp(int asn, String routerId, int spt, boolean fbit) {
198         bcm.startBgp(asn, routerId, spt, fbit);
199     }
200
201     public void stopBgp() {
202         bcm.stopBgp();
203     }
204
205     public void startConfig(String host, int port) {
206         bcm.startConfig(host, port);
207     }
208
209     public void stopConfig() {
210         bcm.stopConfig();
211     }
212
213     @Override
214     public String getDCGwIP() {
215         Bgp conf = getConfig();
216         if (conf == null) {
217             return null;
218         }
219         List<Neighbors> nbrs = conf.getNeighbors();
220         if (nbrs == null) {
221             return null;
222         }
223         return nbrs.get(0).getAddress().getValue();
224     }
225
226     public MBeanServer getBgpAlarmServer() {
227         return qbgpAlarmServer;
228     }
229
230     public synchronized void sendNotificationEvent(String pfx, int code, int subcode) {
231         BgpAlarmErrorCodes errorSubCode;
232         if (code != BgpConstants.BGP_NOTIFY_CEASE_CODE) {
233             // CEASE Notifications alone have to be reported to the CBA.
234             // Silently return here. No need to log because tons
235             // of non-alarm notifications will be sent to the SDNc.
236             return;
237         }
238         errorSubCode = BgpAlarmErrorCodes.checkErrorSubcode(subcode);
239         if (errorSubCode == BgpAlarmErrorCodes.ERROR_IGNORE) {
240             // Need to report only those subcodes, defined in
241             // BgpAlarmErrorCodes enum class.
242             return;
243         }
244         String alarmString = "";
245         alarmString = "Alarm (" + code + "," + subcode + ") from neighbor " + pfx;
246         qbgpAlarmProducer.sendBgpAlarmInfo(pfx, code, subcode);
247     }
248
249     public Timer getBgpCountersTimer() {
250         return bgpCountersTimer;
251     }
252
253     public BgpCounters getBgpCounters() {
254         return bgpCounters;
255     }
256
257     public  void setBgpCountersTimer (Timer t) {
258         bgpCountersTimer = t;
259     }
260
261     public void startBgpCountersTask() {
262         if (getBgpCounters() == null) {
263
264             try {
265                 bgpCounters = new BgpCounters();
266                 setBgpCountersTimer(new Timer(true));
267                 getBgpCountersTimer().scheduleAtFixedRate(bgpCounters, 0, 120 * 1000);
268
269
270                 LOGGER.info("Bgp Counters task scheduled for every two minutes.");
271             } catch (Exception e) {
272                 System.out.println("Could not start the timertask for Bgp Counters.");
273                 e.printStackTrace();
274             }
275
276             try {
277                 setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
278             } catch (Exception e) {
279                 System.out.println("Could not set the default options for logging");
280             }
281         }
282     }
283
284     public void stopBgpCountersTask() {
285         Timer t = getBgpCountersTimer();
286         if (getBgpCounters() != null) {
287             t.cancel();
288             setBgpCountersTimer(null);
289             bgpCounters = null;
290         }
291     }
292
293     public FibDSWriter getFibWriter() {
294         return fibDSWriter;
295     }
296
297     public DataBroker getBroker() {
298         return dataBroker;
299     }
300
301     public String getConfigHost() {
302         return bcm.getConfigHost();
303     }
304
305     public int getConfigPort() {
306         return bcm.getConfigPort();
307     }
308
309     public void bgpRestarted() {
310         bcm.bgpRestarted();
311     }
312
313     public boolean isBgpConnected() {
314         return bcm.isBgpConnected();
315     }
316
317     public long getLastConnectedTS() {
318         return bcm.getLastConnectedTS();
319     }
320     public long getConnectTS() {
321         return bcm.getConnectTS();
322     }
323     public long getStartTS() {
324         return bcm.getStartTS();
325     }
326
327     public long getqBGPrestartTS() {
328         return qBGPrestartTS;
329     }
330
331     public void setqBGPrestartTS(long qBGPrestartTS) {
332         this.qBGPrestartTS = qBGPrestartTS;
333     }
334     public long getStaleStartTime() {
335         return bcm.getStaleStartTime();
336     }
337     public long getStaleEndTime() {
338         return bcm.getStaleEndTime();
339     }
340     public long getCfgReplayStartTime() {
341         return bcm.getCfgReplayStartTime();
342     }
343     public long getCfgReplayEndTime() {
344         return bcm.getCfgReplayEndTime();
345     }
346     public long getStaleCleanupTime() {
347         return bcm.getStaleCleanupTime();
348     }
349
350 }