[ONOS-5778] OVSDB protocol-OVSDB controller connection failure (maximum retry exceeded failure)
            handling
            + checkstyle error fixed
            + changing 'log.info'-> 'log.warn' (applying module owner's comment)

Change-Id: I43aff90a15d7e0b82029fa11ed5dacaa358cb337
diff --git a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java
index a0d1c4d..08d405e 100644
--- a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java
+++ b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java
@@ -19,6 +19,7 @@
 import org.onlab.packet.TpPort;
 
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Abstraction of an ovsdb controller. Serves as an one stop shop for obtaining
@@ -76,4 +77,13 @@
      * @param port port number
      */
     void connect(IpAddress ip, TpPort port);
+
+    /**
+     * Connect to the ovsdb server with given ip address, port number, and connection failure handler.
+     *
+     * @param ip ip address
+     * @param port port number
+     * @param failhandler connection failure handler
+     */
+    void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler);
 }
diff --git a/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java b/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java
index 0a3ebf8..6d7d4fb 100644
--- a/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java
+++ b/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java
@@ -28,6 +28,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
 
 /**
  * Test Adapter for OvsdbController.
@@ -72,4 +73,9 @@
     public void connect(IpAddress ip, TpPort port) {
 
     }
+
+    @Override
+    public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
+
+    }
 }
diff --git a/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java b/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java
index 924ad87..1b285ec 100644
--- a/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java
+++ b/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java
@@ -46,6 +46,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.TpPort;
@@ -226,32 +227,43 @@
      * @param port port number
      */
     public void connect(IpAddress ip, TpPort port) {
-        ChannelFutureListener listener = new ConnectionListener(this, ip, port);
-        connectRetry(ip, port, listener);
+        connect(ip, port, e -> log.warn("Connection to the ovsdb {}:{} failed(cause: {})", ip, port, e));
+    }
+
+    /**
+     * Connect to the ovsdb server with given ip address, port number, and failhandler.
+     *
+     * @param ip ip address
+     * @param port port number
+     * @param failhandler connection failure handler
+     */
+    public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
+        ChannelFutureListener listener = new ConnectionListener(this, ip, port, failhandler);
+        try {
+            connectRetry(ip, port, listener);
+        } catch (Exception e) {
+            failhandler.accept(e);
+        }
     }
 
     private void connectRetry(IpAddress ip, TpPort port, ChannelFutureListener listener) {
-        try {
-            Bootstrap b = new Bootstrap();
-            b.group(workerGroup)
-                    .channel(NioSocketChannel.class)
-                    .option(ChannelOption.TCP_NODELAY, true)
-                    .handler(new ChannelInitializer<SocketChannel>() {
+        Bootstrap b = new Bootstrap();
+        b.group(workerGroup)
+                .channel(NioSocketChannel.class)
+                .option(ChannelOption.TCP_NODELAY, true)
+                .handler(new ChannelInitializer<SocketChannel>() {
 
-                        @Override
-                        protected void initChannel(SocketChannel channel) throws Exception {
-                            ChannelPipeline p = channel.pipeline();
-                            p.addLast(new MessageDecoder(),
-                                      new StringEncoder(CharsetUtil.UTF_8),
-                                      new IdleStateHandler(IDLE_TIMEOUT_SEC, 0, 0),
-                                      new ConnectionHandler());
-                        }
-                    });
-            b.remoteAddress(ip.toString(), port.toInt());
-            b.connect().addListener(listener);
-        } catch (Exception e) {
-            log.warn("Connection to the ovsdb server {}:{} failed", ip.toString(), port.toString());
-        }
+                    @Override
+                    protected void initChannel(SocketChannel channel) throws Exception {
+                        ChannelPipeline p = channel.pipeline();
+                        p.addLast(new MessageDecoder(),
+                                  new StringEncoder(CharsetUtil.UTF_8),
+                                  new IdleStateHandler(IDLE_TIMEOUT_SEC, 0, 0),
+                                  new ConnectionHandler());
+                    }
+                });
+        b.remoteAddress(ip.toString(), port.toInt());
+        b.connect().addListener(listener);
     }
 
     private class ConnectionListener implements ChannelFutureListener {
@@ -259,13 +271,16 @@
         private IpAddress ip;
         private TpPort port;
         private AtomicInteger count = new AtomicInteger();
+        private Consumer<Exception> failhandler;
 
         public ConnectionListener(Controller controller,
                                   IpAddress ip,
-                                  TpPort port) {
+                                  TpPort port,
+                                  Consumer<Exception> failhandler) {
             this.controller = controller;
             this.ip = ip;
             this.port = port;
+            this.failhandler = failhandler;
         }
 
         @Override
@@ -277,11 +292,14 @@
                     final EventLoop loop = channelFuture.channel().eventLoop();
 
                     loop.schedule(() -> {
-                        controller.connectRetry(this.ip, this.port, this);
+                        try {
+                            controller.connectRetry(this.ip, this.port, this);
+                        } catch (Exception e) {
+                            log.warn("Connection to the ovsdb server {}:{} failed(cause: {})", ip, port, e);
+                        }
                     }, 1L, TimeUnit.SECONDS);
                 } else {
-                    log.info("Connection to the ovsdb {}:{} failed",
-                             this.ip.toString(), this.port.toString());
+                    failhandler.accept(new Exception("max connection retry(" + MAX_RETRY + ") exceeded"));
                 }
             } else {
                 handleNewNodeConnection(channelFuture.channel());
diff --git a/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java b/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
index 86e6bd4..04199e2 100644
--- a/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
+++ b/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
@@ -67,6 +67,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.ExecutionException;
+import java.util.function.Consumer;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -147,6 +148,11 @@
         controller.connect(ip, port);
     }
 
+    @Override
+    public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
+        controller.connect(ip, port, failhandler);
+    }
+
     /**
      * Implementation of an Ovsdb Agent which is responsible for keeping track
      * of connected node and the state in which they are.
diff --git a/providers/ovsdb/device/src/test/java/org/onosproject/ovsdb/providers/device/OvsdbDeviceProviderTest.java b/providers/ovsdb/device/src/test/java/org/onosproject/ovsdb/providers/device/OvsdbDeviceProviderTest.java
index b4b73d2..11bcd36 100644
--- a/providers/ovsdb/device/src/test/java/org/onosproject/ovsdb/providers/device/OvsdbDeviceProviderTest.java
+++ b/providers/ovsdb/device/src/test/java/org/onosproject/ovsdb/providers/device/OvsdbDeviceProviderTest.java
@@ -22,6 +22,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import org.junit.After;
 import org.junit.Before;
@@ -198,6 +199,12 @@
         public void connect(IpAddress ip, TpPort port) {
 
         }
+
+        @Override
+        public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
+
+        }
+
     }
 
 }
diff --git a/providers/ovsdb/host/src/test/java/org/onosproject/ovsdb/provider/host/OvsdbHostProviderTest.java b/providers/ovsdb/host/src/test/java/org/onosproject/ovsdb/provider/host/OvsdbHostProviderTest.java
index d9c4e4f..c5eeedd 100644
--- a/providers/ovsdb/host/src/test/java/org/onosproject/ovsdb/provider/host/OvsdbHostProviderTest.java
+++ b/providers/ovsdb/host/src/test/java/org/onosproject/ovsdb/provider/host/OvsdbHostProviderTest.java
@@ -20,6 +20,7 @@
 
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import org.junit.After;
 import org.junit.Before;
@@ -207,5 +208,10 @@
         public void connect(IpAddress ip, TpPort port) {
 
         }
+
+        @Override
+        public void connect(IpAddress ip, TpPort port, Consumer<Exception> failhandler) {
+
+        }
     }
 }