BUG-4672: BMP client reconnection not working 51/30251/2
authorMilos Fabian <milfabia@cisco.com>
Wed, 25 Nov 2015 14:06:47 +0000 (15:06 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 26 Nov 2015 21:22:11 +0000 (21:22 +0000)
-get rid of protocol-framework's reconnect strategy
-introduce simple initial reconnection as suggested in
https://tools.ietf.org/html/draft-ietf-grow-bmp-15#section-3.2
-BMP session should go to "up" state once the connection is established (channel is active),
introduced "IDLE" state of a BMP session
-added commented sample of active client (monired router) configuration

Introduces "IDLE" state of a BMP session,
session goes up once the channel is active.

Change-Id: Ibd78fe708162a710fdcc20c614cc1d9c1be6eb95
Signed-off-by: Milos Fabian <milfabia@cisco.com>
14 files changed:
bgp/bmp-impl/pom.xml
bgp/bmp-impl/src/main/java/org/opendaylight/controller/config/yang/bmp/impl/BmpDispatcherImplModule.java
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/BmpDispatcherImpl.java
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/app/BmpMonitoringStationImpl.java
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/session/BmpSessionImpl.java
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/session/DefaultBmpSessionFactory.java
bgp/bmp-impl/src/main/yang/odl-bmp-impl-cfg.yang
bgp/bmp-impl/src/test/java/org/opendaylight/controller/config/yang/bmp/impl/BmpDispatcherImplModuleTest.java
bgp/bmp-impl/src/test/java/org/opendaylight/controller/config/yang/bmp/impl/BmpMonitorImplModuleTest.java
bgp/bmp-impl/src/test/java/org/opendaylight/protocol/bmp/impl/app/BmpMonitorImplTest.java
bgp/bmp-impl/src/test/java/org/opendaylight/protocol/bmp/impl/session/BmpDispatcherImplTest.java
bgp/bmp-impl/src/test/java/org/opendaylight/protocol/bmp/impl/session/BmpSessionImplTest.java
bgp/controller-config/src/main/resources/initial/32-bmp.xml
bgp/controller-config/src/main/resources/initial/42-bmp-example.xml

index 5261d21f08247bc47e48f8048b2f8616f227de77..6251033c7af961df50a94432902db4282a12e29b 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-inet</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>protocol-framework</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.tcpmd5</groupId>
             <artifactId>tcpmd5-api</artifactId>
index 82eba26aa2a44d763d4a37f8551d07df089a20af..d5095184658b61207b0bf314bf61ac3a43635015 100644 (file)
@@ -15,11 +15,11 @@ import org.opendaylight.tcpmd5.netty.MD5ChannelFactory;
 import org.opendaylight.tcpmd5.netty.MD5ServerChannelFactory;
 
 public class BmpDispatcherImplModule extends org.opendaylight.controller.config.yang.bmp.impl.AbstractBmpDispatcherImplModule {
-    public BmpDispatcherImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public BmpDispatcherImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public BmpDispatcherImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.bmp.impl.BmpDispatcherImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public BmpDispatcherImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.bmp.impl.BmpDispatcherImplModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -33,8 +33,7 @@ public class BmpDispatcherImplModule extends org.opendaylight.controller.config.
         return new BmpDispatcherImpl(getBossGroupDependency(), getWorkerGroupDependency(),
                 getBmpExtensionsDependency().getBmpMessageRegistry(), new DefaultBmpSessionFactory(),
                 Optional.<MD5ChannelFactory<?>>fromNullable(getMd5ChannelFactoryDependency()),
-                Optional.<MD5ServerChannelFactory<?>>fromNullable(getMd5ServerChannelFactoryDependency()),
-                getBmpReconnectStrategyFactoryDependency());
+                Optional.<MD5ServerChannelFactory<?>>fromNullable(getMd5ServerChannelFactoryDependency()));
     }
 
 }
index 284cde330845af47d124bddeb2c2c7937f0e7a94..13a89003ec74b6e73d0334daf8f72acad9d9157b 100644 (file)
@@ -18,17 +18,17 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoop;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
 import org.opendaylight.protocol.bmp.api.BmpSessionFactory;
 import org.opendaylight.protocol.bmp.api.BmpSessionListenerFactory;
 import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
 import org.opendaylight.tcpmd5.api.KeyMapping;
 import org.opendaylight.tcpmd5.netty.MD5ChannelFactory;
 import org.opendaylight.tcpmd5.netty.MD5ChannelOption;
@@ -40,33 +40,34 @@ import org.slf4j.LoggerFactory;
 public class BmpDispatcherImpl implements BmpDispatcher {
 
     private static final Logger LOG = LoggerFactory.getLogger(BmpDispatcherImpl.class);
+
     private static final int MAX_CONNECTIONS_COUNT = 128;
 
+    private static final int CONNECT_TIMEOUT = 5000;
+    private static final int INITIAL_BACKOFF = 30_000;
+    private static final int MAXIMUM_BACKOFF = 720_000;
+
     private final BmpHandlerFactory hf;
     private final EventLoopGroup bossGroup;
     private final EventLoopGroup workerGroup;
     private final BmpSessionFactory sessionFactory;
     private final Optional<MD5ServerChannelFactory<?>> md5ServerChFactory;
     private final Optional<MD5ChannelFactory<?>> md5ChannelFactory;
-    private final ReconnectStrategy strategy;
 
     public BmpDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
-            final BmpMessageRegistry registry, final BmpSessionFactory sessionFactory,
-            final ReconnectStrategyFactory brsf) {
-        this(bossGroup, workerGroup, registry, sessionFactory, Optional.<MD5ChannelFactory<?>>absent(), Optional.<MD5ServerChannelFactory<?>>absent(), brsf);
+            final BmpMessageRegistry registry, final BmpSessionFactory sessionFactory) {
+        this(bossGroup, workerGroup, registry, sessionFactory, Optional.<MD5ChannelFactory<?>>absent(), Optional.<MD5ServerChannelFactory<?>>absent());
     }
 
     public BmpDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
             final BmpMessageRegistry registry, final BmpSessionFactory sessionFactory,
-            final Optional<MD5ChannelFactory<?>> cf, final Optional<MD5ServerChannelFactory<?>> scf,
-            final ReconnectStrategyFactory brsf) {
+            final Optional<MD5ChannelFactory<?>> cf, final Optional<MD5ServerChannelFactory<?>> scf) {
         this.bossGroup = Preconditions.checkNotNull(bossGroup);
         this.workerGroup = Preconditions.checkNotNull(workerGroup);
         this.hf = new BmpHandlerFactory(Preconditions.checkNotNull(registry));
         this.sessionFactory = Preconditions.checkNotNull(sessionFactory);
         this.md5ServerChFactory = Preconditions.checkNotNull(scf);
         this.md5ChannelFactory  = Preconditions.checkNotNull(cf);
-        this.strategy = Preconditions.checkNotNull(brsf).createReconnectStrategy();
     }
 
     @Override
@@ -85,6 +86,7 @@ public class BmpDispatcherImpl implements BmpDispatcher {
             b.channel(NioSocketChannel.class);
         }
         b.option(ChannelOption.SO_KEEPALIVE, true);
+        b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT);
         b.group(workergroup);
 
         b.handler(new ChannelInitializer<NioSocketChannel>() {
@@ -95,8 +97,9 @@ public class BmpDispatcherImpl implements BmpDispatcher {
             }
         });
 
-        ChannelFuture channelPromise = b.connect(address);
-        channelPromise.addListener(new BmpDispatcherImpl.BootstrapListener());
+        b.remoteAddress(address);
+        final ChannelFuture channelPromise = b.connect();
+        channelPromise.addListener(new BmpDispatcherImpl.BootstrapListener(b, address));
         return channelPromise;
     }
 
@@ -138,16 +141,40 @@ public class BmpDispatcherImpl implements BmpDispatcher {
     }
 
     private class BootstrapListener implements ChannelFutureListener {
+
+        private final Bootstrap bootstrap;
+
+        private long delay;
+
+        private final InetSocketAddress address;
+
+        public BootstrapListener(final Bootstrap bootstrap, final InetSocketAddress address) {
+            this.bootstrap = bootstrap;
+            this.address = address;
+            this.delay = INITIAL_BACKOFF;
+        }
+
         @Override
         public void operationComplete(final ChannelFuture cf) throws Exception {
-
             if (cf.isCancelled()) {
-                LOG.debug("connection {} cancelled!", cf);
+                LOG.debug("Connection {} cancelled!", cf);
             } else if (cf.isSuccess()) {
-                LOG.debug("connection {} succeeded!", cf);
+                LOG.debug("Connection {} succeeded!", cf);
             } else {
-                LOG.debug("connection attmpt {} failed! Reconnecting...", cf);
-                BmpDispatcherImpl.this.strategy.scheduleReconnect(cf.cause());
+                if (delay > MAXIMUM_BACKOFF) {
+                    LOG.warn("The time of maximum backoff has been exceeded. No further connection attempts with BMP router {}.", this.address);
+                    cf.cancel(false);
+                    return;
+                }
+                final EventLoop loop = cf.channel().eventLoop();
+                loop.schedule(new Runnable() {
+                    @Override
+                    public void run() {
+                        BootstrapListener.this.bootstrap.connect().addListener(BootstrapListener.this);
+                    }
+                }, this.delay, TimeUnit.MILLISECONDS);
+                LOG.info("The connection try to BMP router {} failed. Next reconnection attempt in {} milliseconds.", this.address, this.delay);
+                this.delay *= 2;
             }
         }
     }
index e4ce297deaac04a53eceb39d318a6b16f2f85d97..2bfeef1d6cb72627f26c1373bd44762344b0326f 100644 (file)
@@ -18,7 +18,6 @@ import io.netty.channel.ChannelFutureListener;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
 import org.opendaylight.controller.config.yang.bmp.impl.MonitoredRouter;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -58,7 +57,6 @@ public final class BmpMonitoringStationImpl implements BmpMonitoringStation {
     private final Channel channel;
     private final MonitorId monitorId;
     private final List<MonitoredRouter> monitoredRouters;
-    private final List<Channel> clientChannels;
 
     private BmpMonitoringStationImpl(final DOMDataBroker domDataBroker, final YangInstanceIdentifier yangMonitorId,
             final Channel channel, final RouterSessionManager sessionManager, final MonitorId monitorId,
@@ -69,7 +67,6 @@ public final class BmpMonitoringStationImpl implements BmpMonitoringStation {
         this.sessionManager = Preconditions.checkNotNull(sessionManager);
         this.monitorId = monitorId;
         this.monitoredRouters = mrs;
-        this.clientChannels = new CopyOnWriteArrayList<Channel>();
 
         createEmptyMonitor();
         LOG.info("BMP Monitoring station {} started", this.monitorId.getValue());
@@ -92,14 +89,9 @@ public final class BmpMonitoringStationImpl implements BmpMonitoringStation {
                         ret = new KeyMapping();
                         ret.put(addr, rfc2385KeyPassword.getValue().getBytes(Charsets.US_ASCII));
                     }
-                    try {
-                        this.clientChannels.add(dispatcher.createClient(
-                            Ipv4Util.toInetSocketAddress(mr.getAddress(), mr.getPort()),
-                            this.sessionManager, Optional.<KeyMapping>fromNullable(ret)).sync().channel());
-                    } catch (final InterruptedException ex) {
-                        LOG.error("failed to connect bmp client {}", mr);
-                    }
-                    ret.remove(addr);
+                    dispatcher.createClient(
+                        Ipv4Util.toInetSocketAddress(mr.getAddress(), mr.getPort()),
+                        this.sessionManager, Optional.<KeyMapping>fromNullable(ret));
                 }
             }
         }
@@ -159,10 +151,6 @@ public final class BmpMonitoringStationImpl implements BmpMonitoringStation {
             }
         }).await();
 
-        for (final Channel ch : BmpMonitoringStationImpl.this.clientChannels) {
-            ch.close().await();
-        }
-
         final DOMDataWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
         wTx.delete(LogicalDatastoreType.OPERATIONAL, this.yangMonitorId);
         wTx.submit().checkedGet();
index da83ac78c1d87cc7b188864959a3d7127da83c52..bdf6b77a130901be5e028b15004b191ff398ea00 100644 (file)
@@ -34,14 +34,13 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
 
     private final BmpSessionListener listener;
 
-    private final Channel channel;
+    private Channel channel;
 
-    private State state = State.UP;
+    private State state;
 
-    public BmpSessionImpl(@Nonnull final BmpSessionListener listener, @Nonnull final Channel channel) {
+    public BmpSessionImpl(@Nonnull final BmpSessionListener listener) {
         this.listener = Preconditions.checkNotNull(listener);
-        this.channel = Preconditions.checkNotNull(channel);
-        LOG.info("Session {} <-> {} started.", channel.localAddress(), channel.remoteAddress());
+        this.state = State.IDLE;
     }
 
     @Override
@@ -62,18 +61,25 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
     }
 
     @Override
-    public void handlerAdded(final ChannelHandlerContext ctx) {
-        this.sessionUp();
+    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
+        this.channel = ctx.channel();
+        sessionUp();
+        LOG.info("Session {} <-> {} started.", channel.localAddress(), channel.remoteAddress());
     }
 
     @Override
     public synchronized void close() {
         LOG.info("Closing session: {}", this);
-        this.channel.close();
+        if (this.channel != null) {
+            this.channel.close();
+            this.channel = null;
+            this.state = State.IDLE;
+        }
     }
 
     @Override
     public InetAddress getRemoteAddress() {
+        Preconditions.checkState(this.state != State.IDLE, "BMP Session %s is not active.", this);
         return ((InetSocketAddress) this.channel.remoteAddress()).getAddress();
     }
 
@@ -81,6 +87,7 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
     public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
         LOG.error("Exception caught in BMP Session.", cause);
         close();
+        this.listener.onSessionDown(this, new IllegalStateException(cause));
     }
 
     @Override
@@ -100,6 +107,7 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
                 this.state = State.INITIATED;
                 this.listener.onMessage(this, msg);
             } else {
+                LOG.warn("Unexpected message recieved {}, expected was BMP Initiation Message. Closing session.", msg);
                 close();
             }
             break;
@@ -111,6 +119,9 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
                 this.listener.onMessage(this, msg);
             }
             break;
+        case IDLE:
+            new IllegalStateException("Recieved message" + msg + "while BMP Session" + this + "was not active.");
+            break;
         default:
             break;
         }
@@ -129,10 +140,15 @@ public final class BmpSessionImpl extends SimpleChannelInboundHandler<Notificati
     }
 
     private void sessionUp() {
+        this.state = State.UP;
         this.listener.onSessionUp(this);
     }
 
     protected enum State {
+        /**
+         * Waiting for connection to be established.
+         */
+        IDLE,
         /**
          * The connection has been established. Waiting for Initiation Message.
          */
index 4f04ff7a14c1dd74ff35b83a8b7f359662fe1eaf..ae17eeb0a320281793e652fc87baf42116590d6a 100644 (file)
@@ -17,7 +17,7 @@ public class DefaultBmpSessionFactory implements BmpSessionFactory {
 
     @Override
     public BmpSession getSession(final Channel channel, final BmpSessionListenerFactory sessionListenerFactory) {
-        return new BmpSessionImpl(sessionListenerFactory.getSessionListener(), channel);
+        return new BmpSessionImpl(sessionListenerFactory.getSessionListener());
     }
 
 }
index 10e6fe3431c560c02f575c8e3586d728ba33dae4..b5c7edc061d5c8d916d7c8cb4cc1de64ce1528cb 100644 (file)
@@ -9,7 +9,6 @@ module odl-bmp-impl-cfg {
     import odl-bgp-parser-spi-cfg { prefix bgp-spi; revision-date 2013-11-15; }
     import odl-tcpmd5-netty-cfg { prefix tcpmd5-netty; revision-date 2014-04-27; }
     import odl-tcpmd5-cfg { prefix tcpmd5; revision-date 2014-04-27; }
-    import protocol-framework { prefix pf; revision-date 2014-03-13; }
     import netty { prefix netty; revision-date 2013-11-19; }
     import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
     import opendaylight-md-sal-binding {prefix mdsb; revision-date 2013-10-28; }
@@ -119,15 +118,6 @@ module odl-bmp-impl-cfg {
                     }
                 }
             }
-
-            container bmp-reconnect-strategy-factory {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity pf:reconnect-strategy-factory;
-                    }
-                }
-            }
         }
     }
 
index d739a47fd9a535bccbb1b15bc465cb9b3185b2a2..bf2892fb7a6b136d77c89961cd2386d2bf89d2d5 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.bmp.impl;
 
-import java.math.BigDecimal;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 import org.junit.Before;
@@ -21,8 +20,6 @@ import org.opendaylight.controller.config.yang.bmp.spi.SimpleBmpExtensionProvide
 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
 import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
 import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleMXBean;
-import org.opendaylight.controller.config.yang.protocol.framework.TimedReconnectStrategyFactoryModuleFactory;
-import org.opendaylight.controller.config.yang.protocol.framework.TimedReconnectStrategyFactoryModuleMXBean;
 
 public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
     private static final String INSTANCE_NAME = "bmp-message-fct";
@@ -31,14 +28,12 @@ public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
     private static final String BMP_EXTENSION_INSTANCE_NAME = "bmp-extension-impl";
     private static final String BOSS_TG_INSTANCE_NAME = "boss-threadgroup-impl";
     private static final String WORKER_TG_INSTANCE_NAME = "worker-threadgroup-impl";
-    private static final String RECONNECT_STRATEGY_NAME = "timed-reconnect-strategy-factory";
 
     @Before
     public void setUp() throws Exception {
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext,
             new BmpDispatcherImplModuleFactory(),
             new NettyThreadgroupModuleFactory(),
-            new TimedReconnectStrategyFactoryModuleFactory(),
             new GlobalEventExecutorModuleFactory(),
             new SimpleBmpExtensionProviderContextModuleFactory()));
     }
@@ -47,7 +42,7 @@ public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
     public void testCreateBean() throws Exception {
         final CommitStatus status = createInstance();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 6, 0, 0);
+        assertStatus(status, 4, 0, 0);
     }
 
     @Test
@@ -57,7 +52,7 @@ public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
         assertBeanCount(1, FACTORY_NAME);
         final CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 6);
+        assertStatus(status, 0, 0, 4);
     }
 
     private CommitStatus createInstance() throws Exception {
@@ -72,7 +67,6 @@ public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
         mxBean.setBossGroup(createThreadgroupInstance(transaction, BOSS_TG_INSTANCE_NAME, 10));
         mxBean.setWorkerGroup(createThreadgroupInstance(transaction, WORKER_TG_INSTANCE_NAME, 10));
         mxBean.setBmpExtensions(createBmpExtensionsInstance(transaction));
-        mxBean.setBmpReconnectStrategyFactory(createBmpReconnectStrategyFactoryInstance(transaction));
         return nameCreated;
     }
 
@@ -90,22 +84,4 @@ public class BmpDispatcherImplModuleTest extends AbstractConfigTest {
         transaction.newMXBeanProxy(nameCreated, SimpleBmpExtensionProviderContextModuleMXBean.class);
         return nameCreated;
     }
-
-    private static ObjectName createGlobalEventExecutor(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
-        final ObjectName nameCreated = transaction.createModule(GlobalEventExecutorModuleFactory.NAME, GlobalEventExecutorModuleFactory.SINGLETON_NAME);
-        return nameCreated;
-    }
-
-    private static ObjectName createBmpReconnectStrategyFactoryInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
-        final ObjectName nameCreated = transaction.createModule(TimedReconnectStrategyFactoryModuleFactory.NAME, RECONNECT_STRATEGY_NAME);
-        final TimedReconnectStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, TimedReconnectStrategyFactoryModuleMXBean.class);
-        mxBean.setConnectTime(720000);
-        mxBean.setDeadline(720000L);
-        mxBean.setMaxAttempts(10L);
-        mxBean.setMaxSleep(30000L);
-        mxBean.setMinSleep(30000L);
-        mxBean.setSleepFactor(new BigDecimal(1.0));
-        mxBean.setTimedReconnectExecutor(createGlobalEventExecutor(transaction));
-        return nameCreated;
-    }
 }
index 354c0cdc4866f3078543329a87a724389653a42b..74063949190ded87b534edaebcc8d0e0402e7758 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.config.yang.bmp.impl;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
+
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.io.ByteSource;
@@ -195,7 +196,7 @@ public class BmpMonitorImplModuleTest extends AbstractConfigTest {
     public void testCreateBean() throws Exception {
         final CommitStatus status = createInstance();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 11, 0, 0);
+        assertStatus(status, 9, 0, 0);
     }
 
     @Test
@@ -205,7 +206,7 @@ public class BmpMonitorImplModuleTest extends AbstractConfigTest {
         assertBeanCount(1, FACTORY_NAME);
         final CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 11);
+        assertStatus(status, 0, 0, 9);
     }
 
     private CommitStatus createInstance() throws Exception {
index 94af4ac01db1a50309bd9c64894bb7c6de6c31d1..1d41ea749e2eaa184433c3dbbaf1bb038a9e5410 100644 (file)
@@ -25,7 +25,6 @@ import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
-import io.netty.util.concurrent.GlobalEventExecutor;;
 import java.net.InetSocketAddress;
 import java.util.List;
 import javassist.ClassPool;
@@ -57,8 +56,6 @@ import org.opendaylight.protocol.bmp.impl.spi.BmpMonitoringStation;
 import org.opendaylight.protocol.bmp.impl.test.TestUtil;
 import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
 import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpExtensionProviderContext;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
 import org.opendaylight.tcpmd5.api.KeyAccess;
 import org.opendaylight.tcpmd5.api.KeyAccessFactory;
 import org.opendaylight.tcpmd5.api.KeyMapping;
@@ -110,12 +107,9 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class BmpMonitorImplTest extends AbstractDataBrokerTest {
 
-    private static final Logger LOG = LoggerFactory.getLogger(BmpMonitorImplTest.class);
     private static final int PORT = 12345;
     private static final String LOCAL_ADDRESS = "127.0.0.10";
     private static final InetSocketAddress CLIENT_REMOTE = new InetSocketAddress("127.0.0.10", PORT);
@@ -125,10 +119,6 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
     private static final RouterId ROUTER_ID = new RouterId(new IpAddress(new Ipv4Address(LOCAL_ADDRESS)));
     private static final PeerId PEER_ID = new PeerId(PEER1.getValue());
     private static final String MD5_PASSWORD = "abcdef";
-    private static final int CONNECT_TIME = 720000;
-    private static final int MAX_SLEEP = 30000;
-    private static final int MIN_SLEEP = 30000;
-    private static final int SLEEP_FACTOR = 1;
 
     private BindingToNormalizedNodeCodec mappingService;
     private RIBActivator ribActivator;
@@ -139,7 +129,6 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
     private BmpMessageRegistry msgRegistry;
     private MD5NioServerSocketChannelFactory scfServerMd5;
     private MD5NioSocketChannelFactory scfMd5;
-    private ReconnectStrategyFactory brsf;
     private List<MonitoredRouter> mrs;
 
     @Mock private KeyAccess mockKeyAccess;
@@ -170,7 +159,6 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
 
         this.scfServerMd5 = new MD5NioServerSocketChannelFactory(this.kaf);
         this.scfMd5 = new MD5NioSocketChannelFactory(this.kaf);
-        this.brsf = new ReconnectStrategyFctImpl();
 
         this.ribActivator = new RIBActivator();
         final RIBExtensionProviderContext ribExtension = new SimpleRIBExtensionProviderContext();
@@ -186,7 +174,7 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
 
         this.dispatcher = new BmpDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(),
                 ctx.getBmpMessageRegistry(), new DefaultBmpSessionFactory(), Optional.<MD5ChannelFactory<?>>of(this.scfMd5),
-                Optional.<MD5ServerChannelFactory<?>>of(this.scfServerMd5), this.brsf);
+                Optional.<MD5ServerChannelFactory<?>>of(this.scfServerMd5));
 
         this.bmpApp = BmpMonitoringStationImpl.createBmpMonitorInstance(ribExtension, this.dispatcher, getDomBroker(),
                 MONITOR_ID, new InetSocketAddress(InetAddresses.forString("127.0.0.10"), PORT), Optional.of(keys),
@@ -294,7 +282,7 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
             assertEquals(tlvs.getPerAfiSafiLocRibTlv().getCount().toString(), peerStats.getPerAfiSafiLocRibRoutes().getAfiSafi().get(0).getCount().toString());
 
             // route mirror message test
-            RouteMirroringMessage routeMirrorMsg = TestUtil.createRouteMirrorMsg(PEER1);
+            final RouteMirroringMessage routeMirrorMsg = TestUtil.createRouteMirrorMsg(PEER1);
             channel.writeAndFlush(routeMirrorMsg);
             Thread.sleep(500);
             final Mirrors routeMirrors = getBmpData(peerIId.child(Mirrors.class)).get();
@@ -324,7 +312,7 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
             final Monitor monitorAfterClose = getBmpData(monitorIId).get();
             assertTrue(monitorAfterClose.getRouter().isEmpty());
         } catch (final Exception e) {
-            StringBuffer ex = new StringBuffer();
+            final StringBuffer ex = new StringBuffer();
             ex.append(e.getMessage() + "\n");
             for (final StackTraceElement element: e.getStackTrace()) {
                 ex.append(element.toString() + "\n");
@@ -351,13 +339,6 @@ public class BmpMonitorImplTest extends AbstractDataBrokerTest {
         return b.connect(CLIENT_REMOTE).sync();
     }
 
-    private static final class ReconnectStrategyFctImpl implements ReconnectStrategyFactory {
-        @Override
-        public NeverReconnectStrategy createReconnectStrategy() {
-            return new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, CONNECT_TIME);
-        }
-    }
-
     private <T extends DataObject> Optional<T> getBmpData(final InstanceIdentifier<T> iid) throws ReadFailedException {
         try (final ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) {
             return tx.read(LogicalDatastoreType.OPERATIONAL, iid).checkedGet();
index 47c0b9d8dc6b07a1b993af4cb760e852feb87abb..a3bc7a5e8166e55bc196be54fb9a540f8abd785b 100644 (file)
@@ -13,7 +13,6 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.concurrent.GlobalEventExecutor;
 import java.net.InetSocketAddress;
 import org.junit.After;
 import org.junit.Assert;
@@ -33,8 +32,6 @@ import org.opendaylight.protocol.bmp.impl.BmpActivator;
 import org.opendaylight.protocol.bmp.impl.BmpDispatcherImpl;
 import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
 import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpExtensionProviderContext;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.TimedReconnectStrategy;
 import org.opendaylight.tcpmd5.api.KeyMapping;
 import org.opendaylight.tcpmd5.netty.MD5ChannelFactory;
 import org.opendaylight.tcpmd5.netty.MD5ServerChannelFactory;
@@ -55,8 +52,6 @@ public class BmpDispatcherImplTest {
     private BmpSessionListenerFactory mockedListenerFactory;
     @Mock
     private ChannelHandler mockedChannelHandler;
-    @Mock
-    private ReconnectStrategyFactory mockedReconnectStrategyFactory;
 
     @Before
     public void setUp() throws Exception {
@@ -69,8 +64,6 @@ public class BmpDispatcherImplTest {
         Mockito.doNothing().when(this.mockedSession).channelUnregistered(Mockito.any(ChannelHandlerContext.class));
         Mockito.doNothing().when(this.mockedSession).channelReadComplete(Mockito.any(ChannelHandlerContext.class));
 
-        Mockito.doReturn(new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, 720000, 30000L, 1.0, 30000L, 10L, 720000L)).when(this.mockedReconnectStrategyFactory).createReconnectStrategy();
-
         this.bgpActivator = new BGPActivator();
         final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
         this.bgpActivator.start(context);
@@ -85,8 +78,7 @@ public class BmpDispatcherImplTest {
                     final BmpSessionListenerFactory sessionListenerFactory) {
                 return BmpDispatcherImplTest.this.mockedSession;
             }
-        }, Optional.<MD5ChannelFactory<?>>absent(), Optional.<MD5ServerChannelFactory<?>>absent(),
-        mockedReconnectStrategyFactory);
+        }, Optional.<MD5ChannelFactory<?>>absent(), Optional.<MD5ServerChannelFactory<?>>absent());
     }
 
     @After
index 26eacb3e4dd78cbb794ddda6169f50795239e5b1..578f91b180703d1558cad34edcdb73505a30dbcb 100644 (file)
@@ -8,11 +8,8 @@
 
 package org.opendaylight.protocol.bmp.impl.session;
 
-import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.embedded.EmbeddedChannel;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -26,27 +23,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.mess
 
 public class BmpSessionImplTest {
 
-    private static final SocketAddress FAKE_ADDRESS = InetSocketAddress.createUnresolved("localhost", 12345);
-
     private BmpSession session;
     private EmbeddedChannel channel;
     private BmpTestSessionListener listener;
     @Mock
-    private Channel mockedChannel;
-    @Mock
     private ChannelHandlerContext mockedHandlerContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        Mockito.doReturn(FAKE_ADDRESS).when(this.mockedChannel).localAddress();
-        Mockito.doReturn(FAKE_ADDRESS).when(this.mockedChannel).remoteAddress();
-        Mockito.doReturn(null).when(this.mockedChannel).close();
-        Mockito.doReturn("").when(this.mockedChannel).toString();
         Mockito.doReturn(null).when(this.mockedHandlerContext).channel();
         Mockito.doReturn(null).when(this.mockedHandlerContext).fireChannelInactive();
         this.listener = new BmpTestSessionListener();
-        this.session = new BmpSessionImpl(this.listener, this.mockedChannel);
+        this.session = new BmpSessionImpl(this.listener);
         this.channel = new EmbeddedChannel(this.session);
         Assert.assertTrue(this.listener.isUp());
     }
@@ -65,21 +54,21 @@ public class BmpSessionImplTest {
         Assert.assertEquals(this.listener.getListMsg().size(), 1);
         this.channel.writeInbound(TestUtil.createTerminationMsg());
         Assert.assertEquals(this.listener.getListMsg().size(), 1);
-        Mockito.verify(this.mockedChannel, Mockito.times(1)).close();
+        Assert.assertFalse(this.listener.isUp());
     }
 
     @Test
     public void testOnTermination() {
         this.channel.writeInbound(TestUtil.createTerminationMsg());
         Assert.assertEquals(this.listener.getListMsg().size(), 0);
-        Mockito.verify(this.mockedChannel, Mockito.times(1)).close();
+        Assert.assertFalse(this.listener.isUp());
     }
 
     @Test
     public void testOnUnexpectedMessage() {
         this.channel.writeInbound(TestUtil.createPeerDownFSM());
         Assert.assertEquals(this.listener.getListMsg().size(), 0);
-        Mockito.verify(this.mockedChannel, Mockito.times(1)).close();
+        Assert.assertFalse(this.listener.isUp());
     }
 
     @Test
@@ -87,7 +76,7 @@ public class BmpSessionImplTest {
         try {
             this.session.exceptionCaught(this.mockedHandlerContext, new BmpDeserializationException(""));
             Assert.assertEquals(this.listener.getListMsg().size(), 0);
-            Mockito.verify(this.mockedChannel, Mockito.times(1)).close();
+            Assert.assertFalse(this.listener.isUp());
         } catch (final Exception e) {
             Assert.fail(e.getMessage());
         }
index 5b3b76732ae5fcaa3dfcf7bd2a5738dade9c052e..3fc0f5c11cbb6d4787cab207fdc9058275382cc4 100644 (file)
@@ -13,7 +13,6 @@
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bmp:impl?module=odl-bmp-impl-cfg&amp;revision=2015-05-18</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi?module=odl-bgp-parser-spi-cfg&amp;revision=2013-11-15</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework?module=protocol-framework&amp;revision=2014-03-13</capability>
     </required-capabilities>
     <configuration>
         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
                         <name>global-bgp-extensions</name>
                     </bgp-extensions>
                 </module>
-                <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:protocol:framework">prefix:timed-reconnect-strategy-factory</type>
-                    <name>example-reconnect-strategy-factory</name>
-                    <min-sleep>30000</min-sleep>
-                    <max-sleep>720000</max-sleep>
-                    <sleep-factor>1.00</sleep-factor>
-                    <connect-time>5000</connect-time>
-                    <timed-reconnect-executor>
-                        <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
-                        <name>global-event-executor</name>
-                    </timed-reconnect-executor>
-                </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bmp:impl">prefix:bmp-dispatcher-impl</type>
                     <name>global-bmp-dispatcher</name>
                         <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
                         <name>global-worker-group</name>
                     </worker-group>
-                    <bmp-reconnect-strategy-factory>
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:protocol:framework">prefix:reconnect-strategy-factory</type>
-                        <name>example-reconnect-strategy-factory</name>
-                    </bmp-reconnect-strategy-factory>
 
                     <!--
                          Uncomment this block to enable TCP MD5 Signature support
                         <provider>/modules/module[type='bmp-dispatcher-impl'][name='global-bmp-dispatcher']</provider>
                     </instance>
                 </service>
-                <service>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:protocol:framework">prefix:reconnect-strategy-factory</type>
-                    <instance>
-                        <name>example-reconnect-strategy-factory</name>
-                        <provider>/config/modules/module[name='timed-reconnect-strategy-factory']/instance[name='example-reconnect-strategy-factory']</provider>
-                    </instance>
-                </service>
             </services>
         </data>
 
index a99108119f444d7ecc5c8036dba66bbe05a05d80..eba3b2d963e376a36da834741cded57bf1d602a1 100644 (file)
                         <password>changeme</password>
                     </monitored-router>
                     -->
+                    <!-- To enable active TCP connection, configure monitored-router with address, port and active flag.
+                    <monitored-router>
+                        <address>192.0.2.2</address>
+                        <port>1234</port>
+                        <active>true</active>
+                    </monitored-router>
+                     -->
                     <extensions>
                         <type xmlns:ribspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">ribspi:extensions</type>
                         <name>global-rib-extensions</name>