com.spotify.ffwd.protocol.ProtocolServersImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.spotify.ffwd.protocol.ProtocolServersImpl.java

Source

/*-
 * -\-\-
 * FastForward Core
 * --
 * Copyright (C) 2016 - 2018 Spotify AB
 * --
 * 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 com.spotify.ffwd.protocol;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import eu.toolchain.async.AsyncFramework;
import eu.toolchain.async.AsyncFuture;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.Timer;
import org.slf4j.Logger;

public class ProtocolServersImpl implements ProtocolServers {
    @Inject
    private AsyncFramework async;

    @Inject
    @Named("boss")
    private EventLoopGroup boss;

    @Inject
    @Named("worker")
    private EventLoopGroup worker;

    @Inject
    private Timer timer;

    @Override
    public AsyncFuture<ProtocolConnection> bind(Logger log, Protocol protocol, ProtocolServer server,
            RetryPolicy policy) {
        if (protocol.getType() == ProtocolType.UDP) {
            return bindUDP(log, protocol, server, policy);
        }

        if (protocol.getType() == ProtocolType.TCP) {
            return bindTCP(log, protocol, server, policy);
        }

        throw new IllegalArgumentException("Unsupported protocol: " + protocol);
    }

    private AsyncFuture<ProtocolConnection> bindTCP(final Logger log, final Protocol protocol,
            ProtocolServer server, RetryPolicy policy) {
        final ServerBootstrap b = new ServerBootstrap();

        b.group(boss, worker);
        b.channel(NioServerSocketChannel.class);
        b.childHandler(server.initializer());

        b.option(ChannelOption.SO_BACKLOG, 128);

        if (protocol.getReceiveBufferSize() != null) {
            b.childOption(ChannelOption.SO_RCVBUF, protocol.getReceiveBufferSize());
        }

        b.childOption(ChannelOption.SO_KEEPALIVE, true);

        final String host = protocol.getAddress().getHostString();
        final int port = protocol.getAddress().getPort();

        final RetryingProtocolConnection connection = new RetryingProtocolConnection(async, timer, log, policy,
                new ProtocolChannelSetup() {
                    @Override
                    public ChannelFuture setup() {
                        return b.bind(host, port);
                    }

                    @Override
                    public String toString() {
                        return String.format("bind tcp://%s:%d", host, port);
                    }
                });

        return connection.getInitialFuture();
    }

    private AsyncFuture<ProtocolConnection> bindUDP(final Logger log, final Protocol protocol,
            ProtocolServer server, RetryPolicy policy) {
        final Bootstrap b = new Bootstrap();

        b.group(worker);
        b.channel(NioDatagramChannel.class);
        b.handler(server.initializer());

        if (protocol.getReceiveBufferSize() != null) {
            b.option(ChannelOption.SO_RCVBUF, protocol.getReceiveBufferSize());
        }

        final String host = protocol.getAddress().getHostString();
        final int port = protocol.getAddress().getPort();

        final RetryingProtocolConnection connection = new RetryingProtocolConnection(async, timer, log, policy,
                new ProtocolChannelSetup() {
                    @Override
                    public ChannelFuture setup() {
                        return b.bind(host, port);
                    }

                    @Override
                    public String toString() {
                        return String.format("bind tcp://%s:%d", host, port);
                    }
                });

        return connection.getInitialFuture();
    }
}