XMPP as SBI support: implementation of core XMPP and Xmpp Device Provider

State machine handled by XmppSession interface, most of tests implemented

XmppDeviceFactory re-designed, tests updated

pom and BUCK files updated

Change-Id: I4c6955e091169c945415084cbb000c61b474c0fc
diff --git a/protocols/xmpp/core/ctl/src/main/java/org/onosproject/xmpp/core/ctl/XmppServer.java b/protocols/xmpp/core/ctl/src/main/java/org/onosproject/xmpp/core/ctl/XmppServer.java
new file mode 100644
index 0000000..42c9b39
--- /dev/null
+++ b/protocols/xmpp/core/ctl/src/main/java/org/onosproject/xmpp/core/ctl/XmppServer.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xmpp.core.ctl;
+
+import com.google.common.base.Strings;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.PooledByteBufAllocator;
+import io.netty.channel.AbstractChannel;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import org.onosproject.xmpp.core.XmppDeviceFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+import java.util.Dictionary;
+
+import static org.onlab.util.Tools.get;
+
+/**
+ *  The XMPP server class. Starts XMPP server and listens to new XMPP device TCP connections.
+ */
+public class XmppServer {
+
+    protected static final Logger log = LoggerFactory.getLogger(XmppServer.class);
+
+    protected Integer port = 5259;
+
+    protected Channel channel;
+    protected EventLoopGroup eventLoopGroup;
+    protected Class<? extends AbstractChannel> channelClass;
+
+
+    /**
+     * Initializes XMPP server.
+     */
+    public void init() {
+
+    }
+
+    /**
+     * Runs XMPP server thread.
+     * @param deviceFactory XMPP devices factory
+     */
+    public void run(XmppDeviceFactory deviceFactory) {
+        try {
+            final ServerBootstrap bootstrap = createServerBootStrap(deviceFactory);
+
+            InetSocketAddress socketAddress = new InetSocketAddress(port);
+            channel = bootstrap.bind(socketAddress).sync().channel().closeFuture().channel();
+
+            log.info("Listening for device connections on {}", socketAddress);
+
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private ServerBootstrap createServerBootStrap(XmppDeviceFactory deviceFactory) {
+
+        ServerBootstrap bootstrap = new ServerBootstrap();
+        configureBootstrap(bootstrap);
+        initEventLoopGroup();
+
+        bootstrap.group(eventLoopGroup)
+                .channel(NioServerSocketChannel.class)
+                .childHandler(new XmppChannelInitializer(deviceFactory));
+
+        return bootstrap;
+    }
+
+    /**
+     * Initializes event loop group.
+     */
+    private void initEventLoopGroup() {
+
+        // try to use EpollEventLoopGroup if possible,
+        // if OS does not support native Epoll, fallback to use netty NIO
+        try {
+            eventLoopGroup = new EpollEventLoopGroup();
+            channelClass = EpollSocketChannel.class;
+            return;
+        } catch (Error e) {
+            log.debug("Failed to initialize native (epoll) transport. "
+                    + "Reason: {}. Proceeding with NIO event group.", e);
+        }
+        eventLoopGroup = new NioEventLoopGroup();
+        channelClass = NioServerSocketChannel.class;
+    }
+
+    private void configureBootstrap(ServerBootstrap bootstrap) {
+        bootstrap.option(ChannelOption.TCP_NODELAY, true);
+        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
+        bootstrap.option(ChannelOption.SO_RCVBUF, 2048);
+    }
+
+    /**
+     * TLS/SSL setup. If needed.
+     */
+    private void initTls() {
+        // TODO: add support for TLS/SSL
+    }
+
+    /**
+     * Sets configuration parameters defined via ComponentConfiguration subsystem.
+     * @param properties properties to be set
+     */
+    public void setConfiguration(Dictionary<?, ?> properties) {
+        String port = get(properties, "xmppPort");
+        if (!Strings.isNullOrEmpty(port)) {
+            this.port = Integer.parseInt(port);
+        }
+        log.debug("XMPP port set to {}", this.port);
+    }
+
+    /**
+     * Starts XMPP server.
+     *
+     * @param deviceFactory XMPP devices factory
+     */
+    public void start(XmppDeviceFactory deviceFactory) {
+        log.info("XMPP Server has started.");
+        this.run(deviceFactory);
+    }
+
+    /**
+     * Stops XMPP server.
+     *
+     */
+    public void stop() {
+        log.info("Stopping XMPP I/O");
+        channel.close();
+        eventLoopGroup.shutdownGracefully();
+    }
+}