BUG-4531: Error channelFactory set already 31/28831/7
authorClaudio D. Gasparini <cgaspari@cisco.com>
Mon, 26 Oct 2015 18:20:51 +0000 (19:20 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 28 Oct 2015 12:24:53 +0000 (12:24 +0000)
When we change the MD5 password we see
IllegalStateException: channelFactory set already.
Fix by setting only once the channelFactory, according
the case, MD5ServerChannelFactory when MD5 instead of
NioServerSocketChannel.

Change-Id: I5d02b1a3e325f1cd47099ee13397d141105969a3
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPDispatcherImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPDispatcher.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/TestClientDispatcher.java
pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPDispatcher.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImpl.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java

index 6dbe27074aff7d5cbc5b6e8474e145f557069ada..620d67e074c92029be8ed0d187976b5623867633 100644 (file)
@@ -17,6 +17,7 @@
 package org.opendaylight.controller.config.yang.bgp.rib.impl;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.net.InetAddresses;
 import io.netty.util.concurrent.Future;
@@ -207,16 +208,15 @@ public final class BGPPeerModule extends org.opendaylight.controller.config.yang
     }
 
     private io.netty.util.concurrent.Future<Void> initiateConnection(final InetSocketAddress address, final String password, final BGPPeerRegistry registry) {
-        final KeyMapping keys;
+        KeyMapping keys = null;
         if (password != null) {
             keys = new KeyMapping();
             keys.put(address.getAddress(), password.getBytes(Charsets.US_ASCII));
-        } else {
-            keys = null;
         }
 
         final RIB rib = getRibDependency();
-        return rib.getDispatcher().createReconnectingClient(address, registry, rib.getTcpStrategyFactory(), keys);
+        final Optional<KeyMapping> optionalKey = Optional.fromNullable(keys);
+        return rib.getDispatcher().createReconnectingClient(address, registry, rib.getTcpStrategyFactory(), optionalKey);
     }
 
     private BGPPeerRegistry getPeerRegistryBackwards() {
index 8b0b7c756d4ebe29a5bbeade56cffca1bb509c62..f53dbdaf1cce0cad0c3b4f6b7f560a0e91dd0a6c 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.bgp.rib.impl;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.bootstrap.ServerBootstrap;
@@ -54,7 +55,7 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
     private final EventLoopGroup bossGroup;
     private final EventLoopGroup workerGroup;
     private final EventExecutor executor;
-    private KeyMapping keys;
+    private Optional<KeyMapping> keys;
 
     public BGPDispatcherImpl(final MessageRegistry messageRegistry, final EventLoopGroup bossGroup, final EventLoopGroup workerGroup) {
         this(messageRegistry, bossGroup, workerGroup, null, null);
@@ -67,7 +68,7 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
         this.handlerFactory = new BGPHandlerFactory(messageRegistry);
         this.channelFactory = cf;
         this.serverChannelFactory = scf;
-        this.keys = null;
+        this.keys = Optional.absent();
     }
 
     @Override
@@ -75,17 +76,37 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
         final BGPClientSessionNegotiatorFactory snf = new BGPClientSessionNegotiatorFactory(listener);
         final ChannelPipelineInitializer initializer = BGPChannel.createChannelPipelineInitializer(BGPDispatcherImpl.this.handlerFactory, snf);
 
-        final Bootstrap bootstrap = new Bootstrap();
+        final Bootstrap bootstrap = createClientBootStrap();
         final BGPProtocolSessionPromise sessionPromise = new BGPProtocolSessionPromise(this.executor, address, strategy, bootstrap);
-        bootstrap.option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);
         bootstrap.handler(BGPChannel.createChannelInitializer(initializer, sessionPromise));
-        this.customizeBootstrap(bootstrap);
-        setWorkerGroup(bootstrap);
         sessionPromise.connect();
         LOG.debug("Client created.");
         return sessionPromise;
     }
 
+    protected Bootstrap createClientBootStrap() {
+        final Bootstrap bootstrap = new Bootstrap();
+        if (this.keys.isPresent()) {
+            if (this.channelFactory == null) {
+                throw new UnsupportedOperationException("No key access instance available, cannot use key mapping");
+            }
+            bootstrap.channelFactory(this.channelFactory);
+            bootstrap.option(MD5ChannelOption.TCP_MD5SIG, this.keys.get());
+        } else {
+            bootstrap.channel(NioSocketChannel.class);
+        }
+
+        // Make sure we are doing round-robin processing
+        bootstrap.option(ChannelOption.MAX_MESSAGES_PER_READ, 1);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);
+
+        if (bootstrap.group() == null) {
+            bootstrap.group(this.workerGroup);
+        }
+
+        return bootstrap;
+    }
+
     @Override
     public void close() {
         try {
@@ -97,20 +118,14 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
 
     @Override
     public synchronized Future<Void> createReconnectingClient(final InetSocketAddress address, final BGPPeerRegistry peerRegistry,
-        final ReconnectStrategyFactory connectStrategyFactory, final KeyMapping keys) {
+        final ReconnectStrategyFactory connectStrategyFactory, final Optional<KeyMapping> keys) {
         final BGPClientSessionNegotiatorFactory snf = new BGPClientSessionNegotiatorFactory(peerRegistry);
         this.keys = keys;
-
-        final Bootstrap bootstrap = new Bootstrap();
+        final Bootstrap bootstrap = createClientBootStrap();
         final BGPReconnectPromise reconnectPromise = new BGPReconnectPromise<BGPSessionImpl>(GlobalEventExecutor.INSTANCE, address,
             connectStrategyFactory, bootstrap, BGPChannel.createChannelPipelineInitializer(BGPDispatcherImpl.this.handlerFactory, snf));
-        bootstrap.option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);
-        this.customizeBootstrap(bootstrap);
-        setWorkerGroup(bootstrap);
         reconnectPromise.connect();
-
         this.keys = null;
-
         return reconnectPromise;
     }
 
@@ -118,37 +133,25 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
     public ChannelFuture createServer(final BGPPeerRegistry registry, final InetSocketAddress address) {
         final BGPServerSessionNegotiatorFactory snf = new BGPServerSessionNegotiatorFactory(registry);
         final ChannelPipelineInitializer initializer = BGPChannel.createChannelPipelineInitializer(BGPDispatcherImpl.this.handlerFactory, snf);
-        final ServerBootstrap serverBootstrap = new ServerBootstrap();
-        serverBootstrap.childHandler(BGPChannel.createChannelInitializer(initializer, new DefaultPromise(BGPDispatcherImpl.this.executor)));
-        serverBootstrap.option(ChannelOption.SO_BACKLOG, Integer.valueOf(SOCKET_BACKLOG_SIZE));
-        serverBootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
-        this.customizeBootstrap(serverBootstrap);
-
+        final ServerBootstrap serverBootstrap = createServerBootstrap(initializer);
         final ChannelFuture channelFuture = serverBootstrap.bind(address);
         LOG.debug("Initiated server {} at {}.", channelFuture, address);
         return channelFuture;
     }
 
-    protected void customizeBootstrap(final Bootstrap bootstrap) {
-        if (this.keys != null && !this.keys.isEmpty()) {
-            if (this.channelFactory == null) {
-                throw new UnsupportedOperationException("No key access instance available, cannot use key mapping");
-            }
-            bootstrap.channelFactory(this.channelFactory);
-            bootstrap.option(MD5ChannelOption.TCP_MD5SIG, this.keys);
-        }
-
-        // Make sure we are doing round-robin processing
-        bootstrap.option(ChannelOption.MAX_MESSAGES_PER_READ, 1);
-    }
-
-    private void customizeBootstrap(final ServerBootstrap serverBootstrap) {
-        if (this.keys != null && !this.keys.isEmpty()) {
+    private ServerBootstrap createServerBootstrap(final ChannelPipelineInitializer initializer) {
+        final ServerBootstrap serverBootstrap = new ServerBootstrap();
+        serverBootstrap.childHandler(BGPChannel.createChannelInitializer(initializer, new DefaultPromise(BGPDispatcherImpl.this.executor)));
+        serverBootstrap.option(ChannelOption.SO_BACKLOG, Integer.valueOf(SOCKET_BACKLOG_SIZE));
+        serverBootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
+        if (this.keys.isPresent()) {
             if (this.serverChannelFactory == null) {
                 throw new UnsupportedOperationException("No key access instance available, cannot use key mapping");
             }
             serverBootstrap.channelFactory(this.serverChannelFactory);
-            serverBootstrap.option(MD5ChannelOption.TCP_MD5SIG, this.keys);
+            serverBootstrap.option(MD5ChannelOption.TCP_MD5SIG, this.keys.get());
+        } else {
+            serverBootstrap.channel(NioServerSocketChannel.class);
         }
 
         // Make sure we are doing round-robin processing
@@ -157,23 +160,7 @@ public class BGPDispatcherImpl implements BGPDispatcher, AutoCloseable {
         if (serverBootstrap.group() == null) {
             serverBootstrap.group(this.bossGroup, this.workerGroup);
         }
-
-        try {
-            serverBootstrap.channel(NioServerSocketChannel.class);
-        } catch (final IllegalStateException e) {
-            LOG.trace("Not overriding channelFactory on bootstrap {}", serverBootstrap, e);
-        }
-    }
-
-    private void setWorkerGroup(final Bootstrap bootstrap) {
-        if (bootstrap.group() == null) {
-            bootstrap.group(this.workerGroup);
-        }
-        try {
-            bootstrap.channel(NioSocketChannel.class);
-        } catch (final IllegalStateException e) {
-            LOG.trace("Not overriding channelFactory on bootstrap {}", bootstrap, e);
-        }
+        return serverBootstrap;
     }
 
     private static final class BGPChannel {
index 966e4fea9c7eb033a66321464bca9305aab85c40..39b292b256d29fc6d9b22feee4accae34e0dc814 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.bgp.rib.impl.spi;
 
+import com.google.common.base.Optional;
 import io.netty.channel.ChannelFuture;
 import io.netty.util.concurrent.Future;
 import java.net.InetSocketAddress;
@@ -40,7 +41,7 @@ public interface BGPDispatcher{
      * @return Future promising a client session
      */
     Future<Void> createReconnectingClient(InetSocketAddress address,
-        BGPPeerRegistry peerRegistry, ReconnectStrategyFactory connectStrategyFactory, KeyMapping keys);
+        BGPPeerRegistry peerRegistry, ReconnectStrategyFactory connectStrategyFactory, Optional<KeyMapping> keys);
 
     /**
      * Create new BGP server to accept incoming bgp connections (bound to provided socket address).
index 41efe6932fe986a30306df3576be8d66a99f43ac..516aaabd8aeabe15c6730e45fcf030623a615319 100644 (file)
@@ -43,7 +43,6 @@ import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
 import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
 import org.opendaylight.protocol.bgp.util.HexDumpBGPFileParser;
 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.tcpmd5.api.KeyMapping;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route;
@@ -114,7 +113,7 @@ public class ParserToSalTest extends AbstractDataBrokerTest {
         this.mock = new BGPMock(new EventBus("test"), ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry(), Lists.newArrayList(fixMessages(bgpMessages)));
 
         Mockito.doReturn(GlobalEventExecutor.INSTANCE.newSucceededFuture(null)).when(this.dispatcher).createReconnectingClient(
-                Mockito.any(InetSocketAddress.class), Mockito.any(BGPPeerRegistry.class), Mockito.eq(this.tcpStrategyFactory), Mockito.any(KeyMapping.class));
+                Mockito.any(InetSocketAddress.class), Mockito.any(BGPPeerRegistry.class), Mockito.eq(this.tcpStrategyFactory), Mockito.any(Optional.class));
 
         this.ext1 = new SimpleRIBExtensionProviderContext();
         this.ext2 = new SimpleRIBExtensionProviderContext();
index c87c3f28b80c9662ce07554ef1ad68429c6eba97..e20259d92d262a91d1b16bb6b0bf76235f0e3491 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Optional;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
 import io.netty.util.concurrent.Future;
 import java.net.InetSocketAddress;
 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
@@ -30,9 +31,19 @@ public class TestClientDispatcher {
                                    final InetSocketAddress locaAddress) {
         this.disp = new BGPDispatcherImpl(messageRegistry, bossGroup, workerGroup) {
             @Override
-            protected void customizeBootstrap(final Bootstrap b) {
-                b.localAddress(locaAddress);
-                b.option(ChannelOption.SO_REUSEADDR, true);
+            protected Bootstrap createClientBootStrap() {
+                final Bootstrap bootstrap = new Bootstrap();
+                bootstrap.channel(NioSocketChannel.class);
+                // Make sure we are doing round-robin processing
+                bootstrap.option(ChannelOption.MAX_MESSAGES_PER_READ, 1);
+                bootstrap.option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);
+
+                if (bootstrap.group() == null) {
+                    bootstrap.group(workerGroup);
+                }
+                bootstrap.localAddress(locaAddress);
+                bootstrap.option(ChannelOption.SO_REUSEADDR, true);
+                return bootstrap;
             }
         };
         this.hf = new BGPHandlerFactory(messageRegistry);
index aadbbdcac54c713e2225440f7c3fdca60207413d..4b173ab596c5bb18f9722eb840cc7991b7d60bce 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.pcep;
 
+import com.google.common.base.Optional;
 import io.netty.channel.ChannelFuture;
 import java.net.InetSocketAddress;
 import org.opendaylight.tcpmd5.api.KeyMapping;
@@ -34,5 +35,5 @@ public interface PCEPDispatcher {
      * @param peerProposal information used in our Open message
      * @return instance of PCEPServer
      */
-    ChannelFuture createServer(InetSocketAddress address, KeyMapping keys, PCEPSessionListenerFactory listenerFactory, PCEPPeerProposal peerProposal);
+    ChannelFuture createServer(InetSocketAddress address, Optional<KeyMapping> keys, PCEPSessionListenerFactory listenerFactory, PCEPPeerProposal peerProposal);
 }
index 94e36019e431705f34a428c63adc66fc7ea01335..de7710d5c7b104fde729def115e3b041cf554651 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.pcep.impl;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.buffer.PooledByteBufAllocator;
@@ -47,7 +48,7 @@ public class PCEPDispatcherImpl implements PCEPDispatcher, Closeable {
     private final EventLoopGroup workerGroup;
     private final EventExecutor executor;
     private final MD5ServerChannelFactory<?> scf;
-    private KeyMapping keys;
+    private Optional<KeyMapping> keys;
 
     /**
      * Creates an instance of PCEPDispatcherImpl, gets the default selector and opens it.
@@ -87,11 +88,11 @@ public class PCEPDispatcherImpl implements PCEPDispatcher, Closeable {
     @Override
     public synchronized ChannelFuture createServer(final InetSocketAddress address,
                                                    final PCEPSessionListenerFactory listenerFactory, final PCEPPeerProposal peerProposal) {
-        return createServer(address, null, listenerFactory, peerProposal);
+        return createServer(address, Optional.<KeyMapping>absent(), listenerFactory, peerProposal);
     }
 
     @Override
-    public synchronized ChannelFuture createServer(final InetSocketAddress address, final KeyMapping keys,
+    public synchronized ChannelFuture createServer(final InetSocketAddress address, final Optional<KeyMapping> keys,
                                                    final PCEPSessionListenerFactory listenerFactory, final PCEPPeerProposal peerProposal) {
         this.keys = keys;
 
@@ -103,6 +104,16 @@ public class PCEPDispatcherImpl implements PCEPDispatcher, Closeable {
                 ch.pipeline().addLast(PCEPDispatcherImpl.this.hf.getEncoders());
             }
         };
+
+        final ServerBootstrap b = createServerBootstrap(initializer);
+        final ChannelFuture f = b.bind(address);
+        LOG.debug("Initiated server {} at {}.", f, address);
+
+        this.keys = null;
+        return f;
+    }
+
+    protected ServerBootstrap createServerBootstrap(final ChannelPipelineInitializer initializer) {
         final ServerBootstrap b = new ServerBootstrap();
         b.childHandler(new ChannelInitializer<SocketChannel>() {
             @Override
@@ -113,37 +124,27 @@ public class PCEPDispatcherImpl implements PCEPDispatcher, Closeable {
         b.option(ChannelOption.SO_BACKLOG, SOCKET_BACKLOG_SIZE);
 
         b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
-        this.customizeBootstrap(b);
-        if (b.group() == null) {
-            b.group(this.bossGroup, this.workerGroup);
-        }
-
-        try {
-            b.channel(NioServerSocketChannel.class);
-        } catch (final IllegalStateException e) {
-            LOG.trace("Not overriding channelFactory on bootstrap {}", b, e);
-        }
 
-        final ChannelFuture f = b.bind(address);
-        LOG.debug("Initiated server {} at {}.", f, address);
-
-        this.keys = null;
-        return f;
-    }
-
-    protected void customizeBootstrap(final ServerBootstrap b) {
-        if (this.keys != null && !this.keys.isEmpty()) {
+        if (this.keys.isPresent()) {
             if (this.scf == null) {
                 throw new UnsupportedOperationException("No key access instance available, cannot use key mapping");
             }
 
-            LOG.debug("Adding MD5 keys {} to bootstrap {}", this.keys, b);
+            LOG.debug("Adding MD5 keys {} to bootstrap {}", this.keys.get(), b);
             b.channelFactory(this.scf);
-            b.option(MD5ChannelOption.TCP_MD5SIG, this.keys);
+            b.option(MD5ChannelOption.TCP_MD5SIG, this.keys.get());
+        } else {
+            b.channel(NioServerSocketChannel.class);
         }
 
         // Make sure we are doing round-robin processing
         b.childOption(ChannelOption.MAX_MESSAGES_PER_READ, 1);
+
+        if (b.group() == null) {
+            b.group(this.bossGroup, this.workerGroup);
+        }
+
+        return b;
     }
 
     @Override
index 2434d410845ec6540abe7e014dc146eaf7ced2e8..1879bd21551a53ead6981649f14640e0afc629c5 100644 (file)
@@ -8,9 +8,9 @@
 
 package org.opendaylight.protocol.pcep.impl;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.netty.bootstrap.Bootstrap;
-import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelOption;
@@ -210,14 +210,14 @@ public class PCEPDispatcherImplTest {
         keys.put(CLIENT1_ADDRESS.getAddress(), new String("CLIENT1_ADDRESS").getBytes() );
         keys.put(CLIENT2_ADDRESS.getAddress(), new String("CLIENT2_ADDRESS").getBytes() );
 
-        final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", PORT), keys,
+        final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", PORT), Optional.fromNullable(keys),
             new PCEPSessionListenerFactory() {
                 @Override
                 public PCEPSessionListener getSessionListener() {
                     return new SimpleSessionListener();
                 }
             }, null);
-        Mockito.verify(this.disp2Spy).customizeBootstrap(Mockito.any(ServerBootstrap.class));
+        Mockito.verify(this.disp2Spy).createServerBootstrap(Mockito.any(PCEPDispatcherImpl.ChannelPipelineInitializer.class));
     }
 
     @After
index 6a5ef4737e0268e217c3660078beda3e63432aba..e5999cd3bf39de23a6ce11fab76f9a6d43763cca 100644 (file)
@@ -50,7 +50,7 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
         this.network = Preconditions.checkNotNull(network);
     }
 
-    public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final KeyMapping keys,
+    public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final Optional<KeyMapping> keys,
             final InstructionScheduler scheduler, final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry,
             final InstanceIdentifier<Topology> topology, final TopologySessionListenerFactory listenerFactory,
             final Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator) throws InterruptedException,
index e0a8dd09a7227a524702fd6cd65ddbaf02fca5bf..731c4f7000e8b397f207c7d842a9524bd3b5cada 100644 (file)
@@ -22,6 +22,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.net.InetAddresses;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.List;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
@@ -57,10 +58,13 @@ public final class PCEPTopologyProviderModule extends
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
-    private KeyMapping contructKeys() {
-        final KeyMapping ret = new KeyMapping();
-        if (getClient() != null) {
-            for (final Client c : getClient()) {
+    private Optional<KeyMapping> contructKeys() {
+        KeyMapping ret = null;
+        final List<Client> clients = getClient();
+
+        if (clients != null && !clients.isEmpty()) {
+            ret = new KeyMapping();
+            for (final Client c : clients) {
                 if (c.getAddress() == null) {
                     LOG.warn("Client {} does not have an address skipping it", c);
                     continue;
@@ -71,7 +75,7 @@ public final class PCEPTopologyProviderModule extends
                 }
             }
         }
-        return ret;
+        return Optional.fromNullable(ret);
     }
 
 
@@ -91,8 +95,8 @@ public final class PCEPTopologyProviderModule extends
         JmxAttributeValidationException.checkNotNull(getListenPort(), IS_NOT_SET, listenPortJmxAttribute);
         JmxAttributeValidationException.checkNotNull(getStatefulPlugin(), IS_NOT_SET, statefulPluginJmxAttribute);
 
-        final KeyMapping keys = contructKeys();
-        if (!keys.isEmpty()) {
+        final Optional<KeyMapping> keys = contructKeys();
+        if (keys.isPresent()) {
             /*
              *  This is a nasty hack, but we don't have another clean solution. We cannot allow
              *  password being set if the injected dispatcher does not have the optional
@@ -125,10 +129,9 @@ public final class PCEPTopologyProviderModule extends
         final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class,
                 new TopologyKey(getTopologyId())).build();
         final InetSocketAddress address = new InetSocketAddress(listenAddress(), getListenPort().getValue());
-        final KeyMapping keys = contructKeys();
 
         try {
-            return PCEPTopologyProvider.create(getDispatcherDependency(), address, keys.isEmpty() ? null : keys, getSchedulerDependency(),
+            return PCEPTopologyProvider.create(getDispatcherDependency(), address, contructKeys(), getSchedulerDependency(),
                     getDataProviderDependency(), getRpcRegistryDependency(), topology, getStatefulPluginDependency(),
                     Optional.of(getRootRuntimeBeanRegistratorWrapper()));
         } catch (InterruptedException | ExecutionException | TransactionCommitFailedException | ReadFailedException e) {