blob: 3913d64927d1e45b5a299177c01e5ba0fb860dfe [file] [log] [blame]
Tomek Osińskie9ccf412018-01-13 19:44:11 +01001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.xmpp.core.ctl;
18
19import com.google.common.base.Strings;
20import io.netty.bootstrap.ServerBootstrap;
21import io.netty.buffer.PooledByteBufAllocator;
22import io.netty.channel.AbstractChannel;
23import io.netty.channel.Channel;
24import io.netty.channel.ChannelOption;
25import io.netty.channel.EventLoopGroup;
26import io.netty.channel.epoll.EpollEventLoopGroup;
27import io.netty.channel.epoll.EpollSocketChannel;
28import io.netty.channel.nio.NioEventLoopGroup;
29import io.netty.channel.socket.nio.NioServerSocketChannel;
30import org.onosproject.xmpp.core.XmppDeviceFactory;
31import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
34import java.net.InetSocketAddress;
35import java.util.Dictionary;
36
37import static org.onlab.util.Tools.get;
38
39/**
40 * The XMPP server class. Starts XMPP server and listens to new XMPP device TCP connections.
41 */
42public class XmppServer {
43
44 protected static final Logger log = LoggerFactory.getLogger(XmppServer.class);
45
46 protected Integer port = 5259;
47
48 protected Channel channel;
49 protected EventLoopGroup eventLoopGroup;
50 protected Class<? extends AbstractChannel> channelClass;
51
52
53 /**
54 * Initializes XMPP server.
55 */
56 public void init() {
57
58 }
59
60 /**
61 * Runs XMPP server thread.
62 * @param deviceFactory XMPP devices factory
63 */
64 public void run(XmppDeviceFactory deviceFactory) {
65 try {
66 final ServerBootstrap bootstrap = createServerBootStrap(deviceFactory);
67
68 InetSocketAddress socketAddress = new InetSocketAddress(port);
69 channel = bootstrap.bind(socketAddress).sync().channel().closeFuture().channel();
70
71 log.info("Listening for device connections on {}", socketAddress);
72
73 } catch (Exception ex) {
Ray Milkey8124ac92018-03-06 17:56:03 -080074 throw new IllegalStateException(ex);
Tomek Osińskie9ccf412018-01-13 19:44:11 +010075 }
76 }
77
78 private ServerBootstrap createServerBootStrap(XmppDeviceFactory deviceFactory) {
79
80 ServerBootstrap bootstrap = new ServerBootstrap();
81 configureBootstrap(bootstrap);
82 initEventLoopGroup();
83
84 bootstrap.group(eventLoopGroup)
85 .channel(NioServerSocketChannel.class)
86 .childHandler(new XmppChannelInitializer(deviceFactory));
87
88 return bootstrap;
89 }
90
91 /**
92 * Initializes event loop group.
93 */
94 private void initEventLoopGroup() {
95
96 // try to use EpollEventLoopGroup if possible,
97 // if OS does not support native Epoll, fallback to use netty NIO
98 try {
99 eventLoopGroup = new EpollEventLoopGroup();
100 channelClass = EpollSocketChannel.class;
101 return;
102 } catch (Error e) {
103 log.debug("Failed to initialize native (epoll) transport. "
104 + "Reason: {}. Proceeding with NIO event group.", e);
105 }
106 eventLoopGroup = new NioEventLoopGroup();
107 channelClass = NioServerSocketChannel.class;
108 }
109
110 private void configureBootstrap(ServerBootstrap bootstrap) {
111 bootstrap.option(ChannelOption.TCP_NODELAY, true);
112 bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
113 bootstrap.option(ChannelOption.SO_RCVBUF, 2048);
114 }
115
116 /**
117 * TLS/SSL setup. If needed.
118 */
119 private void initTls() {
120 // TODO: add support for TLS/SSL
121 }
122
123 /**
124 * Sets configuration parameters defined via ComponentConfiguration subsystem.
125 * @param properties properties to be set
126 */
127 public void setConfiguration(Dictionary<?, ?> properties) {
128 String port = get(properties, "xmppPort");
129 if (!Strings.isNullOrEmpty(port)) {
130 this.port = Integer.parseInt(port);
131 }
132 log.debug("XMPP port set to {}", this.port);
133 }
134
135 /**
136 * Starts XMPP server.
137 *
138 * @param deviceFactory XMPP devices factory
139 */
140 public void start(XmppDeviceFactory deviceFactory) {
141 log.info("XMPP Server has started.");
142 this.run(deviceFactory);
143 }
144
145 /**
146 * Stops XMPP server.
147 *
148 */
149 public void stop() {
150 log.info("Stopping XMPP I/O");
151 channel.close();
152 eventLoopGroup.shutdownGracefully();
153 }
154}