blob: 0970d829e7094f2334ec8bf22f22b3a6485f4861 [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;
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070038import static org.onosproject.xmpp.core.ctl.OsgiPropertyConstants.XMPP_PORT;
Tomek Osińskie9ccf412018-01-13 19:44:11 +010039
40/**
41 * The XMPP server class. Starts XMPP server and listens to new XMPP device TCP connections.
42 */
43public class XmppServer {
44
45 protected static final Logger log = LoggerFactory.getLogger(XmppServer.class);
46
47 protected Integer port = 5259;
48
49 protected Channel channel;
50 protected EventLoopGroup eventLoopGroup;
51 protected Class<? extends AbstractChannel> channelClass;
52
53
54 /**
55 * Initializes XMPP server.
56 */
57 public void init() {
58
59 }
60
61 /**
62 * Runs XMPP server thread.
63 * @param deviceFactory XMPP devices factory
64 */
65 public void run(XmppDeviceFactory deviceFactory) {
66 try {
67 final ServerBootstrap bootstrap = createServerBootStrap(deviceFactory);
68
69 InetSocketAddress socketAddress = new InetSocketAddress(port);
70 channel = bootstrap.bind(socketAddress).sync().channel().closeFuture().channel();
71
72 log.info("Listening for device connections on {}", socketAddress);
73
74 } catch (Exception ex) {
Ray Milkey8124ac92018-03-06 17:56:03 -080075 throw new IllegalStateException(ex);
Tomek Osińskie9ccf412018-01-13 19:44:11 +010076 }
77 }
78
79 private ServerBootstrap createServerBootStrap(XmppDeviceFactory deviceFactory) {
80
81 ServerBootstrap bootstrap = new ServerBootstrap();
82 configureBootstrap(bootstrap);
83 initEventLoopGroup();
84
85 bootstrap.group(eventLoopGroup)
86 .channel(NioServerSocketChannel.class)
87 .childHandler(new XmppChannelInitializer(deviceFactory));
88
89 return bootstrap;
90 }
91
92 /**
93 * Initializes event loop group.
94 */
95 private void initEventLoopGroup() {
96
97 // try to use EpollEventLoopGroup if possible,
98 // if OS does not support native Epoll, fallback to use netty NIO
99 try {
100 eventLoopGroup = new EpollEventLoopGroup();
101 channelClass = EpollSocketChannel.class;
102 return;
103 } catch (Error e) {
104 log.debug("Failed to initialize native (epoll) transport. "
105 + "Reason: {}. Proceeding with NIO event group.", e);
106 }
107 eventLoopGroup = new NioEventLoopGroup();
108 channelClass = NioServerSocketChannel.class;
109 }
110
111 private void configureBootstrap(ServerBootstrap bootstrap) {
Tomek Osińskie9ccf412018-01-13 19:44:11 +0100112 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) {
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700128 String port = get(properties, XMPP_PORT);
Tomek Osińskie9ccf412018-01-13 19:44:11 +0100129 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}