b12f9278dc15add82d3233022c198ce5af77a8fb
[vpnservice.git] / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / bgpmanager / BgpConfigurationManager.java
1 /*
2  * Copyright (c) 2015 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.bgpmanager;
9
10 import java.util.Collections;
11 import java.util.Map;
12 import java.util.Set;
13
14 import org.apache.thrift.TException;
15 import org.opendaylight.bgpmanager.globals.BgpConfiguration;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
21 import org.opendaylight.yangtools.concepts.ListenerRegistration;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpRouter;
25 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpNeighbors;
26 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.BgpNeighbor;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import java.util.List;
32
33 import com.google.common.base.Optional;
34 import com.google.common.base.Preconditions;
35
36 public class BgpConfigurationManager {
37     private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
38     private ListenerRegistration<DataChangeListener> listenerRegistration;
39     private BgpConfiguration bgpConfiguration;
40     private BgpManager bgpManager;
41     private final DataBroker broker;
42     private static final int MAX_RETRIES_BGP_COMMUNICATION = 1;
43
44     public BgpConfigurationManager(final DataBroker db, BgpConfiguration bgpCfg, BgpManager bgpMgr) {
45         broker = db;
46         bgpConfiguration = bgpCfg;
47         bgpManager = bgpMgr;
48         BgpRtrCfgManager rtrCfgManager = new BgpRtrCfgManager(broker);
49         BgpNghbrCfgManager nghbrCfgManager = new BgpNghbrCfgManager(broker);
50     }
51
52     public class BgpRtrCfgManager extends AbstractDataChangeListener<BgpRouter> implements AutoCloseable {
53
54         public BgpRtrCfgManager(final DataBroker db) {
55             super(BgpRouter.class);
56             registerListener(db);
57         }
58
59         private void registerListener(final DataBroker db) {
60             try {
61                 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
62                     getWildCardPath(), BgpRtrCfgManager.this, DataChangeScope.SUBTREE);
63             } catch (final Exception e) {
64                 LOG.error("BGP Configuration DataChange listener registration fail!", e);
65                 throw new IllegalStateException("BGP Configuration registration Listener failed.", e);
66             }
67         }
68
69         private synchronized void removeBgpRouter(BgpRouter del)
70         {
71
72         }
73
74         @Override
75         protected void remove(InstanceIdentifier<BgpRouter> identifier,
76                               BgpRouter del) {
77
78             LOG.info("Bgp Router deleted in DS - " + "key: " + identifier + ", value=" + del);
79
80             removeBgpRouter(del);
81
82         }
83
84         private synchronized void updateBgpRouter(BgpRouter original, BgpRouter update)
85         {
86             if(bgpConfiguration.getAsNum() != update.getLocalAsNumber()) {
87                 bgpConfiguration.setAsNum(update.getLocalAsNumber());
88                 bgpConfiguration.setConfigUpdated();
89             }
90             if(bgpConfiguration.getRouterId() != update.getLocalAsIdentifier().getIpv4Address().getValue()) {
91                 bgpConfiguration.setRouterId(update.getLocalAsIdentifier().getIpv4Address().getValue());
92                 bgpConfiguration.setConfigUpdated();
93             }
94
95             if(bgpConfiguration.isConfigUpdated()) {
96                 int retryCount = 0;
97                 boolean retry = false;
98                 do {
99                     try {
100                         if(retry)
101                             LOG.info("Retrying BgpService start.." + "retry count:" + retryCount);
102                         //bgpManager.waitForBgpInit();
103                         bgpManager.startBgpService();
104                         LOG.info("BgpService start done..");
105                         retry = false;
106                     } catch (TException t) {
107                         LOG.info("BgpService start failed..");
108                         retry = true;
109                         retryCount++;
110                     }
111                 } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
112
113                 bgpConfiguration.unsetConfigUpdated();
114             }
115
116         }
117
118         @Override
119         protected void update(InstanceIdentifier<BgpRouter> identifier,
120                               BgpRouter original, BgpRouter update) {
121
122             LOG.info("Bgp Router Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + update);
123
124             updateBgpRouter(original, update);
125         }
126
127         private synchronized void addBgpRouter(BgpRouter value){
128             if(value.getLocalAsNumber() != null) {
129                 bgpConfiguration.setAsNum(value.getLocalAsNumber());
130             }
131             if(value.getLocalAsIdentifier() != null) {
132                 bgpConfiguration.setRouterId(value.getLocalAsIdentifier().getIpv4Address().getValue());
133             }
134
135             if(value.getLocalAsNumber() == null || value.getLocalAsIdentifier() == null)
136                 return;
137
138             int retryCount = 0;
139             boolean retry = false;
140
141             do {
142                 try {
143                     //bgpManager.waitForBgpInit();
144                     bgpManager.startBgpService();
145                     retry = false;
146                 } catch (TException t) {
147                     retry = true;
148                     retryCount++;
149                 }
150             } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
151         }
152
153         @Override
154         protected void add(InstanceIdentifier<BgpRouter> identifier,
155                            BgpRouter value) {
156             LOG.info("Bgp Router added in DS - " + "key: " + identifier + ", value=" + value);
157             LOG.info("Bgp Router localASNumber:" + value.getLocalAsNumber());
158             LOG.info("Bgp Router localASIdentifier:" + value.getLocalAsIdentifier());
159
160             addBgpRouter(value);
161         }
162
163         private InstanceIdentifier<BgpRouter> getWildCardPath() {
164             return InstanceIdentifier.create(BgpRouter.class);
165         }
166
167         @Override
168         public void close() throws Exception {
169             if (listenerRegistration != null) {
170                 try {
171                     listenerRegistration.close();
172                 } catch (final Exception e) {
173                     LOG.error("Error when cleaning up DataChangeListener.", e);
174                 }
175                 listenerRegistration = null;
176             }
177             LOG.info("Bgp Router Manager Closed");
178         }
179
180     }
181     public class BgpNghbrCfgManager extends AbstractDataChangeListener<BgpNeighbors> implements AutoCloseable {
182
183         public BgpNghbrCfgManager(final DataBroker db) {
184             super(BgpNeighbors.class);
185             registerListener(db);
186         }
187
188         private void registerListener(final DataBroker db) {
189             try {
190                 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
191                     getWildCardPath(), BgpNghbrCfgManager.this, DataChangeScope.SUBTREE);
192             } catch (final Exception e) {
193                 LOG.error("BGP Neighbor DataChange listener registration fail!", e);
194                 throw new IllegalStateException("BGP Neighbor registration Listener failed.", e);
195             }
196         }
197
198         private synchronized void removeBgpNeighbors(BgpNeighbors del) {
199             List<BgpNeighbor> bgpNeighborList = del.getBgpNeighbor();
200             BgpNeighbor gateway = bgpNeighborList.get(0);
201
202             if(gateway != null) {
203                 if ((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
204                     IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress) gateway.getPeerAddressType()).getIpAddress();
205                     LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
206                     bgpConfiguration.setNeighbourIp("");
207                     bgpConfiguration.setNeighbourAsNum(0);
208
209                     int retryCount = 0;
210                     boolean retry = false;
211
212                     do {
213                         try {
214                             bgpManager.deleteNeighbor(neighborIPAddr.getIpv4Address().getValue());
215                             retry = false;
216                         } catch (TException t) {
217                             retry = true;
218                             retryCount++;
219                         }
220                     } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
221
222                 }
223             }
224
225         }
226
227         @Override
228         protected void remove(InstanceIdentifier<BgpNeighbors> identifier,
229                               BgpNeighbors del) {
230
231             LOG.info("Bgp Neighbors deleted in DS - " + "key: " + identifier + ", value=" + del);
232             removeBgpNeighbors(del);
233         }
234
235         private synchronized void updateBgpNeighbors(BgpNeighbors original, BgpNeighbors update) {
236             List<BgpNeighbor> bgpNeighborList = update.getBgpNeighbor();
237
238             //We will always consider the first element of this list, since there can be just one DC Gateway
239             BgpNeighbor gateway = bgpNeighborList.get(0);
240
241             if(gateway != null) {
242                 if(gateway.getAsNumber() != null) {
243                     LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
244                     if(bgpConfiguration.getNeighbourAsNum() != gateway.getAsNumber()) {
245                         bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
246                         bgpConfiguration.setConfigUpdated();
247                     }
248                 }
249                 if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
250                     IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
251                     LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
252                     if(bgpConfiguration.getNeighbourIp() != neighborIPAddr.getIpv4Address().getValue()) {
253                         bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
254                         bgpConfiguration.setConfigUpdated();
255                     }
256
257                 }
258             }
259             if(bgpConfiguration.isConfigUpdated()) {
260                 //delete old neighbor
261                 BgpNeighbor old = original.getBgpNeighbor().get(0);
262                 IpAddress oldIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)old.getPeerAddressType()).getIpAddress();
263                 int retryCount = 0;
264                 boolean retry = false;
265                 do {
266                     try {
267                         bgpManager.deleteNeighbor(oldIPAddr.getIpv4Address().getValue());
268                         retry = false;
269                     } catch (TException t) {
270                         retry = true;
271                         retryCount++;
272                     }
273                 } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
274
275                 //add the newly configured neighbor
276                 retryCount = 0;
277                 retry = false;
278                 do {
279                     try {
280                         bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
281                         retry = false;
282                     } catch (TException t) {
283                         retry = true;
284                         retryCount++;
285                     }
286                 } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
287             }
288         }
289
290         @Override
291         protected void update(InstanceIdentifier<BgpNeighbors> identifier,
292                               BgpNeighbors original, BgpNeighbors update) {
293
294             LOG.info("Bgp Neighbors Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + update);
295
296             updateBgpNeighbors(original, update);
297
298         }
299
300         private synchronized void addBgpNeighbors(BgpNeighbors value) {
301             List<BgpNeighbor> bgpNeighborList = value.getBgpNeighbor();
302
303             //We will always consider the first element of this list, since there can be just one DC Gateway
304             BgpNeighbor gateway = bgpNeighborList.get(0);
305
306             if(gateway != null) {
307                 if(gateway.getAsNumber() != null) {
308                     LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
309                     bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
310                 }
311                 if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
312                     IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
313                     LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
314                     bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
315
316                 }
317                 if(bgpConfiguration.getNeighbourAsNum() != 0  && bgpConfiguration.getNeighbourIp() != null) {
318                     int retryCount = 0;
319                     boolean retry = false;
320                     do {
321                         try {
322                             bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
323                             retry = false;
324                         } catch (TException t) {
325                             retry = true;
326                             retryCount++;
327                         }
328                     } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
329                 }
330             }
331
332         }
333
334         @Override
335         protected void add(InstanceIdentifier<BgpNeighbors> identifier,
336                            BgpNeighbors value) {
337             LOG.info("key: " + identifier + ", value=" + value);
338             LOG.info("Bgp Neighbor added in DS - " + "key: " + identifier + ", value=" + value);
339
340             addBgpNeighbors(value);
341         }
342
343         private InstanceIdentifier<?> getWildCardPath() {
344             return InstanceIdentifier.create(BgpNeighbors.class);
345         }
346
347         @Override
348         public void close() throws Exception {
349             if (listenerRegistration != null) {
350                 try {
351                     listenerRegistration.close();
352                 } catch (final Exception e) {
353                     LOG.error("Error when cleaning up DataChangeListener.", e);
354                 }
355                 listenerRegistration = null;
356             }
357             LOG.info("Bgp Neighbor Manager Closed");
358         }
359
360     }
361 }