org.proton.plug.test.minimalserver.MinimalServer.java Source code

Java tutorial

Introduction

Here is the source code for org.proton.plug.test.minimalserver.MinimalServer.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.proton.plug.test.minimalserver;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.ResourceLeakDetector;
import io.netty.util.concurrent.GlobalEventExecutor;

import org.proton.plug.AMQPServerConnectionContext;
import org.proton.plug.context.server.ProtonServerConnectionContextFactory;
import org.proton.plug.test.Constants;

/**
 * A Netty TCP Acceptor that supports SSL
 */
public class MinimalServer {

    static {
        // Disable resource leak detection for performance reasons by default
        ResourceLeakDetector.setEnabled(false);
    }

    private Class<? extends ServerChannel> channelClazz;

    private EventLoopGroup eventLoopGroup;

    private volatile ChannelGroup serverChannelGroup;

    private volatile ChannelGroup channelGroup;

    private ServerBootstrap bootstrap;

    private String host;

    private boolean sasl;

    // Constants.PORT is the default here
    private int port;

    public synchronized void start(String host, int port, final boolean sasl) throws Exception {
        this.host = host;
        this.port = port;
        this.sasl = sasl;

        if (channelClazz != null) {
            // Already started
            return;
        }

        int threadsToUse = Runtime.getRuntime().availableProcessors() * 3;
        channelClazz = NioServerSocketChannel.class;
        eventLoopGroup = new NioEventLoopGroup(threadsToUse, new SimpleServerThreadFactory("simple-server", true,
                Thread.currentThread().getContextClassLoader()));

        bootstrap = new ServerBootstrap();
        bootstrap.group(eventLoopGroup);
        bootstrap.channel(channelClazz);

        ChannelInitializer<Channel> factory = new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(Channel channel) throws Exception {
                ChannelPipeline pipeline = channel.pipeline();
                pipeline.addLast("amqp-handler", new ProtocolDecoder());
            }
        };
        bootstrap.childHandler(factory);

        bootstrap.option(ChannelOption.SO_REUSEADDR, true).childOption(ChannelOption.SO_REUSEADDR, true)
                .childOption(ChannelOption.SO_KEEPALIVE, true).
                //       childOption(ChannelOption.AUTO_READ, false).
                childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

        channelGroup = new DefaultChannelGroup("activemq-accepted-channels", GlobalEventExecutor.INSTANCE);

        serverChannelGroup = new DefaultChannelGroup("activemq-acceptor-channels", GlobalEventExecutor.INSTANCE);

        SocketAddress address;
        address = new InetSocketAddress(host, port);
        Channel serverChannel = bootstrap.bind(address).syncUninterruptibly().channel();
        serverChannelGroup.add(serverChannel);

    }

    class ProtocolDecoder extends ByteToMessageDecoder {

        AMQPServerConnectionContext connection;

        public ProtocolDecoder() {
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            connection = ProtonServerConnectionContextFactory.getFactory()
                    .createConnection(new MinimalConnectionSPI(ctx.channel()));
            //ctx.read();
        }

        @Override
        protected void decode(final ChannelHandlerContext ctx, ByteBuf byteIn, List<Object> out) throws Exception {
            connection.inputBuffer(byteIn);
            ctx.flush();
            //         if (connection.capacity() > 0)
            //         {
            //            ctx.read();
            //         }
        }
    }

    public synchronized void stop() {
        if (serverChannelGroup != null) {
            serverChannelGroup.close().awaitUninterruptibly();
        }

        if (channelGroup != null) {
            ChannelGroupFuture future = channelGroup.close().awaitUninterruptibly();
        }
    }

    public static void main(String[] arg) {
        MinimalServer server = new MinimalServer();
        try {
            server.start("127.0.0.1", Constants.PORT, true);

            while (true) {
                Thread.sleep(360000000);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}