Shashikanth VH

[ONOS-2592] BGP peer connection initiation on peer configuration.

Change-Id: I1892c9b9f702a4a233790a69f4289e5f4edb0ec3
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
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 + */
13 +package org.onosproject.bgp.controller.impl;
14 +
15 +import java.net.InetSocketAddress;
16 +import java.util.concurrent.Executors;
17 +import java.util.concurrent.ScheduledExecutorService;
18 +import java.util.concurrent.TimeUnit;
19 +
20 +import org.jboss.netty.bootstrap.ClientBootstrap;
21 +import org.jboss.netty.channel.ChannelFuture;
22 +import org.jboss.netty.channel.ChannelFutureListener;
23 +import org.jboss.netty.channel.ChannelPipelineFactory;
24 +import org.onosproject.bgp.controller.BGPCfg;
25 +import org.onosproject.bgp.controller.BGPController;
26 +import org.onosproject.bgp.controller.BGPPeerCfg;
27 +import org.onosproject.bgp.controller.BgpConnectPeer;
28 +import org.slf4j.Logger;
29 +import org.slf4j.LoggerFactory;
30 +
31 +/**
32 + * Implements connection initiation to peer on peer configuration and manage channel using netty channel handler.
33 + */
34 +public 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;
45 + private BGPCfg bgpconfig;
46 +
47 + /**
48 + * Initialize timer and initiate pipeline factory.
49 + *
50 + * @param bgpController parent BGP controller
51 + * @param remoteHost remote host to connect
52 + * @param remotePort remote port to connect
53 + */
54 + public BgpConnectPeerImpl(BGPController bgpController, String remoteHost, int remotePort) {
55 +
56 + this.bgpconfig = bgpController.getConfig();
57 + this.pfact = new BGPPipelineFactory(bgpController, false);
58 + this.peerBootstrap = Controller.peerBootstrap();
59 + this.peerBootstrap.setPipelineFactory(pfact);
60 + this.peerHost = remoteHost;
61 + this.peerPort = remotePort;
62 + this.connectRetryTime = 0;
63 + }
64 +
65 + @Override
66 + public void disconnectPeer() {
67 + if (connectExecutor != null) {
68 + connectExecutor.shutdown();
69 + connectExecutor = null;
70 + }
71 + }
72 +
73 + @Override
74 + public void connectPeer() {
75 + scheduleConnectionRetry(this.connectRetryTime);
76 + }
77 +
78 + /**
79 + * Retry connection with exponential back-off mechanism.
80 + *
81 + * @param retryDelay retry delay
82 + */
83 + private void scheduleConnectionRetry(long retryDelay) {
84 + if (this.connectExecutor == null) {
85 + this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
86 + }
87 + this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
88 + }
89 +
90 + /**
91 + * Implements BGP connection and manages connection to peer with back-off mechanism in case of failure.
92 + */
93 + class ConnectionRetry implements Runnable {
94 + @Override
95 + public void run() {
96 + log.debug("Connect to peer {}", peerHost);
97 +
98 + InetSocketAddress connectToSocket = new InetSocketAddress(peerHost, peerPort);
99 +
100 + try {
101 + bgpconfig.setPeerConnState(peerHost, BGPPeerCfg.State.CONNECT);
102 + peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
103 + @Override
104 + public void operationComplete(ChannelFuture future) throws Exception {
105 + if (!future.isSuccess()) {
106 + bgpconfig.setPeerConnState(peerHost, BGPPeerCfg.State.ACTIVE);
107 + connectRetryCounter++;
108 + log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
109 + peerHost);
110 + /*
111 + * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
112 + * mins.
113 + */
114 + if (connectRetryTime < RETRY_INTERVAL) {
115 + connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
116 + }
117 + scheduleConnectionRetry(connectRetryTime);
118 + } else {
119 +
120 + connectRetryCounter++;
121 + log.info("Connected to remote host {}, Connect Counter {}", peerHost, connectRetryCounter);
122 + disconnectPeer();
123 + return;
124 + }
125 + }
126 + });
127 + } catch (Exception e) {
128 + log.info("Connect peer exception : " + e.toString());
129 + disconnectPeer();
130 + }
131 + }
132 + }
133 +}