Opening update server port with specified IP address (if configured)
[netvirt.git] / bgpmanager / impl / src / main / java / org / opendaylight / netvirt / bgpmanager / thrift / server / BgpThriftService.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
9 package org.opendaylight.netvirt.bgpmanager.thrift.server;
10
11 import com.google.common.util.concurrent.ThreadFactoryBuilder;
12 import java.net.InetSocketAddress;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.Executors;
15 import java.util.concurrent.Future;
16 import java.util.concurrent.ThreadFactory;
17 import org.apache.thrift.protocol.TBinaryProtocol;
18 import org.apache.thrift.protocol.TProtocol;
19 import org.apache.thrift.server.ServerContext;
20 import org.apache.thrift.server.TServer;
21 import org.apache.thrift.server.TServerEventHandler;
22 import org.apache.thrift.server.TThreadedSelectorServer;
23 import org.apache.thrift.transport.TFramedTransport;
24 import org.apache.thrift.transport.TNonblockingServerSocket;
25 import org.apache.thrift.transport.TNonblockingServerTransport;
26 import org.apache.thrift.transport.TTransport;
27 import org.apache.thrift.transport.TTransportException;
28 import org.opendaylight.netvirt.bgpmanager.BgpConfigurationManager;
29 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
30 import org.opendaylight.netvirt.bgpmanager.thrift.gen.BgpUpdater;
31 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
32 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class BgpThriftService {
37     private static final Logger LOG = LoggerFactory.getLogger(BgpThriftService.class);
38
39     private final InetSocketAddress bgpThriftServerSocketAddr;
40     private final IBgpManager bgpManager;
41     private final BgpConfigurationManager bgpConfigManager;
42     private volatile TServer server;
43     private static ThreadFactory thriftServerThreadFactory = new ThreadFactoryBuilder()
44             .setNameFormat("bgp-thrift-server-%d").build();
45     private static ExecutorService threadPool = Executors.newFixedThreadPool(1, thriftServerThreadFactory);
46     private volatile Future ft;
47
48     public BgpThriftService(InetSocketAddress bgpThriftServerSocketAddr, IBgpManager bm,
49                             BgpConfigurationManager bgpConfigManager) {
50         this.bgpThriftServerSocketAddr = bgpThriftServerSocketAddr;
51         bgpManager = bm;
52         this.bgpConfigManager = bgpConfigManager;
53     }
54
55     public static class ThriftClientContext implements ServerContext {
56         TProtocol in;
57
58         public ThriftClientContext(TProtocol in) {
59             this.in = in;
60         }
61
62         public TProtocol getIn() {
63             return in;
64         }
65     }
66
67     public class BgpUpdateServer implements Runnable, BgpUpdater.Iface {
68
69         ThriftClientContext oldThriftClientContext;
70
71         BgpUpdateServer() {
72         }
73
74         @Override
75         public void run() {
76             try {
77                 BgpUpdater.Processor processor = new BgpUpdater.Processor(this);
78
79                 TNonblockingServerTransport trans = new TNonblockingServerSocket(bgpThriftServerSocketAddr);
80                 TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(trans);
81                 args.transportFactory(new TFramedTransport.Factory());
82                 args.protocolFactory(new TBinaryProtocol.Factory());
83                 args.processor(processor);
84                 args.selectorThreads(1);
85                 args.workerThreads(1);
86                 server = new TThreadedSelectorServer(args);
87                 server.setServerEventHandler(new TServerEventHandler() {
88                     @Override
89                     public void preServe() {
90                         LOG.info("Bgp thrift server pre serve event");
91                     }
92
93                     @Override
94                     public ServerContext createContext(TProtocol input, TProtocol output) {
95                         LOG.info("Bgp thrift server create context event");
96                         synchronized (this) {
97                             if (oldThriftClientContext != null) {
98                                 LOG.info("Bgp thrift server closing old context");
99                                 oldThriftClientContext.getIn().getTransport().close();
100                             } else {
101                                 LOG.info("Bgp thrift server old context is null nothing to close");
102                             }
103                             oldThriftClientContext = new ThriftClientContext(input);
104                             return oldThriftClientContext;
105                         }
106                     }
107
108                     @Override
109                     public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output) {
110                         LOG.info("Bgp thrift server delete context event");
111                         if (oldThriftClientContext == serverContext) {
112                             LOG.info("Bgp thrift server cleanup old context");
113                             oldThriftClientContext = null;
114                         } else {
115                             LOG.info("Bgp thrift server cleanup context");
116                         }
117                     }
118
119                     @Override
120                     public void processContext(ServerContext serverContext, TTransport inputTransport,
121                             TTransport outputTransport) {
122                         LOG.trace("Bgp thrift server process context event");
123                     }
124                 });
125                 server.serve();
126             } catch (TTransportException e) {
127                 LOG.error("Exception in BGP Updater server", e);
128             }
129         }
130
131         @Override
132         @SuppressWarnings("checkstyle:IllegalCatch")
133         public void onUpdatePushRoute(protocol_type protocolType,
134                                       String rd,
135                                       String prefix,
136                                       int plen,
137                                       String nexthop,
138                                       int ethtag,
139                                       String esi,
140                                       String macaddress,
141                                       int l3label,
142                                       int l2label,
143                                       String routermac,
144                                       af_afi afi) {
145             LOG.debug("Update on push route : rd {} prefix {} plen {}", rd, prefix, plen);
146
147             // l2label is ignored even in case of RT5. only l3label considered
148             bgpConfigManager.onUpdatePushRoute(
149                     protocolType,
150                     rd,
151                     prefix,
152                     plen,
153                     nexthop,
154                     macaddress,
155                     l3label,
156                     l2label,
157                     routermac,
158                     afi);
159         }
160
161         @Override
162         public void onUpdateWithdrawRoute(protocol_type protocolType,
163                                           String rd,
164                                           String prefix,
165                                           int plen,
166                                           String nexthop,
167                                           int ethtag,
168                                           String esi,
169                                           String macaddress,
170                                           int l3label,
171                                           int l2label,
172                                           af_afi afi) {
173             LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
174             bgpConfigManager.onUpdateWithdrawRoute(
175                     protocolType,
176                     rd,
177                     prefix,
178                     plen,
179                     nexthop,
180                     macaddress);
181         }
182
183         @Override
184         public void onStartConfigResyncNotification() {
185             LOG.info("BGP (re)started");
186             bgpManager.setQbgprestartTS(System.currentTimeMillis());
187             bgpManager.bgpRestarted();
188         }
189
190         @Override
191         public void onNotificationSendEvent(String prefix, byte errCode,
192                 byte errSubcode) {
193             bgpManager.sendNotificationEvent((int) errCode, (int) errSubcode);
194         }
195     }
196
197     public synchronized void start() {
198         ft = threadPool.submit(new BgpUpdateServer());
199     }
200
201     public boolean isBgpThriftServiceStarted() {
202         return ((ft == null) ? false : true);
203     }
204
205     public synchronized void stop() {
206         if (server != null) {
207             server.stop();
208             server = null;
209         }
210         if (ft != null && !ft.isDone()) {
211             ft.cancel(true);
212         }
213         ft = null;
214     }
215 }