blob: 2bc96fd53440b9da6b97f262f1e8faa14ad803fe [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) {
Tomek Osińskie9ccf412018-01-13 19:44:11 +0100111 bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
112 bootstrap.option(ChannelOption.SO_RCVBUF, 2048);
113 }
114
115 /**
116 * TLS/SSL setup. If needed.
117 */
118 private void initTls() {
119 // TODO: add support for TLS/SSL
120 }
121
122 /**
123 * Sets configuration parameters defined via ComponentConfiguration subsystem.
124 * @param properties properties to be set
125 */
126 public void setConfiguration(Dictionary<?, ?> properties) {
127 String port = get(properties, "xmppPort");
128 if (!Strings.isNullOrEmpty(port)) {
129 this.port = Integer.parseInt(port);
130 }
131 log.debug("XMPP port set to {}", this.port);
132 }
133
134 /**
135 * Starts XMPP server.
136 *
137 * @param deviceFactory XMPP devices factory
138 */
139 public void start(XmppDeviceFactory deviceFactory) {
140 log.info("XMPP Server has started.");
141 this.run(deviceFactory);
142 }
143
144 /**
145 * Stops XMPP server.
146 *
147 */
148 public void stop() {
149 log.info("Stopping XMPP I/O");
150 channel.close();
151 eventLoopGroup.shutdownGracefully();
152 }
153}