/* * Copyright 2014-2016 the original author or authors. * * 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.springframework.cloud.stream.module.websocket.sink; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Bootstraps a Netty server using the {@link WebsocketSinkServerInitializer}. Also adds * a {@link LoggingHandler} and uses the <tt>websocketLoglevel</tt> * from {@link WebsocketSinkProperties#websocketLoglevel}. * * @author Oliver Moser * @author Gary Russell */ public class WebsocketSinkServer { private static final Log logger = LogFactory.getLog(WebsocketSinkServer.class); static final List<Channel> channels = Collections.synchronizedList(new ArrayList<Channel>()); @Autowired WebsocketSinkProperties properties; @Autowired WebsocketSinkServerInitializer initializer; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; private int port; public int getPort() { return this.port; } @PostConstruct public void init() { bossGroup = new NioEventLoopGroup(properties.getThreads()); workerGroup = new NioEventLoopGroup(); } @PreDestroy public void shutdown() { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } public void run() throws InterruptedException { NioServerSocketChannel channel = (NioServerSocketChannel) new ServerBootstrap().group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(nettyLogLevel())) .childHandler(initializer) .bind(properties.getWebsocketPort()) .sync() .channel(); this.port = channel.localAddress().getPort(); dumpProperties(); } private void dumpProperties() { logger.info("███████████████████████████████████████████████████████████"); logger.info(" >> websocket-sink config << "); logger.info(""); logger.info(String.format("websocketPort: %s", this.port)); logger.info(String.format("ssl: %s", this.properties.isSsl())); logger.info(String.format("websocketPath: %s", this.properties.getWebsocketPath())); logger.info(String.format("websocketLoglevel: %s", this.properties.getWebsocketLoglevel())); logger.info(String.format("threads: %s", this.properties.getThreads())); logger.info(""); logger.info("████████████████████████████████████████████████████████████"); } // // HELPERS // private LogLevel nettyLogLevel() { return LogLevel.valueOf(properties.getWebsocketLoglevel().toUpperCase()); } }