org.jboss.aerogear.webpush.netty.WebPushNettyServer.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.aerogear.webpush.netty.WebPushNettyServer.java

Source

/**
 * JBoss, Home of Professional Open Source
 * Copyright Red Hat, Inc., and individual contributors.
 *
 * 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.jboss.aerogear.webpush.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http2.Http2SecurityUtil;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.ApplicationProtocolNames;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import org.jboss.aerogear.webpush.WebPushServerConfig;
import org.jboss.aerogear.webpush.datastore.DataStore;
import org.jboss.aerogear.webpush.datastore.InMemoryDataStore;
import org.jboss.aerogear.webpush.standalone.ConfigReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A HTTP/2 based WebPush Server.
 */
public final class WebPushNettyServer {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebPushNettyServer.class);
    private static final String DEFAULT_CONFIG = "/webpush-config.json";

    public static void main(final String[] args) throws Exception {
        final WebPushServerConfig config = readConfig(args);
        final DataStore inMemoryDataStore = new InMemoryDataStore();
        final SslContext sslCtx = createSslContext(config);

        final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        final EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            final ServerBootstrap b = new ServerBootstrap();
            b.option(ChannelOption.SO_BACKLOG, 1024).group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new WebPushChannelInitializer(sslCtx, inMemoryDataStore, config));
            final Channel ch = b.bind(config.host(), config.port()).sync().channel();
            LOGGER.info("WebPush server bound to {}:{}", config.host(), config.port());
            ch.closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static WebPushServerConfig readConfig(final String[] args) throws Exception {
        return ConfigReader.parse(args.length == 1 ? args[0] : DEFAULT_CONFIG);
    }

    private static SslContext createSslContext(final WebPushServerConfig config) throws Exception {
        if (config.useEndpointTls()) {
            return SslContextBuilder.forServer(config.cert(), config.privateKey()).sslProvider(SslProvider.JDK)
                    .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
                    .applicationProtocolConfig(new ApplicationProtocolConfig(protocol(config),
                            SelectorFailureBehavior.FATAL_ALERT, SelectedListenerFailureBehavior.FATAL_ALERT,
                            ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1))
                    .build();
        }
        return null;
    }

    private static Protocol protocol(final WebPushServerConfig config) {
        switch (config.protocol()) {
        case ALPN:
            return Protocol.ALPN;
        default:
            throw new IllegalStateException("Protocol not supported [" + config.protocol() + "]");
        }
    }
}