blob: a53bf239457f73687ffef0a482a1705bb67625f4 [file] [log] [blame]
Shashikanth VH9ac1dee2015-11-21 00:15:51 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Shashikanth VH9ac1dee2015-11-21 00:15:51 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5 * the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 * specific language governing permissions and limitations under the License.
12 */
13package org.onosproject.bgp.controller.impl;
14
15import java.net.InetSocketAddress;
16import java.util.concurrent.Executors;
17import java.util.concurrent.ScheduledExecutorService;
18import java.util.concurrent.TimeUnit;
19
20import org.jboss.netty.bootstrap.ClientBootstrap;
21import org.jboss.netty.channel.ChannelFuture;
22import org.jboss.netty.channel.ChannelFutureListener;
23import org.jboss.netty.channel.ChannelPipelineFactory;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053024import org.onosproject.bgp.controller.BgpCfg;
25import org.onosproject.bgp.controller.BgpController;
26import org.onosproject.bgp.controller.BgpPeerCfg;
Shashikanth VH9ac1dee2015-11-21 00:15:51 +053027import org.onosproject.bgp.controller.BgpConnectPeer;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31/**
32 * Implements connection initiation to peer on peer configuration and manage channel using netty channel handler.
33 */
34public class BgpConnectPeerImpl implements BgpConnectPeer {
35 private static final Logger log = LoggerFactory.getLogger(BgpConnectPeerImpl.class);
36
37 private ScheduledExecutorService connectExecutor = null;
38 private final String peerHost;
39 private static final int RETRY_INTERVAL = 4;
40 private final int peerPort;
41 private int connectRetryCounter = 0;
42 private int connectRetryTime;
43 private ChannelPipelineFactory pfact;
44 private ClientBootstrap peerBootstrap;
mohamedrahil00f6f262016-11-24 20:20:41 +053045 public String getPeerHost() {
46 return peerHost;
47 }
48 public static int getRetryInterval() {
49 return RETRY_INTERVAL;
50 }
51
52 @Override
53 public int getPeerPort() {
54 return peerPort;
55 }
56 @Override
57 public int getConnectRetryCounter() {
58 return connectRetryCounter;
59 }
60
61 public void setConnectRetryCounter(int connectRetryCounter) {
62 this.connectRetryCounter = connectRetryCounter;
63 }
64
65 public void setConnectRetryTime(int connectRetryTime) {
66 this.connectRetryTime = connectRetryTime;
67 }
68
69 public BgpCfg getBgpconfig() {
70 return bgpconfig;
71 }
72
73 public void setBgpconfig(BgpCfg bgpconfig) {
74 this.bgpconfig = bgpconfig;
75 }
76
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053077 private BgpCfg bgpconfig;
Shashikanth VH9ac1dee2015-11-21 00:15:51 +053078
79 /**
80 * Initialize timer and initiate pipeline factory.
81 *
82 * @param bgpController parent BGP controller
83 * @param remoteHost remote host to connect
84 * @param remotePort remote port to connect
85 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053086 public BgpConnectPeerImpl(BgpController bgpController, String remoteHost, int remotePort) {
Shashikanth VH9ac1dee2015-11-21 00:15:51 +053087
88 this.bgpconfig = bgpController.getConfig();
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053089 this.pfact = new BgpPipelineFactory(bgpController, false);
Shashikanth VH9ac1dee2015-11-21 00:15:51 +053090 this.peerBootstrap = Controller.peerBootstrap();
91 this.peerBootstrap.setPipelineFactory(pfact);
92 this.peerHost = remoteHost;
93 this.peerPort = remotePort;
94 this.connectRetryTime = 0;
95 }
96
97 @Override
98 public void disconnectPeer() {
99 if (connectExecutor != null) {
100 connectExecutor.shutdown();
101 connectExecutor = null;
102 }
103 }
104
105 @Override
106 public void connectPeer() {
107 scheduleConnectionRetry(this.connectRetryTime);
108 }
109
110 /**
111 * Retry connection with exponential back-off mechanism.
112 *
113 * @param retryDelay retry delay
114 */
115 private void scheduleConnectionRetry(long retryDelay) {
116 if (this.connectExecutor == null) {
117 this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
118 }
119 this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
120 }
121
122 /**
123 * Implements BGP connection and manages connection to peer with back-off mechanism in case of failure.
124 */
125 class ConnectionRetry implements Runnable {
126 @Override
127 public void run() {
128 log.debug("Connect to peer {}", peerHost);
129
130 InetSocketAddress connectToSocket = new InetSocketAddress(peerHost, peerPort);
131
132 try {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530133 bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.CONNECT);
Shashikanth VH9ac1dee2015-11-21 00:15:51 +0530134 peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
135 @Override
136 public void operationComplete(ChannelFuture future) throws Exception {
137 if (!future.isSuccess()) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530138 bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.ACTIVE);
Shashikanth VH9ac1dee2015-11-21 00:15:51 +0530139 connectRetryCounter++;
140 log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
141 peerHost);
142 /*
143 * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
144 * mins.
145 */
146 if (connectRetryTime < RETRY_INTERVAL) {
147 connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
148 }
149 scheduleConnectionRetry(connectRetryTime);
150 } else {
151
152 connectRetryCounter++;
mohamedrahil00f6f262016-11-24 20:20:41 +0530153 log.debug("Connected to remote host {}, Connect Counter {}", peerHost, connectRetryCounter);
Shashikanth VH9ac1dee2015-11-21 00:15:51 +0530154 disconnectPeer();
155 return;
156 }
157 }
158 });
159 } catch (Exception e) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530160 log.debug("Connect peer exception : " + e.toString());
Shashikanth VH9ac1dee2015-11-21 00:15:51 +0530161 disconnectPeer();
162 }
163 }
164 }
165}